1 /* $NetBSD: edc_mca.c,v 1.16 2002/03/31 10:01:26 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 * - improve error recovery 45 * Issue soft reset on error or timeout? 46 * - test with > 1 disk (this is supported by some controllers) 47 * - test with > 1 ESDI controller in machine; shared interrupts 48 * necessary for this to work should be supported - edc_intr() specifically 49 * checks if the interrupt is for this controller 50 */ 51 52 #include <sys/cdefs.h> 53 __KERNEL_RCSID(0, "$NetBSD: edc_mca.c,v 1.16 2002/03/31 10:01:26 jdolecek Exp $"); 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 #include <sys/kthread.h> 70 #if NRND > 0 71 #include <sys/rnd.h> 72 #endif 73 74 #include <machine/bus.h> 75 #include <machine/intr.h> 76 77 #include <dev/mca/mcareg.h> 78 #include <dev/mca/mcavar.h> 79 #include <dev/mca/mcadevs.h> 80 81 #include <dev/mca/edcreg.h> 82 #include <dev/mca/edvar.h> 83 #include <dev/mca/edcvar.h> 84 85 #define EDC_ATTN_MAXTRIES 10000 /* How many times check for unbusy */ 86 #define EDC_MAX_CMD_RES_LEN 8 87 88 struct edc_mca_softc { 89 struct device sc_dev; 90 91 bus_space_tag_t sc_iot; 92 bus_space_handle_t sc_ioh; 93 94 /* DMA related stuff */ 95 bus_dma_tag_t sc_dmat; /* DMA tag as passed by parent */ 96 bus_dmamap_t sc_dmamap_xfer; /* transfer dma map */ 97 98 void *sc_ih; /* interrupt handle */ 99 100 int sc_flags; 101 #define DASD_QUIET 0x01 /* don't dump cmd error info */ 102 103 #define DASD_MAXDEVS 8 104 struct ed_softc *sc_ed[DASD_MAXDEVS]; 105 int sc_maxdevs; /* max number of disks attached to this 106 * controller */ 107 108 /* I/O results variables */ 109 volatile int sc_stat; 110 #define STAT_START 0 111 #define STAT_ERROR 1 112 #define STAT_DONE 2 113 volatile int sc_resblk; /* residual block count */ 114 115 /* CMD status block - only set & used in edc_intr() */ 116 u_int16_t status_block[EDC_MAX_CMD_RES_LEN]; 117 }; 118 119 int edc_mca_probe __P((struct device *, struct cfdata *, void *)); 120 void edc_mca_attach __P((struct device *, struct device *, void *)); 121 122 struct cfattach edc_mca_ca = { 123 sizeof(struct edc_mca_softc), edc_mca_probe, edc_mca_attach 124 }; 125 126 static int edc_intr __P((void *)); 127 static void edc_dump_status_block __P((struct edc_mca_softc *, 128 u_int16_t *, int)); 129 static int edc_do_attn __P((struct edc_mca_softc *, int, int, int)); 130 static void edc_cmd_wait __P((struct edc_mca_softc *, int, int)); 131 static void edcworker __P((void *)); 132 static void edc_spawn_worker __P((void *)); 133 134 int 135 edc_mca_probe(parent, match, aux) 136 struct device *parent; 137 struct cfdata *match; 138 void *aux; 139 { 140 struct mca_attach_args *ma = aux; 141 142 switch (ma->ma_id) { 143 case MCA_PRODUCT_IBM_ESDIC: 144 case MCA_PRODUCT_IBM_ESDIC_IG: 145 return (1); 146 default: 147 return (0); 148 } 149 } 150 151 void 152 edc_mca_attach(parent, self, aux) 153 struct device *parent, *self; 154 void *aux; 155 { 156 struct edc_mca_softc *sc = (void *) self; 157 struct mca_attach_args *ma = aux; 158 struct ed_attach_args eda; 159 int pos2, pos3, pos4; 160 int irq, drq, iobase; 161 const char *typestr; 162 int devno, error; 163 164 pos2 = mca_conf_read(ma->ma_mc, ma->ma_slot, 2); 165 pos3 = mca_conf_read(ma->ma_mc, ma->ma_slot, 3); 166 pos4 = mca_conf_read(ma->ma_mc, ma->ma_slot, 4); 167 168 /* 169 * POS register 2: (adf pos0) 170 * 171 * 7 6 5 4 3 2 1 0 172 * \ \____/ \ \__ enable: 0=adapter disabled, 1=adapter enabled 173 * \ \ \___ Primary/Alternate Port Adresses: 174 * \ \ 0=0x3510-3517 1=0x3518-0x351f 175 * \ \_____ DMA Arbitration Level: 0101=5 0110=6 0111=7 176 * \ 0000=0 0001=1 0011=3 0100=4 177 * \_________ Fairness On/Off: 1=On 0=Off 178 * 179 * POS register 3: (adf pos1) 180 * 181 * 7 6 5 4 3 2 1 0 182 * 0 0 \_/ 183 * \__________ DMA Burst Pacing Interval: 10=24ms 11=31ms 184 * 01=16ms 00=Burst Disabled 185 * 186 * POS register 4: (adf pos2) 187 * 188 * 7 6 5 4 3 2 1 0 189 * \_/ \__ DMA Pacing Control: 1=Disabled 0=Enabled 190 * \____ Time to Release: 1X=6ms 01=3ms 00=Immediate 191 * 192 * IRQ is fixed to 14 (0x0e). 193 */ 194 195 switch (ma->ma_id) { 196 case MCA_PRODUCT_IBM_ESDIC: 197 typestr = "IBM ESDI Fixed Disk Controller"; 198 break; 199 case MCA_PRODUCT_IBM_ESDIC_IG: 200 typestr = "IBM Integ. ESDI Fixed Disk & Controller"; 201 break; 202 default: 203 /* never reached */ ; 204 } 205 206 irq = ESDIC_IRQ; 207 iobase = (pos2 & IO_IS_ALT) ? ESDIC_IOALT : ESDIC_IOPRM; 208 drq = (pos2 & DRQ_MASK) >> 2; 209 210 printf(" slot %d irq %d drq %d: %s\n", ma->ma_slot+1, 211 irq, drq, typestr); 212 213 #ifdef DIAGNOSTIC 214 /* 215 * It's not strictly necessary to check this, machine configuration 216 * utility uses only valid adresses. 217 */ 218 if (drq == 2 || drq >= 8) { 219 printf("%s: invalid DMA Arbitration Level %d\n", 220 sc->sc_dev.dv_xname, drq); 221 return; 222 } 223 #endif 224 225 printf("%s: Fairness %s, Release %s, ", 226 sc->sc_dev.dv_xname, 227 (pos2 & FAIRNESS_ENABLE) ? "On" : "Off", 228 (pos4 & RELEASE_1) ? "6ms" 229 : ((pos4 & RELEASE_2) ? "3ms" : "Immediate") 230 ); 231 if ((pos4 & PACING_CTRL_DISABLE) == 0) { 232 static const char * const pacint[] = 233 { "disabled", "16ms", "24ms", "31ms"}; 234 printf("DMA burst pacing interval %s\n", 235 pacint[(pos3 & PACING_INT_MASK) >> 4]); 236 } else 237 printf("DMA pacing control disabled\n"); 238 239 sc->sc_iot = ma->ma_iot; 240 241 if (bus_space_map(sc->sc_iot, iobase, 242 ESDIC_REG_NPORTS, 0, &sc->sc_ioh)) { 243 printf("%s: couldn't map registers\n", 244 sc->sc_dev.dv_xname); 245 return; 246 } 247 248 sc->sc_ih = mca_intr_establish(ma->ma_mc, irq, IPL_BIO, edc_intr, sc); 249 if (sc->sc_ih == NULL) { 250 printf("%s: couldn't establish interrupt handler\n", 251 sc->sc_dev.dv_xname); 252 return; 253 } 254 255 /* Create a MCA DMA map, used for data transfer */ 256 sc->sc_dmat = ma->ma_dmat; 257 if ((error = mca_dmamap_create(sc->sc_dmat, MAXPHYS, 258 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | MCABUS_DMA_16BIT, 259 &sc->sc_dmamap_xfer, drq)) != 0){ 260 printf("%s: couldn't create DMA map - error %d\n", 261 sc->sc_dev.dv_xname, error); 262 return; 263 } 264 265 /* 266 * Integrated ESDI controller supports only one disk, other 267 * controllers support two disks. 268 */ 269 if (ma->ma_id == MCA_PRODUCT_IBM_ESDIC_IG) 270 sc->sc_maxdevs = 1; 271 else 272 sc->sc_maxdevs = 2; 273 274 /* 275 * Reset controller and attach individual disks. ed attach routine 276 * uses polling so that this works with interrupts disabled. 277 */ 278 279 /* Do a reset to ensure sane state after warm boot. */ 280 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) { 281 /* hard reset */ 282 printf("%s: controller busy, performing hardware reset ...\n", 283 sc->sc_dev.dv_xname); 284 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 285 BCR_INT_ENABLE|BCR_RESET); 286 } else { 287 /* "SOFT" reset */ 288 edc_do_attn(sc, ATN_RESET_ATTACHMENT, DASD_DEVNO_CONTROLLER,0); 289 } 290 291 /* 292 * Since interrupts are disabled, it's necessary 293 * to detect the interrupt request and call edc_intr() 294 * explicitly. See also edc_run_cmd(). 295 */ 296 while(bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_BUSY) { 297 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) 298 edc_intr(sc); 299 300 delay(100); 301 } 302 303 /* be quiet during probes */ 304 sc->sc_flags |= DASD_QUIET; 305 306 /* check for attached disks */ 307 for(devno=0; devno < sc->sc_maxdevs; devno++) { 308 eda.edc_drive = devno; 309 sc->sc_ed[devno] = 310 (void *) config_found_sm(self, &eda, NULL, NULL); 311 312 /* If initialization did not succeed, NULL the pointer. */ 313 if (sc->sc_ed[devno] 314 && (sc->sc_ed[devno]->sc_flags & EDF_INIT) == 0) 315 sc->sc_ed[devno] = NULL; 316 } 317 318 /* enable full error dumps again */ 319 sc->sc_flags &= ~DASD_QUIET; 320 321 /* 322 * Check if there are any disks attached. If not, disestablish 323 * the interrupt. 324 */ 325 for(devno=0; devno < sc->sc_maxdevs; devno++) { 326 if (sc->sc_ed[devno]) 327 break; 328 } 329 330 if (devno == sc->sc_maxdevs) { 331 printf("%s: disabling controller (no drives attached)\n", 332 sc->sc_dev.dv_xname); 333 mca_intr_disestablish(ma->ma_mc, sc->sc_ih); 334 return; 335 } 336 337 /* 338 * Run the worker thread. 339 */ 340 config_pending_incr(); 341 kthread_create(edc_spawn_worker, (void *) sc); 342 } 343 344 void 345 edc_add_disk(sc, ed) 346 struct edc_mca_softc *sc; 347 struct ed_softc *ed; 348 { 349 sc->sc_ed[ed->sc_devno] = ed; 350 } 351 352 static int 353 edc_intr(arg) 354 void *arg; 355 { 356 struct edc_mca_softc *sc = arg; 357 u_int8_t isr, intr_id; 358 u_int16_t sifr; 359 int cmd=-1, devno; 360 361 /* 362 * Check if the interrupt was for us. 363 */ 364 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) & BSR_INTR) == 0) 365 return (0); 366 367 /* 368 * Read ISR to find out interrupt type. This also clears the interrupt 369 * condition and BSR_INTR flag. Accordings to docs interrupt ID of 0, 2 370 * and 4 are reserved and not used. 371 */ 372 isr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ISR); 373 intr_id = isr & ISR_INTR_ID_MASK; 374 375 #ifdef EDC_DEBUG 376 if (intr_id == 0 || intr_id == 2 || intr_id == 4) { 377 printf("%s: bogus interrupt id %d\n", sc->sc_dev.dv_xname, 378 (int) intr_id); 379 return (0); 380 } 381 #endif 382 383 /* Get number of device whose intr this was */ 384 devno = (isr & 0xe0) >> 5; 385 386 /* 387 * Get Status block. Higher byte always says how long the status 388 * block is, rest is device number and command code. 389 * Check the status block length against our supported maximum length 390 * and fetch the data. 391 */ 392 if (bus_space_read_1(sc->sc_iot, sc->sc_ioh,BSR) & BSR_SIFR_FULL) { 393 size_t len; 394 int i; 395 396 sifr = le16toh(bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); 397 len = (sifr & 0xff00) >> 8; 398 #ifdef DEBUG 399 if (len > EDC_MAX_CMD_RES_LEN) 400 panic("%s: maximum Status Length exceeded: %d > %d", 401 sc->sc_dev.dv_xname, 402 len, EDC_MAX_CMD_RES_LEN); 403 #endif 404 405 /* Get command code */ 406 cmd = sifr & SIFR_CMD_MASK; 407 408 /* Read whole status block */ 409 sc->status_block[0] = sifr; 410 for(i=1; i < len; i++) { 411 while((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) 412 & BSR_SIFR_FULL) == 0) 413 ; 414 415 sc->status_block[i] = le16toh( 416 bus_space_read_2(sc->sc_iot, sc->sc_ioh, SIFR)); 417 } 418 /* zero out rest */ 419 if (i < EDC_MAX_CMD_RES_LEN) { 420 memset(&sc->status_block[i], 0, 421 (EDC_MAX_CMD_RES_LEN-i)*sizeof(u_int16_t)); 422 } 423 } 424 425 switch (intr_id) { 426 case ISR_DATA_TRANSFER_RDY: 427 /* 428 * Ready to do DMA. The DMA controller has already been 429 * setup, now just kick disk controller to do the transfer. 430 */ 431 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 432 BCR_INT_ENABLE|BCR_DMA_ENABLE); 433 break; 434 435 case ISR_COMPLETED: 436 case ISR_COMPLETED_WITH_ECC: 437 case ISR_COMPLETED_RETRIES: 438 case ISR_COMPLETED_WARNING: 439 /* 440 * Copy device config data if appropriate. sc->sc_ed[] 441 * entry might be NULL during probe. 442 */ 443 if (cmd == CMD_GET_DEV_CONF && sc->sc_ed[devno]) { 444 memcpy(sc->sc_ed[devno]->sense_data, sc->status_block, 445 sizeof(sc->sc_ed[devno]->sense_data)); 446 } 447 448 sc->sc_stat = STAT_DONE; 449 break; 450 451 case ISR_RESET_COMPLETED: 452 case ISR_ABORT_COMPLETED: 453 /* nothing to do */ 454 break; 455 456 case ISR_ATTN_ERROR: 457 /* 458 * Basically, this means driver bug or something seriously 459 * hosed. panic rather than extending the lossage. 460 * No status block available, so no further info. 461 */ 462 panic("%s: dev %d: attention error", 463 sc->sc_dev.dv_xname, 464 devno); 465 /* NOTREACHED */ 466 break; 467 468 default: 469 if ((sc->sc_flags & DASD_QUIET) == 0) 470 edc_dump_status_block(sc, sc->status_block, intr_id); 471 472 sc->sc_stat = STAT_ERROR; 473 break; 474 } 475 476 /* 477 * Unless the interrupt is for Data Transfer Ready or 478 * Attention Error, finish by assertion EOI. This makes 479 * attachment aware the interrupt is processed and system 480 * is ready to accept another one. 481 */ 482 if (intr_id != ISR_DATA_TRANSFER_RDY && intr_id != ISR_ATTN_ERROR) 483 edc_do_attn(sc, ATN_END_INT, devno, intr_id); 484 485 /* If Read or Write Data, wakeup worker thread to finish it */ 486 if (intr_id != ISR_DATA_TRANSFER_RDY) { 487 if (cmd == CMD_READ_DATA || cmd == CMD_WRITE_DATA) 488 sc->sc_resblk = sc->status_block[SB_RESBLKCNT_IDX]; 489 wakeup_one(sc); 490 } 491 492 return (1); 493 } 494 495 /* 496 * This follows the exact order for Attention Request as 497 * written in DASD Storage Interface Specification MC (Rev 2.2). 498 */ 499 static int 500 edc_do_attn(sc, attn_type, devno, intr_id) 501 struct edc_mca_softc *sc; 502 int attn_type, devno, intr_id; 503 { 504 int tries; 505 506 /* 1. Disable interrupts in BCR. */ 507 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, 0); 508 509 /* 510 * 2. Assure NOT BUSY and NO INTERRUPT PENDING, unless acknowledging 511 * a RESET COMPLETED interrupt. 512 */ 513 if (intr_id != ISR_RESET_COMPLETED) { 514 #ifdef EDC_DEBUG 515 if (attn_type == ATN_CMD_REQ 516 && (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) 517 & BSR_INT_PENDING)) 518 panic("%s: edc int pending", sc->sc_dev.dv_xname); 519 #endif 520 521 for(tries=1; tries < EDC_ATTN_MAXTRIES; tries++) { 522 if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) 523 & BSR_BUSY) == 0) 524 break; 525 } 526 527 if (tries == EDC_ATTN_MAXTRIES) { 528 printf("%s: edc_do_attn: timeout waiting for attachment to become available\n", 529 sc->sc_ed[devno]->sc_dev.dv_xname); 530 return (EIO); 531 } 532 } 533 534 /* 535 * 3. Write proper DEVICE NUMBER and Attention number to ATN. 536 */ 537 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ATN, attn_type | (devno<<5)); 538 539 /* 540 * 4. Enable interrupts via BCR. 541 */ 542 bus_space_write_1(sc->sc_iot, sc->sc_ioh, BCR, BCR_INT_ENABLE); 543 544 return (0); 545 } 546 547 /* 548 * Wait until command is processed, timeout after 'secs' seconds. 549 * We use mono_time, since we don't need actual RTC, just time 550 * interval. 551 */ 552 static void 553 edc_cmd_wait(sc, secs, poll) 554 struct edc_mca_softc *sc; 555 int secs, poll; 556 { 557 int val; 558 559 if (!poll) { 560 int s; 561 562 /* Not polling, can sleep. Sleep until we are awakened, 563 * but maximum secs seconds. 564 */ 565 s = splbio(); 566 if (sc->sc_stat != STAT_DONE) 567 (void) tsleep(sc, PRIBIO, "edcwcmd", secs * hz); 568 splx(s); 569 } 570 571 /* Wait until the command is completely finished */ 572 while((val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR)) 573 & BSR_CMD_INPROGRESS) { 574 if (poll && (val & BSR_INTR)) 575 edc_intr(sc); 576 } 577 } 578 579 /* 580 * Command controller to execute specified command on a device. 581 */ 582 int 583 edc_run_cmd(sc, cmd, devno, cmd_args, cmd_len, poll) 584 struct edc_mca_softc *sc; 585 int cmd; 586 int devno; 587 u_int16_t cmd_args[]; 588 int cmd_len, poll; 589 { 590 int i, error, tries; 591 u_int16_t cmd0; 592 593 sc->sc_stat = STAT_START; 594 595 /* Do Attention Request for Command Request. */ 596 if ((error = edc_do_attn(sc, ATN_CMD_REQ, devno, 0))) 597 return (error); 598 599 /* 600 * Construct the command. The bits are like this: 601 * 602 * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 603 * \_/ 0 0 1 0 \__/ \_____/ 604 * \ \__________/ \ \_ Command Code (see CMD_*) 605 * \ \ \__ Device: 0 common, 7 controller 606 * \ \__ Options: reserved, bit 10=cache bypass bit 607 * \_ Type: 00=2B, 01=4B, 10 and 11 reserved 608 * 609 * We always use device 0 or 1, so difference is made only by Command 610 * Code, Command Options and command length. 611 */ 612 cmd0 = ((cmd_len == 4) ? (CIFR_LONG_CMD) : 0) 613 | (devno << 5) 614 | (cmd_args[0] << 8) | cmd; 615 cmd_args[0] = cmd0; 616 617 /* 618 * Write word of CMD to the CIFR. This sets "Command 619 * Interface Register Full (CMD IN)" in BSR. Once the attachment 620 * detects it, it reads the word and clears CMD IN. This all should 621 * be quite fast, so don't sleep in !poll case neither. 622 */ 623 for(i=0; i < cmd_len; i++) { 624 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CIFR, 625 htole16(cmd_args[i])); 626 627 /* Wait until CMD IN is cleared. */ 628 tries = 0; 629 for(; (bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) 630 & BSR_CIFR_FULL) && tries < 10000 ; tries++) 631 delay(poll ? 1000 : 1); 632 ; 633 634 if (tries == 10000 635 && bus_space_read_1(sc->sc_iot, sc->sc_ioh, BSR) 636 & BSR_CIFR_FULL) { 637 printf("%s: device too slow to accept command %d\n", 638 sc->sc_dev.dv_xname, cmd); 639 return (EIO); 640 } 641 } 642 643 /* Wait for command to complete, but maximum 15 seconds. */ 644 edc_cmd_wait(sc, 15, poll); 645 646 return ((sc->sc_stat != STAT_DONE) ? EIO : 0); 647 } 648 649 #ifdef EDC_DEBUG 650 static const char * const edc_commands[] = { 651 "Invalid Command", 652 "Read Data", 653 "Write Data", 654 "Read Verify", 655 "Write with Verify", 656 "Seek", 657 "Park Head", 658 "Get Command Complete Status", 659 "Get Device Status", 660 "Get Device Configuration", 661 "Get POS Information", 662 "Translate RBA", 663 "Write Attachment Buffer", 664 "Read Attachment Buffer", 665 "Run Diagnostic Test", 666 "Get Diagnostic Status Block", 667 "Get MFG Header", 668 "Format Unit", 669 "Format Prepare", 670 "Set MAX RBA", 671 "Set Power Saving Mode", 672 "Power Conservation Command", 673 }; 674 675 static const char * const edc_cmd_status[256] = { 676 "Reserved", 677 "Command completed successfully", 678 "Reserved", 679 "Command completed successfully with ECC applied", 680 "Reserved", 681 "Command completed successfully with retries", 682 "Format Command partially completed", /* Status available */ 683 "Command completed successfully with ECC and retries", 684 "Command completed with Warning", /* Command Error is available */ 685 "Aborted", 686 "Reset completed", 687 "Data Transfer Ready", /* No Status Block available */ 688 "Command terminated with failure", /* Device Error is available */ 689 "DMA Error", /* Retry entire command as recovery */ 690 "Command Block Error", 691 "Attention Error (Illegal Attention Code)", 692 /* 0x14 - 0xff reserved */ 693 }; 694 695 static const char * const edc_cmd_error[256] = { 696 "No Error", 697 "Invalid parameter in the command block", 698 "Reserved", 699 "Command not supported", 700 "Command Aborted per request", 701 "Reserved", 702 "Command rejected", /* Attachment diagnostic failure */ 703 "Format Rejected", /* Prepare Format command is required */ 704 "Format Error (Primary Map is not readable)", 705 "Format Error (Secondary map is not readable)", 706 "Format Error (Diagnostic Failure)", 707 "Format Warning (Secondary Map Overflow)", 708 "Reserved" 709 "Format Error (Host Checksum Error)", 710 "Reserved", 711 "Format Warning (Push table overflow)", 712 "Format Warning (More pushes than allowed)", 713 "Reserved", 714 "Format Warning (Error during verifying)", 715 "Invalid device number for the command", 716 /* 0x14-0xff reserved */ 717 }; 718 719 static const char * const edc_dev_errors[] = { 720 "No Error", 721 "Seek Fault", /* Device report */ 722 "Interface Fault (Parity, Attn, or Cmd Complete Error)", 723 "Block not found (ID not found)", 724 "Block not found (AM not found)", 725 "Data ECC Error (hard error)", 726 "ID CRC Error", 727 "RBA Out of Range", 728 "Reserved", 729 "Defective Block", 730 "Reserved", 731 "Selection Error", 732 "Reserved", 733 "Write Fault", 734 "No index or sector pulse", 735 "Device Not Ready", 736 "Seek Error", /* Attachment report */ 737 "Bad Format", 738 "Volume Overflow", 739 "No Data AM Found", 740 "Block not found (No ID AM or ID CRC error occurred)", 741 "Reserved", 742 "Reserved", 743 "No ID found on track (ID search)", 744 /* 0x19 - 0xff reserved */ 745 }; 746 #endif /* EDC_DEBUG */ 747 748 static void 749 edc_dump_status_block(sc, status_block, intr_id) 750 struct edc_mca_softc *sc; 751 u_int16_t *status_block; 752 int intr_id; 753 { 754 #ifdef EDC_DEBUG 755 printf("%s: Command: %s, Status: %s (intr %d)\n", 756 sc->sc_dev.dv_xname, 757 edc_commands[status_block[0] & 0x1f], 758 edc_cmd_status[SB_GET_CMD_STATUS(status_block)], 759 intr_id 760 ); 761 #else 762 printf("%s: Command: %d, Status: %d (intr %d)\n", 763 sc->sc_dev.dv_xname, 764 status_block[0] & 0x1f, 765 SB_GET_CMD_STATUS(status_block), 766 intr_id 767 ); 768 #endif 769 printf("%s: # left blocks: %u, last processed RBA: %u\n", 770 sc->sc_dev.dv_xname, 771 status_block[SB_RESBLKCNT_IDX], 772 (status_block[5] << 16) | status_block[4]); 773 774 if (intr_id == ISR_COMPLETED_WARNING) { 775 #ifdef EDC_DEBUG 776 printf("%s: Command Error Code: %s\n", 777 sc->sc_dev.dv_xname, 778 edc_cmd_error[status_block[1] & 0xff]); 779 #else 780 printf("%s: Command Error Code: %d\n", 781 sc->sc_dev.dv_xname, 782 status_block[1] & 0xff); 783 #endif 784 } 785 786 if (intr_id == ISR_CMD_FAILED) { 787 #ifdef EDC_DEBUG 788 char buf[100]; 789 790 printf("%s: Device Error Code: %s\n", 791 sc->sc_dev.dv_xname, 792 edc_dev_errors[status_block[2] & 0xff]); 793 bitmask_snprintf((status_block[2] & 0xff00) >> 8, 794 "\20" 795 "\01SeekOrCmdComplete" 796 "\02Track0Flag" 797 "\03WriteFault" 798 "\04Selected" 799 "\05Ready" 800 "\06Reserved0" 801 "\07STANDBY" 802 "\010Reserved0", 803 buf, sizeof(buf)); 804 printf("%s: Device Status: %s\n", 805 sc->sc_dev.dv_xname, buf); 806 #else 807 printf("%s: Device Error Code: %d, Device Status: %d\n", 808 sc->sc_dev.dv_xname, 809 status_block[2] & 0xff, 810 (status_block[2] & 0xff00) >> 8); 811 #endif 812 } 813 } 814 815 static void 816 edc_spawn_worker(arg) 817 void *arg; 818 { 819 struct edc_mca_softc *sc = (struct edc_mca_softc *) arg; 820 int error; 821 struct proc *wrk; 822 823 /* Now, everything is ready, start a kthread */ 824 if ((error = kthread_create1(edcworker, sc, &wrk, 825 "%s", sc->sc_dev.dv_xname))) { 826 printf("%s: cannot spawn worker thread: errno=%d\n", 827 sc->sc_dev.dv_xname, error); 828 panic("edc_spawn_worker"); 829 } 830 } 831 832 /* 833 * Main worker thread function. 834 */ 835 void 836 edcworker(arg) 837 void *arg; 838 { 839 struct edc_mca_softc *sc = (struct edc_mca_softc *) arg; 840 struct ed_softc *ed; 841 struct buf *bp; 842 int i, error; 843 844 config_pending_decr(); 845 846 for(;;) { 847 /* Wait until awakened */ 848 (void) tsleep(sc, PRIBIO, "edcidle", 0); 849 850 for(i=0; i<sc->sc_maxdevs; ) { 851 if ((ed = sc->sc_ed[i]) == NULL) { 852 i++; 853 continue; 854 } 855 856 /* Is there a buf for us ? */ 857 simple_lock(&ed->sc_q_lock); 858 if ((bp = BUFQ_FIRST(&ed->sc_q)) == NULL) { 859 simple_unlock(&ed->sc_q_lock); 860 i++; 861 continue; 862 } 863 BUFQ_REMOVE(&ed->sc_q, bp); 864 simple_unlock(&ed->sc_q_lock); 865 866 /* Instrumentation. */ 867 disk_busy(&ed->sc_dk); 868 869 error = edc_bio(sc, ed, bp->b_data, bp->b_bcount, 870 bp->b_rawblkno, (bp->b_flags & B_READ), 0); 871 872 if (error) { 873 bp->b_error = error; 874 bp->b_flags |= B_ERROR; 875 } else { 876 /* Set resid, most commonly to zero. */ 877 bp->b_resid = sc->sc_resblk * DEV_BSIZE; 878 } 879 880 disk_unbusy(&ed->sc_dk, (bp->b_bcount - bp->b_resid)); 881 #if NRND > 0 882 rnd_add_uint32(&ed->rnd_source, bp->b_blkno); 883 #endif 884 biodone(bp); 885 } 886 } 887 } 888 889 int 890 edc_bio(struct edc_mca_softc *sc, struct ed_softc *ed, void *data, 891 size_t bcount, daddr_t rawblkno, int isread, int poll) 892 { 893 u_int16_t cmd_args[4]; 894 int error=0, fl; 895 u_int16_t track; 896 u_int16_t cyl; 897 u_int8_t head; 898 u_int8_t sector; 899 900 mca_disk_busy(); 901 902 /* set WAIT and R/W flag appropriately for the DMA transfer */ 903 fl = ((poll) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK) 904 | ((isread) ? BUS_DMA_READ : BUS_DMA_WRITE); 905 906 /* Load the buffer for DMA transfer. */ 907 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_xfer, data, 908 bcount, NULL, BUS_DMA_STREAMING|fl))) { 909 printf("%s: ed_bio: unable to load DMA buffer - error %d\n", 910 ed->sc_dev.dv_xname, error); 911 goto out; 912 } 913 914 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0, 915 bcount, (isread) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 916 917 track = rawblkno / ed->sectors; 918 head = track % ed->heads; 919 cyl = track / ed->heads; 920 sector = rawblkno % ed->sectors; 921 922 /* Read or Write Data command */ 923 cmd_args[0] = 2; /* Options 0000010 */ 924 cmd_args[1] = bcount / DEV_BSIZE; 925 cmd_args[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector; 926 cmd_args[3] = ((cyl & 0x3E0) >> 5); 927 error = edc_run_cmd(sc, 928 (isread) ? CMD_READ_DATA : CMD_WRITE_DATA, 929 ed->sc_devno, cmd_args, 4, poll); 930 931 /* Sync the DMA memory */ 932 if (!error) { 933 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_xfer, 0, bcount, 934 (isread)? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 935 } 936 937 /* We are done, unload buffer from DMA map */ 938 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_xfer); 939 940 out: 941 mca_disk_unbusy(); 942 943 return (error); 944 } 945