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