1 /* $NetBSD: wdc.c,v 1.10 1998/01/07 08:47:54 mikel Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. 5 * 6 * DMA and multi-sector PIO handling are derived from code contributed by 7 * Onno van der Linden. 8 * 9 * Atapi support added by Manuel Bouyer. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by Charles M. Hannum. 22 * 4. The name of the author may not be used to endorse or promote products 23 * derived from this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/conf.h> 41 #include <sys/file.h> 42 #include <sys/stat.h> 43 #include <sys/ioctl.h> 44 #include <sys/buf.h> 45 #include <sys/uio.h> 46 #include <sys/malloc.h> 47 #include <sys/device.h> 48 #include <sys/disklabel.h> 49 #include <sys/disk.h> 50 #include <sys/syslog.h> 51 #include <sys/proc.h> 52 53 #include <vm/vm.h> 54 55 #include <machine/cpu.h> 56 #include <machine/intr.h> 57 #include <machine/bus.h> 58 #include <machine/pio.h> 59 60 #include <dev/isa/isavar.h> 61 #include <dev/isa/isadmavar.h> 62 #include <dev/isa/wdreg.h> 63 #include <dev/isa/wdlink.h> 64 #include "atapibus.h" 65 #include "wd.h" 66 67 #if NATAPIBUS > 0 68 #include <dev/scsipi/scsipi_all.h> 69 #include <dev/scsipi/atapiconf.h> 70 #endif 71 72 #define WAITTIME (10 * hz) /* time to wait for a completion */ 73 /* this is a lot for hard drives, but not for cdroms */ 74 #define RECOVERYTIME hz/2 75 #define WDCDELAY 100 76 #define WDCNDELAY 100000 /* delay = 100us; so 10s for a controller state change */ 77 #if 0 78 /* If you enable this, it will report any delays more than 100us * N long. */ 79 #define WDCNDELAY_DEBUG 50 80 #endif 81 82 #define WDIORETRIES 5 /* number of retries before giving up */ 83 84 #define WDPART(dev) DISKPART(dev) 85 86 LIST_HEAD(xfer_free_list, wdc_xfer) xfer_free_list; 87 88 int wdcprobe __P((struct device *, void *, void *)); 89 void wdcattach __P((struct device *, struct device *, void *)); 90 int wdcintr __P((void *)); 91 92 struct cfattach wdc_ca = { 93 sizeof(struct wdc_softc), wdcprobe, wdcattach 94 }; 95 96 struct cfdriver wdc_cd = { 97 NULL, "wdc", DV_DULL 98 }; 99 100 void wdcstart __P((struct wdc_softc *)); 101 int wdcreset __P((struct wdc_softc *, int)); 102 #define VERBOSE 1 103 #define SILENT 0 104 void wdcrestart __P((void *arg)); 105 void wdcunwedge __P((struct wdc_softc *)); 106 void wdctimeout __P((void *arg)); 107 int wdccontrol __P((struct wdc_softc*, struct wd_link *)); 108 void wdc_free_xfer __P((struct wdc_xfer *)); 109 void wdcerror __P((struct wdc_softc*, char *)); 110 void wdcbit_bucket __P(( struct wdc_softc *, int)); 111 #if NWD > 0 112 int wdprint __P((void *, const char *)); 113 int wdsetctlr __P((struct wd_link *)); 114 int wdc_ata_intr __P((struct wdc_softc *,struct wdc_xfer *)); 115 void wdc_ata_start __P((struct wdc_softc *,struct wdc_xfer *)); 116 void wdc_ata_done __P((struct wdc_softc *, struct wdc_xfer *)); 117 #endif /* NWD > 0 */ 118 #if NATAPIBUS > 0 119 void wdc_atapi_minphys __P((struct buf *bp)); 120 void wdc_atapi_start __P((struct wdc_softc *,struct wdc_xfer *)); 121 int wdc_atapi_intr __P((struct wdc_softc *, struct wdc_xfer *)); 122 void wdc_atapi_done __P((struct wdc_softc *, struct wdc_xfer *)); 123 int wdc_atapi_send_command_packet __P((struct scsipi_xfer *sc_xfer)); 124 #define MAX_SIZE MAXPHYS /* XXX */ 125 #endif 126 127 #ifdef ATAPI_DEBUG2 128 static int wdc_nxfer; 129 #endif 130 131 #ifdef WDDEBUG 132 #define WDDEBUG_PRINT(args) printf args 133 #else 134 #define WDDEBUG_PRINT(args) 135 #endif 136 137 #if NATAPIBUS > 0 138 static struct scsipi_adapter wdc_switch = { 139 wdc_atapi_send_command_packet, 140 wdc_atapi_minphys, 141 0, 142 0 143 }; 144 #endif 145 146 int 147 wdcprobe(parent, match, aux) 148 struct device *parent; 149 void *match, *aux; 150 { 151 struct wdc_softc *wdc = match; 152 struct isa_attach_args *ia = aux; 153 int iobase; 154 155 wdc->sc_iobase = iobase = ia->ia_iobase; 156 157 if (wdcreset(wdc, SILENT) != 0) { 158 /* 159 * if the reset failed, there is no master. test for ATAPI signature 160 * on the slave device. If no ATAPI slave, wait 5s and retry a reset. 161 */ 162 outb(iobase+wd_sdh, WDSD_IBM | 0x10); /* slave */ 163 if (inb(iobase + wd_cyl_lo) == 0x14 && 164 inb(iobase + wd_cyl_hi) == 0xeb) { 165 wdc->sc_flags |= WDCF_ONESLAVE; 166 goto drivefound; 167 } else { 168 delay(500000); 169 if (wdcreset(wdc, SILENT) != 0) 170 return 0; 171 } 172 } 173 delay(1000); 174 /* reset succeeded. Test registers */ 175 if (inb(iobase + wd_cyl_lo) == 0x14 && 176 inb(iobase + wd_cyl_hi) == 0xeb) 177 goto drivefound; 178 /* not ATAPI. Test registers */ 179 outb(iobase+wd_error, 0x58); /* Error register not writable, */ 180 outb(iobase+wd_cyl_lo, 0xa5); /* but all of cyllo are. */ 181 if (inb(iobase+wd_error) != 0x58 && inb(iobase+wd_cyl_lo) == 0xa5) 182 goto drivefound; 183 /* No master. Test atapi signature on slave */ 184 outb(iobase+wd_sdh, WDSD_IBM | 0x10); 185 if (inb(iobase + wd_cyl_lo) == 0x14 && 186 inb(iobase + wd_cyl_hi) == 0xeb) { 187 wdc->sc_flags |= WDCF_ONESLAVE; 188 goto drivefound; 189 } 190 return 0; 191 drivefound: 192 /* Select drive 0 or ATAPI slave device */ 193 if (wdc->sc_flags & WDCF_ONESLAVE) 194 outb(iobase+wd_sdh, WDSD_IBM | 0x10); 195 else 196 outb(iobase+wd_sdh, WDSD_IBM); 197 198 /* Wait for controller to become ready. */ 199 if (wait_for_unbusy(wdc) < 0) 200 return 0; 201 202 /* Start drive diagnostics. */ 203 outb(iobase+wd_command, WDCC_DIAGNOSE); 204 205 /* Wait for command to complete. */ 206 if (wait_for_unbusy(wdc) < 0) 207 return 0; 208 209 ia->ia_iosize = 8; 210 ia->ia_msize = 0; 211 return 1; 212 } 213 214 void 215 wdcattach(parent, self, aux) 216 struct device *parent, *self; 217 void *aux; 218 { 219 struct wdc_softc *wdc = (void *)self; 220 struct isa_attach_args *ia = aux; 221 #if NWD > 0 222 int drive; 223 #endif 224 225 TAILQ_INIT(&wdc->sc_xfer); 226 wdc->sc_drq = ia->ia_drq; 227 228 printf("\n"); 229 if (wdc->sc_drq != -1) { 230 if (isa_dmamap_create(parent, wdc->sc_drq, MAXPHYS, 231 BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 232 printf("%s: can't create map for drq %d\n", 233 wdc->sc_dev.dv_xname, wdc->sc_drq); 234 wdc->sc_drq = -1; 235 } 236 } 237 238 wdc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 239 IPL_BIO, wdcintr, wdc); 240 241 #ifdef ATAPI_DEBUG2 242 wdc_nxfer = 0; 243 #endif 244 245 #if NATAPIBUS > 0 246 /* 247 * Attach an ATAPI bus, if configured. 248 */ 249 wdc->ab_link = malloc(sizeof(struct scsipi_link), M_DEVBUF, M_NOWAIT); 250 if (wdc->ab_link == NULL) { 251 printf("%s: can't allocate ATAPI link\n", self->dv_xname); 252 return; 253 } 254 bzero(wdc->ab_link,sizeof(struct scsipi_link)); 255 wdc->ab_link->type = BUS_ATAPI; 256 wdc->ab_link->openings = 1; 257 wdc->ab_link->scsipi_atapi.type = ATAPI; 258 wdc->ab_link->scsipi_atapi.channel = 0; 259 wdc->ab_link->adapter_softc = (caddr_t)wdc; 260 wdc->ab_link->adapter = &wdc_switch; 261 (void)config_found(self, (void *)wdc->ab_link, NULL); 262 #endif /* NATAPIBUS > 0 */ 263 #if NWD > 0 264 /* 265 * Attach standard IDE/ESDI/etc. disks to the controller. 266 */ 267 for (drive = 0; drive < 2; drive++) { 268 /* if a disk is already present, skip */ 269 if ((wdc->sc_drives_mask & (1 << drive)) != 0) { 270 continue; 271 } 272 /* controller active while autoconf */ 273 wdc->sc_flags |= WDCF_ACTIVE; 274 275 if (wdccommandshort(wdc, drive, WDCC_RECAL) != 0 || 276 wait_for_ready(wdc) != 0) { 277 wdc->d_link[drive] = NULL; 278 wdc->sc_flags &= ~WDCF_ACTIVE; 279 } else { 280 wdc->sc_flags &= ~WDCF_ACTIVE; 281 wdc->d_link[drive] = malloc(sizeof(struct wd_link), 282 M_DEVBUF, M_NOWAIT); 283 if (wdc->d_link[drive] == NULL) { 284 printf("%s: can't allocate link for drive %d\n", 285 self->dv_xname, drive); 286 continue; 287 } 288 bzero(wdc->d_link[drive],sizeof(struct wd_link)); 289 wdc->d_link[drive]->type = ATA; 290 wdc->d_link[drive]->wdc_softc =(caddr_t) wdc; 291 wdc->d_link[drive]->drive = drive; 292 if (wdc->sc_drq != DRQUNK) 293 wdc->d_link[drive]->sc_mode = WDM_DMA; 294 else 295 wdc->d_link[drive]->sc_mode = 0; 296 297 wdc->sc_drives_mask |= (1 << drive); 298 (void)config_found(self, (void *)wdc->d_link[drive], 299 wdprint); 300 } 301 } 302 #endif /* NWD > 0 */ 303 /* explicitly select an existing drive, to avoid spurious interrupts */ 304 if (wdc->sc_flags & WDCF_ONESLAVE) 305 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM | 0x10); /* slave */ 306 else 307 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM); /* master */ 308 /* 309 * Reset controller. The probe, with some combinations of ATA/ATAPI 310 * devices keep it in a mostly working, but strange state (with busy 311 * led on) 312 */ 313 wdcreset(wdc, VERBOSE); 314 } 315 316 /* 317 * Start I/O on a controller. This does the calculation, and starts a read or 318 * write operation. Called to from wdstart() to start a transfer, from 319 * wdcintr() to continue a multi-sector transfer or start the next transfer, or 320 * wdcrestart() after recovering from an error. 321 */ 322 void 323 wdcstart(wdc) 324 struct wdc_softc *wdc; 325 { 326 struct wdc_xfer *xfer; 327 328 if ((wdc->sc_flags & WDCF_ACTIVE) != 0 ) { 329 WDDEBUG_PRINT(("wdcstart: already active\n")); 330 return; /* controller aleady active */ 331 } 332 #ifdef DIAGNOSTIC 333 if ((wdc->sc_flags & WDCF_IRQ_WAIT) != 0) 334 panic("wdcstart: controller waiting for irq\n"); 335 #endif 336 /* is there a xfer ? */ 337 xfer = wdc->sc_xfer.tqh_first; 338 if (xfer == NULL) { 339 #ifdef ATAPI_DEBUG2 340 printf("wdcstart: null xfer\n"); 341 #endif 342 /* 343 * XXX 344 * This is a kluge. See comments in wd_get_parms(). 345 */ 346 if ((wdc->sc_flags & WDCF_WANTED) != 0) { 347 #ifdef ATAPI_DEBUG2 348 printf("WDCF_WANTED\n"); 349 #endif 350 wdc->sc_flags &= ~WDCF_WANTED; 351 wakeup(wdc); 352 } 353 return; 354 } 355 wdc->sc_flags |= WDCF_ACTIVE; 356 #ifdef ATAPI_DEBUG2 357 printf("wdcstart: drive %d\n", (int)xfer->d_link->drive); 358 #endif 359 outb(wdc->sc_iobase+wd_sdh, WDSD_IBM | xfer->d_link->drive << 4); 360 #if NATAPIBUS > 0 && NWD > 0 361 if (xfer->c_flags & C_ATAPI) { 362 #ifdef ATAPI_DEBUG_WDC 363 printf("wdcstart: atapi\n"); 364 #endif 365 wdc_atapi_start(wdc,xfer); 366 } else 367 wdc_ata_start(wdc,xfer); 368 #else /* NATAPIBUS > 0 && NWD > 0 */ 369 #if NATAPIBUS > 0 370 #ifdef ATAPI_DEBUG_WDC 371 printf("wdcstart: atapi\n"); 372 #endif 373 wdc_atapi_start(wdc,xfer); 374 #endif /* NATAPIBUS > */ 375 #if NWD > 0 376 wdc_ata_start(wdc,xfer); 377 #endif /* NWD > 0 */ 378 #endif /* NATAPIBUS > 0 && NWD > 0 */ 379 } 380 381 #if NWD > 0 382 int 383 wdprint(aux, wdc) 384 void *aux; 385 const char *wdc; 386 { 387 struct wd_link *d_link = aux; 388 389 if (!wdc) 390 printf(" drive %d", d_link->drive); 391 return QUIET; 392 } 393 394 void 395 wdc_ata_start(wdc, xfer) 396 struct wdc_softc *wdc; 397 struct wdc_xfer *xfer; 398 { 399 struct wd_link *d_link; 400 struct buf *bp = xfer->c_bp; 401 int nblks; 402 403 d_link=xfer->d_link; 404 405 if (wdc->sc_errors >= WDIORETRIES) { 406 wderror(d_link, bp, "wdc_ata_start hard error"); 407 xfer->c_flags |= C_ERROR; 408 wdc_ata_done(wdc, xfer); 409 return; 410 } 411 412 /* Do control operations specially. */ 413 if (d_link->sc_state < READY) { 414 /* 415 * Actually, we want to be careful not to mess with the control 416 * state if the device is currently busy, but we can assume 417 * that we never get to this point if that's the case. 418 */ 419 if (wdccontrol(wdc, d_link) == 0) { 420 /* The drive is busy. Wait. */ 421 return; 422 } 423 } 424 425 /* 426 * WDCF_ERROR is set by wdcunwedge() and wdcintr() when an error is 427 * encountered. If we are in multi-sector mode, then we switch to 428 * single-sector mode and retry the operation from the start. 429 */ 430 if (wdc->sc_flags & WDCF_ERROR) { 431 wdc->sc_flags &= ~WDCF_ERROR; 432 if ((wdc->sc_flags & WDCF_SINGLE) == 0) { 433 wdc->sc_flags |= WDCF_SINGLE; 434 xfer->c_skip = 0; 435 } 436 } 437 438 439 /* When starting a transfer... */ 440 if (xfer->c_skip == 0) { 441 daddr_t blkno; 442 443 WDDEBUG_PRINT(("\n%s: wdc_ata_start %s %d@%d; map ", 444 wdc->sc_dev.dv_xname, 445 (xfer->c_flags & B_READ) ? "read" : "write", 446 xfer->c_bcount, xfer->c_blkno)); 447 448 blkno = xfer->c_blkno+xfer->c_p_offset; 449 xfer->c_blkno = blkno / (d_link->sc_lp->d_secsize / DEV_BSIZE); 450 } else { 451 WDDEBUG_PRINT((" %d)%x", xfer->c_skip, 452 inb(wdc->sc_iobase + wd_altsts))); 453 } 454 455 /* 456 * When starting a multi-sector transfer, or doing single-sector 457 * transfers... 458 */ 459 if (xfer->c_skip == 0 || (wdc->sc_flags & WDCF_SINGLE) != 0 || 460 d_link->sc_mode == WDM_DMA) { 461 daddr_t blkno = xfer->c_blkno; 462 long cylin, head, sector; 463 int command; 464 465 if ((wdc->sc_flags & WDCF_SINGLE) != 0) 466 nblks = 1; 467 else if (d_link->sc_mode != WDM_DMA) 468 nblks = xfer->c_bcount / d_link->sc_lp->d_secsize; 469 else 470 nblks = 471 min(xfer->c_bcount / d_link->sc_lp->d_secsize, 8); 472 473 /* Check for bad sectors and adjust transfer, if necessary. */ 474 if ((d_link->sc_lp->d_flags & D_BADSECT) != 0 475 #ifdef B_FORMAT 476 && (bp->b_flags & B_FORMAT) == 0 477 #endif 478 ) { 479 long blkdiff; 480 int i; 481 482 for (i = 0; 483 (blkdiff = d_link->sc_badsect[i]) != -1; i++) { 484 blkdiff -= blkno; 485 if (blkdiff < 0) 486 continue; 487 if (blkdiff == 0) { 488 /* Replace current block of transfer. */ 489 blkno = 490 d_link->sc_lp->d_secperunit - 491 d_link->sc_lp->d_nsectors - i - 1; 492 } 493 if (blkdiff < nblks) { 494 /* Bad block inside transfer. */ 495 wdc->sc_flags |= WDCF_SINGLE; 496 nblks = 1; 497 } 498 break; 499 } 500 /* Transfer is okay now. */ 501 } 502 503 if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) { 504 sector = (blkno >> 0) & 0xff; 505 cylin = (blkno >> 8) & 0xffff; 506 head = (blkno >> 24) & 0xf; 507 head |= WDSD_LBA; 508 } else { 509 sector = blkno % d_link->sc_lp->d_nsectors; 510 sector++; /* Sectors begin with 1, not 0. */ 511 blkno /= d_link->sc_lp->d_nsectors; 512 head = blkno % d_link->sc_lp->d_ntracks; 513 blkno /= d_link->sc_lp->d_ntracks; 514 cylin = blkno; 515 head |= WDSD_CHS; 516 } 517 518 if (d_link->sc_mode == WDM_PIOSINGLE || 519 (wdc->sc_flags & WDCF_SINGLE) != 0) 520 xfer->c_nblks = 1; 521 else if (d_link->sc_mode == WDM_PIOMULTI) 522 xfer->c_nblks = min(nblks, d_link->sc_multiple); 523 else 524 xfer->c_nblks = nblks; 525 xfer->c_nbytes = xfer->c_nblks * d_link->sc_lp->d_secsize; 526 527 #ifdef B_FORMAT 528 if (bp->b_flags & B_FORMAT) { 529 sector = d_link->sc_lp->d_gap3; 530 nblks = d_link->sc_lp->d_nsectors; 531 command = WDCC_FORMAT; 532 } else 533 #endif 534 switch (d_link->sc_mode) { 535 case WDM_DMA: 536 command = (xfer->c_flags & B_READ) ? 537 WDCC_READDMA : WDCC_WRITEDMA; 538 /* Start the DMA channel. */ 539 isa_dmastart(wdc->sc_dev.dv_parent, wdc->sc_drq, 540 xfer->databuf + xfer->c_skip, xfer->c_nbytes, 541 NULL, 542 xfer->c_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE, 543 BUS_DMA_NOWAIT); 544 break; 545 546 case WDM_PIOMULTI: 547 command = (xfer->c_flags & B_READ) ? 548 WDCC_READMULTI : WDCC_WRITEMULTI; 549 break; 550 551 case WDM_PIOSINGLE: 552 command = (xfer->c_flags & B_READ) ? 553 WDCC_READ : WDCC_WRITE; 554 break; 555 556 default: 557 #ifdef DIAGNOSTIC 558 panic("bad wd mode"); 559 #endif 560 return; 561 } 562 563 /* Initiate command! */ 564 if (wdccommand(wdc, d_link, command, d_link->drive, 565 cylin, head, sector, nblks) != 0) { 566 wderror(d_link, NULL, 567 "wdc_ata_start: timeout waiting for unbusy"); 568 wdcunwedge(wdc); 569 return; 570 } 571 572 WDDEBUG_PRINT(("sector %d cylin %d head %d addr %x sts %x\n", 573 sector, cylin, head, xfer->databuf, 574 inb(wdc->sc_iobase + wd_altsts))); 575 576 } else if (xfer->c_nblks > 1) { 577 /* The number of blocks in the last stretch may be smaller. */ 578 nblks = xfer->c_bcount / d_link->sc_lp->d_secsize; 579 if (xfer->c_nblks > nblks) { 580 xfer->c_nblks = nblks; 581 xfer->c_nbytes = xfer->c_bcount; 582 } 583 } 584 585 /* If this was a write and not using DMA, push the data. */ 586 if (d_link->sc_mode != WDM_DMA && 587 (xfer->c_flags & (B_READ|B_WRITE)) == B_WRITE) { 588 if (wait_for_drq(wdc) < 0) { 589 wderror(d_link, NULL, 590 "wdc_ata_start: timeout waiting for drq"); 591 wdcunwedge(wdc); 592 return; 593 } 594 595 /* Push out data. */ 596 if ((d_link->sc_flags & WDF_32BIT) == 0) 597 outsw(wdc->sc_iobase + wd_data, 598 xfer->databuf + xfer->c_skip, 599 xfer->c_nbytes >> 1); 600 else 601 outsl(wdc->sc_iobase + wd_data, 602 xfer->databuf + xfer->c_skip, 603 xfer->c_nbytes >> 2); 604 } 605 606 wdc->sc_flags |= WDCF_IRQ_WAIT; 607 WDDEBUG_PRINT(("wdc_ata_start: timeout ")); 608 timeout(wdctimeout, wdc, WAITTIME); 609 WDDEBUG_PRINT(("done\n")); 610 } 611 612 int 613 wdc_ata_intr(wdc,xfer) 614 struct wdc_softc *wdc; 615 struct wdc_xfer *xfer; 616 { 617 struct wd_link *d_link; 618 619 d_link = xfer->d_link; 620 621 if (wait_for_unbusy(wdc) < 0) { 622 wdcerror(wdc, "wdcintr: timeout waiting for unbusy"); 623 return 0; 624 } 625 626 wdc->sc_flags &= ~WDCF_IRQ_WAIT; 627 untimeout(wdctimeout, wdc); 628 629 /* Is it not a transfer, but a control operation? */ 630 if (d_link->sc_state < READY) { 631 if (wdccontrol(wdc, d_link) == 0) { 632 /* The drive is busy. Wait. */ 633 return 1; 634 } 635 WDDEBUG_PRINT(("wdc_ata_start from wdc_ata_intr(open) flags 0x%x\n", 636 dc->sc_flags)); 637 wdc_ata_start(wdc,xfer); 638 return 1; 639 } 640 641 /* Turn off the DMA channel. */ 642 if (d_link->sc_mode == WDM_DMA) 643 isa_dmadone(wdc->sc_dev.dv_parent, wdc->sc_drq); 644 645 /* Have we an error? */ 646 if (wdc->sc_status & WDCS_ERR) { 647 #ifdef WDDEBUG 648 wderror(d_link, NULL, "wdc_ata_start"); 649 #endif 650 if ((wdc->sc_flags & WDCF_SINGLE) == 0) { 651 wdc->sc_flags |= WDCF_ERROR; 652 goto restart; 653 } 654 655 #ifdef B_FORMAT 656 if (bp->b_flags & B_FORMAT) 657 goto bad; 658 #endif 659 660 if (++wdc->sc_errors < WDIORETRIES) { 661 if (wdc->sc_errors == (WDIORETRIES + 1) / 2) { 662 #if 0 663 wderror(wd, NULL, "wedgie"); 664 #endif 665 wdcunwedge(wdc); 666 return 1; 667 } 668 goto restart; 669 } 670 wderror(d_link, xfer->c_bp, "wdc_ata_intr hard error"); 671 672 #ifdef B_FORMAT 673 bad: 674 #endif 675 xfer->c_flags |= C_ERROR; 676 goto done; 677 } 678 679 /* If this was a read and not using DMA, fetch the data. */ 680 if (d_link->sc_mode != WDM_DMA && 681 (xfer->c_flags & (B_READ|B_WRITE)) == B_READ) { 682 if ((wdc->sc_status & (WDCS_DRDY | WDCS_DSC | WDCS_DRQ)) 683 != (WDCS_DRDY | WDCS_DSC | WDCS_DRQ)) { 684 wderror(d_link, NULL, "wdcintr: read intr before drq"); 685 wdcunwedge(wdc); 686 return 1; 687 } 688 689 /* Pull in data. */ 690 if ((d_link->sc_flags & WDF_32BIT) == 0) 691 insw(wdc->sc_iobase+wd_data, 692 xfer->databuf + xfer->c_skip, xfer->c_nbytes >> 1); 693 else 694 insl(wdc->sc_iobase+wd_data, 695 xfer->databuf + xfer->c_skip, xfer->c_nbytes >> 2); 696 } 697 698 /* If we encountered any abnormalities, flag it as a soft error. */ 699 if (wdc->sc_errors > 0 || 700 (wdc->sc_status & WDCS_CORR) != 0) { 701 wderror(d_link, xfer->c_bp, "soft error (corrected)"); 702 wdc->sc_errors = 0; 703 } 704 705 /* Adjust pointers for the next block, if any. */ 706 xfer->c_blkno += xfer->c_nblks; 707 xfer->c_skip += xfer->c_nbytes; 708 xfer->c_bcount -= xfer->c_nbytes; 709 710 /* See if this transfer is complete. */ 711 if (xfer->c_bcount > 0) 712 goto restart; 713 714 done: 715 /* Done with this transfer, with or without error. */ 716 wdc_ata_done(wdc, xfer); 717 return 1; 718 719 restart: 720 /* Start the next operation */ 721 WDDEBUG_PRINT(("wdc_ata_start from wdcintr flags 0x%x\n", 722 wdc->sc_flags)); 723 wdc_ata_start(wdc, xfer); 724 725 return 1; 726 } 727 728 void 729 wdc_ata_done(wdc, xfer) 730 struct wdc_softc *wdc; 731 struct wdc_xfer *xfer; 732 { 733 struct buf *bp = xfer->c_bp; 734 struct wd_link *d_link = xfer->d_link; 735 int s; 736 737 WDDEBUG_PRINT(("wdc_ata_done\n")); 738 739 /* remove this command from xfer queue */ 740 s = splbio(); 741 TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain); 742 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE); 743 wdc->sc_errors = 0; 744 if (bp) { 745 if (xfer->c_flags & C_ERROR) { 746 bp->b_flags |= B_ERROR; 747 bp->b_error = EIO; 748 } 749 bp->b_resid = xfer->c_bcount; 750 wddone(d_link, bp); 751 biodone(bp); 752 } else { 753 wakeup(xfer->databuf); 754 } 755 xfer->c_skip = 0; 756 wdc_free_xfer(xfer); 757 d_link->openings++; 758 wdstart((void*)d_link->wd_softc); 759 WDDEBUG_PRINT(("wdcstart from wdc_ata_done, flags 0x%x\n", 760 wdc->sc_flags)); 761 wdcstart(wdc); 762 splx(s); 763 } 764 765 /* 766 * Get the drive parameters, if ESDI or ATA, or create fake ones for ST506. 767 */ 768 int 769 wdc_get_parms(wdc, d_link) 770 struct wdc_softc * wdc; 771 struct wd_link *d_link; 772 { 773 int i; 774 char tb[DEV_BSIZE]; 775 int s, error; 776 777 /* 778 * XXX 779 * The locking done here, and the length of time this may keep the rest 780 * of the system suspended, is a kluge. This should be rewritten to 781 * set up a transfer and queue it through wdstart(), but it's called 782 * infrequently enough that this isn't a pressing matter. 783 */ 784 785 s = splbio(); 786 787 while ((wdc->sc_flags & WDCF_ACTIVE) != 0) { 788 wdc->sc_flags |= WDCF_WANTED; 789 if ((error = tsleep(wdc, PRIBIO | PCATCH, "wdprm", 0)) != 0) { 790 splx(s); 791 return error; 792 } 793 } 794 795 wdc->sc_flags |= WDCF_ACTIVE; 796 797 if (wdccommandshort(wdc, d_link->drive, WDCC_IDENTIFY) != 0 || 798 wait_for_drq(wdc) != 0) { 799 /* 800 * We `know' there's a drive here; just assume it's old. 801 * This geometry is only used to read the MBR and print a 802 * (false) attach message. 803 */ 804 strncpy(d_link->sc_lp->d_typename, "ST506", 805 sizeof d_link->sc_lp->d_typename); 806 d_link->sc_lp->d_type = DTYPE_ST506; 807 808 strncpy(d_link->sc_params.wdp_model, "unknown", 809 sizeof d_link->sc_params.wdp_model); 810 d_link->sc_params.wdp_config = WD_CFG_FIXED; 811 d_link->sc_params.wdp_cylinders = 1024; 812 d_link->sc_params.wdp_heads = 8; 813 d_link->sc_params.wdp_sectors = 17; 814 d_link->sc_params.wdp_maxmulti = 0; 815 d_link->sc_params.wdp_usedmovsd = 0; 816 d_link->sc_params.wdp_capabilities = 0; 817 } else { 818 strncpy(d_link->sc_lp->d_typename, "ESDI/IDE", 819 sizeof d_link->sc_lp->d_typename); 820 d_link->sc_lp->d_type = DTYPE_ESDI; 821 822 /* Read in parameter block. */ 823 insw(wdc->sc_iobase + wd_data, tb, sizeof(tb) / sizeof(short)); 824 bcopy(tb, &d_link->sc_params, sizeof(struct wdparams)); 825 826 /* Shuffle string byte order. */ 827 for (i = 0; i < sizeof(d_link->sc_params.wdp_model); i += 2) { 828 u_short *p; 829 p = (u_short *)(d_link->sc_params.wdp_model + i); 830 *p = ntohs(*p); 831 } 832 } 833 834 /* Clear any leftover interrupt. */ 835 (void) inb(wdc->sc_iobase + wd_status); 836 837 /* Restart the queue. */ 838 WDDEBUG_PRINT(("wdcstart from wdc_get_parms flags 0x%x\n", 839 wdc->sc_flags)); 840 wdc->sc_flags &= ~WDCF_ACTIVE; 841 wdcstart(wdc); 842 843 splx(s); 844 return 0; 845 } 846 847 /* 848 * Implement operations needed before read/write. 849 * Returns 0 if operation still in progress, 1 if completed. 850 */ 851 int 852 wdccontrol(wdc, d_link) 853 struct wdc_softc *wdc; 854 struct wd_link *d_link; 855 { 856 WDDEBUG_PRINT(("wdccontrol\n")); 857 858 switch (d_link->sc_state) { 859 case RECAL: /* Set SDH, step rate, do recal. */ 860 if (wdccommandshort(wdc, d_link->drive, WDCC_RECAL) != 0) { 861 wderror(d_link, NULL, "wdccontrol: recal failed (1)"); 862 goto bad; 863 } 864 d_link->sc_state = RECAL_WAIT; 865 break; 866 867 case RECAL_WAIT: 868 if (wdc->sc_status & WDCS_ERR) { 869 wderror(d_link, NULL, "wdccontrol: recal failed (2)"); 870 goto bad; 871 } 872 /* fall through */ 873 874 case GEOMETRY: 875 if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) 876 goto multimode; 877 if (wdsetctlr(d_link) != 0) { 878 /* Already printed a message. */ 879 goto bad; 880 } 881 d_link->sc_state = GEOMETRY_WAIT; 882 break; 883 884 case GEOMETRY_WAIT: 885 if (wdc->sc_status & WDCS_ERR) { 886 wderror(d_link, NULL, "wdccontrol: geometry failed"); 887 goto bad; 888 } 889 /* fall through */ 890 891 case MULTIMODE: 892 multimode: 893 if (d_link->sc_mode != WDM_PIOMULTI) 894 goto ready; 895 outb(wdc->sc_iobase + wd_seccnt, d_link->sc_multiple); 896 if (wdccommandshort(wdc, d_link->drive, 897 WDCC_SETMULTI) != 0) { 898 wderror(d_link, NULL, 899 "wdccontrol: setmulti failed (1)"); 900 goto bad; 901 } 902 d_link->sc_state = MULTIMODE_WAIT; 903 break; 904 905 case MULTIMODE_WAIT: 906 if (wdc->sc_status & WDCS_ERR) { 907 wderror(d_link, NULL, 908 "wdccontrol: setmulti failed (2)"); 909 goto bad; 910 } 911 /* fall through */ 912 913 case READY: 914 ready: 915 wdc->sc_errors = 0; 916 d_link->sc_state = READY; 917 /* 918 * The rest of the initialization can be done by normal means. 919 */ 920 return 1; 921 922 bad: 923 wdcunwedge(wdc); 924 return 0; 925 } 926 927 wdc->sc_flags |= WDCF_IRQ_WAIT; 928 timeout(wdctimeout, wdc, WAITTIME); 929 return 0; 930 } 931 932 #endif /* NWD > 0 */ 933 934 935 /* 936 * Interrupt routine for the controller. Acknowledge the interrupt, check for 937 * errors on the current operation, mark it done if necessary, and start the 938 * next request. Also check for a partially done transfer, and continue with 939 * the next chunk if so. 940 */ 941 int 942 wdcintr(arg) 943 void *arg; 944 { 945 struct wdc_softc *wdc = arg; 946 struct wdc_xfer *xfer; 947 948 if ((wdc->sc_flags & WDCF_IRQ_WAIT) == 0) { 949 /* Clear the pending interrupt and abort. */ 950 u_char s = inb(wdc->sc_iobase+wd_status); 951 952 #ifdef ATAPI_DEBUG_WDC 953 u_char e = inb(wdc->sc_iobase+wd_error); 954 u_char i = inb(wdc->sc_iobase+wd_seccnt); 955 printf("wdcintr: inactive controller, " 956 "punting st=%02x er=%02x irr=%02x\n", s, e, i); 957 #else 958 inb(wdc->sc_iobase+wd_error); 959 inb(wdc->sc_iobase+wd_seccnt); 960 #endif 961 962 if (s & WDCS_DRQ) { 963 int len = inb (wdc->sc_iobase + wd_cyl_lo) + 964 256 * inb (wdc->sc_iobase + wd_cyl_hi); 965 #ifdef ATAPI_DEBUG_WDC 966 printf ("wdcintr: clearing up %d bytes\n", len); 967 #endif 968 wdcbit_bucket (wdc, len); 969 } 970 return 0; 971 } 972 973 WDDEBUG_PRINT(("wdcintr\n")); 974 975 xfer = wdc->sc_xfer.tqh_first; 976 #if NATAPIBUS > 0 && NWD > 0 977 if (xfer->c_flags & C_ATAPI) { 978 return wdc_atapi_intr(wdc,xfer); 979 } else 980 return wdc_ata_intr(wdc,xfer); 981 #else /* NATAPIBUS > 0 && NWD > 0 */ 982 #if NATAPIBUS > 0 983 return wdc_atapi_intr(wdc,xfer); 984 #endif /* NATAPIBUS > 0 */ 985 #if NWD > 0 986 return wdc_ata_intr(wdc,xfer); 987 #endif /* NWD > 0 */ 988 #endif /* NATAPIBUS > 0 && NWD > 0 */ 989 } 990 991 int 992 wdcreset(wdc, verb) 993 struct wdc_softc *wdc; 994 int verb; 995 { 996 int iobase = wdc->sc_iobase; 997 998 /* Reset the device. */ 999 outb(iobase+wd_ctlr, WDCTL_RST | WDCTL_IDS); 1000 delay(1000); 1001 outb(iobase+wd_ctlr, WDCTL_IDS); 1002 delay(1000); 1003 (void) inb(iobase+wd_error); 1004 outb(iobase+wd_ctlr, WDCTL_4BIT); 1005 1006 if (wait_for_unbusy(wdc) < 0) { 1007 if (verb) 1008 printf("%s: reset failed\n", wdc->sc_dev.dv_xname); 1009 return 1; 1010 } 1011 1012 return 0; 1013 } 1014 1015 void 1016 wdcrestart(arg) 1017 void *arg; 1018 { 1019 struct wdc_softc *wdc = arg; 1020 int s; 1021 1022 s = splbio(); 1023 wdcstart(wdc); 1024 splx(s); 1025 } 1026 1027 /* 1028 * Unwedge the controller after an unexpected error. We do this by resetting 1029 * it, marking all drives for recalibration, and stalling the queue for a short 1030 * period to give the reset time to finish. 1031 * NOTE: We use a timeout here, so this routine must not be called during 1032 * autoconfig or dump. 1033 */ 1034 void 1035 wdcunwedge(wdc) 1036 struct wdc_softc *wdc; 1037 { 1038 int unit; 1039 1040 #ifdef ATAPI_DEBUG 1041 printf("wdcunwedge\n"); 1042 #endif 1043 1044 untimeout(wdctimeout, wdc); 1045 wdc->sc_flags &= ~WDCF_IRQ_WAIT; 1046 (void) wdcreset(wdc, VERBOSE); 1047 1048 /* Schedule recalibrate for all drives on this controller. */ 1049 for (unit = 0; unit < 2; unit++) { 1050 if (!wdc->d_link[unit]) 1051 wdccommandshort(wdc, unit, ATAPI_SOFT_RESET); 1052 else if (wdc->d_link[unit]->sc_state > RECAL) 1053 wdc->d_link[unit]->sc_state = RECAL; 1054 } 1055 1056 wdc->sc_flags |= WDCF_ERROR; 1057 ++wdc->sc_errors; 1058 1059 /* Wake up in a little bit and restart the operation. */ 1060 WDDEBUG_PRINT(("wdcrestart from wdcunwedge\n")); 1061 wdc->sc_flags &= ~WDCF_ACTIVE; 1062 timeout(wdcrestart, wdc, RECOVERYTIME); 1063 } 1064 1065 int 1066 wdcwait(wdc, mask) 1067 struct wdc_softc *wdc; 1068 int mask; 1069 { 1070 int iobase = wdc->sc_iobase; 1071 int timeout = 0; 1072 u_char status; 1073 #ifdef WDCNDELAY_DEBUG 1074 extern int cold; 1075 #endif 1076 1077 WDDEBUG_PRINT(("wdcwait iobase %x\n", iobase)); 1078 1079 for (;;) { 1080 wdc->sc_status = status = inb(iobase+wd_status); 1081 /* 1082 * XXX 1083 * If a single slave ATAPI device is attached, it may 1084 * have released the bus. Select it and try again. 1085 */ 1086 if (status == 0xff && wdc->sc_flags & WDCF_ONESLAVE) { 1087 outb(iobase+wd_sdh, WDSD_IBM | 0x10); 1088 wdc->sc_status = status = inb(iobase+wd_status); 1089 } 1090 if ((status & WDCS_BSY) == 0 && (status & mask) == mask) 1091 break; 1092 if (++timeout > WDCNDELAY) { 1093 #ifdef ATAPI_DEBUG 1094 printf("wdcwait: timeout, status %x error %x\n", status, inb(iobase+wd_error)); 1095 #endif 1096 return -1; 1097 } 1098 delay(WDCDELAY); 1099 } 1100 if (status & WDCS_ERR) { 1101 wdc->sc_error = inb(iobase+wd_error); 1102 return WDCS_ERR; 1103 } 1104 #ifdef WDCNDELAY_DEBUG 1105 /* After autoconfig, there should be no long delays. */ 1106 if (!cold && timeout > WDCNDELAY_DEBUG) { 1107 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first; 1108 if (xfer == NULL) 1109 printf("%s: warning: busy-wait took %dus\n", 1110 wdc->sc_dev.dv_xname, WDCDELAY * timeout); 1111 else 1112 printf("%s(%s): warning: busy-wait took %dus\n", 1113 wdc->sc_dev.dv_xname, 1114 ((struct device*)xfer->d_link->wd_softc)->dv_xname, 1115 WDCDELAY * timeout); 1116 } 1117 #endif 1118 return 0; 1119 } 1120 1121 void 1122 wdctimeout(arg) 1123 void *arg; 1124 { 1125 struct wdc_softc *wdc = (struct wdc_softc *)arg; 1126 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first; 1127 int s; 1128 1129 WDDEBUG_PRINT(("wdctimeout\n")); 1130 1131 s = splbio(); 1132 if ((wdc->sc_flags & WDCF_IRQ_WAIT) != 0) { 1133 wdcerror(wdc, "lost interrupt"); 1134 printf("\ttype: %s\n", (xfer->c_flags & C_ATAPI) ? "atapi":"ata"); 1135 printf("\tc_bcount: %d\n", xfer->c_bcount); 1136 printf("\tc_skip: %d\n", xfer->c_skip); 1137 wdcintr(wdc); 1138 wdc->sc_flags &= ~WDCF_IRQ_WAIT; 1139 wdcunwedge(wdc); 1140 } else 1141 wdcerror(wdc, "missing untimeout"); 1142 splx(s); 1143 } 1144 1145 /* 1146 * Wait for the drive to become ready and send a command. 1147 * Return -1 if busy for too long or 0 otherwise. 1148 * Assumes interrupts are blocked. 1149 */ 1150 int 1151 wdccommand(wdc, d_link, command, drive, cylin, head, sector, count) 1152 struct wdc_softc *wdc; 1153 struct wd_link *d_link; 1154 int command; 1155 int drive, cylin, head, sector, count; 1156 { 1157 int iobase = wdc->sc_iobase; 1158 int stat; 1159 1160 WDDEBUG_PRINT(("wdccommand drive %d\n", drive)); 1161 1162 #if defined(DIAGNOSTIC) && defined(WDCDEBUG) 1163 if ((wdc->sc_flags & WDCF_ACTIVE) == 0) 1164 printf("wdccommand: controler not active (drive %d)\n", drive); 1165 #endif 1166 1167 /* Select drive, head, and addressing mode. */ 1168 outb(iobase+wd_sdh, WDSD_IBM | (drive << 4) | head); 1169 1170 /* Wait for it to become ready to accept a command. */ 1171 if (command == WDCC_IDP || d_link->type == ATAPI) 1172 stat = wait_for_unbusy(wdc); 1173 else 1174 stat = wdcwait(wdc, WDCS_DRDY); 1175 1176 if (stat < 0) { 1177 #ifdef ATAPI_DEBUG 1178 printf("wdcommand: xfer failed (wait_for_unbusy) status %d\n", 1179 stat); 1180 #endif 1181 return -1; 1182 } 1183 1184 /* Load parameters. */ 1185 if (d_link->type == ATA && d_link->sc_lp->d_type == DTYPE_ST506) 1186 outb(iobase + wd_precomp, d_link->sc_lp->d_precompcyl / 4); 1187 else 1188 outb(iobase + wd_features, 0); 1189 outb(iobase + wd_cyl_lo, cylin); 1190 outb(iobase + wd_cyl_hi, cylin >> 8); 1191 outb(iobase + wd_sector, sector); 1192 outb(iobase + wd_seccnt, count); 1193 1194 /* Send command. */ 1195 outb(iobase + wd_command, command); 1196 1197 return 0; 1198 } 1199 1200 /* 1201 * Simplified version of wdccommand(). 1202 */ 1203 int 1204 wdccommandshort(wdc, drive, command) 1205 struct wdc_softc *wdc; 1206 int drive; 1207 int command; 1208 { 1209 int iobase = wdc->sc_iobase; 1210 1211 WDDEBUG_PRINT(("wdccommandshort\n")); 1212 1213 #if defined(DIAGNOSTIC) && defined(WDCDEBUG) 1214 if ((wdc->sc_flags & WDCF_ACTIVE) == 0) 1215 printf("wdccommandshort: controller not active (drive %d)\n", 1216 drive); 1217 #endif 1218 1219 /* Select drive. */ 1220 outb(iobase + wd_sdh, WDSD_IBM | (drive << 4)); 1221 1222 if (wdcwait(wdc, WDCS_DRDY) < 0) 1223 return -1; 1224 1225 outb(iobase + wd_command, command); 1226 1227 return 0; 1228 } 1229 1230 void 1231 wdc_exec_xfer(wdc, d_link, xfer) 1232 struct wdc_softc *wdc; 1233 struct wd_link *d_link; 1234 struct wdc_xfer *xfer; 1235 { 1236 int s; 1237 1238 WDDEBUG_PRINT(("wdc_exec_xfer\n")); 1239 1240 s = splbio(); 1241 1242 /* insert at the end of command list */ 1243 TAILQ_INSERT_TAIL(&wdc->sc_xfer,xfer , c_xferchain) 1244 WDDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n", 1245 wdc->sc_flags)); 1246 wdcstart(wdc); 1247 xfer->c_flags |= C_NEEDDONE; /* we can now call upper level done() */ 1248 splx(s); 1249 } 1250 1251 struct wdc_xfer * 1252 wdc_get_xfer(flags) 1253 int flags; 1254 { 1255 struct wdc_xfer *xfer; 1256 int s; 1257 1258 s = splbio(); 1259 if ((xfer = xfer_free_list.lh_first) != NULL) { 1260 LIST_REMOVE(xfer, free_list); 1261 splx(s); 1262 #ifdef DIAGNOSTIC 1263 if ((xfer->c_flags & C_INUSE) != 0) 1264 panic("wdc_get_xfer: xfer already in use\n"); 1265 #endif 1266 } else { 1267 splx(s); 1268 #ifdef ATAPI_DEBUG2 1269 printf("wdc:making xfer %d\n",wdc_nxfer); 1270 #endif 1271 xfer = malloc(sizeof(*xfer), M_DEVBUF, 1272 ((flags & IDE_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK)); 1273 if (xfer == NULL) 1274 return 0; 1275 1276 #ifdef DIAGNOSTIC 1277 xfer->c_flags &= ~C_INUSE; 1278 #endif 1279 #ifdef ATAPI_DEBUG2 1280 wdc_nxfer++; 1281 #endif 1282 } 1283 #ifdef DIAGNOSTIC 1284 if ((xfer->c_flags & C_INUSE) != 0) 1285 panic("wdc_get_xfer: xfer already in use\n"); 1286 #endif 1287 bzero(xfer,sizeof(struct wdc_xfer)); 1288 xfer->c_flags = C_INUSE; 1289 return xfer; 1290 } 1291 1292 void 1293 wdc_free_xfer(xfer) 1294 struct wdc_xfer *xfer; 1295 { 1296 int s; 1297 1298 s = splbio(); 1299 xfer->c_flags &= ~C_INUSE; 1300 LIST_INSERT_HEAD(&xfer_free_list, xfer, free_list); 1301 splx(s); 1302 } 1303 1304 void 1305 wdcerror(wdc, msg) 1306 struct wdc_softc *wdc; 1307 char *msg; 1308 { 1309 struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first; 1310 if (xfer == NULL) 1311 printf("%s: %s\n", wdc->sc_dev.dv_xname, msg); 1312 else 1313 printf("%s(%d): %s\n", wdc->sc_dev.dv_xname, 1314 xfer->d_link->drive, msg); 1315 } 1316 1317 /* 1318 * the bit bucket 1319 */ 1320 void 1321 wdcbit_bucket(wdc, size) 1322 struct wdc_softc *wdc; 1323 int size; 1324 { 1325 int iobase = wdc->sc_iobase; 1326 int i; 1327 1328 for (i = 0 ; i < size / 2 ; i++) { 1329 short null; 1330 (void)insw(iobase + wd_data, &null, 1); 1331 } 1332 1333 if (size % 2) 1334 (void)inb(iobase + wd_data); 1335 } 1336 1337 1338 #if NATAPIBUS > 0 1339 1340 void 1341 wdc_atapi_minphys (struct buf *bp) 1342 { 1343 if(bp->b_bcount > MAX_SIZE) 1344 bp->b_bcount = MAX_SIZE; 1345 minphys(bp); 1346 } 1347 1348 1349 void 1350 wdc_atapi_start(wdc, xfer) 1351 struct wdc_softc *wdc; 1352 struct wdc_xfer *xfer; 1353 { 1354 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd; 1355 1356 #ifdef ATAPI_DEBUG_WDC 1357 printf("wdc_atapi_start, acp flags %x \n",sc_xfer->flags); 1358 #endif 1359 if (wdc->sc_errors >= WDIORETRIES) { 1360 if ((wdc->sc_status & WDCS_ERR) == 0) { 1361 sc_xfer->error = XS_DRIVER_STUFFUP; /* XXX do we know more ? */ 1362 } else { 1363 sc_xfer->error = XS_SENSE; 1364 sc_xfer->sense.atapi_sense = inb (wdc->sc_iobase + wd_error); 1365 } 1366 wdc_atapi_done(wdc, xfer); 1367 return; 1368 } 1369 if (wait_for_unbusy(wdc) != 0) { 1370 if ((wdc->sc_status & WDCS_ERR) == 0) { 1371 printf("wdc_atapi_start: not ready, st = %02x\n", 1372 wdc->sc_status); 1373 sc_xfer->error = XS_SELTIMEOUT; 1374 } 1375 #if 0 /* don't get the sense yet, as this may be just UNIT ATTENTION */ 1376 else { 1377 #ifdef ATAPI_DEBUG_WDC 1378 printf("wdc_atapi_start: sense %02x\n", wdc->sc_error); 1379 #endif 1380 sc_xfer->error = XS_SENSE; 1381 sc_xfer->sense.atapi_sense = wdc->sc_error; 1382 } 1383 wdc_atapi_done(wdc, xfer); 1384 return; 1385 #endif 1386 } 1387 1388 if (wdccommand(wdc, (struct wd_link*)xfer->d_link, ATAPI_PACKET_COMMAND, 1389 sc_xfer->sc_link->scsipi_atapi.drive, sc_xfer->datalen, 1390 0, 0, 0) != 0) { 1391 printf("wdc_atapi_start: can't send atapi packet command\n"); 1392 sc_xfer->error = XS_DRIVER_STUFFUP; 1393 wdc_atapi_done(wdc, xfer); 1394 return; 1395 } 1396 if ((sc_xfer->sc_link->scsipi_atapi.cap & 0x0300) != ACAP_DRQ_INTR) { 1397 int i, phase; 1398 for (i=20000; i>0; --i) { 1399 phase = (inb(wdc->sc_iobase + wd_ireason) & 1400 (WDCI_CMD | WDCI_IN)) | 1401 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ); 1402 if (phase == PHASE_CMDOUT) 1403 break; 1404 delay(10); 1405 } 1406 if (phase != PHASE_CMDOUT ) { 1407 printf("wdc_atapi_start: timeout waiting PHASE_CMDOUT"); 1408 sc_xfer->error = XS_SELTIMEOUT; 1409 wdc_atapi_done(wdc, xfer); 1410 return; 1411 } 1412 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd, 1413 sc_xfer->cmdlen / sizeof(short)); 1414 } 1415 wdc->sc_flags |= WDCF_IRQ_WAIT; 1416 1417 #ifdef ATAPI_DEBUG2 1418 printf("wdc_atapi_start: timeout\n"); 1419 #endif 1420 timeout(wdctimeout, wdc, WAITTIME); 1421 return; 1422 } 1423 1424 1425 int 1426 wdc_atapi_get_params(ab_link, drive, id) 1427 struct scsipi_link *ab_link; 1428 u_int8_t drive; 1429 struct atapi_identify *id; 1430 { 1431 struct wdc_softc *wdc = (void*)ab_link->adapter_softc; 1432 int status, len, excess = 0; 1433 int s, error; 1434 1435 /* if a disk is already present, skip */ 1436 if ((wdc->sc_drives_mask & (1 << drive)) != 0) { 1437 #ifdef ATAPI_DEBUG_PROBE 1438 printf("wdc_atapi_get_params: drive %d present\n", drive); 1439 #endif 1440 return 0; 1441 } 1442 1443 /* 1444 * If there is only one ATAPI slave on the bus,don't probe 1445 * drive 0 (master) 1446 */ 1447 1448 if (wdc->sc_flags & WDCF_ONESLAVE && drive != 1) 1449 return 0; 1450 1451 #ifdef ATAPI_DEBUG_PROBE 1452 printf("wdc_atapi_get_params: probing drive %d\n", drive); 1453 #endif 1454 1455 /* 1456 * XXX 1457 * The locking done here, and the length of time this may keep the rest 1458 * of the system suspended, is a kluge. This should be rewritten to 1459 * set up a transfer and queue it through wdstart(), but it's called 1460 * infrequently enough that this isn't a pressing matter. 1461 */ 1462 1463 s = splbio(); 1464 1465 while ((wdc->sc_flags & WDCF_ACTIVE) != 0) { 1466 wdc->sc_flags |= WDCF_WANTED; 1467 if ((error = tsleep(wdc, PRIBIO | PCATCH, "atprm", 0)) != 0) { 1468 splx(s); 1469 return error; 1470 } 1471 } 1472 1473 wdc->sc_flags |= WDCF_ACTIVE; 1474 error = 1; 1475 (void)wdcreset(wdc, VERBOSE); 1476 if ((status = wdccommand(wdc, (struct wd_link*)(&(ab_link->scsipi_atapi)), 1477 ATAPI_SOFT_RESET, drive, 0, 0, 0, 0)) != 0) { 1478 #ifdef ATAPI_DEBUG 1479 printf("wdc_atapi_get_params: ATAPI_SOFT_RESET" 1480 "failed for drive %d: status %d error %d\n", 1481 drive, status, wdc->sc_error); 1482 #endif 1483 error = 0; 1484 goto end; 1485 } 1486 if ((status = wait_for_unbusy(wdc)) != 0) { 1487 #ifdef ATAPI_DEBUG 1488 printf("wdc_atapi_get_params: wait_for_unbusy failed " 1489 "for drive %d: status %d error %d\n", 1490 drive, status, wdc->sc_error); 1491 #endif 1492 error = 0; 1493 goto end; 1494 } 1495 1496 if (wdccommand(wdc, (struct wd_link*)(&(ab_link->scsipi_atapi)), 1497 ATAPI_IDENTIFY_DEVICE, drive, sizeof(struct atapi_identify), 1498 0, 0, 0) != 0 || 1499 atapi_ready(wdc) != 0) { 1500 #ifdef ATAPI_DEBUG_PROBE 1501 printf("ATAPI_IDENTIFY_DEVICE failed for drive %d\n", drive); 1502 #endif 1503 error = 0; 1504 goto end; 1505 } 1506 len = inb(wdc->sc_iobase + wd_cyl_lo) + 256 * 1507 inb(wdc->sc_iobase + wd_cyl_hi); 1508 if (len != sizeof(struct atapi_identify)) { 1509 printf("Warning drive %d returned %d/%d of " 1510 "indentify device data\n", drive, len, 1511 sizeof(struct atapi_identify)); 1512 excess = len - sizeof(struct atapi_identify); 1513 if (excess < 0) 1514 excess = 0; 1515 } 1516 insw(wdc->sc_iobase + wd_data, id, 1517 sizeof(struct atapi_identify)/sizeof(short)); 1518 wdcbit_bucket(wdc, excess); 1519 wdc->sc_drives_mask |= (1 << drive); 1520 1521 end: /* Restart the queue. */ 1522 WDDEBUG_PRINT(("wdcstart from wdc_atapi_get_parms flags 0x%x\n", 1523 wdc->sc_flags)); 1524 wdc->sc_flags &= ~WDCF_ACTIVE; 1525 wdcstart(wdc); 1526 splx(s); 1527 return error; 1528 } 1529 1530 int 1531 wdc_atapi_send_command_packet(sc_xfer) 1532 struct scsipi_xfer *sc_xfer; 1533 { 1534 struct scsipi_link *sc_link = sc_xfer->sc_link; 1535 struct wdc_softc *wdc = (void*)sc_link->adapter_softc; 1536 struct wdc_xfer *xfer; 1537 int flags = sc_xfer->flags; 1538 1539 if (flags & SCSI_POLL) { /* should use the queue and wdc_atapi_start */ 1540 struct wdc_xfer xfer_s; 1541 int i, s; 1542 1543 s = splbio(); 1544 #ifdef ATAPI_DEBUG_WDC 1545 printf("wdc_atapi_send_cmd: " 1546 "flags 0x%x drive %d cmdlen %d datalen %d", 1547 sc_xfer->flags, sc_link->scsipi_atapi.drive, sc_xfer->cmdlen, 1548 sc_xfer->datalen); 1549 #endif 1550 xfer = &xfer_s; 1551 bzero(xfer, sizeof(xfer_s)); 1552 xfer->c_flags = C_INUSE|C_ATAPI|flags; 1553 xfer->d_link = (struct wd_link *)(&sc_link->scsipi_atapi); 1554 xfer->c_bp = sc_xfer->bp; 1555 xfer->atapi_cmd = sc_xfer; 1556 xfer->c_blkno = 0; 1557 xfer->databuf = sc_xfer->data; 1558 xfer->c_bcount = sc_xfer->datalen; 1559 if (wait_for_unbusy (wdc) != 0) { 1560 if ((wdc->sc_status & WDCS_ERR) == 0) { 1561 printf("wdc_atapi_send_command: not ready, " 1562 "st = %02x\n", wdc->sc_status); 1563 sc_xfer->error = XS_SELTIMEOUT; 1564 } else { 1565 sc_xfer->error = XS_SENSE; 1566 sc_xfer->sense.atapi_sense = wdc->sc_error; 1567 } 1568 splx(s); 1569 return COMPLETE; 1570 } 1571 1572 if (wdccommand(wdc, (struct wd_link*)(&sc_link->scsipi_atapi), 1573 ATAPI_PACKET_COMMAND, sc_link->scsipi_atapi.drive, sc_xfer->datalen, 1574 0, 0, 0) != 0) { 1575 printf("can't send atapi packet command\n"); 1576 sc_xfer->error = XS_DRIVER_STUFFUP; 1577 splx(s); 1578 return COMPLETE; 1579 } 1580 1581 /* Wait for cmd i/o phase. */ 1582 for (i = 20000; i > 0; --i) { 1583 int phase; 1584 phase = (inb(wdc->sc_iobase + wd_ireason) & 1585 (WDCI_CMD | WDCI_IN)) | 1586 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ); 1587 if (phase == PHASE_CMDOUT) 1588 break; 1589 delay(10); 1590 } 1591 #ifdef ATAPI_DEBUG_WDC 1592 printf("Wait for cmd i/o phase: i = %d\n", i); 1593 #endif 1594 1595 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd, 1596 sc_xfer->cmdlen/ sizeof (short)); 1597 1598 /* Wait for data i/o phase. */ 1599 for ( i= 20000; i > 0; --i) { 1600 int phase; 1601 phase = (inb(wdc->sc_iobase + wd_ireason) & 1602 (WDCI_CMD | WDCI_IN)) | 1603 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ); 1604 if (phase != PHASE_CMDOUT) 1605 break; 1606 delay(10); 1607 } 1608 1609 #ifdef ATAPI_DEBUG_WDC 1610 printf("Wait for data i/o phase: i = %d\n", i); 1611 #endif 1612 wdc->sc_flags |= WDCF_IRQ_WAIT; 1613 while ((sc_xfer->flags & ITSDONE) == 0) { 1614 wdc_atapi_intr(wdc, xfer); 1615 for (i = 2000; i > 0; --i) 1616 if ((inb(wdc->sc_iobase + wd_status) 1617 & WDCS_DRQ) == 0) 1618 break; 1619 #ifdef ATAPI_DEBUG_WDC 1620 printf("wdc_atapi_intr: i = %d\n", i); 1621 #endif 1622 } 1623 wdc->sc_flags &= ~(WDCF_IRQ_WAIT | WDCF_SINGLE | WDCF_ERROR); 1624 wdc->sc_errors = 0; 1625 xfer->c_skip = 0; 1626 splx(s); 1627 return COMPLETE; 1628 } else { /* POLLED */ 1629 xfer = wdc_get_xfer(flags & SCSI_NOSLEEP ? IDE_NOSLEEP : 0); 1630 if (xfer == NULL) { 1631 return TRY_AGAIN_LATER; 1632 } 1633 xfer->c_flags |= C_ATAPI|sc_xfer->flags; 1634 xfer->d_link = (struct wd_link*)(&sc_link->scsipi_atapi); 1635 xfer->c_bp = sc_xfer->bp; 1636 xfer->atapi_cmd = sc_xfer; 1637 xfer->c_blkno = 0; 1638 xfer->databuf = sc_xfer->data; 1639 xfer->c_bcount = sc_xfer->datalen; 1640 wdc_exec_xfer(wdc, xfer->d_link, xfer); 1641 #ifdef ATAPI_DEBUG_WDC 1642 printf("wdc_atapi_send_command_packet: wdc_exec_xfer, flags 0x%x\n", 1643 sc_xfer->flags); 1644 #endif 1645 return (sc_xfer->flags & ITSDONE) ? COMPLETE : SUCCESSFULLY_QUEUED; 1646 } 1647 } 1648 1649 int 1650 wdc_atapi_intr(wdc, xfer) 1651 struct wdc_softc *wdc; 1652 struct wdc_xfer *xfer; 1653 { 1654 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd; 1655 int len, phase, i, retries=0; 1656 int err, st, ire; 1657 1658 #ifdef ATAPI_DEBUG2 1659 printf("wdc_atapi_intr: %s\n", wdc->sc_dev.dv_xname); 1660 #endif 1661 1662 if (wait_for_unbusy(wdc) < 0) { 1663 if ((wdc->sc_status & WDCS_ERR) == 0) { 1664 printf("wdc_atapi_intr: controller busy\n"); 1665 return 0; 1666 } else { 1667 sc_xfer->error = XS_SENSE; 1668 sc_xfer->sense.atapi_sense = wdc->sc_error; 1669 } 1670 #ifdef ATAPI_DEBUG_WDC 1671 printf("wdc_atapi_intr: wdc_atapi_done(), error %d\n", 1672 sc_xfer->error); 1673 #endif 1674 wdc_atapi_done(wdc, xfer); 1675 return 0; 1676 } 1677 1678 1679 again: 1680 len = inb(wdc->sc_iobase + wd_cyl_lo) + 1681 256 * inb(wdc->sc_iobase + wd_cyl_hi); 1682 1683 st = inb(wdc->sc_iobase + wd_status); 1684 err = inb(wdc->sc_iobase + wd_error); 1685 ire = inb(wdc->sc_iobase + wd_ireason); 1686 1687 phase = (ire & (WDCI_CMD | WDCI_IN)) | (st & WDCS_DRQ); 1688 #ifdef ATAPI_DEBUG_WDC 1689 printf("wdc_atapi_intr: len %d st %d err %d ire %d :", 1690 len, st, err, ire); 1691 #endif 1692 switch (phase) { 1693 case PHASE_CMDOUT: 1694 /* send packet command */ 1695 #ifdef ATAPI_DEBUG_WDC 1696 printf("PHASE_CMDOUT\n"); 1697 #endif 1698 1699 #ifdef ATAPI_DEBUG_WDC 1700 { 1701 int i; 1702 char *c = (char *)sc_xfer->cmd; 1703 printf("wdc_atapi_intr: cmd "); 1704 for (i = 0; i < sc_xfer->cmdlen; i++) 1705 printf("%x ", c[i]); 1706 printf("\n"); 1707 } 1708 #endif 1709 1710 outsw(wdc->sc_iobase + wd_data, sc_xfer->cmd, 1711 sc_xfer->cmdlen/ sizeof (short)); 1712 return 1; 1713 1714 case PHASE_DATAOUT: 1715 /* write data */ 1716 #ifdef ATAPI_DEBUG_WDC 1717 printf("PHASE_DATAOUT\n"); 1718 #endif 1719 if ((sc_xfer->flags & SCSI_DATA_OUT) == 0) { 1720 printf("wdc_atapi_intr: bad data phase\n"); 1721 sc_xfer->error = XS_DRIVER_STUFFUP; 1722 return 0; 1723 } 1724 if (xfer->c_bcount < len) { 1725 printf("wdc_atapi_intr: warning: write only " 1726 "%d of %d requested bytes\n", xfer->c_bcount, len); 1727 outsw(wdc->sc_iobase + wd_data, 1728 xfer->databuf + xfer->c_skip, 1729 xfer->c_bcount / sizeof(short)); 1730 for (i = xfer->c_bcount; i < len; i += sizeof(short)) 1731 outw(wdc->sc_iobase + wd_data, 0); 1732 xfer->c_skip += xfer->c_bcount; 1733 xfer->c_bcount = 0; 1734 } else { 1735 outsw(wdc->sc_iobase + wd_data, 1736 xfer->databuf + xfer->c_skip, len / sizeof(short)); 1737 xfer->c_skip += len; 1738 xfer->c_bcount -= len; 1739 } 1740 return 1; 1741 1742 case PHASE_DATAIN: 1743 /* Read data */ 1744 #ifdef ATAPI_DEBUG_WDC 1745 printf("PHASE_DATAIN\n"); 1746 #endif 1747 if ((sc_xfer->flags & SCSI_DATA_IN) == 0) { 1748 printf("wdc_atapi_intr: bad data phase\n"); 1749 sc_xfer->error = XS_DRIVER_STUFFUP; 1750 return 0; 1751 } 1752 if (xfer->c_bcount < len) { 1753 printf("wdc_atapi_intr: warning: reading only " 1754 "%d of %d bytes\n", xfer->c_bcount, len); 1755 insw(wdc->sc_iobase + wd_data, 1756 xfer->databuf + xfer->c_skip, 1757 xfer->c_bcount / sizeof(short)); 1758 wdcbit_bucket(wdc, len - xfer->c_bcount); 1759 xfer->c_skip += xfer->c_bcount; 1760 xfer->c_bcount = 0; 1761 } else { 1762 insw(wdc->sc_iobase + wd_data, 1763 xfer->databuf + xfer->c_skip, len / sizeof(short)); 1764 xfer->c_skip += len; 1765 xfer->c_bcount -=len; 1766 } 1767 return 1; 1768 1769 case PHASE_ABORTED: 1770 case PHASE_COMPLETED: 1771 #ifdef ATAPI_DEBUG_WDC 1772 printf("PHASE_COMPLETED\n"); 1773 #endif 1774 if (st & WDCS_ERR) { 1775 sc_xfer->error = XS_SENSE; 1776 sc_xfer->sense.atapi_sense = inb (wdc->sc_iobase + wd_error); 1777 } 1778 #ifdef ATAPI_DEBUG_WDC 1779 if (xfer->c_bcount != 0) { 1780 printf("wdc_atapi_intr warning: bcount value " 1781 "is %d after io\n", xfer->c_bcount); 1782 } 1783 #endif 1784 break; 1785 1786 default: 1787 if (++retries<500) { 1788 DELAY(100); 1789 goto again; 1790 } 1791 printf("wdc_atapi_intr: unknown phase %d\n", phase); 1792 if (st & WDCS_ERR) { 1793 sc_xfer->error = XS_SENSE; 1794 sc_xfer->sense.atapi_sense = inb (wdc->sc_iobase + wd_error); 1795 } else { 1796 sc_xfer->error = XS_DRIVER_STUFFUP; 1797 } 1798 } 1799 1800 #ifdef ATAPI_DEBUG_WDC 1801 printf("wdc_atapi_intr: wdc_atapi_done() (end), error %d\n", 1802 sc_xfer->error); 1803 #endif 1804 wdc_atapi_done(wdc, xfer); 1805 return (1); 1806 } 1807 1808 1809 void 1810 wdc_atapi_done(wdc, xfer) 1811 struct wdc_softc *wdc; 1812 struct wdc_xfer *xfer; 1813 { 1814 struct scsipi_xfer *sc_xfer = xfer->atapi_cmd; 1815 int s; 1816 int need_done = xfer->c_flags & C_NEEDDONE; 1817 1818 #ifdef ATAPI_DEBUG 1819 printf("wdc_atapi_done: flags 0x%x\n", (u_int)xfer->c_flags); 1820 #endif 1821 sc_xfer->resid = xfer->c_bcount; 1822 wdc->sc_flags &= ~WDCF_IRQ_WAIT; 1823 1824 /* remove this command from xfer queue */ 1825 wdc->sc_errors = 0; 1826 xfer->c_skip = 0; 1827 if ((xfer->c_flags & SCSI_POLL) == 0) { 1828 s = splbio(); 1829 untimeout(wdctimeout, wdc); 1830 TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain); 1831 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE); 1832 wdc_free_xfer(xfer); 1833 sc_xfer->flags |= ITSDONE; 1834 if (need_done) { 1835 #ifdef ATAPI_DEBUG 1836 printf("wdc_atapi_done: scsipi_done\n"); 1837 #endif 1838 scsipi_done(sc_xfer); 1839 } 1840 #ifdef WDDEBUG 1841 printf("wdcstart from wdc_atapi_intr, flags 0x%x\n", 1842 wdc->sc_flags); 1843 #endif 1844 wdcstart(wdc); 1845 splx(s); 1846 } else { 1847 wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE); 1848 sc_xfer->flags |= ITSDONE; 1849 } 1850 } 1851 1852 #endif /* NATAPIBUS > 0 */ 1853