1 /* $NetBSD: mscp_subr.c,v 1.25 2004/10/28 07:07:40 yamt 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.25 2004/10/28 07:07:40 yamt 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 <machine/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 __P((struct device *, struct cfdata *, void *)); 100 void mscp_attach __P((struct device *, struct device *, void *)); 101 void mscp_start __P((struct mscp_softc *)); 102 int mscp_init __P((struct mscp_softc *)); 103 void mscp_initds __P((struct mscp_softc *)); 104 int mscp_waitstep __P((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 = (void *)self; 170 volatile struct mscp *mp; 171 volatile int i; 172 int timeout, next = 0; 173 174 mi->mi_mc = ma->ma_mc; 175 mi->mi_me = NULL; 176 mi->mi_type = ma->ma_type; 177 mi->mi_uda = ma->ma_uda; 178 mi->mi_dmat = ma->ma_dmat; 179 mi->mi_dmam = ma->ma_dmam; 180 mi->mi_iot = ma->ma_iot; 181 mi->mi_iph = ma->ma_iph; 182 mi->mi_sah = ma->ma_sah; 183 mi->mi_swh = ma->ma_swh; 184 mi->mi_ivec = ma->ma_ivec; 185 mi->mi_adapnr = ma->ma_adapnr; 186 mi->mi_ctlrnr = ma->ma_ctlrnr; 187 *ma->ma_softc = mi; 188 /* 189 * Go out to init the bus, so that we can give commands 190 * to its devices. 191 */ 192 mi->mi_cmd.mri_size = NCMD; 193 mi->mi_cmd.mri_desc = mi->mi_uda->mp_ca.ca_cmddsc; 194 mi->mi_cmd.mri_ring = mi->mi_uda->mp_cmd; 195 mi->mi_rsp.mri_size = NRSP; 196 mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc; 197 mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp; 198 bufq_alloc(&mi->mi_resq, BUFQ_FCFS); 199 200 if (mscp_init(mi)) { 201 printf("%s: can't init, controller hung\n", 202 mi->mi_dev.dv_xname); 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 mi->mi_dev.dv_xname); 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: ", mi->mi_dev.dv_xname, 299 mp->mscp_unit); 300 mscp_printevent((struct mscp *)mp); 301 next++; 302 goto findunit; 303 } 304 break; 305 306 default: 307 printf("%s: unable to get unit status: ", mi->mi_dev.dv_xname); 308 mscp_printevent((struct mscp *)mp); 309 return; 310 } 311 312 /* 313 * If we get a lower number, we have circulated around all 314 * devices and are finished, otherwise try to find next unit. 315 * We shouldn't ever get this, it's a workaround. 316 */ 317 if (mp->mscp_unit < next) 318 return; 319 320 next = mp->mscp_unit + 1; 321 goto findunit; 322 } 323 324 325 /* 326 * The ctlr gets initialised, normally after boot but may also be 327 * done if the ctlr gets in an unknown state. Returns 1 if init 328 * fails, 0 otherwise. 329 */ 330 int 331 mscp_init(mi) 332 struct mscp_softc *mi; 333 { 334 struct mscp *mp; 335 volatile int i; 336 int status, count; 337 unsigned int j = 0; 338 339 /* 340 * While we are thinking about it, reset the next command 341 * and response indicies. 342 */ 343 mi->mi_cmd.mri_next = 0; 344 mi->mi_rsp.mri_next = 0; 345 346 mi->mi_flags |= MSC_IGNOREINTR; 347 348 if ((mi->mi_type & MSCPBUS_KDB) == 0) 349 WRITE_IP(0); /* Kick off */; 350 351 status = mscp_waitstep(mi, MP_STEP1, MP_STEP1);/* Wait to it wakes up */ 352 if (status == 0) 353 return 1; /* Init failed */ 354 if (READ_SA & MP_ERR) { 355 (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0); 356 return 1; 357 } 358 359 /* step1 */ 360 WRITE_SW(MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) | 361 MP_IE | (mi->mi_ivec >> 2)); 362 status = mscp_waitstep(mi, STEP1MASK, STEP1GOOD); 363 if (status == 0) { 364 (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0); 365 return 1; 366 } 367 368 /* step2 */ 369 WRITE_SW(((mi->mi_dmam->dm_segs[0].ds_addr & 0xffff) + 370 offsetof(struct mscp_pack, mp_ca.ca_rspdsc[0])) | 371 (vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0)); 372 status = mscp_waitstep(mi, STEP2MASK, STEP2GOOD(mi->mi_ivec >> 2)); 373 if (status == 0) { 374 (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0); 375 return 1; 376 } 377 378 /* step3 */ 379 WRITE_SW((mi->mi_dmam->dm_segs[0].ds_addr >> 16)); 380 status = mscp_waitstep(mi, STEP3MASK, STEP3GOOD); 381 if (status == 0) { 382 (*mi->mi_mc->mc_saerror)(mi->mi_dev.dv_parent, 0); 383 return 1; 384 } 385 i = READ_SA & 0377; 386 printf(": version %d model %d\n", i & 15, i >> 4); 387 388 #define BURST 4 /* XXX */ 389 if (mi->mi_type & MSCPBUS_UDA) { 390 WRITE_SW(MP_GO | (BURST - 1) << 2); 391 printf("%s: DMA burst size set to %d\n", 392 mi->mi_dev.dv_xname, BURST); 393 } 394 WRITE_SW(MP_GO); 395 396 mscp_initds(mi); 397 mi->mi_flags &= ~MSC_IGNOREINTR; 398 399 /* 400 * Set up all necessary info in the bus softc struct, get a 401 * mscp packet and set characteristics for this controller. 402 */ 403 mi->mi_credits = MSCP_MINCREDITS + 1; 404 mp = mscp_getcp(mi, MSCP_DONTWAIT); 405 406 mi->mi_credits = 0; 407 mp->mscp_opcode = M_OP_SETCTLRC; 408 mp->mscp_unit = mp->mscp_modifier = mp->mscp_flags = 409 mp->mscp_sccc.sccc_version = mp->mscp_sccc.sccc_hosttimo = 410 mp->mscp_sccc.sccc_time = mp->mscp_sccc.sccc_time1 = 411 mp->mscp_sccc.sccc_errlgfl = 0; 412 mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | M_CF_THIS; 413 *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 414 i = READ_IP; 415 416 count = 0; 417 while (count < DELAYTEN) { 418 if (((volatile int)mi->mi_flags & MSC_READY) != 0) 419 break; 420 if ((j = READ_SA) & MP_ERR) 421 goto out; 422 DELAY(10000); 423 count += 1; 424 } 425 if (count == DELAYTEN) { 426 out: 427 printf("%s: couldn't set ctlr characteristics, sa=%x\n", 428 mi->mi_dev.dv_xname, 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 mi->mi_dev.dv_parent->dv_xname); 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)(mi->mi_dev.dv_parent, &mi->mi_xi[next]); 570 (void)BUFQ_GET(&mi->mi_resq); 571 } 572 } 573 574 void 575 mscp_dgo(mi, mxi) 576 struct mscp_softc *mi; 577 struct mscp_xi *mxi; 578 { 579 volatile int i; 580 struct mscp *mp; 581 582 /* 583 * Fill in the MSCP packet and move the buffer to the I/O wait queue. 584 */ 585 mp = mxi->mxi_mp; 586 mp->mscp_seq.seq_buffer = mxi->mxi_dmam->dm_segs[0].ds_addr; 587 588 *mp->mscp_addr |= MSCP_OWN | MSCP_INT; 589 i = READ_IP; 590 } 591 592 #ifdef DIAGNOSTIC 593 /* 594 * Dump the entire contents of an MSCP packet in hex. Mainly useful 595 * for debugging.... 596 */ 597 void 598 mscp_hexdump(mp) 599 struct mscp *mp; 600 { 601 long *p = (long *) mp; 602 int i = mp->mscp_msglen; 603 604 if (i > 256) /* sanity */ 605 i = 256; 606 i /= sizeof (*p); /* ASSUMES MULTIPLE OF sizeof(long) */ 607 while (--i >= 0) 608 printf("0x%x ", (int)*p++); 609 printf("\n"); 610 } 611 #endif 612 613 /* 614 * MSCP error reporting 615 */ 616 617 /* 618 * Messages for the various subcodes. 619 */ 620 static char unknown_msg[] = "unknown subcode"; 621 622 /* 623 * Subcodes for Success (0) 624 */ 625 static char *succ_msgs[] = { 626 "normal", /* 0 */ 627 "spin down ignored", /* 1 = Spin-Down Ignored */ 628 "still connected", /* 2 = Still Connected */ 629 unknown_msg, 630 "dup. unit #", /* 4 = Duplicate Unit Number */ 631 unknown_msg, 632 unknown_msg, 633 unknown_msg, 634 "already online", /* 8 = Already Online */ 635 unknown_msg, 636 unknown_msg, 637 unknown_msg, 638 unknown_msg, 639 unknown_msg, 640 unknown_msg, 641 unknown_msg, 642 "still online", /* 16 = Still Online */ 643 }; 644 645 /* 646 * Subcodes for Invalid Command (1) 647 */ 648 static char *icmd_msgs[] = { 649 "invalid msg length", /* 0 = Invalid Message Length */ 650 }; 651 652 /* 653 * Subcodes for Command Aborted (2) 654 */ 655 /* none known */ 656 657 /* 658 * Subcodes for Unit Offline (3) 659 */ 660 static char *offl_msgs[] = { 661 "unknown drive", /* 0 = Unknown, or online to other ctlr */ 662 "not mounted", /* 1 = Unmounted, or RUN/STOP at STOP */ 663 "inoperative", /* 2 = Unit Inoperative */ 664 unknown_msg, 665 "duplicate", /* 4 = Duplicate Unit Number */ 666 unknown_msg, 667 unknown_msg, 668 unknown_msg, 669 "in diagnosis", /* 8 = Disabled by FS or diagnostic */ 670 }; 671 672 /* 673 * Subcodes for Unit Available (4) 674 */ 675 /* none known */ 676 677 /* 678 * Subcodes for Media Format Error (5) 679 */ 680 static char *media_fmt_msgs[] = { 681 "fct unread - edc", /* 0 = FCT unreadable */ 682 "invalid sector header",/* 1 = Invalid Sector Header */ 683 "not 512 sectors", /* 2 = Not 512 Byte Sectors */ 684 "not formatted", /* 3 = Not Formatted */ 685 "fct ecc", /* 4 = FCT ECC */ 686 }; 687 688 /* 689 * Subcodes for Write Protected (6) 690 * N.B.: Code 6 subcodes are 7 bits higher than other subcodes 691 * (i.e., bits 12-15). 692 */ 693 static char *wrprot_msgs[] = { 694 unknown_msg, 695 "software", /* 1 = Software Write Protect */ 696 "hardware", /* 2 = Hardware Write Protect */ 697 }; 698 699 /* 700 * Subcodes for Compare Error (7) 701 */ 702 /* none known */ 703 704 /* 705 * Subcodes for Data Error (8) 706 */ 707 static char *data_msgs[] = { 708 "forced error", /* 0 = Forced Error (software) */ 709 unknown_msg, 710 "header compare", /* 2 = Header Compare Error */ 711 "sync timeout", /* 3 = Sync Timeout Error */ 712 unknown_msg, 713 unknown_msg, 714 unknown_msg, 715 "uncorrectable ecc", /* 7 = Uncorrectable ECC */ 716 "1 symbol ecc", /* 8 = 1 bit ECC */ 717 "2 symbol ecc", /* 9 = 2 bit ECC */ 718 "3 symbol ecc", /* 10 = 3 bit ECC */ 719 "4 symbol ecc", /* 11 = 4 bit ECC */ 720 "5 symbol ecc", /* 12 = 5 bit ECC */ 721 "6 symbol ecc", /* 13 = 6 bit ECC */ 722 "7 symbol ecc", /* 14 = 7 bit ECC */ 723 "8 symbol ecc", /* 15 = 8 bit ECC */ 724 }; 725 726 /* 727 * Subcodes for Host Buffer Access Error (9) 728 */ 729 static char *host_buffer_msgs[] = { 730 unknown_msg, 731 "odd xfer addr", /* 1 = Odd Transfer Address */ 732 "odd xfer count", /* 2 = Odd Transfer Count */ 733 "non-exist. memory", /* 3 = Non-Existent Memory */ 734 "memory parity", /* 4 = Memory Parity Error */ 735 }; 736 737 /* 738 * Subcodes for Controller Error (10) 739 */ 740 static char *cntlr_msgs[] = { 741 unknown_msg, 742 "serdes overrun", /* 1 = Serialiser/Deserialiser Overrun */ 743 "edc", /* 2 = Error Detection Code? */ 744 "inconsistant internal data struct",/* 3 = Internal Error */ 745 }; 746 747 /* 748 * Subcodes for Drive Error (11) 749 */ 750 static char *drive_msgs[] = { 751 unknown_msg, 752 "sdi command timeout", /* 1 = SDI Command Timeout */ 753 "ctlr detected protocol",/* 2 = Controller Detected Protocol Error */ 754 "positioner", /* 3 = Positioner Error */ 755 "lost rd/wr ready", /* 4 = Lost R/W Ready Error */ 756 "drive clock dropout", /* 5 = Lost Drive Clock */ 757 "lost recvr ready", /* 6 = Lost Receiver Ready */ 758 "drive detected error", /* 7 = Drive Error */ 759 "ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */ 760 }; 761 762 /* 763 * The following table correlates message codes with the 764 * decoding strings. 765 */ 766 struct code_decode { 767 char *cdc_msg; 768 int cdc_nsubcodes; 769 char **cdc_submsgs; 770 } code_decode[] = { 771 #define SC(m) sizeof (m) / sizeof (m[0]), m 772 {"success", SC(succ_msgs)}, 773 {"invalid command", SC(icmd_msgs)}, 774 {"command aborted", 0, 0}, 775 {"unit offline", SC(offl_msgs)}, 776 {"unit available", 0, 0}, 777 {"media format error", SC(media_fmt_msgs)}, 778 {"write protected", SC(wrprot_msgs)}, 779 {"compare error", 0, 0}, 780 {"data error", SC(data_msgs)}, 781 {"host buffer access error", SC(host_buffer_msgs)}, 782 {"controller error", SC(cntlr_msgs)}, 783 {"drive error", SC(drive_msgs)}, 784 #undef SC 785 }; 786 787 /* 788 * Print the decoded error event from an MSCP error datagram. 789 */ 790 void 791 mscp_printevent(mp) 792 struct mscp *mp; 793 { 794 int event = mp->mscp_event; 795 struct code_decode *cdc; 796 int c, sc; 797 char *cm, *scm; 798 799 /* 800 * The code is the lower six bits of the event number (aka 801 * status). If that is 6 (write protect), the subcode is in 802 * bits 12-15; otherwise, it is in bits 5-11. 803 * I WONDER WHAT THE OTHER BITS ARE FOR. IT SURE WOULD BE 804 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 805 */ 806 c = event & M_ST_MASK; 807 sc = (c != 6 ? event >> 5 : event >> 12) & 0x7ff; 808 if (c >= sizeof code_decode / sizeof code_decode[0]) 809 cm = "- unknown code", scm = "??"; 810 else { 811 cdc = &code_decode[c]; 812 cm = cdc->cdc_msg; 813 if (sc >= cdc->cdc_nsubcodes) 814 scm = unknown_msg; 815 else 816 scm = cdc->cdc_submsgs[sc]; 817 } 818 printf(" %s (%s) (code %d, subcode %d)\n", cm, scm, c, sc); 819 } 820 821 static char *codemsg[16] = { 822 "lbn", "code 1", "code 2", "code 3", 823 "code 4", "code 5", "rbn", "code 7", 824 "code 8", "code 9", "code 10", "code 11", 825 "code 12", "code 13", "code 14", "code 15" 826 }; 827 /* 828 * Print the code and logical block number for an error packet. 829 * THIS IS PROBABLY PECULIAR TO DISK DRIVES. IT SURE WOULD BE 830 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS. 831 */ 832 int 833 mscp_decodeerror(name, mp, mi) 834 char *name; 835 struct mscp *mp; 836 struct mscp_softc *mi; 837 { 838 int issoft; 839 /* 840 * We will get three sdi errors of type 11 after autoconfig 841 * is finished; depending of searching for non-existing units. 842 * How can we avoid this??? 843 */ 844 if (((mp->mscp_event & M_ST_MASK) == 11) && (mi->mi_ierr++ < 3)) 845 return 1; 846 /* 847 * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and 848 * the logical block number. Code 0 is a regular block; code 6 849 * is a replacement block. The remaining codes are currently 850 * undefined. The code is in the upper four bits of the header 851 * (bits 0-27 are the lbn). 852 */ 853 issoft = mp->mscp_flags & (M_LF_SUCC | M_LF_CONT); 854 #define BADCODE(h) (codemsg[(unsigned)(h) >> 28]) 855 #define BADLBN(h) ((h) & 0xfffffff) 856 857 printf("%s: drive %d %s error datagram%s:", name, mp->mscp_unit, 858 issoft ? "soft" : "hard", 859 mp->mscp_flags & M_LF_CONT ? " (continuing)" : ""); 860 switch (mp->mscp_format & 0377) { 861 862 case M_FM_CTLRERR: /* controller error */ 863 break; 864 865 case M_FM_BUSADDR: /* host memory access error */ 866 printf(" memory addr 0x%x:", (int)mp->mscp_erd.erd_busaddr); 867 break; 868 869 case M_FM_DISKTRN: 870 printf(" unit %d: level %d retry %d, %s %d:", 871 mp->mscp_unit, 872 mp->mscp_erd.erd_level, mp->mscp_erd.erd_retry, 873 BADCODE(mp->mscp_erd.erd_hdr), 874 (int)BADLBN(mp->mscp_erd.erd_hdr)); 875 break; 876 877 case M_FM_SDI: 878 printf(" unit %d: %s %d:", mp->mscp_unit, 879 BADCODE(mp->mscp_erd.erd_hdr), 880 (int)BADLBN(mp->mscp_erd.erd_hdr)); 881 break; 882 883 case M_FM_SMLDSK: 884 printf(" unit %d: small disk error, cyl %d:", 885 mp->mscp_unit, mp->mscp_erd.erd_sdecyl); 886 break; 887 888 case M_FM_TAPETRN: 889 printf(" unit %d: tape transfer error, grp 0x%x event 0%o:", 890 mp->mscp_unit, mp->mscp_erd.erd_sdecyl, mp->mscp_event); 891 break; 892 893 case M_FM_STIERR: 894 printf(" unit %d: STI error, event 0%o:", mp->mscp_unit, 895 mp->mscp_event); 896 break; 897 898 default: 899 printf(" unit %d: unknown error, format 0x%x:", 900 mp->mscp_unit, mp->mscp_format); 901 } 902 mscp_printevent(mp); 903 return 0; 904 #undef BADCODE 905 #undef BADLBN 906 } 907