1: #define TMSDEBUG 1 2: 3: /* @(#)tmscp.c 1.12 (2.11BSD) 1999/2/25 */ 4: 5: #if !defined(lint) && defined(DOSCCS) 6: static char *sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86"; 7: #endif 8: 9: /************************************************************************ 10: * Licensed from Digital Equipment Corporation * 11: * Copyright (c) * 12: * Digital Equipment Corporation * 13: * Maynard, Massachusetts * 14: * 1985, 1986 * 15: * All rights reserved. * 16: * * 17: * The Information in this software is subject to change * 18: * without notice and should not be construed as a commitment * 19: * by Digital Equipment Corporation. Digital makes no * 20: * representations about the suitability of this software for * 21: * any purpose. It is supplied "As Is" without expressed or * 22: * implied warranty. * 23: * * 24: * If the Regents of the University of California or its * 25: * licensees modify the software in a manner creating * 26: * diriviative copyright rights, appropriate copyright * 27: * legends may be placed on the drivative work in addition * 28: * to that set forth above. * 29: ************************************************************************ 30: * 31: * tmscp.c - TMSCP (TK50/TU81) tape device driver 32: * 33: * Modification History: 34: * 25-Feb-99 - sms 35: * Fix density selection to preserve the high byte of m_format. This 36: * is required devices (such as the TK70) which have a nonzero value 37: * in this field. 38: * 39: * 22-Feb-99 - sms 40: * Add timeout logic to tmscpcommand to catch hardware going catatonic. 41: * When tmscpcommand() was first created the only use was to issue a 42: * nonblocking rewind upon close. Tmscpcommand is now called for many 43: * other functions some of which can leave a process (and the drive) hung 44: * unless a timeout is done. 45: * 46: * Remove special treatment of OFFLINE and AVLBL status codes in 47: * tms_iodone(). The code is suspected of having been a bug even in 48: * its old location but is definitely causing problems now - if a read 49: * completes with a 'AVLBL' status the drive is hung because an iodone() 50: * is never performed. 51: * 52: * Minor cleanup done thruout (reduce D space consumption ,etc). 53: * 54: * 24-Apr-98 - sms 55: * An incorrect pointer was being passed to tms_iodone() from tmscprsp() 56: * when dealing with the 'invalid endcode' case. While that value should 57: * never be generated by normal hardware the kernel should not panic. 58: * 59: * 07-Mar-98 - sms 60: * Fix a bug that caused EOM to be 'sticky'. Once EndOfMedia was detected 61: * the only way to clear it was to unload and reload the tape. Remove 62: * unused flag definitions. Only use a single 'written' flag instead of 63: * two (one in tms_flags and another in Tflags). 64: * 65: * 01-Feb-98 - sms 66: * Initially the thought was the driver was broken sometime around June 67: * 1996. After adding additional logging and the 'sysctl' interface it 68: * was discovered (eventually after several long nights) that both my 69: * TK50 and another person's TU81+ had developed hardware problems. The 70: * better logging and sysctl changes were retained for future use ;) 71: * 72: * Failure to 'online' a drive was changed to return EIO instead of ENXIO 73: * because 'device not configured' means the drive is not present. 74: * 75: * A 'sysctl' interface was added so that 'tmscpprintf' could be changed 76: * without rebooting/recompiling the system. Also sysctl can be used to 77: * set the cache on/off status even if a tape is not at the load point - 78: * the setting takes effect on the next open(). 79: * 80: * 14-May-96 - sms 81: * Missing parens caused mtflush,mtcache,mtnocache to be always skipped. 82: * The use cache bit was being cleared in tmscpopen(). The use cache bit 83: * is sticky in that once set via MTCACHE it stays set until cleared by 84: * MTNOCACHE. 85: * 86: * 14-Dec-95 - sms@wlv... 87: * Success! But the size of the driver is even more of a problem now. 88: * If the crash dump option is defined the driver could exceed the max 89: * size permitted for an overlay. The 'tmsdump' routine was moved to 90: * a separate file. This driver almost always must be in an overlay 91: * by itself now. 92: * 93: * 08-Dec-95 - sms@wlv... 94: * Begin serious surgery on this driver. The goals are: 1) to correctly 95: * handle TU81/81+ drives (do not set density unless at BOT), 2) support 96: * use of the cache on drives which implement it (TU81+), 3) improve 97: * error detection and reporting, 4) improve readability by replacing 98: * multipage 'switch' statements with calls to functions, 5) make it 99: * easier to add new capabilities and fix problems without wholescale 100: * changes again. 101: * 102: * 30-Nov-95 - sms@wlv... 103: * Experiment to see if M_MD_IMMED being set for the rewind on close 104: * obviates the need for skipping the iowait(). Success - only 2 ticks 105: * elapse doing the iowait!. 106: * 107: * 02-Jan-93 - sms@wlv. [2.11BSD] 108: * Remove unibus map ifdefs and rely on run time testing of 'ubmap' which 109: * does the right thing and makes kernels easier to move between machines. 110: * 111: * 20-Nov-92 - sms@wlv.iipo.gtegsc.com [2.11BSD] 112: * Add tmsVec() for autoconfig to use in passing the vector from /etc/dtab 113: * to this driver. The previous scheme of having a fixed vector with 114: * all TMSCP vectors contiguous has been removed. 115: * 116: * 23-May-91 - sms@wlv.iipo.gtegsc.com [2.11BSD] 117: * Minor typo in the multicontroller support fixed. Major overhaul 118: * of the density selection, apparently some TMSCP controllers 119: * do not treat 0 in the mscp_format word as meaning the highest 120: * density, instead leaving the drive in the current/last-used 121: * density. 122: * 123: * 29-Mar-91 - sms@wlv.iipo.gtegsc.com [2.11BSD] 124: * Major changes to 1) support multiple drives per controller 125: * (the maximum number of drives per controller is 4 for now in order 126: * to maximize compatibility with existing minor device numbers - the 127: * norewind and density bit stay in the same place) and 2) more 128: * importantly reduce the bloat of this driver. The command 129: * packet area is now allocated from an external heap setup at boot 130: * time (the MSCP, ra.c driver also does this). Allocating from an 131: * external arena save approximately 2kb of kernel D space PER CONTROLLER 132: * and costs little in speed because the amount of remapping involved is 133: * quite small. 134: * 135: * The 'errinfo' routine was removed in the interest of space savings, 136: * the error code was already being printed out in hex and it's not 137: * worth eating up another 250 or so bytes of kernel D space to pretty 138: * print messages for which tmscp.h provides the cross reference (I space 139: * is also saved by not printing the messages). Besides, the ra.c (MSCP) 140: * driver doesn't do it and it is worth a degree of non 4.3BSD verisimility 141: * to save a significant amount of space. 142: * 143: * The tms_type field should have been a 'long' (mediatype). Since the 144: * drives are not probed at autoconfigure time a GTUNT (TMS_SENSE) command 145: * is done at open() time to fetch the format/density menu and unit flags. 146: * iodone() proccessing was missing for the GTUNT function in tmscprsp() 147: * causing hangs in both open and ioctl functions. 148: * 149: * Multiple controller support made to work, the top 2 bits of the minor 150: * device number are used to designate the controller, thus there is 151: * a maximum of 4 TMSCP controllers per system. 152: * 153: * 17-Jun-90,14Aug90 - sms@wlv.iipo.gtegsc.com 154: * Began porting to 2.10.1BSD/2.11BSD. Multiple drives per controller 155: * NOT supported, although multiple controllers are (maybe). Programmable 156: * vectors don't work very well with the autoconfigure scheme in use. 157: * the define TMSCP_VEC will have to be adjusted in tms.h (see 158: * conf/config and the sample config files). For patching purposes 159: * the global "TMSvec" is declared and initialized with TMSCP_VEC. 160: * 161: * 06-Jan-86 - afd 162: * Changed the probe routine to use DELAY (not TODR). This now 163: * works for MicroVAXen as well. This eliminates the busy-wait 164: * for MicroVAXen so a dead TK50 controller will not hang autoconf. 165: * 166: * 06-Dec-85 - afd 167: * Fixed a bug in density selection. The "set unit characteristics" 168: * command to select density, was clearing the "unit flags" field 169: * where the CACHE bit was for TU81-E. Now the unit's "format" and 170: * "unitflgs" are saved in tms_info struct. And are used on STUNT 171: * commands. 172: * 173: * 19-Oct-85 - afd 174: * Added support to the open routine to allow drives to be opened 175: * for low density (800 or 1600 bpi) use. When the slave routine 176: * initiates a "get-unit-char" cmd, the format menu for the unit 177: * is saved in the tms_info structure. The format menu is used in the 178: * start routine to select the proper low density. 179: * 180: * 02-Oct-85 - afd 181: * When a tmscp-type controller is initializing, it is possible for 182: * the sa reg to become 0 between states. Thus the init code in 183: * the interrupt routine had to be modified to reflect this. 184: * 185: * 21-Sep-85 - afd 186: * The TK50 declares a serious exception when a tape mark is encountered. 187: * This causes problems to dd (& other UN*X utilities). So a flag 188: * is set in the rsp() routine when a tape mark is encountered. If 189: * this flag is set, the start() routine appends the Clear Serious 190: * Exception modifier to the next command. 191: * 192: * 03-Sep-85 -- jaw 193: * messed up previous edit.. 194: * 195: * 29-Aug-85 - jaw 196: * fixed bugs in 8200 and 750 buffered datapath handling. 197: * 198: * 06-Aug-85 - afd 199: * 1. When repositioning records or files, the count of items skipped 200: * does NOT HAVE to be returned by controllers (& the TU81 doesn't). 201: * So tmscprsp() had to be modified to stop reporting 202: * residual count errors on reposition commands. 203: * 204: * 2. Fixed bug in the open routine which allowed multiple opens. 205: * 206: * 18-Jul-85 - afd 207: * 1. Need to return status when mt status (or corresponding ioctl) is done. 208: * Save resid, flags, endcode & status in tmscprsp() routine (except on 209: * clear serious exception no-op). Return these fields when status 210: * ioctl is done (in tmscpcommand()). How they are returned: 211: * mt_resid = resid 212: * mt_dsreg = flags|endcode 213: * mt_erreg = status 214: * 215: * 2. Added latent support for enabling/disabling caching. This is 216: * handled along with all other ioctl commands. 217: * 218: * 3. Need to issue a no-op on unrecognized ioctl in tmsstart(), since 219: * we have already commited to issuing a command at that point. 220: * 221: * 4. In tmscprsp() routine if encode is 0200 (invalid command issued); 222: * We need to: Unlink the buffer from the I/O wait queue, 223: * and signal iodone, so the higher level command can exit! 224: * Just as if it were a valid command. 225: * 226: * 11-jul-85 -- jaw 227: * fix bua/bda map registers. 228: * 229: * 19-Jun-85 -- jaw 230: * VAX8200 name change. 231: * 232: * 06-Jun-85 - jaw 233: * fixes for 8200. 234: * 235: * 9-Apr-85 - afd 236: * Added timeout code to the probe routine, so if the controller 237: * fails to init in 10 seconds we return failed status. 238: * 239: * 13-Mar-85 -jaw 240: * Changes for support of the VAX8200 were merged in. 241: * 242: * 27-Feb-85 -tresvik 243: * Changes for support of the VAX8600 were merged in. 244: * 245: */ 246: 247: #include "tms.h" 248: #if NTMSCP > 0 249: 250: #include "param.h" 251: #include "systm.h" 252: #include "buf.h" 253: #include "conf.h" 254: #include "user.h" 255: #include "file.h" 256: #include "map.h" 257: #include "ioctl.h" 258: #include "syslog.h" 259: #include "mtio.h" 260: #include "uio.h" 261: #include "tty.h" 262: #include "uba.h" 263: #include "kernel.h" 264: 265: #include "tmscpreg.h" 266: #include "../pdp/tmscp.h" 267: #include "../machine/seg.h" 268: 269: /* 270: * The density array is indexed by the density bits (bits 3 and 4) of the 271: * minor device number AND the format menu returned for the drive. Since 272: * only 3 densities are apparently supported by TMSCP (no DPE/3200bpi), the 273: * second MEDium table is a copy of the first MEDium entry. 274: */ 275: 276: char Dmatrix[4][8] = 277: { 278: /* LOW */ {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_800}, 279: /* MED1 */ {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_PE }, 280: /* MED2 */ {0,M_TF_800,M_TF_PE,M_TF_800,M_TF_GCR,M_TF_800,M_TF_PE,M_TF_PE }, 281: /* HI */ {0,M_TF_800,M_TF_PE,M_TF_PE,M_TF_GCR,M_TF_GCR,M_TF_GCR,M_TF_GCR} 282: }; 283: 284: struct tmscp_softc tmscp_softc[NTMSCP]; /* Controller info */ 285: struct tms_info tms_info[NTMS]; /* Drive info */ 286: 287: memaddr tmscp[NTMSCP]; /* click addresses of ctrl comm area */ 288: 289: /* 290: * Tflags definitions. These take the place of several 291: * individual structure members in tms_info. 292: */ 293: 294: #define _SEREX 0x0001 /* Serious Exception exists */ 295: #define _CLSEREX 0x0002 /* Do Clear Serious Exception */ 296: #define _LOST 0x0004 /* Position lost error happened */ 297: #define _BUFMARK 0x0008 /* Encountered a tape mark */ 298: #define _HASCACHE 0x0010 /* Drive has cache capability */ 299: #define _CACHE_ON 0x0020 /* Cache enabled */ 300: #define _CACHE_LOST 0x0040 /* Cache data loss has happened */ 301: #define _CACHE_WRITTEN 0x0080 /* Cache has been written */ 302: #define _INUSE 0x0100 /* Drive is in use */ 303: #define _ONLINE 0x0200 /* Drive is online */ 304: 305: /* 306: * Internal (ioctl) command codes (these must also be declared in the 307: * tmscpioctl routine). These correspond to ioctls in mtio.h 308: */ 309: #define TMS_WRITM 0 /* write tape mark */ 310: #define TMS_FSF 1 /* forward space file */ 311: #define TMS_BSF 2 /* backward space file */ 312: #define TMS_FSR 3 /* forward space record */ 313: #define TMS_BSR 4 /* backward space record */ 314: #define TMS_REW 5 /* rewind tape */ 315: #define TMS_OFFL 6 /* rewind tape & mark unit offline */ 316: #define TMS_SENSE 7 /* noop - do a get unit status */ 317: #define TMS_CACHE 8 /* enable cache */ 318: #define TMS_NOCACHE 9 /* disable cache */ 319: #define TMS_FLUSH 10 /* flush cache */ 320: /* These go last: after all real mt cmds, just bump the numbers up */ 321: #define TMS_CSE 11 /* clear serious exception */ 322: #define TMS_SETDENSITY 12 /* set unit density */ 323: 324: /* 325: * Controller states 326: */ 327: #define S_IDLE 0 /* hasn't been initialized */ 328: #define S_STEP1 1 /* doing step 1 init */ 329: #define S_STEP2 2 /* doing step 2 init */ 330: #define S_STEP3 3 /* doing step 3 init */ 331: #define S_SCHAR 4 /* doing "set controller characteristics" */ 332: #define S_RUN 5 /* running */ 333: 334: static char *tmscpstepfailed = "step%d init failed: sa %x\n"; 335: char *tmscpfatalerr = "tms%d,%d: fatal error %x\n"; 336: 337: int tmscp_cp_wait = 0; /* Something to wait on for command */ 338: /* packets and or credits. */ 339: int wakeup(); 340: int tmswatchdog(); 341: extern int hz; /* Should find the right include */ 342: extern long _iomap(); 343: extern u_int tmscp_cache; /* See pdp/kern_pdp.c */ 344: 345: /* 346: * Bit 0 = print all non-successful response packets _except_ hitting a 347: * tapemark (which really isn't an error). 348: * Bit 1 = print datagram arrival message. 349: * Bit 2 = print status of all response packets except datagrams. 350: * Bit 3 = enable debugging print and log statements not covered above 351: */ 352: int tmscpprintf = 1; 353: 354: /* 355: * This is settable via "sysctl -w machdep.tmscp.cache=0xXXXX". There is one 356: * bit per drive. Bit 0 is the first drive on the first controller, bit 4 is 357: * the first drive on the second controller, and so on. 358: * 359: */ 360: 361: int tmscpcache = 0; 362: 363: struct mscp *tmscpgetcp(); 364: 365: #define b_qsize b_resid /* queue size per drive, in tmsutab */ 366: 367: tmsVec(ctlr, vector) 368: int ctlr, vector; 369: { 370: register struct tmscp_softc *sc = &tmscp_softc[ctlr]; 371: 372: if (ctlr >= NTMSCP || sc->sc_ivec) 373: return(-1); 374: sc->sc_ivec = vector; 375: return(0); 376: } 377: 378: /* 379: * Open routine will issue the online command, later. 380: * 381: * This routine attaches controllers, not drives - sc_unit and 'unit' are 382: * the controller number not a drive unit number. sc_com is initialized 383: * to SEG5 because all communication areas are mapped to the same virtual 384: * address now. 385: */ 386: tmsattach(addr, unit) 387: struct tmscpdevice *addr; 388: register int unit; 389: { 390: register struct tmscp_softc *sc = &tmscp_softc[unit]; 391: 392: if (unit >= NTMSCP) 393: return(0); 394: if (sc->sc_addr == NULL && addr != NULL) { 395: tmscp[unit] = (memaddr)_ioget(sizeof (struct tmscp)); 396: if (tmscp[unit] == NULL) 397: return(0); 398: sc->sc_addr = addr; 399: sc->sc_unit = unit; 400: sc->sc_com = (struct tmscp *)SEG5; 401: return (1); 402: } 403: return(0); 404: } 405: 406: struct tms_info * 407: getdd() 408: { 409: register struct tms_info *p; 410: 411: for (p = tms_info; p < &tms_info[NTMS]; p++) 412: { 413: if (p->tms_type == 0) 414: { 415: /* 416: * Set the type with a placeholder value - we may have to sleep waiting for 417: * the drive to come on line and we don't want this slot to be grabbed again. 418: * The online response will load the real drive type. 419: */ 420: p->tms_type = 1; /* XXX */ 421: return(p); 422: } 423: } 424: log(LOG_INFO, "tms: !drives\n"); 425: return(NULL); 426: } 427: 428: static int 429: wait_step(mask, good, csr, sc) 430: u_short mask, good; 431: register struct tmscpdevice *csr; 432: register struct tmscp_softc *sc; 433: { 434: register int i; 435: 436: for (i = 0; i < 150; i++) 437: { 438: if ((csr->tmscpsa & mask) == good) 439: return(0); 440: delay(10000L); /* still in step - wait 1/100 sec */ 441: } 442: sc->sc_state = S_IDLE; 443: sc->sc_ctab.b_active = 0; 444: log(LOG_INFO, tmscpstepfailed, sc->sc_state, csr->tmscpsa); 445: wakeup((caddr_t)&sc->sc_ctab); 446: return(-1); 447: } 448: 449: /* 450: * TMSCP interrupt routine. 451: */ 452: tmsintr(dev) 453: dev_t dev; 454: { 455: register struct tmscpdevice *tmscpaddr; 456: struct buf *bp; 457: int i; 458: register struct tmscp_softc *sc = &tmscp_softc[dev]; 459: register struct tmscp *tm = sc->sc_com; 460: struct mscp *mp; 461: segm seg5; 462: 463: tmscpaddr = sc->sc_addr; 464: 465: /* 466: * How the interrupt is handled depends on the state of the controller. 467: */ 468: switch (sc->sc_state) { 469: 470: case S_IDLE: 471: log(LOG_INFO, "tms%d: rand intr\n", dev); 472: return; 473: 474: /* Controller was in step 1 last, see if its gone to step 2 */ 475: case S_STEP1: 476: # define STEP1MASK 0174377 477: # define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2) 478: 479: if (wait_step(STEP1MASK, STEP1GOOD, tmscpaddr, sc) < 0) 480: return; 481: tmscpaddr->tmscpsa = (short)sc->sc_ctab.b_un.b_addr; 482: sc->sc_state = S_STEP2; 483: return; 484: 485: /* Controller was in step 2 last, see if its gone to step 3 */ 486: case S_STEP2: 487: # define STEP2MASK 0174377 488: # define STEP2GOOD (TMSCP_STEP3|TMSCP_IE|(sc->sc_ivec/4)) 489: 490: if (wait_step(STEP2MASK, STEP2GOOD, tmscpaddr, sc) < 0) 491: return; 492: tmscpaddr->tmscpsa = sc->sc_ctab.b_xmem; 493: sc->sc_state = S_STEP3; 494: return; 495: 496: /* Controller was in step 3 last, see if its gone to step 4 */ 497: case S_STEP3: 498: # define STEP3MASK 0174000 499: # define STEP3GOOD TMSCP_STEP4 500: 501: if (wait_step(STEP3MASK, STEP3GOOD, tmscpaddr, sc) < 0) 502: return; 503: /* 504: * Get microcode version and model number of controller; 505: * Signal initialization complete (_GO) (to the controller); 506: * Set state to "set controller characteristics". 507: */ 508: i = tmscpaddr->tmscpsa; 509: tmscpaddr->tmscpsa = TMSCP_GO | TMSCP_LF; 510: sc->sc_state = S_SCHAR; 511: 512: log(LOG_INFO, "tms%d Ver %d Mod %d\n", dev, i & 0xf, 513: (i >> 4) & 0xf); 514: 515: /* 516: * Initialize the data structures (response and command queues). 517: */ 518: saveseg5(seg5); 519: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); 520: tmsginit(sc, sc->sc_com->tmscp_ca.ca_rspdsc, sc->sc_com->tmscp_rsp, 521: 0, NRSP, TMSCP_OWN|TMSCP_INT); 522: tmsginit(sc, sc->sc_com->tmscp_ca.ca_cmddsc, sc->sc_com->tmscp_cmd, 523: NRSP, NCMD, TMSCP_INT); 524: bp = &sc->sc_wtab; 525: bp->av_forw = bp->av_back = bp; 526: sc->sc_lastcmd = 1; 527: sc->sc_lastrsp = 0; 528: mp = sc->sc_com->tmscp_cmd; 529: mp->mscp_unit = mp->mscp_modifier = 0; 530: mp->mscp_flags = 0; 531: mp->mscp_version = 0; 532: mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS; 533: /* 534: * A host time out value of 0 means that the controller will not 535: * time out. This is ok for the TK50. 536: */ 537: mp->mscp_hsttmo = 0; 538: bzero(&mp->mscp_time, sizeof (mp->mscp_time)); 539: mp->mscp_cntdep = 0; 540: mp->mscp_opcode = M_OP_STCON; 541: ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT); 542: i = tmscpaddr->tmscpip; /* initiate polling */ 543: restorseg5(seg5); 544: return; 545: 546: case S_SCHAR: 547: case S_RUN: 548: break; 549: 550: default: 551: log(LOG_INFO, "tms%d: ST %d\n", dev, sc->sc_state); 552: return; 553: } /* end switch */ 554: 555: /* 556: * The controller state is S_SCHAR or S_RUN 557: */ 558: 559: /* 560: * If the error bit is set in the SA register then print an error 561: * message and reinitialize the controller. 562: */ 563: if (tmscpaddr->tmscpsa&TMSCP_ERR) 564: { 565: log(LOG_INFO, tmscpfatalerr, dev, sc->sc_unit, tmscpaddr->tmscpsa); 566: tmscpaddr->tmscpip = 0; 567: sc->sc_state = S_IDLE; 568: sc->sc_ctab.b_active = 0; 569: wakeup((caddr_t)&sc->sc_ctab); 570: } 571: /* 572: * Check for a buffer purge request. (Won't happen w/ TK50 on Q22 bus) 573: */ 574: saveseg5(seg5); 575: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); 576: if (tm->tmscp_ca.ca_bdp) 577: { 578: tm->tmscp_ca.ca_bdp = 0; 579: tmscpaddr->tmscpsa = 0; /* signal purge complete */ 580: } 581: 582: /* 583: * Check for response ring transition. 584: */ 585: if (tm->tmscp_ca.ca_rspint) 586: { 587: tm->tmscp_ca.ca_rspint = 0; 588: for (i = sc->sc_lastrsp;; i++) 589: { 590: i %= NRSP; 591: if (tm->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN) 592: break; 593: tmscprsp(sc, i); 594: tm->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN; 595: } 596: sc->sc_lastrsp = i; 597: } 598: 599: /* 600: * Check for command ring transition. (Should never happen!) 601: */ 602: if (tm->tmscp_ca.ca_cmdint) 603: tm->tmscp_ca.ca_cmdint = 0; 604: restorseg5(seg5); 605: if (tmscp_cp_wait) 606: wakeup((caddr_t)&tmscp_cp_wait); 607: (void) tmsstart(sc); 608: } 609: 610: 611: /* 612: * Open a tmscp device and set the unit online. If the controller is not 613: * in the run state, call init to initialize the tmscp controller first. 614: */ 615: 616: /* ARGSUSED */ 617: tmscpopen(dev, flag) 618: dev_t dev; 619: int flag; 620: { 621: register int unit = TMSUNIT(dev); 622: int ctlr = TMSCTLR(dev); 623: register struct tmscp_softc *sc; 624: register struct tms_info *tms; 625: register struct mscp *mp; 626: struct tmscpdevice *tmscpaddr; 627: u_short cmdref; 628: int s,i; 629: 630: if (ctlr >= NTMSCP) 631: return (ENXIO); 632: sc = &tmscp_softc[ctlr]; 633: if (sc->sc_addr == NULL) 634: return (ENXIO); 635: if ((tms = sc->sc_drives[unit]) == NULL) { 636: tms = getdd(); 637: if (!tms) 638: return(ENXIO); 639: tms->Tflags = 0; 640: sc->sc_drives[unit] = tms; 641: } 642: else if (tms->Tflags & _INUSE) 643: return(EBUSY); 644: tms->Tflags |= _INUSE; 645: 646: s = spl5(); 647: if (sc->sc_state != S_RUN) 648: { 649: if (sc->sc_state == S_IDLE) 650: if (!tkini(sc)) 651: { 652: log(LOG_INFO, "tms%d init\n", ctlr); 653: sc->sc_drives[unit] = NULL; 654: tms->Tflags = 0; 655: tms->tms_type = 0; 656: (void) splx(s); 657: return(ENXIO); 658: } 659: /* 660: * Wait for initialization to complete 661: */ 662: timeout(wakeup,(caddr_t)&sc->sc_ctab,11*hz); /* to be sure*/ 663: sleep((caddr_t)&sc->sc_ctab, PSWP+1); 664: if (sc->sc_state != S_RUN) 665: { 666: sc->sc_drives[unit] = NULL; 667: tms->Tflags = 0; 668: tms->tms_type = 0; 669: (void) splx(s); 670: return(EIO); 671: } 672: } 673: (void) splx(s); 674: 675: /* 676: * If drive is not online get a command packet, sleeping if no 677: * controller credits are available at the moment. Then start 678: * the ONLINE process. 679: */ 680: tmscpaddr = (struct tmscpdevice *) sc->sc_addr; 681: if (!(tms->Tflags & _ONLINE)) 682: { 683: s = spl5(); 684: while ((mp = tmscpgetcp(sc)) == 0) 685: { 686: tmscp_cp_wait++; 687: sleep((caddr_t)&tmscp_cp_wait,PSWP+1); 688: tmscp_cp_wait--; 689: } 690: (void) splx(s); 691: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); 692: mp->mscp_opcode = M_OP_ONLIN; 693: mp->mscp_unit = unit; /* unit? */ 694: tms_clrerr(tms, mp); 695: /* calculate this once instead of 4 times */ 696: cmdref = (u_short)&tms->tms_type; 697: mp->mscp_cmdref = cmdref; /* need to sleep on something */ 698: ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN | TMSCP_INT); 699: normalseg5(); 700: i = tmscpaddr->tmscpip; 701: /* 702: * To make sure we wake up, timeout in 240 seconds. 703: * Wakeup in tmscprsp routine. 704: * 240 seconds (4 minutes) is necessary since a rewind 705: * can take a few minutes. 706: */ 707: timeout(wakeup,(caddr_t) cmdref,240 * hz); 708: sleep((caddr_t)cmdref,PSWP+1); 709: untimeout(wakeup, cmdref); 710: } 711: if (!(tms->Tflags & _ONLINE)) 712: { 713: oops: tms->Tflags = 0; 714: tms->tms_type = 0; 715: sc->sc_drives[unit] = NULL; 716: return(EIO); /* Didn't go online */ 717: } 718: /* 719: * Get the unit characteristics (GTUNT). This 1) Verifies the drive 720: * is really still online and 2) Retrieves information about the drive 721: * such as density choices, cache presence, etc. 722: */ 723: tms->tms_flags = 0; 724: if (tmscpcache & ((1 << unit) << (4 * ctlr))) 725: tms->Tflags |= _CACHE_ON; 726: i = tms->Tflags & _CACHE_ON; 727: tms->Tflags = _ONLINE | _INUSE | i; /* Clear all other flags */ 728: tmscpcommand(dev, TMS_SENSE, 1); 729: if (!(tms->Tflags & _ONLINE)) 730: goto oops; 731: 732: /* 733: * Next issue a reposition NOP by spacing forward 0 records. This returns 734: * the current position (so we can tell if we're at BOT or not) and also 735: * clears any serious exceptions outstanding. 736: */ 737: tmscpcommand(dev, TMS_CSE, 1); 738: 739: /* 740: * Now go set the density - the lower level routines set the density if 741: * the drive is at BOT. 742: */ 743: tmscpcommand(dev, TMS_SETDENSITY, 1); 744: return(0); 745: } 746: 747: /* 748: * Close tape device. 749: * 750: * If tape was open for writing or last operation was 751: * a write, then write two EOF's and backspace over the last one. 752: * Unless this is a non-rewinding special file, rewind the tape. 753: */ 754: tmscpclose(dev, flag) 755: register dev_t dev; 756: register flag; 757: { 758: struct tmscp_softc *sc; 759: register struct tms_info *tms; 760: int unit = TMSUNIT(dev); 761: 762: sc = &tmscp_softc[TMSCTLR(dev)]; 763: tms = sc->sc_drives[unit]; 764: 765: if ((tms->Tflags & _CACHE_ON) && (tms->Tflags & _CACHE_WRITTEN)) 766: { 767: /* 768: * A misbehaving application has closed the device without flushing 769: * the enabled cache by issuing a MTFLUSH - we'll do it for it. 770: */ 771: tmscpcommand(dev, TMS_FLUSH, 1); 772: if (tms->tms_status != M_ST_SUCC) 773: { 774: /* 775: * This is BAD news - the flush didn't work. The drive is in a serious 776: * exception state, leave that alone for the non-rewind case so that further 777: * operations fail. About all that can be done now is log the error. 778: */ 779: log(LOG_INFO, "tms%d,%d flsh\n", TMSCTLR(dev), unit); 780: tms->Tflags &= ~_CACHE_WRITTEN; 781: } 782: } 783: if (tms->tms_flags & MTF_WRITTEN) 784: tms_wrteof(dev, tms); 785: tms->Tflags &= ~(_BUFMARK | _INUSE); 786: if ((dev & T_NOREWIND) == 0) 787: { 788: tmscpcommand(dev, TMS_REW, 0); 789: tms->Tflags &= ~(_LOST | _CLSEREX | _SEREX); 790: } 791: return(0); 792: } 793: 794: /* 795: * Execute a command on the tape drive a specified number of times. 796: * This routine sets up a buffer and calls the strategy routine which 797: * links the buffer onto the drive's buffer queue. 798: * The start routine will take care of creating a tmscp command packet 799: * with the command. The start routine is called by the strategy or the 800: * interrupt routine. 801: */ 802: 803: tmscpcommand(dev, com, count) 804: register dev_t dev; 805: int com, count; 806: { 807: register struct buf *bp; 808: register int s; 809: int unit = TMSUNIT(dev); 810: 811: bp = &tmscp_softc[TMSCTLR(dev)].sc_cmdbuf; 812: 813: s = spl5(); 814: while (bp->b_flags&B_BUSY) 815: { 816: bp->b_flags |= B_WANTED; 817: sleep((caddr_t)bp, PRIBIO); 818: } 819: bp->b_flags = B_BUSY|B_READ; 820: splx(s); 821: /* 822: * Load the buffer. The b_count field gets used to hold the command 823: * count. the b_resid field gets used to hold the command mneumonic. 824: * These 2 fields are "known" to be "safe" to use for this purpose. 825: * (Most other drivers also use these fields in this way.) 826: */ 827: bp->b_dev = dev; 828: bp->b_bcount = count; 829: bp->b_resid = com; 830: bp->b_blkno = 0; 831: /* 832: * Start the timer before entering the strategy routine. If it declares 833: * an immediate error it will also perform an iodone which will cause us 834: * to fall thru and cancel the timer. 835: */ 836: timeout(tmswatchdog, bp, 240 * hz); 837: tmscpstrategy(bp); 838: iowait(bp); 839: untimeout(tmswatchdog, bp); 840: if (bp->b_flags & B_WANTED) /* Anyone waiting above? */ 841: wakeup(bp); 842: bp->b_flags &= B_ERROR; /* Clears B_BUSY */ 843: } 844: 845: /* 846: * If this routine is called then (after 4 minutes) something is hung. 847: * Set the I/O done flag, set error to be ETIMEDOUT, and issue the wakeup. 848: */ 849: tmswatchdog(bp) 850: struct buf *bp; 851: { 852: 853: bp->b_error = ETIMEDOUT; 854: biodone(bp); 855: } 856: 857: /* 858: * Init mscp communications area 859: */ 860: tmsginit(sc, com, msgs, offset, length, flags) 861: register struct tmscp_softc *sc; 862: register Trl *com; 863: register struct mscp *msgs; 864: int offset; 865: int length; 866: int flags; 867: { 868: long vaddr; 869: 870: /* 871: * Figure out virtual address of message 872: * skip comm area and mscp messages header and previous messages 873: * 874: * N.B. Assumes SEG5 has been remapped to the comm area for this 875: * controller. 876: */ 877: vaddr = _iomap(tmscp[sc->sc_unit]); 878: vaddr += sizeof(struct tmscpca) /* skip comm area */ 879: +sizeof(struct mscp_header); /* m_cmdref disp */ 880: vaddr += offset * sizeof(struct mscp); /* skip previous */ 881: while (length--) { 882: com->lsh = loint(vaddr); 883: com->hsh = flags | hiint(vaddr); 884: msgs->mscp_dscptr = (long *)com; 885: msgs->mscp_header.mscp_msglen = sizeof(struct mscp); 886: msgs->mscp_header.mscp_vcid = 1; /* tape VCID = 1 */ 887: ++com; ++msgs; vaddr += sizeof(struct mscp); 888: } 889: } 890: 891: /* 892: * Find an unused command packet 893: */ 894: struct mscp * 895: tmscpgetcp(sc) 896: register struct tmscp_softc *sc; 897: { 898: register struct mscp *mp = NULL; 899: register struct tmscpca *cp; 900: int i; 901: int s; 902: segm seg5; 903: 904: s = spl5(); 905: saveseg5(seg5); 906: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); 907: cp = &sc->sc_com->tmscp_ca; 908: /* 909: * If no credits, can't issue any commands 910: * until some outstanding commands complete. 911: */ 912: i = sc->sc_lastcmd; 913: if (((cp->ca_cmddsc[i].hsh&(TMSCP_OWN|TMSCP_INT))==TMSCP_INT) && 914: (sc->sc_credits >= 2)) 915: { 916: sc->sc_credits--; /* This commits to issuing a command */ 917: cp->ca_cmddsc[i].hsh &= ~TMSCP_INT; 918: mp = &sc->sc_com->tmscp_cmd[i]; 919: mp->mscp_cmdref = 0; 920: mp->mscp_modifier = 0; 921: mp->mscp_flags = 0; 922: bzero(&mp->un, sizeof (mp->un)); 923: sc->sc_lastcmd = (i + 1) % NCMD; 924: } 925: restorseg5(seg5); 926: (void) splx(s); 927: return(mp); 928: } 929: 930: /* 931: * Initialize a TMSCP device. Set up UBA mapping registers, 932: * initialize data structures, and start hardware 933: * initialization sequence. 934: */ 935: tkini(sc) 936: register struct tmscp_softc *sc; 937: { 938: register struct tmscpdevice *tmscpaddr; 939: long adr; 940: 941: sc->sc_ctab.b_active++; 942: adr = _iomap(tmscp[sc->sc_unit]) + (u_int)RINGBASE; 943: sc->sc_ctab.b_un.b_addr = (caddr_t)loint(adr); 944: sc->sc_ctab.b_xmem = hiint(adr); 945: tmscpaddr = sc->sc_addr; 946: 947: /* 948: * Start the hardware initialization sequence. 949: */ 950: tmscpaddr->tmscpip = 0; /* start initialization */ 951: 952: while((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0) 953: { 954: if (tmscpaddr->tmscpsa & TMSCP_ERR) 955: return(0); /* CHECK */ 956: } 957: tmscpaddr->tmscpsa=TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8)|TMSCP_IE|(sc->sc_ivec/4); 958: /* 959: * Initialization continues in the interrupt routine. 960: */ 961: sc->sc_state = S_STEP1; 962: sc->sc_credits = 0; 963: return(1); 964: } 965: 966: /* 967: * Start I/O operation 968: * This code is convoluted. The majority of it was copied from the uda driver. 969: */ 970: 971: tmsstart(sc) 972: register struct tmscp_softc *sc; 973: { 974: register struct mscp *mp; 975: register struct buf *bp, *dp; 976: register struct tms_info *tms; 977: struct tmscpdevice *tmscpaddr; 978: int i, unit; 979: segm seg5; 980: 981: saveseg5(seg5); /* save just once at top */ 982: for(;;) 983: { 984: if ((dp = sc->sc_ctab.b_actf) == NULL) 985: { 986: /* (drive was inactive) */ 987: sc->sc_ctab.b_active = 0; 988: break; 989: } 990: if ((bp = dp->b_actf) == NULL) 991: { 992: /* 993: * No more requests for this drive, remove 994: * from controller queue and look at next drive. 995: * We know we're at the head of the controller queue. 996: */ 997: dp->b_active = 0; 998: sc->sc_ctab.b_actf = dp->b_forw; 999: continue; 1000: } 1001: sc->sc_ctab.b_active++; 1002: unit = TMSUNIT(bp->b_dev); 1003: tmscpaddr = (struct tmscpdevice *)sc->sc_addr; 1004: tms = sc->sc_drives[unit]; 1005: if ((tmscpaddr->tmscpsa&TMSCP_ERR) || sc->sc_state != S_RUN) 1006: { 1007: log(LOG_INFO, "tms%d,%d: sa %x st %d\n", sc->sc_unit, 1008: unit, tmscpaddr->tmscpsa, sc->sc_state); 1009: (void)tkini(sc); 1010: /* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE TMSCPRESET */ 1011: break; 1012: } 1013: 1014: if (!(tms->Tflags & _ONLINE)) 1015: { 1016: if ((mp = tmscpgetcp(sc)) == NULL) 1017: break; 1018: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); 1019: mp->mscp_opcode = M_OP_ONLIN; 1020: mp->mscp_unit = unit; 1021: tms_clrerr(tms, mp); 1022: dp->b_active = 2; 1023: sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */ 1024: ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT); 1025: if (tmscpaddr->tmscpsa&TMSCP_ERR) 1026: log(LOG_INFO, tmscpfatalerr, sc->sc_unit, 1027: TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa); 1028: restorseg5(seg5); 1029: i = tmscpaddr->tmscpip; 1030: continue; 1031: } 1032: if ((mp = tmscpgetcp(sc)) == NULL) 1033: break; 1034: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); 1035: mp->mscp_cmdref = (u_short)bp; /* pointer to get back */ 1036: mp->mscp_unit = unit; 1037: /* 1038: * If its an ioctl-type command then set up the appropriate 1039: * tmscp command; by doing a switch on the "b_resid" field where 1040: * the command mneumonic is stored. 1041: */ 1042: if (bp == &sc->sc_cmdbuf) 1043: { 1044: /* 1045: * The reccnt and tmkcnt fields are set to zero by the getcp 1046: * routine (as bytecnt and buffer fields). Thus reccnt and 1047: * tmkcnt are only modified here if they need to be set to 1048: * a non-zero value. 1049: */ 1050: switch ((int)bp->b_resid) { 1051: 1052: case TMS_WRITM: 1053: tms_wtm_st(mp, sc, 0); 1054: break; 1055: case TMS_FSF: 1056: tms_repos_st(mp, sc, 0); 1057: break; 1058: case TMS_BSF: 1059: tms_repos_st(mp, sc, M_MD_REVRS); 1060: break; 1061: case TMS_FSR: 1062: tms_reposrec_st(mp, sc, M_MD_OBJCT); 1063: break; 1064: case TMS_BSR: 1065: tms_reposrec_st(mp, sc, M_MD_OBJCT | M_MD_REVRS); 1066: break; 1067: case TMS_REW: 1068: if (bp->b_bcount) 1069: i = M_MD_REWND; 1070: else 1071: i = M_MD_REWND | M_MD_IMMED; 1072: bp->b_bcount = 0; /* XXX */ 1073: tms_repos_st(mp, sc, i); 1074: break; 1075: case TMS_OFFL: 1076: tms_avail_st(mp, sc, M_MD_UNLOD); 1077: break; 1078: case TMS_SENSE: 1079: mp->mscp_opcode = M_OP_GTUNT; 1080: break; 1081: case TMS_FLUSH: 1082: mp->mscp_opcode = M_OP_FLUSH; 1083: break; 1084: case TMS_CACHE: 1085: tms->tms_unitflgs |= M_UF_WBKNV; 1086: tms->tms_unitflgs &= ~M_UF_SCCHH; 1087: tms->Tflags |= _CACHE_ON; 1088: tms_stunt_st(mp, sc, 0); 1089: break; 1090: case TMS_NOCACHE: 1091: tms->tms_unitflgs &= ~M_UF_WBKNV; 1092: tms->tms_unitflgs |= M_UF_SCCHH; 1093: tms->Tflags &= ~_CACHE_ON; 1094: tms_stunt_st(mp, sc, 0); 1095: break; 1096: case TMS_CSE: 1097: bp->b_bcount = 0; /* 0 objects to skip */ 1098: tms_repos_st(mp, sc, M_MD_OBJCT); 1099: break; 1100: case TMS_SETDENSITY: 1101: tms->tms_format &= ~M_TF_MASK; 1102: tms->tms_format |= Dmatrix[TMSDENS(bp->b_dev)][tms->tms_fmtmenu & FMTMASK]; 1103: tms_stunt_st(mp, sc, 0); 1104: break; 1105: default: 1106: log(LOG_INFO, "ioctl %x\n", bp->b_resid); 1107: /* Need a no-op. Reposition no amount */ 1108: mp->mscp_opcode = M_OP_REPOS; 1109: break; 1110: } /* end switch (bp->b_resid) */ 1111: } 1112: else /* Its a read/write command (not an ioctl) */ 1113: { 1114: mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE; 1115: mp->mscp_bytecnt = bp->b_bcount; 1116: mp->mscp_buffer_l = (u_short) bp->b_un.b_addr; 1117: mp->mscp_buffer_h = bp->b_xmem; 1118: } 1119: 1120: if ((tms->Tflags & _CACHE_ON) && (mp->mscp_opcode == M_OP_WRITE)) 1121: tms->Tflags |= _CACHE_WRITTEN; 1122: if ((tms->Tflags & _BUFMARK) && (mp->mscp_opcode == M_OP_READ) && 1123: (tms->Tflags & _CLSEREX)) 1124: { 1125: tms->Tflags &= ~(_BUFMARK | _CLSEREX); 1126: mp->mscp_modifier |= M_MD_CLSEX; 1127: } 1128: 1129: if (tmscpprintf & 0x8) 1130: { 1131: log(LOG_INFO, "tms%d,%d -> op %x fl %x mod %x\n", 1132: sc->sc_unit, mp->mscp_unit, 1133: mp->mscp_opcode, mp->mscp_flags, mp->mscp_modifier); 1134: } 1135: 1136: ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT); 1137: i = tmscpaddr->tmscpip; /* initiate polling */ 1138: dp->b_qsize++; 1139: /* 1140: * Move drive to the end of the controller queue 1141: */ 1142: if (dp->b_forw != NULL) 1143: { 1144: sc->sc_ctab.b_actf = dp->b_forw; 1145: sc->sc_ctab.b_actl->b_forw = dp; 1146: sc->sc_ctab.b_actl = dp; 1147: dp->b_forw = NULL; 1148: } 1149: /* 1150: * Move buffer to I/O wait queue 1151: */ 1152: dp->b_actf = bp->av_forw; 1153: dp = &sc->sc_wtab; 1154: bp->av_forw = dp; 1155: bp->av_back = dp->av_back; 1156: dp->av_back->av_forw = bp; 1157: dp->av_back = bp; 1158: if (tmscpaddr->tmscpsa&TMSCP_ERR) 1159: { 1160: log(LOG_INFO, tmscpfatalerr,sc->sc_unit, 1161: mp->mscp_unit, tmscpaddr->tmscpsa); 1162: (void)tkini(sc); 1163: break; 1164: } 1165: } /* end for */ 1166: /* 1167: * Check for response ring transitions lost in the 1168: * Race condition. Map SEG5 in case we escaped early from the for(). 1169: */ 1170: mapseg5(tmscp[sc->sc_unit], MAPBUFDESC); 1171: for (i = sc->sc_lastrsp;; i++) 1172: { 1173: i %= NRSP; 1174: if (sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh&TMSCP_OWN) 1175: break; 1176: tmscprsp(sc, i); 1177: sc->sc_com->tmscp_ca.ca_rspdsc[i].hsh |= TMSCP_OWN; 1178: } 1179: sc->sc_lastrsp = i; 1180: restorseg5(seg5); 1181: } 1182: 1183: 1184: /* 1185: * Process a response packet. N.B. Assumes SEG5 maps comm area for controller 1186: */ 1187: tmscprsp(sc, i) 1188: register struct tmscp_softc *sc; 1189: int i; 1190: { 1191: register struct mscp *mp; 1192: register struct tms_info *tms; 1193: struct buf *dp, *bp; 1194: int em_status, em_endcode; 1195: 1196: mp = &sc->sc_com->tmscp_rsp[i]; 1197: mp->mscp_header.mscp_msglen = sizeof (struct mscp); 1198: sc->sc_credits += mp->mscp_header.mscp_credits & 0xf; /* low 4 bits */ 1199: if ((mp->mscp_header.mscp_credits & 0xf0) > 0x10) /* Check */ 1200: return; 1201: 1202: /* 1203: * If it's an error log message (datagram), 1204: * pass it on for more extensive processing. 1205: */ 1206: if ((mp->mscp_header.mscp_credits & 0xf0) == 0x10) 1207: { 1208: tmserror(sc->sc_unit, (struct mslg *)mp); 1209: return; 1210: } 1211: 1212: if (tmscpprintf & 0x4) 1213: log(LOG_INFO, "tms%d,%d: op %x st %x\n", sc->sc_unit, 1214: mp->mscp_unit,mp->mscp_opcode, 1215: mp->mscp_status & M_ST_MASK); 1216: 1217: em_status = mp->mscp_status&M_ST_MASK; 1218: em_endcode = mp->mscp_endcode & ~M_OP_END; 1219: /* 1220: * The controller interrupts as any drive. 1221: * This means that you must check for controller interrupts 1222: * before drive responses. 1223: */ 1224: if (em_endcode == M_OP_STCON) 1225: { 1226: if (em_status == M_ST_SUCC) 1227: sc->sc_state = S_RUN; 1228: else 1229: sc->sc_state = S_IDLE; 1230: sc->sc_ctab.b_active = 0; 1231: wakeup((caddr_t)&sc->sc_ctab); 1232: return; 1233: } 1234: if (mp->mscp_unit >= 4) 1235: return; 1236: tms = sc->sc_drives[mp->mscp_unit]; 1237: if (!tms) /* unopened unit coming online - ignore it */ 1238: return; 1239: dp = &tms->tms_dtab; 1240: 1241: switch (em_endcode) { 1242: case M_OP_ONLIN: 1243: if (em_status == M_ST_SUCC || em_status == M_ST_WRTPR) 1244: { 1245: tms->Tflags |= _ONLINE; 1246: tms->Tflags &= ~_CACHE_WRITTEN; 1247: /* 1248: * Normally this is done in the 'tms_check_ret' routine. The ONLIN case is 1249: * special (well, ok - weird) in that it was never put on the I/O wait queue. 1250: * Thus we need to do this here. 1251: */ 1252: tms->tms_endcode = em_endcode; 1253: tms->tms_status = em_status; 1254: tms->tms_type = mp->mscp_mediaid; 1255: tms->tms_unitflgs = mp->mscp_unitflgs; 1256: tms->tms_format = mp->mscp_format; 1257: /* 1258: * Link the drive onto the controller queue 1259: */ 1260: dp->b_forw = NULL; 1261: if (sc->sc_ctab.b_actf == NULL) 1262: sc->sc_ctab.b_actf = dp; 1263: else 1264: sc->sc_ctab.b_actl->b_forw = dp; 1265: sc->sc_ctab.b_actl = dp; 1266: dp->b_active = 1; 1267: } 1268: else 1269: { 1270: while (bp = dp->b_actf) 1271: { 1272: dp->b_actf = bp->av_forw; 1273: bp->b_flags |= B_ERROR; 1274: iodone(bp); 1275: } 1276: } 1277: if (mp->mscp_cmdref) 1278: wakeup((caddr_t)mp->mscp_cmdref); 1279: return; 1280: /* 1281: * The AVAILABLE ATTENTION message occurs when the 1282: * unit becomes available after loading. 1283: * Marking the unit offline will force an 1284: * online command prior to using the unit. 1285: */ 1286: case M_OP_AVATN: 1287: tms->Tflags &= ~_ONLINE; 1288: return; 1289: /* 1290: * An endcode with no opcode (0x80) is an invalid command. This is supposed 1291: * to indicate a protocol error (illegal opcode, parameter error, etc) but 1292: * without the real opcode we don't know which command (reposition, write, 1293: * read, ...) failed. So, just declare I/O done and hope for the best. 1294: */ 1295: case 0: 1296: if (tmscpprintf & 0x8) 1297: log(LOG_INFO, "tms%d,%d: inv end=%x st=%x\n", 1298: sc->sc_unit,mp->mscp_unit,em_endcode,em_status); 1299: tms_iodone(mp, sc); 1300: return; 1301: case M_OP_WRITE: 1302: case M_OP_READ: 1303: tms_rw_em(mp, sc); 1304: return; 1305: case M_OP_WRITM: 1306: tms_wtm_em(mp, sc); 1307: return; 1308: case M_OP_REPOS: 1309: tms_repos_em(mp, sc); 1310: return; 1311: case M_OP_STUNT: 1312: tms_stunt_em(mp, sc); 1313: return; 1314: case M_OP_AVAIL: 1315: tms_avail_em(mp, sc); 1316: return; 1317: case M_OP_GTUNT: 1318: tms_gtunt_em(mp, sc); 1319: return; 1320: case M_OP_FLUSH: 1321: tms_flush_em(mp, sc); 1322: return; 1323: default: 1324: if (tmscpprintf & 0x8) 1325: log(LOG_INFO, "tms%d,%d rsp %x\n", sc->sc_unit, 1326: mp->mscp_unit, em_endcode); 1327: return; 1328: } /* end switch mp->mscp_opcode */ 1329: } 1330: 1331: /* 1332: * Manage buffers and perform block mode read and write operations. 1333: */ 1334: 1335: tmscpstrategy (bp) 1336: register struct buf *bp; 1337: { 1338: register struct buf *dp; 1339: register struct tmscp_softc *sc; 1340: struct tms_info *tms; 1341: int ctlr = TMSCTLR(bp->b_dev); 1342: int s; 1343: 1344: sc = &tmscp_softc[ctlr]; 1345: tms = sc->sc_drives[TMSUNIT(bp->b_dev)]; 1346: if (!tms || !(tms->Tflags & _ONLINE)) 1347: { 1348: bp->b_flags |= B_ERROR; 1349: iodone(bp); 1350: return; 1351: } 1352: /* 1353: * If we're at the end of the tape and this is not an 'ioctl' command 1354: * then return an error rather than reading or writing off the end of the tape. 1355: * Ioctl commands are allowed to proceed so that tapemarks can be written and 1356: * repositioning (rewind, etc) can be done. 1357: */ 1358: if ((tms->tms_flags & MTF_EOM) && bp != &sc->sc_cmdbuf) 1359: { 1360: bp->b_resid = bp->b_bcount; 1361: bp->b_error = ENOSPC; 1362: bp->b_flags |= B_ERROR; 1363: iodone(bp); 1364: return; 1365: } 1366: mapalloc(bp); 1367: s = spl5(); 1368: /* 1369: * Link the buffer onto the drive queue 1370: */ 1371: dp = &tms->tms_dtab; 1372: if (dp->b_actf == 0) 1373: dp->b_actf = bp; 1374: else 1375: dp->b_actl->av_forw = bp; 1376: dp->b_actl = bp; 1377: bp->av_forw = 0; 1378: /* 1379: * Link the drive onto the controller queue 1380: */ 1381: if (dp->b_active == 0) 1382: { 1383: dp->b_forw = NULL; 1384: if (sc->sc_ctab.b_actf == NULL) 1385: sc->sc_ctab.b_actf = dp; 1386: else 1387: sc->sc_ctab.b_actl->b_forw = dp; 1388: sc->sc_ctab.b_actl = dp; 1389: dp->b_active = 1; 1390: } 1391: /* 1392: * If the controller is not active, start it. 1393: */ 1394: if (sc->sc_ctab.b_active == 0) 1395: (void) tmsstart(sc); 1396: splx(s); 1397: return; 1398: } 1399: 1400: /* ARGSUSED */ 1401: tmscpioctl(dev, cmd, data, flag) 1402: dev_t dev; 1403: int cmd; 1404: caddr_t data; 1405: int flag; 1406: { 1407: struct tmscp_softc *sc = &tmscp_softc[TMSCTLR(dev)]; 1408: struct buf *bp = &sc->sc_cmdbuf; 1409: register struct tms_info *tms = sc->sc_drives[TMSUNIT(dev)]; 1410: int fcount; /* number of files (or records) to space */ 1411: register struct mtop *mtop; /* mag tape cmd op to perform */ 1412: register struct mtget *mtget; /* mag tape struct to get info in */ 1413: 1414: /* we depend of the values and order of the TMS ioctl codes here */ 1415: static char tmsops[] = 1416: {TMS_WRITM,TMS_FSF,TMS_BSF,TMS_FSR,TMS_BSR,TMS_REW,TMS_OFFL,TMS_SENSE, 1417: TMS_CACHE,TMS_NOCACHE,TMS_FLUSH}; 1418: 1419: if (!tms) 1420: return(ENXIO); 1421: if (cmd != MTIOCGET) 1422: tms->tms_status = ~M_ST_SUCC; 1423: if (tms->tms_position == 0) 1424: tms->tms_flags |= MTF_BOM; 1425: else 1426: tms->tms_flags &= ~MTF_BOM; 1427: 1428: switch (cmd) { 1429: case MTIOCTOP: 1430: mtop = (struct mtop *)data; 1431: switch (mtop->mt_op) { 1432: 1433: case MTWEOF: 1434: return(tms_wrteof(dev, tms)); 1435: case MTFSF: 1436: case MTBSF: 1437: case MTFSR: 1438: case MTBSR: 1439: fcount = mtop->mt_count; 1440: break; 1441: case MTFLUSH: 1442: case MTCACHE: 1443: case MTNOCACHE: 1444: if ((tms->Tflags & (_HASCACHE|_ONLINE)) != 1445: (_HASCACHE|_ONLINE)) 1446: return(0); 1447: case MTREW: 1448: case MTOFFL: 1449: case MTNOP: 1450: fcount = 1; 1451: break; 1452: default: 1453: return(ENXIO); 1454: } /* end switch mtop->mt_op */ 1455: 1456: if (fcount <= 0) 1457: return(EINVAL); 1458: tmscpcommand(dev, tmsops[mtop->mt_op], fcount); 1459: if (tms->tms_status != M_ST_SUCC) 1460: { 1461: if (tms->Tflags & _CLSEREX) 1462: tmscpcommand(dev, TMS_CSE, 1); 1463: return(EIO); 1464: } 1465: return(geterror(bp)); 1466: 1467: case MTIOCGET: 1468: /* 1469: * Return status info associated with the particular UNIT. 1470: */ 1471: mtget = (struct mtget *)data; 1472: mtget->mt_type = MT_ISTMSCP; 1473: mtget->mt_dsreg = tms->tms_flags << 8; 1474: mtget->mt_dsreg |= tms->tms_endcode; 1475: mtget->mt_erreg = tms->tms_status; 1476: mtget->mt_resid = tms->tms_resid; 1477: break; 1478: default: 1479: return(ENXIO); 1480: } 1481: return (0); 1482: } 1483: 1484: tms_wrteof(dev, tms) 1485: dev_t dev; 1486: register struct tms_info *tms; 1487: { 1488: 1489: tmscpcommand(dev, TMS_WRITM, 1); 1490: if (tms->tms_status != M_ST_SUCC) 1491: return(EIO); 1492: tms->tms_status = ~M_ST_SUCC; 1493: tmscpcommand(dev, TMS_WRITM, 1); 1494: if (tms->tms_status != M_ST_SUCC) 1495: return(EIO); 1496: tms->Tflags &= ~_CACHE_WRITTEN; 1497: tms->tms_status = ~M_ST_SUCC; 1498: tmscpcommand(dev, TMS_BSR, 1); 1499: if (tms->tms_status != M_ST_SUCC) 1500: return(EIO); 1501: return(0); 1502: } 1503: 1504: /* 1505: * Initialize the mscp packet for a STUNT command. If the drive is in a 1506: * 'cache lost' but 'written' state then clear it and log the error. 1507: */ 1508: 1509: tms_stunt_st(mp, sc, flgs) 1510: register struct mscp *mp; 1511: register struct tmscp_softc *sc; 1512: int flgs; 1513: { 1514: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1515: 1516: mp->mscp_opcode = M_OP_STUNT; 1517: mp->mscp_modifier = flgs | M_MD_EXCAC; 1518: tms_cache_cmn(sc, tms, mp); 1519: 1520: /* 1521: * Set the unit flags - this includes the cache enable/disable flags. 1522: */ 1523: 1524: mp->mscp_unitflgs = tms->tms_unitflgs; 1525: 1526: /* 1527: * Only initialize the density if the position is not at BOT. On some 1528: * drives (notably the TU81) selecting a density other than the 'current' 1529: * (0) causes an illegal command error. 1530: */ 1531: if (tms->tms_position != 0) 1532: mp->mscp_format = 0; 1533: else 1534: mp->mscp_format = tms->tms_format; 1535: } 1536: 1537: /* 1538: * Initialize the mscp packet for a REPOS command. The 'flgs' parameter 1539: * specifies if the movement if forwards or backwards and if records or 1540: * tape marks (objects) are to be skipped. 1541: */ 1542: 1543: tms_repos_st(mp, sc, flgs) 1544: register struct mscp *mp; 1545: register struct tmscp_softc *sc; 1546: int flgs; 1547: { 1548: struct buf *bp = (struct buf *)mp->mscp_cmdref; 1549: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1550: 1551: mp->mscp_opcode = M_OP_REPOS; 1552: mp->mscp_modifier = flgs | M_MD_CLSEX; 1553: tms->Tflags &= ~_CLSEREX; 1554: tms_cache_cmn(sc, tms, mp); /* shared code with tms_reposrec_st */ 1555: if (mp->mscp_modifier & M_MD_OBJCT) 1556: mp->mscp_reccnt = bp->b_bcount; 1557: else 1558: mp->mscp_tmkcnt = bp->b_bcount; 1559: } 1560: 1561: /* 1562: * Initialize the mscp packet for a REPOS 'record' command. Tape records do 1563: * not include tapemarks (which is why this is a separate routine from 1564: * tms_repos_st above). 1565: */ 1566: 1567: tms_reposrec_st(mp, sc, flgs) 1568: register struct mscp *mp; 1569: register struct tmscp_softc *sc; 1570: int flgs; 1571: { 1572: struct buf *bp = (struct buf *)mp->mscp_cmdref; 1573: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1574: 1575: mp->mscp_opcode = M_OP_REPOS; 1576: mp->mscp_modifier = flgs; 1577: tms_cache_cmn(sc, tms, mp); 1578: mp->mscp_reccnt = bp->b_bcount; 1579: } 1580: 1581: /* 1582: * Initialize the mscp packet for an AVAIL command. The only time this is 1583: * done is on a 'rewoffl' command. 1584: */ 1585: 1586: tms_avail_st(mp, sc, flgs) 1587: register struct mscp *mp; 1588: struct tmscp_softc *sc; 1589: int flgs; 1590: { 1591: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1592: 1593: mp->mscp_opcode = M_OP_AVAIL; 1594: mp->mscp_modifier = flgs; 1595: tms_clrerr(tms, mp); 1596: } 1597: 1598: tms_clrerr(tms, mp) 1599: register struct tms_info *tms; 1600: register struct mscp *mp; 1601: { 1602: 1603: mp->mscp_modifier |= M_MD_CLSEX; 1604: tms->Tflags &= ~_CLSEREX; 1605: if (tms->Tflags & _CACHE_LOST) 1606: { 1607: tms->Tflags &= ~(_CACHE_LOST | _CACHE_WRITTEN); 1608: mp->mscp_modifier |= M_MD_CDATL; 1609: } 1610: } 1611: 1612: /* 1613: * Initialize the mscp packet for a WTM (write tapemark) command. 1614: */ 1615: 1616: tms_wtm_st(mp, sc, flgs) 1617: register struct mscp *mp; 1618: register struct tmscp_softc *sc; 1619: int flgs; 1620: { 1621: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1622: 1623: mp->mscp_opcode = M_OP_WRITM; 1624: mp->mscp_modifier = flgs | M_MD_CLSEX; 1625: tms->Tflags &= ~_CLSEREX; 1626: tms_cache_cmn(sc, tms, mp); 1627: } 1628: 1629: tms_cache_cmn(sc, tms, mp) 1630: register struct tmscp_softc *sc; 1631: register struct tms_info *tms; 1632: register struct mscp *mp; 1633: { 1634: 1635: if (tms->Tflags & _CACHE_LOST) 1636: { 1637: if (!(tms->Tflags & _CACHE_WRITTEN)) 1638: { 1639: tms->Tflags &= ~(_CACHE_LOST | _CACHE_WRITTEN); 1640: mp->mscp_modifier |= M_MD_CDATL; 1641: } 1642: else 1643: log(LOG_INFO, "tms%d,%d clost\n", 1644: sc->sc_unit, mp->mscp_unit); 1645: } 1646: } 1647: 1648: /* 1649: * Process the end message from a REPOS command. Called from tmscprsp(). 1650: */ 1651: 1652: tms_repos_em(mp, sc) 1653: register struct mscp *mp; 1654: register struct tmscp_softc *sc; 1655: { 1656: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1657: u_short em_status = mp->mscp_status & M_ST_MASK; 1658: 1659: (void)tms_check_ret(mp, sc); 1660: if (em_status == M_ST_SUCC) 1661: { 1662: if (tms->tms_position != mp->mscp_position) 1663: tms->tms_flags &= ~MTF_WRITTEN; 1664: if (tms->tms_position = mp->mscp_position) 1665: tms->tms_flags &= ~MTF_BOM; 1666: else 1667: { 1668: tms->tms_flags |= MTF_BOM; 1669: tms->Tflags &= ~_LOST; 1670: } 1671: tms->Tflags &= ~_CACHE_WRITTEN; 1672: } 1673: tms->tms_resid = 0; 1674: tms_iodone(mp, sc); 1675: } 1676: 1677: /* 1678: * Process the end message from a STUNT command. 1679: */ 1680: 1681: tms_stunt_em(mp, sc) 1682: register struct mscp *mp; 1683: register struct tmscp_softc *sc; 1684: { 1685: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1686: u_short em_status = mp->mscp_status & M_ST_MASK; 1687: 1688: (void)tms_check_ret(mp, sc); 1689: tms->Tflags &= ~_CACHE_WRITTEN; 1690: if (em_status == M_ST_SUCC) 1691: { 1692: tms->tms_unitflgs = mp->mscp_unitflgs; 1693: tms->tms_format = mp->mscp_format; 1694: tms->tms_type = mp->mscp_mediaid; 1695: tms->Tflags |= _ONLINE; 1696: } 1697: tms->tms_resid = 0; 1698: tms_iodone(mp, sc); 1699: } 1700: 1701: /* 1702: * Process the end message from a WRITM (Write Tape Mark) command. 1703: */ 1704: 1705: tms_wtm_em(mp, sc) 1706: register struct mscp *mp; 1707: register struct tmscp_softc *sc; 1708: { 1709: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1710: u_short em_status = mp->mscp_status & M_ST_MASK; 1711: 1712: if (em_status == M_ST_SUCC) 1713: { 1714: tms->tms_flags &= ~MTF_WRITTEN; 1715: tms->tms_position = mp->mscp_position; 1716: } 1717: (void)tms_check_ret(mp, sc); 1718: tms->tms_resid = 0; 1719: tms_iodone(mp, sc); 1720: } 1721: 1722: tms_avail_em(mp, sc) 1723: register struct mscp *mp; 1724: register struct tmscp_softc *sc; 1725: { 1726: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1727: 1728: (void)tms_check_ret(mp, sc); 1729: tms->Tflags &= ~(_INUSE | _ONLINE); 1730: tms->tms_position = 0; 1731: tms->tms_flags |= MTF_BOM; 1732: if (tms->tms_status == M_ST_SUCC) 1733: tms->Tflags &= ~_CACHE_WRITTEN; 1734: tms->tms_resid = 0; 1735: tms_iodone(mp, sc); 1736: } 1737: 1738: tms_flush_em(mp, sc) 1739: register struct mscp *mp; 1740: register struct tmscp_softc *sc; 1741: { 1742: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1743: u_short em_status = mp->mscp_status & M_ST_MASK; 1744: 1745: if (em_status == M_ST_SUCC) 1746: tms->Tflags &= ~_CACHE_WRITTEN; 1747: else 1748: log(LOG_INFO, "tms%d,%d Flush\n",sc->sc_unit,mp->mscp_unit); 1749: tms->tms_position = mp->mscp_position; 1750: (void)tms_check_ret(mp, sc); 1751: tms->tms_resid = 0; 1752: tms_iodone(mp, sc); 1753: } 1754: 1755: tms_gtunt_em(mp, sc) 1756: register struct mscp *mp; 1757: register struct tmscp_softc *sc; 1758: { 1759: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1760: u_short em_status = mp->mscp_status & M_ST_MASK; 1761: u_short em_flags = mp->mscp_unitflgs; 1762: 1763: (void)tms_check_ret(mp, sc); 1764: if (em_status == M_ST_SUCC) 1765: { 1766: tms->tms_format = mp->mscp_format; 1767: tms->tms_type = mp->mscp_mediaid; 1768: tms->tms_fmtmenu = mp->mscp_fmtmenu; 1769: tms->tms_unitflgs = mp->mscp_unitflgs; 1770: tms->Tflags |= _ONLINE; 1771: if (em_flags & (M_UF_WRTPH | M_UF_WRTPS | M_UF_WRTPD)) 1772: tms->tms_flags |= MTF_WRTLCK; 1773: else 1774: tms->tms_flags &= ~MTF_WRTLCK; 1775: if (em_flags & M_UF_CACH) 1776: { 1777: tms->Tflags |= _HASCACHE; 1778: if (tms->Tflags & _CACHE_ON) 1779: { 1780: tms->tms_unitflgs |= M_UF_WBKNV; 1781: tms->tms_unitflgs &= ~M_UF_SCCHH; 1782: } 1783: else 1784: { 1785: tms->tms_unitflgs &= ~M_UF_WBKNV; 1786: tms->tms_unitflgs |= M_UF_SCCHH; 1787: } 1788: } 1789: if (tms->tms_position == 0) 1790: tms->tms_flags |= MTF_BOM; 1791: else 1792: tms->tms_flags &= ~MTF_BOM; 1793: } 1794: tms->tms_resid = 0; 1795: tms_iodone(mp, sc); 1796: } 1797: 1798: tms_rw_em(mp, sc) 1799: register struct mscp *mp; 1800: register struct tmscp_softc *sc; 1801: { 1802: struct buf *bp = (struct buf *)mp->mscp_cmdref; 1803: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1804: u_short em_status = mp->mscp_status & M_ST_MASK; 1805: 1806: tms->tms_flags &= ~MTF_WRITTEN; 1807: (void)tms_check_ret(mp, sc); 1808: if (em_status == M_ST_SUCC) 1809: { 1810: if ((tms->tms_endcode & ~M_OP_END) == M_OP_WRITE) 1811: tms->tms_flags |= MTF_WRITTEN; 1812: else 1813: tms->Tflags &= ~_CACHE_WRITTEN; 1814: } 1815: tms->tms_resid = bp->b_bcount - mp->mscp_bytecnt; 1816: if (tms->tms_position = mp->mscp_position) 1817: tms->tms_flags &= ~MTF_BOM; 1818: else 1819: tms->tms_flags |= MTF_BOM; 1820: tms_iodone(mp, sc); 1821: } 1822: 1823: tms_iodone(mp, sc) 1824: struct mscp *mp; 1825: struct tmscp_softc *sc; 1826: { 1827: struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1828: register struct buf *bp = (struct buf *)mp->mscp_cmdref; 1829: register struct buf *dp = &tms->tms_dtab; 1830: 1831: /* 1832: * Remove the buffer from the I/O wait queue. Set the residual count and 1833: * declare the I/O done. 1834: */ 1835: bp->av_back->av_forw = bp->av_forw; 1836: bp->av_forw->av_back = bp->av_back; 1837: dp->b_qsize--; 1838: bp->b_resid = tms->tms_resid; 1839: iodone(bp); 1840: } 1841: 1842: /* 1843: * Check the return status of an mscp packet and adjust the drive's flags 1844: * appropriately. On error conditions set the error flag and code in the 1845: * buffer header. 1846: * 1847: * Many of the 'case' statements below are finer grained than strictly 1848: * necessary - this is done to provide easy access for logging of specific 1849: * conditions during debugging. 1850: */ 1851: 1852: tms_check_ret(mp, sc) 1853: struct mscp *mp; 1854: struct tmscp_softc *sc; 1855: { 1856: register struct tms_info *tms = sc->sc_drives[mp->mscp_unit]; 1857: register struct buf *bp = (struct buf *)mp->mscp_cmdref; 1858: u_short em_status = mp->mscp_status & M_ST_MASK; 1859: u_short em_subcode = mp->mscp_status >> M_ST_SBBIT; 1860: u_short em_flags = mp->mscp_flags; 1861: u_short em_endcode = mp->mscp_endcode & ~M_OP_END; 1862: char berr, unkerr; 1863: 1864: if (em_status != M_ST_SUCC && em_status != M_ST_TAPEM && 1865: (tmscpprintf & 0x1)) 1866: log(LOG_INFO, "tms%d,%d st=%x sb=%x fl=%x en=%x\n", 1867: sc->sc_unit, mp->mscp_unit, 1868: em_status, em_subcode, em_flags, em_endcode); 1869: tms->tms_endcode = mp->mscp_endcode; 1870: if (em_flags & M_EF_EOT) 1871: tms->tms_flags |= MTF_EOM; 1872: else 1873: tms->tms_flags &= ~MTF_EOM; 1874: if (em_flags & M_EF_DLS) 1875: tms->Tflags |= _CACHE_LOST; 1876: if (em_flags & M_EF_PLS) 1877: tms->Tflags |= _LOST; 1878: tms->tms_status = mp->mscp_status; 1879: 1880: berr = 0; 1881: unkerr = 0; 1882: 1883: switch (em_status) 1884: { 1885: case M_ST_SUCC: 1886: { 1887: switch (em_subcode) 1888: { 1889: case M_SC_DUPUN: /* Duplicate unit */ 1890: berr = ENXIO; 1891: break; 1892: case M_SC_ALONL: /* Already online */ 1893: case M_SC_STONL: /* Still online */ 1894: case M_SC_UNIGN: /* Unload ignored */ 1895: case M_SC_ROVOL: /* Readonly unit */ 1896: tms->Tflags |= _ONLINE; 1897: break; 1898: case M_SC_EOT: /* End of Tape */ 1899: tms->tms_flags |= MTF_EOM; 1900: break; 1901: } 1902: } 1903: break; 1904: case M_ST_OFFLN: 1905: tms->Tflags &= ~_ONLINE; 1906: if ((tms->Tflags & _CACHE_ON) && 1907: (tms->Tflags & _CACHE_WRITTEN)) 1908: log(LOG_INFO, "tms%d,%d closs2\n", 1909: sc->sc_unit, mp->mscp_unit); 1910: berr = ENXIO; 1911: break; 1912: case M_ST_WRTPR: /* Write Protected */ 1913: tms->tms_flags |= MTF_WRTLCK; 1914: berr = EACCES; /* Really an error ? */ 1915: break; 1916: case M_ST_ICMD: /* Byte count too big */ 1917: case M_ST_ABRTD: /* Command aborted */ 1918: case M_ST_COMP: /* Data Compare error */ 1919: case M_ST_DATA: /* Data error */ 1920: case M_ST_HSTBF: /* Host buffer error */ 1921: case M_ST_CNTLR: /* Controller error */ 1922: case M_ST_FMTER: /* Formatter error */ 1923: berr = EIO; 1924: break; 1925: case M_ST_AVLBL: /* Unit available */ 1926: tms->Tflags &= ~(_LOST | _CLSEREX | _SEREX | _ONLINE); 1927: break; 1928: case M_ST_BOT: /* Beginning of tape */ 1929: tms->tms_flags |= MTF_BOM; 1930: tms->tms_position = 0; 1931: break; 1932: case M_ST_TAPEM: /* Tape Mark */ 1933: tms->Tflags |= (_BUFMARK | _CLSEREX); 1934: break; 1935: case M_ST_SEX: /* Serious Exception */ 1936: if (em_flags & M_EF_EOT) 1937: { 1938: tms->tms_flags |= MTF_EOM; 1939: berr = ENOSPC; 1940: } 1941: else 1942: { 1943: tms->Tflags &= ~_CLSEREX; 1944: log(LOG_INFO, "tms%d,%d serex sb %x\n", 1945: sc->sc_unit, mp->mscp_unit, em_subcode); 1946: berr = EIO; 1947: } 1948: break; 1949: case M_ST_PLOST: /* Position Lost */ 1950: log(LOG_INFO, "tms%d,%d plost\n", sc->sc_unit, 1951: mp->mscp_unit); 1952: tms->Tflags |= (_LOST | _SEREX); 1953: tms->Tflags &= ~_CLSEREX; 1954: berr = EIO; 1955: break; 1956: case M_ST_LED: /* Logical end of dev */ 1957: tms->Tflags |= _CLSEREX; 1958: break; 1959: case M_ST_MFMTE: /* Media format err */ 1960: case M_ST_DRIVE: /* Drive error */ 1961: case M_ST_RDTRN: /* Record truncated */ 1962: tms->Tflags |= _SEREX; 1963: tms->Tflags &= ~_CLSEREX; 1964: case M_ST_LOADR: 1965: case M_ST_DIAG: /* Intern diag err */ 1966: case M_ST_IPARM: /* Invalid parameter */ 1967: berr = EIO; 1968: break; 1969: default: 1970: unkerr = 1; 1971: berr = EIO; 1972: break; 1973: } 1974: if (unkerr) 1975: log(LOG_INFO, "tms%d,%d: st/sb =%x/%x\n", 1976: sc->sc_unit, mp->mscp_unit, em_status, em_subcode); 1977: if (berr && bp) 1978: { 1979: bp->b_flags |= B_ERROR; 1980: bp->b_error = berr; 1981: } 1982: return; 1983: } 1984: 1985: /* 1986: * Process an error log datagram. 1987: * 1988: * No decoding is done - it wasn't worth the D space. If bit 1 is set 1989: * in the print flags then a simple message is generated out of (hopefully) 1990: * useful fields. 1991: * 1992: * Eventually a error log daemon will be written and the datagram sent to 1993: * it for capture and detailed analysis. Until then the logging in 1994: * 'tms_check_ret' and a few other strategic spots will have to suffice. 1995: */ 1996: 1997: u_short tms_datagrams[NTMSCP]; 1998: 1999: tmserror(ctlr, mp) 2000: int ctlr; 2001: register struct mslg *mp; 2002: { 2003: 2004: tms_datagrams[ctlr]++; 2005: if (tmscpprintf & 0x2) 2006: log(LOG_INFO, 2007: "tms%d,%d dgram fmt=%x evt=%x grp=%x flg=%x pos=%D\n", 2008: ctlr, mp->mslg_unit, mp->mslg_format, 2009: mp->mslg_event, mp->mslg_group, mp->mslg_flags, 2010: mp->mslg_position); 2011: } 2012: #endif NTMSCP