1 /* $OpenBSD: ata_wdc.c,v 1.33 2009/01/21 21:53:59 grange Exp $ */ 2 /* $NetBSD: ata_wdc.c,v 1.21 1999/08/09 09:43:11 bouyer Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 2001 Manuel Bouyer. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Manuel Bouyer. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 */ 34 35 /*- 36 * Copyright (c) 1998 The NetBSD Foundation, Inc. 37 * All rights reserved. 38 * 39 * This code is derived from software contributed to The NetBSD Foundation 40 * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 52 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 #include <sys/param.h> 65 #include <sys/systm.h> 66 #include <sys/kernel.h> 67 #include <sys/file.h> 68 #include <sys/stat.h> 69 #include <sys/buf.h> 70 #include <sys/malloc.h> 71 #include <sys/device.h> 72 #include <sys/disklabel.h> 73 #include <sys/syslog.h> 74 #include <sys/proc.h> 75 76 #include <machine/intr.h> 77 #include <machine/bus.h> 78 79 #include <dev/ata/atareg.h> 80 #include <dev/ata/atavar.h> 81 #include <dev/ic/wdcreg.h> 82 #include <dev/ic/wdcvar.h> 83 #include <dev/ata/wdvar.h> 84 85 #define DEBUG_INTR 0x01 86 #define DEBUG_XFERS 0x02 87 #define DEBUG_STATUS 0x04 88 #define DEBUG_FUNCS 0x08 89 #define DEBUG_PROBE 0x10 90 91 #ifdef WDCDEBUG 92 #ifndef WDCDEBUG_WD_MASK 93 #define WDCDEBUG_WD_MASK 0x00 94 #endif 95 int wdcdebug_wd_mask = WDCDEBUG_WD_MASK; 96 #define WDCDEBUG_PRINT(args, level) do { \ 97 if ((wdcdebug_wd_mask & (level)) != 0) \ 98 printf args; \ 99 } while (0) 100 #else 101 #define WDCDEBUG_PRINT(args, level) 102 #endif 103 104 #define ATA_DELAY 10000 /* 10s for a drive I/O */ 105 106 struct cfdriver wdc_cd = { 107 NULL, "wdc", DV_DULL 108 }; 109 110 void wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *); 111 void _wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *); 112 int wdc_ata_bio_intr(struct channel_softc *, struct wdc_xfer *, int); 113 void wdc_ata_bio_kill_xfer(struct channel_softc *, struct wdc_xfer *); 114 void wdc_ata_bio_done(struct channel_softc *, struct wdc_xfer *); 115 int wdc_ata_ctrl_intr(struct channel_softc *, struct wdc_xfer *, int); 116 int wdc_ata_err(struct ata_drive_datas *, struct ata_bio *); 117 #define WDC_ATA_NOERR 0x00 /* Drive doesn't report an error */ 118 #define WDC_ATA_RECOV 0x01 /* There was a recovered error */ 119 #define WDC_ATA_ERR 0x02 /* Drive reports an error */ 120 121 /* 122 * Handle block I/O operation. Return WDC_COMPLETE, WDC_QUEUED, or 123 * WDC_TRY_AGAIN. Must be called at splbio(). 124 */ 125 int 126 wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio) 127 { 128 struct wdc_xfer *xfer; 129 struct channel_softc *chp = drvp->chnl_softc; 130 131 xfer = wdc_get_xfer(WDC_NOSLEEP); 132 if (xfer == NULL) 133 return WDC_TRY_AGAIN; 134 if (ata_bio->flags & ATA_POLL) 135 xfer->c_flags |= C_POLL; 136 if (!(ata_bio->flags & ATA_POLL) && 137 (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) && 138 (ata_bio->flags & ATA_SINGLE) == 0 && 139 (ata_bio->bcount > 512 || 140 (chp->wdc->quirks & WDC_QUIRK_NOSHORTDMA) == 0)) 141 xfer->c_flags |= C_DMA; 142 xfer->drive = drvp->drive; 143 xfer->cmd = ata_bio; 144 xfer->databuf = ata_bio->databuf; 145 xfer->c_bcount = ata_bio->bcount; 146 xfer->c_start = wdc_ata_bio_start; 147 xfer->c_intr = wdc_ata_bio_intr; 148 xfer->c_kill_xfer = wdc_ata_bio_kill_xfer; 149 wdc_exec_xfer(chp, xfer); 150 return (ata_bio->flags & ATA_ITSDONE) ? WDC_COMPLETE : WDC_QUEUED; 151 } 152 153 void 154 wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer) 155 { 156 struct ata_bio *ata_bio = xfer->cmd; 157 WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n", 158 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), 159 DEBUG_XFERS); 160 161 /* start timeout machinery */ 162 if ((ata_bio->flags & ATA_POLL) == 0) 163 timeout_add_msec(&chp->ch_timo, ATA_DELAY); 164 _wdc_ata_bio_start(chp, xfer); 165 } 166 167 void 168 _wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer) 169 { 170 struct ata_bio *ata_bio = xfer->cmd; 171 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive]; 172 u_int16_t cyl; 173 u_int8_t head, sect, cmd = 0; 174 int nblks; 175 int ata_delay; 176 int dma_flags = 0; 177 178 WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n", 179 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), 180 DEBUG_INTR | DEBUG_XFERS); 181 /* Do control operations specially. */ 182 if (drvp->state < READY) { 183 /* 184 * Actually, we want to be careful not to mess with the control 185 * state if the device is currently busy, but we can assume 186 * that we never get to this point if that's the case. 187 */ 188 /* at this point, we should only be in RECAL state */ 189 if (drvp->state != RECAL) { 190 printf("%s:%d:%d: bad state %d in _wdc_ata_bio_start\n", 191 chp->wdc->sc_dev.dv_xname, chp->channel, 192 xfer->drive, drvp->state); 193 panic("_wdc_ata_bio_start: bad state"); 194 } 195 xfer->c_intr = wdc_ata_ctrl_intr; 196 wdc_set_drive(chp, xfer->drive); 197 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY) != 0) 198 goto timeout; 199 wdccommandshort(chp, xfer->drive, WDCC_RECAL); 200 drvp->state = RECAL_WAIT; 201 if ((ata_bio->flags & ATA_POLL) == 0) { 202 chp->ch_flags |= WDCF_IRQ_WAIT; 203 } else { 204 /* Wait for at last 400ns for status bit to be valid */ 205 DELAY(1); 206 wdc_ata_ctrl_intr(chp, xfer, 0); 207 } 208 return; 209 } 210 211 if (xfer->c_flags & C_DMA) { 212 if (drvp->n_xfers <= NXFER) 213 drvp->n_xfers++; 214 dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0; 215 if (ata_bio->flags & ATA_LBA48) 216 dma_flags |= WDC_DMA_LBA48; 217 } 218 if (ata_bio->flags & ATA_SINGLE) 219 ata_delay = ATA_DELAY; 220 else 221 ata_delay = ATA_DELAY; 222 again: 223 /* 224 * 225 * When starting a multi-sector transfer, or doing single-sector 226 * transfers... 227 */ 228 if (xfer->c_skip == 0 || (ata_bio->flags & ATA_SINGLE) != 0) { 229 if (ata_bio->flags & ATA_SINGLE) 230 nblks = 1; 231 else 232 nblks = xfer->c_bcount / ata_bio->lp->d_secsize; 233 if (ata_bio->flags & ATA_LBA) { 234 sect = (ata_bio->blkno >> 0) & 0xff; 235 cyl = (ata_bio->blkno >> 8) & 0xffff; 236 head = (ata_bio->blkno >> 24) & 0x0f; 237 head |= WDSD_LBA; 238 } else { 239 int blkno = ata_bio->blkno; 240 sect = blkno % ata_bio->lp->d_nsectors; 241 sect++; /* Sectors begin with 1, not 0. */ 242 blkno /= ata_bio->lp->d_nsectors; 243 head = blkno % ata_bio->lp->d_ntracks; 244 blkno /= ata_bio->lp->d_ntracks; 245 cyl = blkno; 246 head |= WDSD_CHS; 247 } 248 if (xfer->c_flags & C_DMA) { 249 ata_bio->nblks = nblks; 250 ata_bio->nbytes = xfer->c_bcount; 251 if (ata_bio->flags & ATA_LBA48) 252 cmd = (ata_bio->flags & ATA_READ) ? 253 WDCC_READDMA_EXT : WDCC_WRITEDMA_EXT; 254 else 255 cmd = (ata_bio->flags & ATA_READ) ? 256 WDCC_READDMA : WDCC_WRITEDMA; 257 /* Init the DMA channel. */ 258 if ((*chp->wdc->dma_init)(chp->wdc->dma_arg, 259 chp->channel, xfer->drive, 260 (char *)xfer->databuf + xfer->c_skip, 261 ata_bio->nbytes, dma_flags) != 0) { 262 ata_bio->error = ERR_DMA; 263 ata_bio->r_error = 0; 264 wdc_ata_bio_done(chp, xfer); 265 return; 266 } 267 /* Initiate command */ 268 wdc_set_drive(chp, xfer->drive); 269 if (wait_for_ready(chp, ata_delay) < 0) 270 goto timeout; 271 if (ata_bio->flags & ATA_LBA48) { 272 wdccommandext(chp, xfer->drive, cmd, 273 (u_int64_t)ata_bio->blkno, nblks); 274 } else { 275 wdccommand(chp, xfer->drive, cmd, cyl, 276 head, sect, nblks, 0); 277 } 278 /* start the DMA channel */ 279 (*chp->wdc->dma_start)(chp->wdc->dma_arg, 280 chp->channel, xfer->drive); 281 chp->ch_flags |= WDCF_DMA_WAIT; 282 /* wait for irq */ 283 goto intr; 284 } /* else not DMA */ 285 ata_bio->nblks = min(nblks, ata_bio->multi); 286 ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize; 287 KASSERT(nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0); 288 if (ata_bio->nblks > 1) { 289 if (ata_bio->flags & ATA_LBA48) 290 cmd = (ata_bio->flags & ATA_READ) ? 291 WDCC_READMULTI_EXT : WDCC_WRITEMULTI_EXT; 292 else 293 cmd = (ata_bio->flags & ATA_READ) ? 294 WDCC_READMULTI : WDCC_WRITEMULTI; 295 } else { 296 if (ata_bio->flags & ATA_LBA48) 297 cmd = (ata_bio->flags & ATA_READ) ? 298 WDCC_READ_EXT : WDCC_WRITE_EXT; 299 else 300 cmd = (ata_bio->flags & ATA_READ) ? 301 WDCC_READ : WDCC_WRITE; 302 } 303 /* Initiate command! */ 304 wdc_set_drive(chp, xfer->drive); 305 if (wait_for_ready(chp, ata_delay) < 0) 306 goto timeout; 307 if (ata_bio->flags & ATA_LBA48) { 308 wdccommandext(chp, xfer->drive, cmd, 309 (u_int64_t)ata_bio->blkno, nblks); 310 } else { 311 wdccommand(chp, xfer->drive, cmd, cyl, 312 head, sect, nblks, 313 (ata_bio->lp->d_type == DTYPE_ST506) ? 314 ata_bio->lp->d_precompcyl / 4 : 0); 315 } 316 } else if (ata_bio->nblks > 1) { 317 /* The number of blocks in the last stretch may be smaller. */ 318 nblks = xfer->c_bcount / ata_bio->lp->d_secsize; 319 if (ata_bio->nblks > nblks) { 320 ata_bio->nblks = nblks; 321 ata_bio->nbytes = xfer->c_bcount; 322 } 323 } 324 /* If this was a write and not using DMA, push the data. */ 325 if ((ata_bio->flags & ATA_READ) == 0) { 326 if (wait_for_drq(chp, ata_delay) != 0) { 327 printf("%s:%d:%d: timeout waiting for DRQ, " 328 "st=0x%b, err=0x%02x\n", 329 chp->wdc->sc_dev.dv_xname, chp->channel, 330 xfer->drive, chp->ch_status, WDCS_BITS, 331 chp->ch_error); 332 if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR) 333 ata_bio->error = TIMEOUT; 334 wdc_ata_bio_done(chp, xfer); 335 return; 336 } 337 if (wdc_ata_err(drvp, ata_bio) == WDC_ATA_ERR) { 338 wdc_ata_bio_done(chp, xfer); 339 return; 340 } 341 wdc_output_bytes(drvp, (char *)xfer->databuf + xfer->c_skip, 342 ata_bio->nbytes); 343 } 344 345 intr: /* Wait for IRQ (either real or polled) */ 346 if ((ata_bio->flags & ATA_POLL) == 0) { 347 chp->ch_flags |= WDCF_IRQ_WAIT; 348 } else { 349 /* Wait for at last 400ns for status bit to be valid */ 350 delay(1); 351 if (chp->ch_flags & WDCF_DMA_WAIT) { 352 wdc_dmawait(chp, xfer, ATA_DELAY); 353 chp->ch_flags &= ~WDCF_DMA_WAIT; 354 } 355 wdc_ata_bio_intr(chp, xfer, 0); 356 if ((ata_bio->flags & ATA_ITSDONE) == 0) 357 goto again; 358 } 359 return; 360 timeout: 361 printf("%s:%d:%d: not ready, st=0x%b, err=0x%02x\n", 362 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, 363 chp->ch_status, WDCS_BITS, chp->ch_error); 364 if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR) 365 ata_bio->error = TIMEOUT; 366 wdc_ata_bio_done(chp, xfer); 367 return; 368 } 369 370 int 371 wdc_ata_bio_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq) 372 { 373 struct ata_bio *ata_bio = xfer->cmd; 374 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive]; 375 int drv_err; 376 377 WDCDEBUG_PRINT(("wdc_ata_bio_intr %s:%d:%d\n", 378 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), 379 DEBUG_INTR | DEBUG_XFERS); 380 381 382 /* Is it not a transfer, but a control operation? */ 383 if (drvp->state < READY) { 384 printf("%s:%d:%d: bad state %d in wdc_ata_bio_intr\n", 385 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, 386 drvp->state); 387 panic("wdc_ata_bio_intr: bad state"); 388 } 389 390 /* 391 * reset on timeout. This will cause extra resets in the case 392 * of occasional lost interrupts 393 */ 394 if (xfer->c_flags & C_TIMEOU) 395 goto timeout; 396 397 /* Ack interrupt done by wait_for_unbusy */ 398 if (wait_for_unbusy(chp, 399 (irq == 0) ? ATA_DELAY : 0) < 0) { 400 if (irq) 401 return 0; /* IRQ was not for us */ 402 printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n", 403 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, 404 xfer->c_bcount, xfer->c_skip); 405 406 goto timeout; 407 } 408 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK) 409 chp->wdc->irqack(chp); 410 411 drv_err = wdc_ata_err(drvp, ata_bio); 412 413 if (xfer->c_flags & C_DMA) { 414 if (chp->wdc->dma_status != 0) { 415 if (drv_err != WDC_ATA_ERR) { 416 ata_bio->error = ERR_DMA; 417 drv_err = WDC_ATA_ERR; 418 } 419 } 420 if (chp->ch_status & WDCS_DRQ) { 421 if (drv_err != WDC_ATA_ERR) { 422 printf("%s:%d:%d: intr with DRQ (st=0x%b)\n", 423 chp->wdc->sc_dev.dv_xname, chp->channel, 424 xfer->drive, chp->ch_status, WDCS_BITS); 425 ata_bio->error = TIMEOUT; 426 drv_err = WDC_ATA_ERR; 427 } 428 } 429 if (drv_err != WDC_ATA_ERR) 430 goto end; 431 ata_dmaerr(drvp); 432 } 433 434 /* if we had an error, end */ 435 if (drv_err == WDC_ATA_ERR) { 436 wdc_ata_bio_done(chp, xfer); 437 return 1; 438 } 439 440 /* If this was a read and not using DMA, fetch the data. */ 441 if ((ata_bio->flags & ATA_READ) != 0) { 442 if ((chp->ch_status & WDCS_DRQ) != WDCS_DRQ) { 443 printf("%s:%d:%d: read intr before drq\n", 444 chp->wdc->sc_dev.dv_xname, chp->channel, 445 xfer->drive); 446 ata_bio->error = TIMEOUT; 447 wdc_ata_bio_done(chp, xfer); 448 return 1; 449 } 450 wdc_input_bytes(drvp, (char *)xfer->databuf + xfer->c_skip, 451 ata_bio->nbytes); 452 } 453 end: 454 ata_bio->blkno += ata_bio->nblks; 455 ata_bio->blkdone += ata_bio->nblks; 456 xfer->c_skip += ata_bio->nbytes; 457 xfer->c_bcount -= ata_bio->nbytes; 458 /* See if this transfer is complete. */ 459 if (xfer->c_bcount > 0) { 460 if ((ata_bio->flags & ATA_POLL) == 0) { 461 /* Start the next operation */ 462 _wdc_ata_bio_start(chp, xfer); 463 } else { 464 /* Let _wdc_ata_bio_start do the loop */ 465 return 1; 466 } 467 } else { /* Done with this transfer */ 468 ata_bio->error = NOERROR; 469 wdc_ata_bio_done(chp, xfer); 470 } 471 return 1; 472 473 timeout: 474 if (xfer->c_flags & C_DMA) 475 ata_dmaerr(drvp); 476 477 ata_bio->error = TIMEOUT; 478 wdc_ata_bio_done(chp, xfer); 479 return 1; 480 } 481 482 void 483 wdc_ata_bio_kill_xfer(struct channel_softc *chp, struct wdc_xfer *xfer) 484 { 485 struct ata_bio *ata_bio = xfer->cmd; 486 487 timeout_del(&chp->ch_timo); 488 /* remove this command from xfer queue */ 489 wdc_free_xfer(chp, xfer); 490 491 ata_bio->flags |= ATA_ITSDONE; 492 ata_bio->error = ERR_NODEV; 493 ata_bio->r_error = WDCE_ABRT; 494 if ((ata_bio->flags & ATA_POLL) == 0) { 495 WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS); 496 wddone(ata_bio->wd); 497 } 498 } 499 500 void 501 wdc_ata_bio_done(struct channel_softc *chp, struct wdc_xfer *xfer) 502 { 503 struct ata_bio *ata_bio = xfer->cmd; 504 505 WDCDEBUG_PRINT(("wdc_ata_bio_done %s:%d:%d: flags 0x%x\n", 506 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, 507 (u_int)xfer->c_flags), 508 DEBUG_XFERS); 509 510 timeout_del(&chp->ch_timo); 511 512 /* feed back residual bcount to our caller */ 513 ata_bio->bcount = xfer->c_bcount; 514 515 /* remove this command from xfer queue */ 516 wdc_free_xfer(chp, xfer); 517 518 ata_bio->flags |= ATA_ITSDONE; 519 if ((ata_bio->flags & ATA_POLL) == 0) { 520 WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS); 521 wddone(ata_bio->wd); 522 } 523 WDCDEBUG_PRINT(("wdcstart from wdc_ata_done, flags 0x%x\n", 524 chp->ch_flags), DEBUG_XFERS); 525 wdcstart(chp); 526 } 527 528 /* 529 * Implement operations needed before read/write. 530 */ 531 int 532 wdc_ata_ctrl_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq) 533 { 534 struct ata_bio *ata_bio = xfer->cmd; 535 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive]; 536 char *errstring = NULL; 537 int delay = (irq == 0) ? ATA_DELAY : 0; 538 539 WDCDEBUG_PRINT(("wdc_ata_ctrl_intr: state %d\n", drvp->state), 540 DEBUG_FUNCS); 541 542 again: 543 switch (drvp->state) { 544 case RECAL: /* Should not be in this state here */ 545 panic("wdc_ata_ctrl_intr: state==RECAL"); 546 break; 547 548 case RECAL_WAIT: 549 errstring = "recal"; 550 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)) 551 goto timeout; 552 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK) 553 chp->wdc->irqack(chp); 554 if (chp->ch_status & (WDCS_ERR | WDCS_DWF)) 555 goto error; 556 /* FALLTHROUGH */ 557 558 case PIOMODE: 559 /* Don't try to set modes if controller can't be adjusted */ 560 if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0) 561 goto geometry; 562 /* Also don't try if the drive didn't report its mode */ 563 if ((drvp->drive_flags & DRIVE_MODE) == 0) 564 goto geometry; 565 /* SET FEATURES 0x08 is only for PIO mode > 2 */ 566 if (drvp->PIO_mode <= 2) 567 goto geometry; 568 wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 569 0x08 | drvp->PIO_mode, WDSF_SET_MODE); 570 drvp->state = PIOMODE_WAIT; 571 break; 572 573 case PIOMODE_WAIT: 574 errstring = "piomode"; 575 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)) 576 goto timeout; 577 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK) 578 chp->wdc->irqack(chp); 579 if (chp->ch_status & (WDCS_ERR | WDCS_DWF)) 580 goto error; 581 /* FALLTHROUGH */ 582 583 case DMAMODE: 584 if (drvp->drive_flags & DRIVE_UDMA) { 585 wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 586 0x40 | drvp->UDMA_mode, WDSF_SET_MODE); 587 } else if (drvp->drive_flags & DRIVE_DMA) { 588 wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 589 0x20 | drvp->DMA_mode, WDSF_SET_MODE); 590 } else { 591 goto geometry; 592 } 593 drvp->state = DMAMODE_WAIT; 594 break; 595 case DMAMODE_WAIT: 596 errstring = "dmamode"; 597 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)) 598 goto timeout; 599 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK) 600 chp->wdc->irqack(chp); 601 if (chp->ch_status & (WDCS_ERR | WDCS_DWF)) 602 goto error; 603 /* FALLTHROUGH */ 604 605 case GEOMETRY: 606 geometry: 607 if (ata_bio->flags & ATA_LBA) 608 goto multimode; 609 wdccommand(chp, xfer->drive, WDCC_IDP, 610 ata_bio->lp->d_ncylinders, 611 ata_bio->lp->d_ntracks - 1, 0, ata_bio->lp->d_nsectors, 612 (ata_bio->lp->d_type == DTYPE_ST506) ? 613 ata_bio->lp->d_precompcyl / 4 : 0); 614 drvp->state = GEOMETRY_WAIT; 615 break; 616 617 case GEOMETRY_WAIT: 618 errstring = "geometry"; 619 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)) 620 goto timeout; 621 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK) 622 chp->wdc->irqack(chp); 623 if (chp->ch_status & (WDCS_ERR | WDCS_DWF)) 624 goto error; 625 /* FALLTHROUGH */ 626 627 case MULTIMODE: 628 multimode: 629 if (ata_bio->multi == 1) 630 goto ready; 631 wdccommand(chp, xfer->drive, WDCC_SETMULTI, 0, 0, 0, 632 ata_bio->multi, 0); 633 drvp->state = MULTIMODE_WAIT; 634 break; 635 636 case MULTIMODE_WAIT: 637 errstring = "setmulti"; 638 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)) 639 goto timeout; 640 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK) 641 chp->wdc->irqack(chp); 642 if (chp->ch_status & (WDCS_ERR | WDCS_DWF)) 643 goto error; 644 /* FALLTHROUGH */ 645 646 case READY: 647 ready: 648 drvp->state = READY; 649 /* 650 * The drive is usable now 651 */ 652 xfer->c_intr = wdc_ata_bio_intr; 653 _wdc_ata_bio_start(chp, xfer); 654 return 1; 655 } 656 657 if ((ata_bio->flags & ATA_POLL) == 0) { 658 chp->ch_flags |= WDCF_IRQ_WAIT; 659 } else { 660 goto again; 661 } 662 return 1; 663 664 timeout: 665 if (irq && (xfer->c_flags & C_TIMEOU) == 0) { 666 return 0; /* IRQ was not for us */ 667 } 668 printf("%s:%d:%d: %s timed out\n", 669 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring); 670 ata_bio->error = TIMEOUT; 671 drvp->state = 0; 672 wdc_ata_bio_done(chp, xfer); 673 return 0; 674 error: 675 printf("%s:%d:%d: %s ", 676 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, 677 errstring); 678 if (chp->ch_status & WDCS_DWF) { 679 printf("drive fault\n"); 680 ata_bio->error = ERR_DF; 681 } else { 682 printf("error (%x)\n", chp->ch_error); 683 ata_bio->r_error = chp->ch_error; 684 ata_bio->error = ERROR; 685 } 686 drvp->state = 0; 687 wdc_ata_bio_done(chp, xfer); 688 return 1; 689 } 690 691 int 692 wdc_ata_err(struct ata_drive_datas *drvp, struct ata_bio *ata_bio) 693 { 694 struct channel_softc *chp = drvp->chnl_softc; 695 ata_bio->error = 0; 696 if (chp->ch_status & WDCS_BSY) { 697 ata_bio->error = TIMEOUT; 698 return WDC_ATA_ERR; 699 } 700 701 if (chp->ch_status & WDCS_DWF) { 702 ata_bio->error = ERR_DF; 703 return WDC_ATA_ERR; 704 } 705 706 if (chp->ch_status & WDCS_ERR) { 707 ata_bio->error = ERROR; 708 ata_bio->r_error = chp->ch_error; 709 if (drvp->drive_flags & DRIVE_UDMA && 710 (ata_bio->r_error & WDCE_CRC)) { 711 /* 712 * Record the CRC error, to avoid downgrading to 713 * multiword DMA 714 */ 715 drvp->drive_flags |= DRIVE_DMAERR; 716 } 717 if (ata_bio->r_error & (WDCE_BBK | WDCE_UNC | WDCE_IDNF | 718 WDCE_ABRT | WDCE_TK0NF | WDCE_AMNF)) 719 return WDC_ATA_ERR; 720 return WDC_ATA_NOERR; 721 } 722 723 if (chp->ch_status & WDCS_CORR) 724 ata_bio->flags |= ATA_CORR; 725 return WDC_ATA_NOERR; 726 } 727 728 #if 0 729 int 730 wdc_ata_addref(drvp) 731 struct ata_drive_datas *drvp; 732 { 733 struct channel_softc *chp = drvp->chnl_softc; 734 735 return (wdc_addref(chp)); 736 } 737 738 void 739 wdc_ata_delref(drvp) 740 struct ata_drive_datas *drvp; 741 { 742 struct channel_softc *chp = drvp->chnl_softc; 743 744 wdc_delref(chp); 745 } 746 #endif 747