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