1 /* $NetBSD: edc_mca.c,v 1.9 2001/05/04 12:58:34 jdolecek Exp $ */ 2 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Jaromir Dolecek. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the NetBSD 20 * Foundation, Inc. and its contributors. 21 * 4. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* 37 * Driver for MCA ESDI controllers and disks conforming to IBM DASD 38 * spec. 39 * 40 * The driver was written with DASD Storage Interface Specification 41 * for MCA rev. 2.2 in hands, thanks to Scott Telford <st@epcc.ed.ac.uk>. 42 * 43 * TODO: 44 * - move the MCA DMA controller (edc_setup_dma()) goo to device driver 45 * independant location 46 * - improve error recovery 47 * add any soft resets when anything gets stuck? 48 * - test with > 1 disk (this is supported by some controllers), eliminate 49 * any remaining devno=0 assumptions if there are any still 50 * - test with > 1 ESDI controller in machine; shared interrupts 51 * necessary for this to work should be supported - edc_intr() specifically 52 * checks if the interrupt is for this controller 53 */ 54 55 #include "rnd.h" 56 57 #include <sys/param.h> 58 #include <sys/systm.h> 59 #include <sys/errno.h> 60 #include <sys/device.h> 61 #include <sys/malloc.h> 62 #include <sys/endian.h> 63 #include <sys/disklabel.h> 64 #include <sys/disk.h> 65 #include <sys/syslog.h> 66 #include <sys/proc.h> 67 #include <sys/vnode.h> 68 #include <sys/kernel.h> 69 #if NRND > 0 70 #include <sys/rnd.h> 71 #endif 72 73 #include <machine/bus.h> 74 #include <machine/intr.h> 75 76 #include <dev/mca/mcareg.h> 77 #include <dev/mca/mcavar.h> 78 #include <dev/mca/mcadevs.h> 79 80 #include <dev/mca/edcreg.h> 81 #include <dev/mca/edvar.h> 82 #include <dev/mca/edcvar.h> 83 84 #define EDC_ATTN_MAXTRIES 10000 /* How many times check for unbusy */ 85 86 struct edc_mca_softc { 87 struct device sc_dev; 88 89 bus_space_tag_t sc_iot; 90 bus_space_handle_t sc_ioh; 91 92 bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */ 93 bus_space_handle_t sc_dmaextcmdh; 94 bus_space_handle_t sc_dmaexech; 95 96 void *sc_ih; /* interrupt handle */ 97 int sc_drq; /* DRQ number */ 98 int sc_cmd_async; /* asynchronous cmd pending */ 99 100 int sc_flags; 101 #define DASD_QUIET 0x01 /* don't dump cmd error info */ 102 #define DASD_MAXDEVS 8 103 struct ed_softc *sc_ed[DASD_MAXDEVS]; 104 struct ed_softc sc_controller; 105 }; 106 107 int edc_mca_probe __P((struct device *, struct cfdata *, void *)); 108 void edc_mca_attach __P((struct device *, struct device *, void *)); 109 110 struct cfattach edc_mca_ca = { 111 sizeof(struct edc_mca_softc), edc_mca_probe, edc_mca_attach 112 }; 113 114 #define DMA_EXTCMD 0x18 115 #define DMA_EXEC 0x1A 116 117 static int edc_intr __P((void *)); 118 static void edc_dump_status_block __P((struct edc_mca_softc *, int, int)); 119 static int edc_setup_dma __P((struct edc_mca_softc *, int, 120 bus_addr_t, bus_size_t)); 121 static int edc_do_attn __P((struct edc_mca_softc *, int, int, int)); 122 static int edc_cmd_wait __P((struct edc_mca_softc *, int, int, int)); 123 124 int 125 edc_mca_probe(parent, match, aux) 126 struct device *parent; 127 struct cfdata *match; 128 void *aux; 129 { 130 struct mca_attach_args *ma = aux; 131 132 switch (ma->ma_id) { 133 case MCA_PRODUCT_IBM_ESDIC: 134 case MCA_PRODUCT_IBM_ESDIC_IG: 135 return (1); 136 default: 137 return (0); 138 } 139 } 140 141 void 142 edc_mca_attach(parent, self, aux) 143 struct device *parent, *self; 144 void *aux; 145 { 146 struct edc_mca_softc *sc = (void *) self; 147 struct mca_attach_args *ma = aux; 148 int pos2, pos3, pos4; 149 int irq, drq, iobase; 150 const char *typestr; 151 struct ed_softc *ed; 152 struct ed_attach_args eda; 153 int devno, maxdevs; 154 155 pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2); 156 pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3); 157 pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4); 158 159 /* 160 * POS register 2: (adf pos0) 161 * 162 * 7 6 5 4 3 2 1 0 163 * \ \____/ \ \__ enable: 0=adapter disabled, 1=adapter enabled 164 * \ \ \___ Primary/Alternate Port Adresses: 165 * \ \ 0=0x3510-3517 1=0x3518-0x351f 166 * \ \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7 167 * \ 0000=0 0001=1 0011=3 0100=4 168 * \_________ Fairness On/Off: 1=On 0=Off 169 * 170 * POS register 3: (adf pos1) 171 * 172 * 7 6 5 4 3 2 1 0 173 * 0 0 \_/ 174 * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms 175 * 01=16ms 00=Burst Disabled 176 * 177 * POS register 4: (adf pos2) 178 * 179 * 7 6 5 4 3 2 1 0 180 * \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled 181 * \____ Time to Release: 1X=6ms 01=3ms 00=Immediate 182 * 183 * IRQ is fixed to 14 (0x0e). 184 */ 185 186 switch (ma->ma_id) { 187 case MCA_PRODUCT_IBM_ESDIC: 188 typestr = "IBM ESDI Fixed Disk Controller"; 189 break; 190 case MCA_PRODUCT_IBM_ESDIC_IG: 191 typestr = "IBM Integ. ESDI Fixed Disk & Controller"; 192 break; 193 default: 194 /* never reached */ 195 } 196 197 irq = ESDIC_IRQ; 198 iobase = (pos2 & IO_IS_ALT) ? ESDIC_IOALT : ESDIC_IOPRM; 199 drq = (pos2 & DRQ_MASK) >> 2; 200 201 printf(" slot %d irq %d drq %d: %s\n", ma->ma_slot+1, 202 irq, drq, typestr); 203 204 #ifdef DIAGNOSTIC 205 /* 206 * It's not strictly necessary to check this, machine configuration 207 * utility uses only valid adresses. 208 */ 209 if (drq == 2 || drq >= 8) { 210 printf("%s: invalid DMA Arbitration Level %d\n", 211 sc->sc_dev.dv_xname, drq); 212 return; 213 } 214 #endif 215 216 printf("%s: Fairness %s, Release %s, ", 217 sc->sc_dev.dv_xname, 218 (pos2 & FAIRNESS_ENABLE) ? "On" : "Off", 219 (pos4 & RELEASE_1) ? "6ms" 220 : ((pos4 & RELEASE_2) ? "3ms" : "Immediate") 221 ); 222 if ((pos4 & PACING_CTRL_DISABLE) == 0) { 223 static const char * const pacint[] = 224 { "disabled", "16ms", "24ms", "31ms"}; 225 printf("DMA burst pacing interval %s\n", 226 pacint[(pos3 & PACING_INT_MASK) >> 4]); 227 } else 228 printf("DMA pacing control disabled\n"); 229 230 sc->sc_iot = ma->ma_iot; 231 sc->sc_drq = drq; 232 233 if (bus_space_map(sc->sc_iot, iobase, 234 ESDIC_REG_NPORTS, 0, &sc->sc_ioh)) { 235 printf("%s: couldn't map registers\n", 236 sc->sc_dev.dv_xname); 237 return; 238 } 239 240 if (bus_space_map(sc->sc_iot, DMA_EXTCMD, 1, 0, &sc->sc_dmaextcmdh)) { 241 printf("%s: couldn't map registers\n", 242 sc->sc_dev.dv_xname); 243 return; 244 } 245 if (bus_space_map(sc->sc_iot, DMA_EXEC, 1, 0, &sc->sc_dmaexech)) { 246 printf("%s: couldn't map registers\n", 247 sc->sc_dev.dv_xname); 248 return; 249 } 250 251 sc->sc_dmat = ma->ma_dmat; 252 253 sc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_BIO, edc_intr, sc); 254 if (sc->sc_ih == NULL) { 255 printf("%s: couldn't establish interrupt handler\n", 256 sc->sc_dev.dv_xname); 257 return; 258 } 259 260 /* 261 * Integrated ESDI controller supports only one disk, other 262 * controllers support two disks. 263 */ 264 if (ma->ma_id == MCA_PRODUCT_IBM_ESDIC_IG) 265 maxdevs = 1; 266 else 267 maxdevs = 2; 268 269 /* 270 * Initialize the controller ed softc. We could do without this, 271 * but absence of checks for controller devno simplifies code logic 272 * somewhat. 273 */ 274 sc->sc_ed[DASD_DEVNO_CONTROLLER] = &sc->sc_controller; 275 strcpy(sc->sc_controller.sc_dev.dv_xname, sc->sc_dev.dv_xname);/*safe*/ 276 277 /* 278 * Reset controller and attach individual disks. ed attach routine 279 * uses polling so that this works with interrupts disabled. 280 */ 281 282 /* Do a reset to ensure sane state after warm boot. */ 283 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) { 284 /* hard reset */ 285 printf("%s: controller busy, performing hardware reset ...\n", 286 sc->sc_dev.dv_xname); 287 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 288 BCR_INT_ENABLE|BCR_RESET); 289 } else { 290 /* "SOFT" reset */ 291 edc_do_attn(sc, ATN_RESET_ATTACHMENT, DASD_DEVNO_CONTROLLER,0); 292 } 293 294 /* 295 * Since interrupts are disabled ATM, it's necessary 296 * to detect the interrupt request and call edc_intr() 297 * explicitly. See also edc_run_cmd(). 298 */ 299 while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) { 300 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) 301 edc_intr(sc); 302 303 delay(100); 304 } 305 306 /* 307 * Get dummy ed_softc to be used during probe. Once a disk is 308 * found, ed_mca_attach() calls edc_add_disk() to insert the 309 * right pointer into sc->sc_ed[] array. 310 */ 311 MALLOC(ed, struct ed_softc *, sizeof(struct ed_softc), 312 M_TEMP, M_WAITOK); 313 314 /* be quiet duting probes */ 315 sc->sc_flags |= DASD_QUIET; 316 317 /* check for attached disks */ 318 for(devno=0; devno < maxdevs; devno++) { 319 eda.sc_devno = devno; 320 eda.sc_dmat = sc->sc_dmat; 321 sc->sc_ed[devno] = ed; 322 (void *) config_found_sm(self, &eda, NULL, NULL); 323 } 324 325 /* enable full error dumps again */ 326 sc->sc_flags &= ~DASD_QUIET; 327 328 /* cleanup */ 329 FREE(ed, M_TEMP); 330 331 /* 332 * Check if there are any disks attached. If not, disestablish 333 * the interrupt. 334 */ 335 for(devno=0; devno < maxdevs; devno++) { 336 if (sc->sc_ed[devno] && (sc->sc_ed[devno]->sc_flags & EDF_INIT)) 337 break; 338 } 339 if (devno == maxdevs) { 340 printf("%s: disabling controller (no drives attached)\n", 341 sc->sc_dev.dv_xname); 342 mca_intr_disestablish(ma->ma_mc, sc->sc_ih); 343 } 344 } 345 346 void 347 edc_add_disk(sc, ed, devno) 348 struct edc_mca_softc *sc; 349 struct ed_softc *ed; 350 int devno; 351 { 352 sc->sc_ed[devno] = ed; 353 } 354 355 static int 356 edc_intr(arg) 357 void *arg; 358 { 359 struct edc_mca_softc *sc = arg; 360 u_int8_t isr, intr_id; 361 u_int16_t sifr; 362 int cmd=-1, devno, bioerror=0; 363 struct ed_softc *ed=NULL; 364 365 /* 366 * Check if the interrupt was for us. 367 */ 368 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) == 0) 369 return (0); 370 371 /* 372 * Read ISR to find out interrupt type. This also clears the interrupt 373 * condition and BSR_INTR flag. Accordings to docs interrupt ID of 0, 2 374 * and 4 are reserved and not used. 375 */ 376 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ISR); 377 intr_id = isr & ISR_INTR_ID_MASK; 378 379 #ifdef DEBUG 380 if (intr_id == 0 || intr_id == 2 || intr_id == 4) { 381 printf("%s: bogus interrupt id %d\n", sc->sc_dev.dv_xname, 382 (int) intr_id); 383 return (0); 384 } 385 #endif 386 387 /* Get number of device whose intr this was */ 388 devno = (isr & 0xe0) >> 5; 389 390 /* 391 * Get Status block. Higher byte always says how long the status 392 * block is, rest is device number and command code. 393 * Check the status block length against our supported maximum length 394 * and fetch the data. 395 */ 396 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,BSR) & BSR_SIFR_FULL) { 397 size_t len; 398 int i; 399 400 sifr = le16toh(bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); 401 len = (sifr & 0xff00) >> 8; 402 #ifdef DEBUG 403 if (len > DASD_MAX_CMD_RES_LEN) 404 panic("%s: maximum Status Length exceeded: %d > %d", 405 sc->sc_dev.dv_xname, 406 len, DASD_MAX_CMD_RES_LEN); 407 #endif 408 409 /* Get command code */ 410 cmd = sifr & SIFR_CMD_MASK; 411 412 /* Read whole status block */ 413 ed = sc->sc_ed[devno]; 414 ed->sc_status_block[0] = sifr; 415 for(i=1; i < len; i++) { 416 while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) 417 & BSR_SIFR_FULL) == 0) 418 delay(1); 419 420 ed->sc_status_block[i] = le16toh( 421 bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); 422 } 423 } 424 425 switch (intr_id) { 426 case ISR_DATA_TRANSFER_RDY: 427 /* 428 * Ready to do DMA, setup DMA controller and kick DASD 429 * controller to do the transfer. 430 */ 431 ed = sc->sc_ed[devno]; 432 if (!edc_setup_dma(sc, ed->sc_read, 433 ed->dmamap_xfer->dm_segs[0].ds_addr, 434 ed->dmamap_xfer->dm_segs[0].ds_len)) { 435 /* XXX bail out? */ 436 printf("%s: edc_setup_dma() failed\n", 437 ed->sc_dev.dv_xname); 438 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 439 BCR_INT_ENABLE); 440 } else { 441 /* OK, proceed with DMA */ 442 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 443 BCR_INT_ENABLE|BCR_DMA_ENABLE); 444 } 445 break; 446 case ISR_COMPLETED: 447 case ISR_COMPLETED_WITH_ECC: 448 case ISR_COMPLETED_RETRIES: 449 case ISR_COMPLETED_WARNING: 450 bioerror = 0; 451 break; 452 case ISR_RESET_COMPLETED: 453 case ISR_ABORT_COMPLETED: 454 /* nothing to do */ 455 break; 456 default: 457 if ((sc->sc_flags & DASD_QUIET) == 0) 458 edc_dump_status_block(sc, devno, intr_id); 459 460 bioerror = EIO; 461 break; 462 } 463 464 /* 465 * Unless the interrupt is for Data Transfer Ready or 466 * Attention Error, finish by assertion EOI. This makes 467 * attachment aware the interrupt is processed and system 468 * is ready to accept another one. 469 */ 470 if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR) 471 edc_do_attn(sc, ATN_END_INT, devno, intr_id); 472 473 /* If Read or Write Data, wakeup worker thread to finish it */ 474 if (intr_id != ISR_DATA_TRANSFER_RDY 475 && (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)) { 476 sc->sc_ed[devno]->sc_error = bioerror; 477 wakeup_one(&sc->sc_ed[devno]->edc_softc); 478 } 479 480 return (1); 481 } 482 483 /* 484 * This follows the exact order for Attention Request as 485 * written in DASD Storage Interface Specification MC (Rev 2.2). 486 */ 487 static int 488 edc_do_attn(sc, attn_type, devno, intr_id) 489 struct edc_mca_softc *sc; 490 int attn_type, devno, intr_id; 491 { 492 int tries; 493 494 /* 1. Disable interrupts in BCR. */ 495 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0); 496 497 /* 498 * 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging 499 * a RESET COMPLETED interrupt. 500 */ 501 if (intr_id != ISR_RESET_COMPLETED) { 502 for(tries=1; tries < EDC_ATTN_MAXTRIES; tries++) { 503 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) 504 & BSR_BUSY) == 0) { 505 #ifdef DEBUG 506 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, 507 BSR) & BSR_INT_PENDING) && intr_id) 508 panic("foobar"); 509 #endif 510 break; 511 } 512 } 513 514 if (tries == EDC_ATTN_MAXTRIES) { 515 printf("%s: edc_do_attn: timeout waiting for attachment to become available\n", 516 sc->sc_ed[devno]->sc_dev.dv_xname); 517 return (EAGAIN); 518 } 519 } 520 521 /* 522 * 3. Write proper DEVICE NUMBER and Attention number to ATN. 523 */ 524 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN, 525 attn_type | (devno << 5)); 526 527 /* 528 * 4. Enable interrupts via BCR. 529 */ 530 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE); 531 532 return (0); 533 } 534 535 /* 536 * Wait until command is processed, timeout after 'secs' seconds. 537 * We use mono_time, since we don't need actual RTC, just time 538 * interval. 539 */ 540 static int 541 edc_cmd_wait(sc, devno, secs, poll) 542 struct edc_mca_softc *sc; 543 int devno, secs, poll; 544 { 545 int val, delayed; 546 547 delayed = 0; 548 do { 549 val = bus_space_read_1(sc->sc_iot,sc->sc_ioh, BSR); 550 if ((val & BSR_CMD_INPROGRESS) == 0) 551 break; 552 553 if (poll && (val & BSR_INTR)) 554 goto out; 555 556 if (secs == 0) 557 break; 558 559 delay(1); 560 561 /* 562 * This is not as accurate as checking mono_time, but 563 * it works with hardclock interrupts disabled too. 564 */ 565 delayed++; 566 if (delayed == 1000000) { 567 delayed = 0; 568 secs--; 569 } 570 #if 0 571 if (delayed % 1000) 572 printf("looping ..."); 573 #endif 574 } while(1); 575 576 if (secs == 0 && 577 bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CMD_INPROGRESS){ 578 printf("%s: timed out waiting for previous cmd to finish\n", 579 sc->sc_ed[devno]->sc_dev.dv_xname); 580 return (EAGAIN); 581 } 582 583 out: 584 return (0); 585 } 586 587 int 588 edc_run_cmd(sc, cmd, devno, cmd_args, cmd_len, async, poll) 589 struct edc_mca_softc *sc; 590 int cmd; 591 int devno; 592 u_int16_t cmd_args[]; 593 int cmd_len, async, poll; 594 { 595 int i, error, tries; 596 u_int16_t cmd0; 597 598 /* 599 * If there has been an asynchronous command executed, first wait for it 600 * to finish. 601 */ 602 if (sc->sc_cmd_async) { 603 /* Wait maximum 15s */ 604 if (edc_cmd_wait(sc, devno, 15, 0)) 605 return (EAGAIN); /* Busy */ 606 607 sc->sc_cmd_async = 0; 608 } 609 610 /* Do Attention Request for Command Request. */ 611 if ((error = edc_do_attn(sc, ATN_CMD_REQ, devno, 0))) 612 return (error); 613 614 /* 615 * Construct the command. The bits are like this: 616 * 617 * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 618 * \_/ 0 0 1 0 \__/ \_____/ 619 * \ \__________/ \ \_ Command Code (see CMD_*) 620 * \ \ \__ Device: 0 common, 7 controller 621 * \ \__ Options: reserved, bit 10=cache bypass bit 622 * \_ Type: 00=2B, 01=4B, 10 and 11 reserved 623 * 624 * We always use device 0 or 1, so difference is made only by Command 625 * Code, Command Options and command length. 626 */ 627 cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0) 628 | (devno << 5) 629 | (cmd_args[0] << 8) | cmd; 630 cmd_args[0] = cmd0; 631 632 /* 633 * Write word of CMD to the CIFR. This sets "Command 634 * Interface Register Full (CMD IN)" in BSR. Once the attachment 635 * detects it, it reads the word and clears CMD IN. 636 */ 637 for(i=0; i < cmd_len; i++) { 638 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR, 639 htole16(cmd_args[i])); 640 641 /* 642 * Wait until CMD IN is cleared. The 1ms delay for polling 643 * case is necessary, otherwise e.g. system dump gets stuck 644 * soon. Quirky hw ? 645 */ 646 tries = 0; 647 while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_CIFR_FULL) 648 delay(poll ? 1000 : 1); 649 } 650 651 /* 652 * Attachment is now executing the command. Unless we are executing 653 * command asynchronously, wait until it finishes. 654 */ 655 if (async) { 656 sc->sc_cmd_async = 1; 657 return (0); 658 } 659 660 /* Wait for command to complete, but maximum 15 seconds. */ 661 if (edc_cmd_wait(sc, devno, 15, poll)) 662 return (EAGAIN); 663 664 /* If polling, call edc_intr() explicitly */ 665 if (poll) { 666 edc_intr(sc); 667 668 /* 669 * If got attention id DATA TRANSFER READY, wait for 670 * the transfer to finish. 671 */ 672 if (sc->sc_ed[devno]->sc_error == 0 673 && (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA)) { 674 if (edc_cmd_wait(sc, devno, 15, 1)) 675 return (EAGAIN); 676 edc_intr(sc); 677 } 678 679 if (edc_cmd_wait(sc, devno, 15, 0)) 680 return (EAGAIN); 681 } 682 683 /* Check if the command completed successfully; if not, return error */ 684 switch(SB_GET_CMD_STATUS(sc->sc_ed[devno]->sc_status_block)) { 685 case ISR_COMPLETED: 686 case ISR_COMPLETED_WITH_ECC: 687 case ISR_COMPLETED_RETRIES: 688 case ISR_COMPLETED_WARNING: 689 return (0); 690 default: 691 return (EIO); 692 } 693 } 694 695 static int 696 edc_setup_dma(sc, isread, phys, cnt) 697 struct edc_mca_softc *sc; 698 int isread; 699 bus_addr_t phys; 700 bus_size_t cnt; 701 { 702 /* XXX magic constants, should be moved to device-independant location*/ 703 /* The exact sequence to setup MCA DMA controller is taken from Minix */ 704 705 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, 706 0x90 + sc->sc_drq); 707 /* Disable access to dma channel */ 708 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, 709 0x20 + sc->sc_drq); 710 /* Clear the address byte pointer */ 711 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, 712 (phys >> 0) & 0xff); /* address bits 0..7 */ 713 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, 714 (phys >> 8) & 0xff); /* address bits 8..15 */ 715 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, 716 (phys >> 16) & 0xff); /* address bits 16..23 */ 717 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, 718 0x40 + sc->sc_drq); 719 /* Clear the count byte pointer */ 720 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, 721 ((cnt - 1) >> 0) & 0xff); /* count bits 0..7 */ 722 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, 723 ((cnt - 1) >> 8) & 0xff); /* count bits 8..15 */ 724 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, 725 0x70 + sc->sc_drq); 726 /* Set the transfer mode */ 727 bus_space_write_1(sc->sc_iot, sc->sc_dmaexech, 0, 728 (isread) ? 0x4C : 0x44); 729 bus_space_write_1(sc->sc_iot, sc->sc_dmaextcmdh, 0, 730 0xA0 + sc->sc_drq); 731 /* Enable access to dma channel */ 732 733 return (1); 734 } 735 736 static const char * const edc_commands[] = { 737 "Invalid Command", 738 "Read Data", 739 "Write Data", 740 "Read Verify", 741 "Write with Verify", 742 "Seek", 743 "Park Head", 744 "Get Command Complete Status", 745 "Get Device Status", 746 "Get Device Configuration", 747 "Get POS Information", 748 "Translate RBA", 749 "Write Attachment Buffer", 750 "Read Attachment Buffer", 751 "Run Diagnostic Test", 752 "Get Diagnostic Status Block", 753 "Get MFG Header", 754 "Format Unit", 755 "Format Prepare", 756 "Set MAX RBA", 757 "Set Power Saving Mode", 758 "Power Conservation Command", 759 }; 760 761 static const char * const edc_cmd_status[256] = { 762 "Reserved", 763 "Command completed successfully", 764 "Reserved", 765 "Command completed successfully with ECC applied", 766 "Reserved", 767 "Command completed successfully with retries", 768 "Format Command partially completed", /* Status available */ 769 "Command completed successfully with ECC and retries", 770 "Command completed with Warning", /* Command Error is available */ 771 "Aborted", 772 "Reset completed", 773 "Data Transfer Ready", /* No Status Block available */ 774 "Command terminated with failure", /* Device Error is available */ 775 "DMA Error", /* Retry entire command as recovery */ 776 "Command Block Error", 777 "Attention Error (Illegal Attention Code)", 778 /* 0x14 - 0xff reserved */ 779 }; 780 781 static const char * const edc_cmd_error[256] = { 782 "No Error", 783 "Invalid parameter in the command block", 784 "Reserved", 785 "Command not supported", 786 "Command Aborted per request", 787 "Reserved", 788 "Command rejected", /* Attachment diagnostic failure */ 789 "Format Rejected", /* Prepare Format command is required */ 790 "Format Error (Primary Map is not readable)", 791 "Format Error (Secondary map is not readable)", 792 "Format Error (Diagnostic Failure)", 793 "Format Warning (Secondary Map Overflow)", 794 "Reserved" 795 "Format Error (Host Checksum Error)", 796 "Reserved", 797 "Format Warning (Push table overflow)", 798 "Format Warning (More pushes than allowed)", 799 "Reserved", 800 "Format Warning (Error during verifying)", 801 "Invalid device number for the command", 802 /* 0x14-0xff reserved */ 803 }; 804 805 static const char * const edc_dev_errors[] = { 806 "No Error", 807 "Seek Fault", /* Device report */ 808 "Interface Fault (Parity, Attn, or Cmd Complete Error)", 809 "Block not found (ID not found)", 810 "Block not found (AM not found)", 811 "Data ECC Error (hard error)", 812 "ID CRC Error", 813 "RBA Out of Range", 814 "Reserved", 815 "Defective Block", 816 "Reserved", 817 "Selection Error", 818 "Reserved", 819 "Write Fault", 820 "No index or sector pulse", 821 "Device Not Ready", 822 "Seek Error", /* Attachment report */ 823 "Bad Format", 824 "Volume Overflow", 825 "No Data AM Found", 826 "Block not found (No ID AM or ID CRC error occurred)", 827 "Reserved", 828 "Reserved", 829 "No ID found on track (ID search)", 830 /* 0x19 - 0xff reserved */ 831 }; 832 833 static void 834 edc_dump_status_block(sc, devno, intr_id) 835 struct edc_mca_softc *sc; 836 int devno, intr_id; 837 { 838 struct ed_softc *ed = sc->sc_ed[devno]; 839 printf("%s: Command: %s, Status: %s\n", 840 ed->sc_dev.dv_xname, 841 edc_commands[ed->sc_status_block[0] & 0x1f], 842 edc_cmd_status[SB_GET_CMD_STATUS(ed->sc_status_block)] 843 ); 844 printf("%s: # left blocks: %u, last processed RBA: %u\n", 845 ed->sc_dev.dv_xname, 846 ed->sc_status_block[SB_RESBLKCNT_IDX], 847 (ed->sc_status_block[5] << 16) | ed->sc_status_block[4]); 848 849 if (intr_id == ISR_COMPLETED_WARNING) { 850 printf("%s: Command Error Code: %s\n", 851 ed->sc_dev.dv_xname, 852 edc_cmd_error[ed->sc_status_block[1] & 0xff]); 853 } 854 855 if (intr_id == ISR_CMD_FAILED) { 856 char buf[100]; 857 858 printf("%s: Device Error Code: %s\n", 859 ed->sc_dev.dv_xname, 860 edc_dev_errors[ed->sc_status_block[2] & 0xff]); 861 bitmask_snprintf((ed->sc_status_block[2] & 0xff00) >> 8, 862 "\20" 863 "\01SeekOrCmdComplete" 864 "\02Track0Flag" 865 "\03WriteFault" 866 "\04Selected" 867 "\05Ready" 868 "\06Reserved0" 869 "\07STANDBY" 870 "\010Reserved0", 871 buf, sizeof(buf)); 872 printf("%s: Device Status: %s\n", 873 ed->sc_dev.dv_xname, buf); 874 } 875 } 876