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