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