1 /* 2 * Copyright (c) 1992 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)tz.c 7.1 (Berkeley) 01/07/92 11 * 12 * from: $Header: /sprite/src/kernel/dev/RCS/devSCSITape.c, 13 * v 8.14 89/07/31 17:26:13 mendel Exp $ SPRITE (Berkeley) 14 */ 15 16 /* 17 * SCSI CCS (Command Command Set) tape driver. 18 */ 19 #include "tz.h" 20 #if NTZ > 0 21 22 #include "param.h" 23 #include "systm.h" 24 #include "buf.h" 25 #include "errno.h" 26 #include "file.h" 27 #include "ioctl.h" 28 #include "mtio.h" 29 #include "syslog.h" 30 31 #include "device.h" 32 #include "scsi.h" 33 34 int tzprobe(); 35 void tzstart(), tzdone(); 36 37 struct driver tzdriver = { 38 "tz", tzprobe, tzstart, tzdone, 39 }; 40 41 struct tz_softc { 42 struct scsi_device *sc_sd; /* physical unit info */ 43 int sc_flags; /* see below */ 44 struct buf sc_tab; /* queue of pending operations */ 45 struct buf sc_buf; /* buf for doing I/O */ 46 struct buf sc_errbuf; /* buf for doing REQUEST_SENSE */ 47 struct ScsiCmd sc_cmd; /* command for controller */ 48 ScsiGroup0Cmd sc_rwcmd; /* SCSI cmd for read/write */ 49 struct scsi_fmt_cdb sc_cdb; /* SCSI cmd if not read/write */ 50 struct scsi_fmt_sense sc_sense; /* sense data from last cmd */ 51 } tz_softc[NTZ]; 52 53 /* sc_flags values */ 54 #define TZF_ALIVE 0x01 /* drive found and ready */ 55 #define TZF_SENSEINPROGRESS 0x02 /* REQUEST_SENSE command in progress */ 56 #define TZF_ALTCMD 0x04 /* alternate command in progress */ 57 #define TZF_WRITTEN 0x08 /* tape has been written to */ 58 #define TZF_OPEN 0x10 /* device is open */ 59 #define TZF_WAIT 0x20 /* waiting for sc_tab to drain */ 60 61 /* bits in minor device */ 62 #define tzunit(x) (minor(x) >> 1) /* tz%d unit number */ 63 #define TZ_NOREWIND 0x1 /* don't rewind on close */ 64 65 #define INF (daddr_t)1000000L /* a block number that won't exist */ 66 67 #ifdef DEBUG 68 int tzdebug = 1; 69 #endif 70 71 /* 72 * Test to see if device is present. 73 * Return true if found and initialized ok. 74 */ 75 tzprobe(sd) 76 struct scsi_device *sd; 77 { 78 register struct tz_softc *sc = &tz_softc[sd->sd_unit]; 79 register int i; 80 ScsiInquiryData inqbuf; 81 ScsiClass7Sense *sp; 82 83 printf("tzprobe()\n"); /* XXX */ 84 /* init some parameters that don't change */ 85 sc->sc_sd = sd; 86 sc->sc_cmd.sd = sd; 87 sc->sc_cmd.unit = sd->sd_unit; 88 sc->sc_rwcmd.unitNumber = sd->sd_slave; 89 /* sc->sc_rwcmd.highAddr = 1; /* count in blocks */ 90 91 /* try to find out what type of device this is */ 92 sc->sc_flags = TZF_ALTCMD; /* force use of sc_cdb */ 93 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 94 scsiGroup0Cmd(SCSI_INQUIRY, sd->sd_slave, 0, sizeof(inqbuf), 95 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 96 sc->sc_buf.b_flags = B_BUSY | B_READ; 97 sc->sc_buf.b_bcount = sizeof(inqbuf); 98 sc->sc_buf.b_un.b_addr = (caddr_t)&inqbuf; 99 sc->sc_buf.av_forw = (struct buf *)0; 100 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf; 101 tzstart(sd->sd_unit); 102 if (biowait(&sc->sc_buf) || 103 (i = sizeof(inqbuf) - sc->sc_buf.b_resid) < 5) 104 goto bad; 105 if (inqbuf.type != SCSI_TAPE_TYPE) 106 goto bad; 107 108 /* check for device ready to clear UNIT_ATTN */ 109 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 110 scsiGroup0Cmd(SCSI_TEST_UNIT_READY, sd->sd_slave, 0, 0, 111 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 112 sc->sc_buf.b_flags = B_BUSY | B_READ; 113 sc->sc_buf.b_bcount = 0; 114 sc->sc_buf.b_un.b_addr = (caddr_t)0; 115 sc->sc_buf.av_forw = (struct buf *)0; 116 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf; 117 tzstart(sd->sd_unit); 118 (void) biowait(&sc->sc_buf); 119 120 sc->sc_flags = TZF_ALIVE; 121 sc->sc_buf.b_flags = 0; 122 printf("tz%d at %s%d drive %d slave %d\n", sd->sd_unit, 123 sd->sd_cdriver->d_name, sd->sd_ctlr, sd->sd_drive, 124 sd->sd_slave); 125 return (1); 126 127 bad: 128 /* doesn't exist or not a CCS device */ 129 sc->sc_flags = 0; 130 sc->sc_buf.b_flags = 0; 131 return (0); 132 } 133 134 /* 135 * Perform a special tape command on a SCSI Tape drive. 136 */ 137 tzcommand(dev, command, code, count) 138 dev_t dev; 139 int command; 140 int code; 141 int count; 142 { 143 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 144 int s, error; 145 146 s = splbio(); 147 while (sc->sc_tab.b_actf) { 148 sc->sc_flags |= TZF_WAIT; 149 sleep(&sc->sc_flags, PZERO); 150 } 151 sc->sc_flags |= TZF_ALTCMD; /* force use of sc_cdb */ 152 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 153 scsiGroup0Cmd(command, sc->sc_sd->sd_slave, 154 (code << 16) | ((count >> 8) & 0xFFFF), count & 0xFF, 155 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 156 sc->sc_buf.b_flags = B_BUSY | B_READ; 157 sc->sc_buf.b_bcount = 0; 158 sc->sc_buf.b_un.b_addr = (caddr_t)0; 159 sc->sc_buf.av_forw = (struct buf *)0; 160 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf; 161 tzstart(sc->sc_sd->sd_unit); 162 error = biowait(&sc->sc_buf); 163 sc->sc_flags &= ~TZF_ALTCMD; /* force use of sc_cdb */ 164 sc->sc_buf.b_flags = 0; 165 splx(s); 166 return (error); 167 } 168 169 void 170 tzstart(unit) 171 int unit; 172 { 173 register struct tz_softc *sc = &tz_softc[unit]; 174 register struct buf *bp = sc->sc_tab.b_actf; 175 register int n; 176 extern int sii_debug; /* XXX */ 177 178 sc->sc_cmd.buf = bp->b_un.b_addr; 179 sc->sc_cmd.buflen = bp->b_bcount; 180 181 if (sc->sc_flags & (TZF_SENSEINPROGRESS | TZF_ALTCMD)) { 182 sc->sc_cmd.dataToDevice = !(bp->b_flags & B_READ); 183 sc->sc_cmd.cmd = sc->sc_cdb.cdb; 184 sc->sc_cmd.cmdlen = sc->sc_cdb.len; 185 } else { 186 if (bp->b_flags & B_READ) { 187 sc->sc_cmd.dataToDevice = 0; 188 sc->sc_rwcmd.command = SCSI_READ; 189 } else { 190 sc->sc_cmd.dataToDevice = 1; 191 sc->sc_rwcmd.command = SCSI_WRITE; 192 } 193 sc->sc_cmd.cmd = (u_char *)&sc->sc_rwcmd; 194 sc->sc_cmd.cmdlen = sizeof(sc->sc_rwcmd); 195 n = howmany(bp->b_bcount, 512); 196 sc->sc_rwcmd.midAddr = n >> 16; 197 sc->sc_rwcmd.lowAddr = n >> 8; 198 sc->sc_rwcmd.blockCount = n; 199 if ((bp->b_bcount & (512 - 1)) != 0) 200 printf("tz%d: partial block xfer -- %x bytes\n", 201 unit, bp->b_bcount); 202 } 203 204 printf("tzstart(%d) flags %x, addr %x sz %d\n", unit, 205 sc->sc_flags, sc->sc_cmd.buf, sc->sc_cmd.buflen); /* XXX */ 206 /* tell controller to start this command */ 207 if (sc->sc_cmd.cmd[0] == SCSI_READ) 208 sii_debug = 5; /* XXX */ 209 (*sc->sc_sd->sd_cdriver->d_start)(&sc->sc_cmd); 210 } 211 212 /* 213 * This is called by the controller driver when the command is done. 214 */ 215 void 216 tzdone(unit, error, resid, status) 217 int unit; 218 int error; /* error number from errno.h */ 219 int resid; /* amount not transfered */ 220 int status; /* SCSI status byte */ 221 { 222 register struct tz_softc *sc = &tz_softc[unit]; 223 register struct buf *bp = sc->sc_tab.b_actf; 224 extern int cold; 225 extern int sii_debug; /* XXX */ 226 227 printf("tzdone(%d, %d, %d, %x) %x flags %x\n", unit, error, resid, 228 status, sc, sc->sc_flags); /* XXX */ 229 if (bp == NULL) { 230 printf("tz%d: bp == NULL\n", unit); 231 return; 232 } 233 if (sc->sc_flags & TZF_SENSEINPROGRESS) { 234 sc->sc_flags &= ~TZF_SENSEINPROGRESS; 235 sc->sc_tab.b_actf = bp = bp->b_actf; /* remove sc_errbuf */ 236 if (bp == 0) { 237 sii_DumpLog(); 238 panic("tzdone"); /* XXX */ 239 } 240 241 if (error || (status & SCSI_STATUS_CHECKCOND)) { 242 #ifdef DEBUG 243 if (tzdebug) 244 printf("tz%d: error reading sense data: error %d scsi status 0x%x\n", 245 unit, error, status); 246 #endif 247 /* 248 * We got an error during the REQUEST_SENSE, 249 * fill in no sense for data. 250 */ 251 sc->sc_sense.sense[0] = 0x70; 252 sc->sc_sense.sense[2] = SCSI_CLASS7_NO_SENSE; 253 } else if (!cold 254 #ifdef DEBUG 255 || tzdebug 256 #endif 257 ) { 258 printf("tz%d: ", unit); 259 scsiPrintSense((ScsiClass7Sense *)sc->sc_sense.sense, 260 sizeof(sc->sc_sense.sense) - resid); 261 } 262 } else if (error || (status & SCSI_STATUS_CHECKCOND)) { 263 #ifdef DEBUG 264 if (tzdebug) 265 printf("tz%d: error %d scsi status 0x%x\n", 266 unit, error, status); 267 #endif 268 /* save error info */ 269 sc->sc_sense.status = status; 270 bp->b_flags |= B_ERROR; 271 bp->b_error = error; 272 bp->b_resid = resid; 273 274 if (status & SCSI_STATUS_CHECKCOND) { 275 /* 276 * Start a REQUEST_SENSE command. 277 * Since we are called at interrupt time, we can't 278 * wait for the command to finish; that's why we use 279 * the sc_flags field. 280 */ 281 sc->sc_flags |= TZF_SENSEINPROGRESS; 282 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 283 scsiGroup0Cmd(SCSI_REQUEST_SENSE, sc->sc_sd->sd_slave, 284 0, sizeof(sc->sc_sense.sense), 285 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 286 sc->sc_errbuf.b_flags = B_BUSY | B_READ; 287 sc->sc_errbuf.b_bcount = sizeof(sc->sc_sense.sense); 288 sc->sc_errbuf.b_un.b_addr = (caddr_t)sc->sc_sense.sense; 289 sc->sc_errbuf.av_forw = bp; 290 sc->sc_tab.b_actf = &sc->sc_errbuf; 291 tzstart(unit); 292 return; 293 } 294 } else { 295 sc->sc_sense.status = status; 296 bp->b_resid = resid; 297 } 298 299 sc->sc_tab.b_actf = bp->b_actf; 300 biodone(bp); 301 if (sc->sc_tab.b_actf) 302 tzstart(unit); 303 else { 304 sii_debug = 1; /* XXX */ 305 sc->sc_tab.b_active = 0; 306 if (sc->sc_flags & TZF_WAIT) { 307 sc->sc_flags &= ~TZF_WAIT; 308 wakeup(&sc->sc_flags); 309 } 310 } 311 } 312 313 tzopen(dev, flags) 314 dev_t dev; 315 int flags; 316 { 317 register int unit = tzunit(dev); 318 register struct tz_softc *sc = &tz_softc[unit]; 319 int error; 320 321 if (unit >= NTZ) 322 return (ENXIO); 323 if (!(sc->sc_flags & TZF_ALIVE)) { 324 /* check again, tape may have been turned off at boot time */ 325 if (!tzprobe(sc->sc_sd)) 326 return (ENXIO); 327 } 328 if (sc->sc_flags & TZF_OPEN) 329 return (EBUSY); 330 331 /* clear UNIT_ATTENTION */ 332 error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0); 333 if (error) { 334 ScsiClass7Sense *sp = (ScsiClass7Sense *)sc->sc_sense.sense; 335 336 /* return error if last error was not UNIT_ATTENTION */ 337 if (!(sc->sc_sense.status & SCSI_STATUS_CHECKCOND) || 338 sp->error7 != 0x70 || sp->key != SCSI_CLASS7_UNIT_ATTN) 339 return (error); 340 } 341 342 #ifdef notdef 343 if ((flag&FWRITE) && (sc->sc_dsreg&HTDS_WRL)) { 344 sc->sc_openf = 0; 345 uprintf("tu%d: no write ring\n", tuunit); 346 return (EIO); 347 } 348 sc->sc_ctty = (caddr_t)(u.u_procp->p_flag & SCTTY ? 349 u.u_procp->p_session->s_ttyp : 0); 350 #endif 351 sc->sc_flags = TZF_ALIVE | TZF_OPEN; 352 return (0); 353 } 354 355 tzclose(dev, flag) 356 dev_t dev; 357 int flag; 358 { 359 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 360 361 if (!(sc->sc_flags & TZF_OPEN)) 362 return (0); 363 if (flag == FWRITE || 364 ((flag & FWRITE) && (sc->sc_flags & TZF_WRITTEN))) { 365 (void) tzcommand(dev, SCSI_WRITE_EOF, 0, 1); 366 } 367 if ((minor(dev) & TZ_NOREWIND) == 0) 368 (void) tzcommand(dev, SCSI_REWIND, 0, 0); 369 sc->sc_flags &= ~(TZF_OPEN | TZF_WRITTEN); 370 return (0); 371 } 372 373 tzioctl(dev, cmd, data, flag) 374 dev_t dev; 375 int cmd; 376 caddr_t data; 377 int flag; 378 { 379 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 380 register struct buf *bp = &sc->sc_buf; 381 struct mtop *mtop; 382 struct mtget *mtget; 383 int code, count; 384 static tzops[] = { 385 SCSI_WRITE_EOF, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE, 386 SCSI_REWIND, SCSI_REWIND, SCSI_TEST_UNIT_READY 387 }; 388 389 switch (cmd) { 390 391 case MTIOCTOP: /* tape operation */ 392 mtop = (struct mtop *)data; 393 if ((unsigned)mtop->mt_op < MTREW && mtop->mt_count <= 0) 394 return (EINVAL); 395 switch (mtop->mt_op) { 396 397 case MTWEOF: 398 code = 0; 399 count = mtop->mt_count; 400 break; 401 402 case MTFSF: 403 code = 1; 404 count = mtop->mt_count; 405 break; 406 407 case MTBSF: 408 code = 1; 409 count = -mtop->mt_count; 410 break; 411 412 case MTFSR: 413 code = 0; 414 break; 415 416 case MTBSR: 417 code = 0; 418 count = -mtop->mt_count; 419 break; 420 421 case MTREW: 422 case MTOFFL: 423 case MTNOP: 424 code = 0; 425 count = 0; 426 break; 427 428 default: 429 return (EINVAL); 430 } 431 return (tzcommand(dev, tzops[mtop->mt_op], code, count)); 432 433 case MTIOCGET: 434 mtget = (struct mtget *)data; 435 mtget->mt_dsreg = 0; 436 mtget->mt_erreg = sc->sc_sense.status; 437 mtget->mt_resid = 0; 438 mtget->mt_type = 0; 439 break; 440 441 default: 442 return (EINVAL); 443 } 444 return (0); 445 } 446 447 void 448 tzstrategy(bp) 449 register struct buf *bp; 450 { 451 register int unit = tzunit(bp->b_dev); 452 register struct tz_softc *sc = &tz_softc[unit]; 453 register struct buf *dp; 454 register int s; 455 456 bp->av_forw = NULL; 457 dp = &sc->sc_tab; 458 s = splbio(); 459 if (dp->b_actf == NULL) 460 dp->b_actf = bp; 461 else 462 dp->b_actl->av_forw = bp; 463 dp->b_actl = bp; 464 if (dp->b_active == 0) { 465 dp->b_active = 1; 466 tzstart(unit); 467 } 468 splx(s); 469 } 470 #endif 471