1 /* $NetBSD: mscp_subr.c,v 1.35 2008/04/08 20:10:44 cegger Exp $ */ 2 /* 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Chris Torek. 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. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)mscp.c 7.5 (Berkeley) 12/16/90 34 */ 35 36 /* 37 * Copyright (c) 1996 Ludd, University of Lule}, Sweden. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Chris Torek. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)mscp.c 7.5 (Berkeley) 12/16/90 71 */ 72 73 /* 74 * MSCP generic driver routines 75 */ 76 77 #include <sys/cdefs.h> 78 __KERNEL_RCSID(0, "$NetBSD: mscp_subr.c,v 1.35 2008/04/08 20:10:44 cegger Exp $"); 79 80 #include <sys/param.h> 81 #include <sys/device.h> 82 #include <sys/buf.h> 83 #include <sys/bufq.h> 84 #include <sys/systm.h> 85 #include <sys/proc.h> 86 87 #include <sys/bus.h> 88 #include <machine/sid.h> 89 90 #include <dev/mscp/mscp.h> 91 #include <dev/mscp/mscpreg.h> 92 #include <dev/mscp/mscpvar.h> 93 94 #include "ra.h" 95 #include "mt.h" 96 97 #define b_forw b_hash.le_next 98 99 int mscp_match(struct device *, struct cfdata *, void *); 100 void mscp_attach(struct device *, struct device *, void *); 101 void mscp_start(struct mscp_softc *); 102 int mscp_init(struct mscp_softc *); 103 void mscp_initds(struct mscp_softc *); 104 int mscp_waitstep(struct mscp_softc *, int, int); 105 106 CFATTACH_DECL(mscpbus, sizeof(struct mscp_softc), 107 mscp_match, mscp_attach, NULL, NULL); 108 109 #define READ_SA (bus_space_read_2(mi->mi_iot, mi->mi_sah, 0)) 110 #define READ_IP (bus_space_read_2(mi->mi_iot, mi->mi_iph, 0)) 111 #define WRITE_IP(x) bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x)) 112 #define WRITE_SW(x) bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x)) 113 114 struct mscp slavereply; 115 116 /* 117 * This function is for delay during init. Some MSCP clone card (Dilog) 118 * can't handle fast read from its registers, and therefore need 119 * a delay between them. 120 */ 121 122 #define DELAYTEN 1000 123 int 124 mscp_waitstep(mi, mask, result) 125 struct mscp_softc *mi; 126 int mask, result; 127 { 128 int status = 1; 129 130 if ((READ_SA & mask) != result) { 131 volatile int count = 0; 132 while ((READ_SA & mask) != result) { 133 DELAY(10000); 134 count += 1; 135 if (count > DELAYTEN) 136 break; 137 } 138 if (count > DELAYTEN) 139 status = 0; 140 } 141 return status; 142 } 143 144 int 145 mscp_match(parent, match, aux) 146 struct device *parent; 147 struct cfdata *match; 148 void *aux; 149 { 150 struct mscp_attach_args *ma = aux; 151 152 #if NRA || NRX 153 if (ma->ma_type & MSCPBUS_DISK) 154 return 1; 155 #endif 156 #if NMT 157 if (ma->ma_type & MSCPBUS_TAPE) 158 return 1; 159 #endif 160 return 0; 161 }; 162 163 void 164 mscp_attach(parent, self, aux) 165 struct device *parent, *self; 166 void *aux; 167 { 168 struct mscp_attach_args *ma = aux; 169 struct mscp_softc *mi = device_private(self); 170 struct mscp *mp2; 171 volatile struct mscp *mp; 172 volatile int i; 173 int timeout, next = 0; 174 175 mi->mi_mc = ma->ma_mc; 176 mi->mi_me = NULL; 177 mi->mi_type = ma->ma_type; 178 mi->mi_uda = ma->ma_uda; 179 mi->mi_dmat = ma->ma_dmat; 180 mi->mi_dmam = ma->ma_dmam; 181 mi->mi_iot = ma->ma_iot; 182 mi->mi_iph = ma->ma_iph; 183 mi->mi_sah = ma->ma_sah; 184 mi->mi_swh = ma->ma_swh; 185 mi->mi_ivec = ma->ma_ivec; 186 mi->mi_adapnr = ma->ma_adapnr; 187 mi->mi_ctlrnr = ma->ma_ctlrnr; 188 *ma->ma_softc = mi; 189 /* 190 * Go out to init the bus, so that we can give commands 191 * to its devices. 192 */ 193 mi->mi_cmd.mri_size = NCMD; 194 mi->mi_cmd.mri_desc = mi->mi_uda->mp_ca.ca_cmddsc; 195 mi->mi_cmd.mri_ring = mi->mi_uda->mp_cmd; 196 mi->mi_rsp.mri_size = NRSP; 197 mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc; 198 mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp; 199 bufq_alloc(&mi->mi_resq, "fcfs", 0); 200 201 if (mscp_init(mi)) { 202 aprint_error_dev(&mi->mi_dev, "can't init, controller hung\n"); 203 return; 204 } 205 for (i = 0; i < NCMD; i++) { 206 mi->mi_mxiuse |= (1 << i); 207 if (bus_dmamap_create(mi->mi_dmat, (64*1024), 16, (64*1024), 208 0, BUS_DMA_NOWAIT, &mi->mi_xi[i].mxi_dmam)) { 209 printf("Couldn't alloc dmamap %d\n", i); 210 return; 211 } 212 } 213 214 215 #if NRA 216 if (ma->ma_type & MSCPBUS_DISK) { 217 extern struct mscp_device ra_device; 218 219 mi->mi_me = &ra_device; 220 } 221 #endif 222 #if NMT 223 if (ma->ma_type & MSCPBUS_TAPE) { 224 extern struct mscp_device mt_device; 225 226 mi->mi_me = &mt_device; 227 } 228 #endif 229 /* 230 * Go out and search for sub-units on this MSCP bus, 231 * and call config_found for each found. 232 */ 233 findunit: 234 mp = mscp_getcp(mi, MSCP_DONTWAIT); 235 if (mp == NULL) 236 panic("mscpattach: no packets"); 237 mp->mscp_opcode = M_OP_GETUNITST; 238 mp->mscp_unit = next; 239 mp->mscp_modifier = M_GUM_NEXTUNIT; 240 *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 241 slavereply.mscp_opcode = 0; 242 243 i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0); 244 mp = &slavereply; 245 timeout = 1000; 246 while (timeout-- > 0) { 247 DELAY(10000); 248 if (mp->mscp_opcode) 249 goto gotit; 250 } 251 printf("%s: no response to Get Unit Status request\n", 252 device_xname(&mi->mi_dev)); 253 return; 254 255 gotit: /* 256 * Got a slave response. If the unit is there, use it. 257 */ 258 switch (mp->mscp_status & M_ST_MASK) { 259 260 case M_ST_SUCCESS: /* worked */ 261 case M_ST_AVAILABLE: /* found another drive */ 262 break; /* use it */ 263 264 case M_ST_OFFLINE: 265 /* 266 * Figure out why it is off line. It may be because 267 * it is nonexistent, or because it is spun down, or 268 * for some other reason. 269 */ 270 switch (mp->mscp_status & ~M_ST_MASK) { 271 272 case M_OFFLINE_UNKNOWN: 273 /* 274 * No such drive, and there are none with 275 * higher unit numbers either, if we are 276 * using M_GUM_NEXTUNIT. 277 */ 278 mi->mi_ierr = 3; 279 return; 280 281 case M_OFFLINE_UNMOUNTED: 282 /* 283 * The drive is not spun up. Use it anyway. 284 * 285 * N.B.: this seems to be a common occurrance 286 * after a power failure. The first attempt 287 * to bring it on line seems to spin it up 288 * (and thus takes several minutes). Perhaps 289 * we should note here that the on-line may 290 * take longer than usual. 291 */ 292 break; 293 294 default: 295 /* 296 * In service, or something else equally unusable. 297 */ 298 printf("%s: unit %d off line: ", device_xname(&mi->mi_dev), 299 mp->mscp_unit); 300 mp2 = __UNVOLATILE(mp); 301 mscp_printevent(mp2); 302 next++; 303 goto findunit; 304 } 305 break; 306 307 default: 308 aprint_error_dev(&mi->mi_dev, "unable to get unit status: "); 309 mscp_printevent(__UNVOLATILE(mp)); 310 return; 311 } 312 313 /* 314 * If we get a lower number, we have circulated around all 315 * devices and are finished, otherwise try to find next unit. 316 * We shouldn't ever get this, it's a workaround. 317 */ 318 if (mp->mscp_unit < next) 319 return; 320 321 next = mp->mscp_unit + 1; 322 goto findunit; 323 } 324 325 326 /* 327 * The ctlr gets initialised, normally after boot but may also be 328 * done if the ctlr gets in an unknown state. Returns 1 if init 329 * fails, 0 otherwise. 330 */ 331 int 332 mscp_init(mi) 333 struct mscp_softc *mi; 334 { 335 struct mscp *mp; 336 volatile int i; 337 int status, count; 338 unsigned int j = 0; 339 340 /* 341 * While we are thinking about it, reset the next command 342 * and response indicies. 343 */ 344 mi->mi_cmd.mri_next = 0; 345 mi->mi_rsp.mri_next = 0; 346 347 mi->mi_flags |= MSC_IGNOREINTR; 348 349 if ((mi->mi_type & MSCPBUS_KDB) == 0) 350 WRITE_IP(0); /* Kick off */; 351 352 status = mscp_waitstep(mi, MP_STEP1, MP_STEP1);/* Wait to it wakes up */ 353 if (status == 0) 354 return 1; /* Init failed */ 355 if (READ_SA & MP_ERR) { 356 (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0); 357 return 1; 358 } 359 360 /* step1 */ 361 WRITE_SW(MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | 362 MP_IE | (mi->mi_ivec >> 2)); 363 status = mscp_waitstep(mi, STEP1MASK, STEP1GOOD); 364 if (status == 0) { 365 (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0); 366 return 1; 367 } 368 369 /* step2 */ 370 WRITE_SW(((mi->mi_dmam->dm_segs[0].ds_addr & 0xffff) + 371 offsetof(struct mscp_pack, mp_ca.ca_rspdsc[0])) | 372 (vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0)); 373 status = mscp_waitstep(mi, STEP2MASK, STEP2GOOD(mi->mi_ivec >> 2)); 374 if (status == 0) { 375 (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0); 376 return 1; 377 } 378 379 /* step3 */ 380 WRITE_SW((mi->mi_dmam->dm_segs[0].ds_addr >> 16)); 381 status = mscp_waitstep(mi, STEP3MASK, STEP3GOOD); 382 if (status == 0) { 383 (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0); 384 return 1; 385 } 386 i = READ_SA & 0377; 387 printf(": version %d model %d\n", i & 15, i >> 4); 388 389 #define BURST 4 /* XXX */ 390 if (mi->mi_type & MSCPBUS_UDA) { 391 WRITE_SW(MP_GO | (BURST - 1) << 2); 392 printf("%s: DMA burst size set to %d\n", 393 device_xname(&mi->mi_dev), BURST); 394 } 395 WRITE_SW(MP_GO); 396 397 mscp_initds(mi); 398 mi->mi_flags &= ~MSC_IGNOREINTR; 399 400 /* 401 * Set up all necessary info in the bus softc struct, get a 402 * mscp packet and set characteristics for this controller. 403 */ 404 mi->mi_credits = MSCP_MINCREDITS + 1; 405 mp = mscp_getcp(mi, MSCP_DONTWAIT); 406 407 mi->mi_credits = 0; 408 mp->mscp_opcode = M_OP_SETCTLRC; 409 mp->mscp_unit = mp->mscp_modifier = mp->mscp_flags = 410 mp->mscp_sccc.sccc_version = mp->mscp_sccc.sccc_hosttimo = 411 mp->mscp_sccc.sccc_time = mp->mscp_sccc.sccc_time1 = 412 mp->mscp_sccc.sccc_errlgfl = 0; 413 mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | M_CF_THIS; 414 *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 415 i = READ_IP; 416 417 count = 0; 418 while (count < DELAYTEN) { 419 if (((volatile int)mi->mi_flags & MSC_READY) != 0) 420 break; 421 if ((j = READ_SA) & MP_ERR) 422 goto out; 423 DELAY(10000); 424 count += 1; 425 } 426 if (count == DELAYTEN) { 427 out: 428 aprint_error_dev(&mi->mi_dev, "couldn't set ctlr characteristics, sa=%x\n", j); 429 return 1; 430 } 431 return 0; 432 } 433 434 /* 435 * Initialise the various data structures that control the mscp protocol. 436 */ 437 void 438 mscp_initds(mi) 439 struct mscp_softc *mi; 440 { 441 struct mscp_pack *ud = mi->mi_uda; 442 struct mscp *mp; 443 int i; 444 445 for (i = 0, mp = ud->mp_rsp; i < NRSP; i++, mp++) { 446 ud->mp_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT | 447 (mi->mi_dmam->dm_segs[0].ds_addr + 448 offsetof(struct mscp_pack, mp_rsp[i].mscp_cmdref)); 449 mp->mscp_addr = &ud->mp_ca.ca_rspdsc[i]; 450 mp->mscp_msglen = MSCP_MSGLEN; 451 } 452 for (i = 0, mp = ud->mp_cmd; i < NCMD; i++, mp++) { 453 ud->mp_ca.ca_cmddsc[i] = MSCP_INT | 454 (mi->mi_dmam->dm_segs[0].ds_addr + 455 offsetof(struct mscp_pack, mp_cmd[i].mscp_cmdref)); 456 mp->mscp_addr = &ud->mp_ca.ca_cmddsc[i]; 457 mp->mscp_msglen = MSCP_MSGLEN; 458 if (mi->mi_type & MSCPBUS_TAPE) 459 mp->mscp_vcid = 1; 460 } 461 } 462 463 static void mscp_kickaway(struct mscp_softc *); 464 465 void 466 mscp_intr(mi) 467 struct mscp_softc *mi; 468 { 469 struct mscp_pack *ud = mi->mi_uda; 470 471 if (mi->mi_flags & MSC_IGNOREINTR) 472 return; 473 /* 474 * Check for response and command ring transitions. 475 */ 476 if (ud->mp_ca.ca_rspint) { 477 ud->mp_ca.ca_rspint = 0; 478 mscp_dorsp(mi); 479 } 480 if (ud->mp_ca.ca_cmdint) { 481 ud->mp_ca.ca_cmdint = 0; 482 MSCP_DOCMD(mi); 483 } 484 485 /* 486 * If there are any not-yet-handled request, try them now. 487 */ 488 if (BUFQ_PEEK(mi->mi_resq)) 489 mscp_kickaway(mi); 490 } 491 492 int 493 mscp_print(aux, name) 494 void *aux; 495 const char *name; 496 { 497 struct drive_attach_args *da = aux; 498 struct mscp *mp = da->da_mp; 499 int type = mp->mscp_guse.guse_mediaid; 500 501 if (name) { 502 aprint_normal("%c%c", MSCP_MID_CHAR(2, type), 503 MSCP_MID_CHAR(1, type)); 504 if (MSCP_MID_ECH(0, type)) 505 aprint_normal("%c", MSCP_MID_CHAR(0, type)); 506 aprint_normal("%d at %s drive %d", MSCP_MID_NUM(type), name, 507 mp->mscp_unit); 508 } 509 return UNCONF; 510 } 511 512 /* 513 * common strategy routine for all types of MSCP devices. 514 */ 515 void 516 mscp_strategy(bp, usc) 517 struct buf *bp; 518 struct device *usc; 519 { 520 struct mscp_softc *mi = (void *)usc; 521 int s = spluba(); 522 523 BUFQ_PUT(mi->mi_resq, bp); 524 mscp_kickaway(mi); 525 splx(s); 526 } 527 528 529 void 530 mscp_kickaway(mi) 531 struct mscp_softc *mi; 532 { 533 struct buf *bp; 534 struct mscp *mp; 535 int next; 536 537 while ((bp = BUFQ_PEEK(mi->mi_resq)) != NULL) { 538 /* 539 * Ok; we are ready to try to start a xfer. Get a MSCP packet 540 * and try to start... 541 */ 542 if ((mp = mscp_getcp(mi, MSCP_DONTWAIT)) == NULL) { 543 if (mi->mi_credits > MSCP_MINCREDITS) 544 printf("%s: command ring too small\n", 545 device_xname(device_parent(&mi->mi_dev))); 546 /* 547 * By some (strange) reason we didn't get a MSCP packet. 548 * Just return and wait for free packets. 549 */ 550 return; 551 } 552 553 if ((next = (ffs(mi->mi_mxiuse) - 1)) < 0) 554 panic("no mxi buffers"); 555 mi->mi_mxiuse &= ~(1 << next); 556 if (mi->mi_xi[next].mxi_inuse) 557 panic("mxi inuse"); 558 /* 559 * Set up the MSCP packet and ask the ctlr to start. 560 */ 561 mp->mscp_opcode = 562 (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE; 563 mp->mscp_cmdref = next; 564 mi->mi_xi[next].mxi_bp = bp; 565 mi->mi_xi[next].mxi_mp = mp; 566 mi->mi_xi[next].mxi_inuse = 1; 567 bp->b_resid = next; 568 (*mi->mi_me->me_fillin)(bp, mp); 569 (*mi->mi_mc->mc_go)(device_parent(&mi->mi_dev), 570 &mi->mi_xi[next]); 571 (void)BUFQ_GET(mi->mi_resq); 572 } 573 } 574 575 void 576 mscp_dgo(mi, mxi) 577 struct mscp_softc *mi; 578 struct mscp_xi *mxi; 579 { 580 volatile int i; 581 struct mscp *mp; 582 583 /* 584 * Fill in the MSCP packet and move the buffer to the I/O wait queue. 585 */ 586 mp = mxi->mxi_mp; 587 mp->mscp_seq.seq_buffer = mxi->mxi_dmam->dm_segs[0].ds_addr; 588 589 *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 590 i = READ_IP; 591 } 592 593 #ifdef DIAGNOSTIC 594 /* 595 * Dump the entire contents of an MSCP packet in hex. Mainly useful 596 * for debugging.... 597 */ 598 void 599 mscp_hexdump(mp) 600 struct mscp *mp; 601 { 602 long *p = (long *) mp; 603 int i = mp->mscp_msglen; 604 605 if (i > 256) /* sanity */ 606 i = 256; 607 i /= sizeof (*p); /* ASSUMES MULTIPLE OF sizeof(long) */ 608 while (--i >= 0) 609 printf("0x%x ", (int)*p++); 610 printf("\n"); 611 } 612 #endif 613 614 /* 615 * MSCP error reporting 616 */ 617 618 /* 619 * Messages for the various subcodes. 620 */ 621 static char unknown_msg[] = "unknown subcode"; 622 623 /* 624 * Subcodes for Success (0) 625 */ 626 static const char *succ_msgs[] = { 627 "normal", /* 0 */ 628 "spin down ignored", /* 1 = Spin-Down Ignored */ 629 "still connected", /* 2 = Still Connected */ 630 unknown_msg, 631 "dup. unit #", /* 4 = Duplicate Unit Number */ 632 unknown_msg, 633 unknown_msg, 634 unknown_msg, 635 "already online", /* 8 = Already Online */ 636 unknown_msg, 637 unknown_msg, 638 unknown_msg, 639 unknown_msg, 640 unknown_msg, 641 unknown_msg, 642 unknown_msg, 643 "still online", /* 16 = Still Online */ 644 }; 645 646 /* 647 * Subcodes for Invalid Command (1) 648 */ 649 static const char *icmd_msgs[] = { 650 "invalid msg length", /* 0 = Invalid Message Length */ 651 }; 652 653 /* 654 * Subcodes for Command Aborted (2) 655 */ 656 /* none known */ 657 658 /* 659 * Subcodes for Unit Offline (3) 660 */ 661 static const char *offl_msgs[] = { 662 "unknown drive", /* 0 = Unknown, or online to other ctlr */ 663 "not mounted", /* 1 = Unmounted, or RUN/STOP at STOP */ 664 "inoperative", /* 2 = Unit Inoperative */ 665 unknown_msg, 666 "duplicate", /* 4 = Duplicate Unit Number */ 667 unknown_msg, 668 unknown_msg, 669 unknown_msg, 670 "in diagnosis", /* 8 = Disabled by FS or diagnostic */ 671 }; 672 673 /* 674 * Subcodes for Unit Available (4) 675 */ 676 /* none known */ 677 678 /* 679 * Subcodes for Media Format Error (5) 680 */ 681 static const char *media_fmt_msgs[] = { 682 "fct unread - edc", /* 0 = FCT unreadable */ 683 "invalid sector header",/* 1 = Invalid Sector Header */ 684 "not 512 sectors", /* 2 = Not 512 Byte Sectors */ 685 "not formatted", /* 3 = Not Formatted */ 686 "fct ecc", /* 4 = FCT ECC */ 687 }; 688 689 /* 690 * Subcodes for Write Protected (6) 691 * N.B.: Code 6 subcodes are 7 bits higher than other subcodes 692 * (i.e., bits 12-15). 693 */ 694 static const char *wrprot_msgs[] = { 695 unknown_msg, 696 "software", /* 1 = Software Write Protect */ 697 "hardware", /* 2 = Hardware Write Protect */ 698 }; 699 700 /* 701 * Subcodes for Compare Error (7) 702 */ 703 /* none known */ 704 705 /* 706 * Subcodes for Data Error (8) 707 */ 708 static const char *data_msgs[] = { 709 "forced error", /* 0 = Forced Error (software) */ 710 unknown_msg, 711 "header compare", /* 2 = Header Compare Error */ 712 "sync timeout", /* 3 = Sync Timeout Error */ 713 unknown_msg, 714 unknown_msg, 715 unknown_msg, 716 "uncorrectable ecc", /* 7 = Uncorrectable ECC */ 717 "1 symbol ecc", /* 8 = 1 bit ECC */ 718 "2 symbol ecc", /* 9 = 2 bit ECC */ 719 "3 symbol ecc", /* 10 = 3 bit ECC */ 720 "4 symbol ecc", /* 11 = 4 bit ECC */ 721 "5 symbol ecc", /* 12 = 5 bit ECC */ 722 "6 symbol ecc", /* 13 = 6 bit ECC */ 723 "7 symbol ecc", /* 14 = 7 bit ECC */ 724 "8 symbol ecc", /* 15 = 8 bit ECC */ 725 }; 726 727 /* 728 * Subcodes for Host Buffer Access Error (9) 729 */ 730 static const char *host_buffer_msgs[] = { 731 unknown_msg, 732 "odd xfer addr", /* 1 = Odd Transfer Address */ 733 "odd xfer count", /* 2 = Odd Transfer Count */ 734 "non-exist. memory", /* 3 = Non-Existent Memory */ 735 "memory parity", /* 4 = Memory Parity Error */ 736 }; 737 738 /* 739 * Subcodes for Controller Error (10) 740 */ 741 static const char *cntlr_msgs[] = { 742 unknown_msg, 743 "serdes overrun", /* 1 = Serialiser/Deserialiser Overrun */ 744 "edc", /* 2 = Error Detection Code? */ 745 "inconsistent internal data struct",/* 3 = Internal Error */ 746 }; 747 748 /* 749 * Subcodes for Drive Error (11) 750 */ 751 static const char *drive_msgs[] = { 752 unknown_msg, 753 "sdi command timeout", /* 1 = SDI Command Timeout */ 754 "ctlr detected protocol",/* 2 = Controller Detected Protocol Error */ 755 "positioner", /* 3 = Positioner Error */ 756 "lost rd/wr ready", /* 4 = Lost R/W Ready Error */ 757 "drive clock dropout", /* 5 = Lost Drive Clock */ 758 "lost recvr ready", /* 6 = Lost Receiver Ready */ 759 "drive detected error", /* 7 = Drive Error */ 760 "ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */ 761 }; 762 763 /* 764 * The following table correlates message codes with the 765 * decoding strings. 766 */ 767 struct code_decode { 768 const char *cdc_msg; 769 int cdc_nsubcodes; 770 const char **cdc_submsgs; 771 } code_decode[] = { 772 #define SC(m) sizeof (m) / sizeof (m[0]), m 773 {"success", SC(succ_msgs)}, 774 {"invalid command", SC(icmd_msgs)}, 775 {"command aborted", 0, 0}, 776 {"unit offline", SC(offl_msgs)}, 777 {"unit available", 0, 0}, 778 {"media format error", SC(media_fmt_msgs)}, 779 {"write protected", SC(wrprot_msgs)}, 780 {"compare error", 0, 0}, 781 {"data error", SC(data_msgs)}, 782 {"host buffer access error", SC(host_buffer_msgs)}, 783 {"controller error", SC(cntlr_msgs)}, 784 {"drive error", SC(drive_msgs)}, 785 #undef SC 786 }; 787 788 /* 789 * Print the decoded error event from an MSCP error datagram. 790 */ 791 void 792 mscp_printevent(mp) 793 struct mscp *mp; 794 { 795 int event = mp->mscp_event; 796 struct code_decode *cdc; 797 int c, sc; 798 const char *cm, *scm; 799 800 /* 801 * The code is the lower six bits of the event number (aka 802 * status). If that is 6 (write protect), the subcode is in 803 * bits 12-15; otherwise, it is in bits 5-11. 804 * I WONDER WHAT THE OTHER BITS ARE FOR. IT SURE WOULD BE 805 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 806 */ 807 c = event & M_ST_MASK; 808 sc = (c != 6 ? event >> 5 : event >> 12) & 0x7ff; 809 if (c >= sizeof code_decode / sizeof code_decode[0]) 810 cm = "- unknown code", scm = "??"; 811 else { 812 cdc = &code_decode[c]; 813 cm = cdc->cdc_msg; 814 if (sc >= cdc->cdc_nsubcodes) 815 scm = unknown_msg; 816 else 817 scm = cdc->cdc_submsgs[sc]; 818 } 819 printf(" %s (%s) (code %d, subcode %d)\n", cm, scm, c, sc); 820 } 821 822 static const char *codemsg[16] = { 823 "lbn", "code 1", "code 2", "code 3", 824 "code 4", "code 5", "rbn", "code 7", 825 "code 8", "code 9", "code 10", "code 11", 826 "code 12", "code 13", "code 14", "code 15" 827 }; 828 /* 829 * Print the code and logical block number for an error packet. 830 * THIS IS PROBABLY PECULIAR TO DISK DRIVES. IT SURE WOULD BE 831 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 832 */ 833 int 834 mscp_decodeerror(name, mp, mi) 835 const char *name; 836 struct mscp *mp; 837 struct mscp_softc *mi; 838 { 839 int issoft; 840 /* 841 * We will get three sdi errors of type 11 after autoconfig 842 * is finished; depending of searching for non-existing units. 843 * How can we avoid this??? 844 */ 845 if (((mp->mscp_event & M_ST_MASK) == 11) && (mi->mi_ierr++ < 3)) 846 return 1; 847 /* 848 * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and 849 * the logical block number. Code 0 is a regular block; code 6 850 * is a replacement block. The remaining codes are currently 851 * undefined. The code is in the upper four bits of the header 852 * (bits 0-27 are the lbn). 853 */ 854 issoft = mp->mscp_flags & (M_LF_SUCC | M_LF_CONT); 855 #define BADCODE(h) (codemsg[(unsigned)(h) >> 28]) 856 #define BADLBN(h) ((h) & 0xfffffff) 857 858 printf("%s: drive %d %s error datagram%s:", name, mp->mscp_unit, 859 issoft ? "soft" : "hard", 860 mp->mscp_flags & M_LF_CONT ? " (continuing)" : ""); 861 switch (mp->mscp_format & 0377) { 862 863 case M_FM_CTLRERR: /* controller error */ 864 break; 865 866 case M_FM_BUSADDR: /* host memory access error */ 867 printf(" memory addr 0x%x:", (int)mp->mscp_erd.erd_busaddr); 868 break; 869 870 case M_FM_DISKTRN: 871 printf(" unit %d: level %d retry %d, %s %d:", 872 mp->mscp_unit, 873 mp->mscp_erd.erd_level, mp->mscp_erd.erd_retry, 874 BADCODE(mp->mscp_erd.erd_hdr), 875 (int)BADLBN(mp->mscp_erd.erd_hdr)); 876 break; 877 878 case M_FM_SDI: 879 printf(" unit %d: %s %d:", mp->mscp_unit, 880 BADCODE(mp->mscp_erd.erd_hdr), 881 (int)BADLBN(mp->mscp_erd.erd_hdr)); 882 break; 883 884 case M_FM_SMLDSK: 885 printf(" unit %d: small disk error, cyl %d:", 886 mp->mscp_unit, mp->mscp_erd.erd_sdecyl); 887 break; 888 889 case M_FM_TAPETRN: 890 printf(" unit %d: tape transfer error, grp 0x%x event 0%o:", 891 mp->mscp_unit, mp->mscp_erd.erd_sdecyl, mp->mscp_event); 892 break; 893 894 case M_FM_STIERR: 895 printf(" unit %d: STI error, event 0%o:", mp->mscp_unit, 896 mp->mscp_event); 897 break; 898 899 default: 900 printf(" unit %d: unknown error, format 0x%x:", 901 mp->mscp_unit, mp->mscp_format); 902 } 903 mscp_printevent(mp); 904 return 0; 905 #undef BADCODE 906 #undef BADLBN 907 } 908