1*54010Sfujita /* 2*54010Sfujita * Copyright (c) 1992 OMRON Corporation. 3*54010Sfujita * Copyright (c) 1992 The Regents of the University of California. 4*54010Sfujita * All rights reserved. 5*54010Sfujita * 6*54010Sfujita * This code is derived from software contributed to Berkeley by 7*54010Sfujita * OMRON Corporation. 8*54010Sfujita * 9*54010Sfujita * %sccs.include.redist.c% 10*54010Sfujita * 11*54010Sfujita * @(#)st.c 7.1 (Berkeley) 06/15/92 12*54010Sfujita */ 13*54010Sfujita 14*54010Sfujita /* 15*54010Sfujita * st.c -- TEAC MT-2ST/N60 SCSI TAPE UNIT Device Driver 16*54010Sfujita * remaked by A.Fujita, MAR-22-1992 17*54010Sfujita */ 18*54010Sfujita 19*54010Sfujita /* 20*54010Sfujita * SCSI CCS (Command Command Set) disk driver. 21*54010Sfujita */ 22*54010Sfujita #include "st.h" 23*54010Sfujita #if NST > 0 24*54010Sfujita 25*54010Sfujita #include "param.h" 26*54010Sfujita #include "buf.h" 27*54010Sfujita #include "file.h" 28*54010Sfujita #include "proc.h" 29*54010Sfujita #include "mtio.h" 30*54010Sfujita #include "tprintf.h" 31*54010Sfujita 32*54010Sfujita #include "device.h" 33*54010Sfujita #include "scsireg.h" 34*54010Sfujita #include "scsivar.h" 35*54010Sfujita 36*54010Sfujita extern int scsi_test_unit_rdy(); 37*54010Sfujita extern int scsi_request_sense(); 38*54010Sfujita extern int scsi_immed_command(); 39*54010Sfujita extern char *scsi_status(); 40*54010Sfujita 41*54010Sfujita extern int scgo(); 42*54010Sfujita extern void scfree(); 43*54010Sfujita 44*54010Sfujita char *sense_key(); 45*54010Sfujita 46*54010Sfujita int stinit(), ststrategy(), ststart(), stintr(); 47*54010Sfujita 48*54010Sfujita struct driver stdriver = { 49*54010Sfujita stinit, "st", ststart, (int (*)()) 0, stintr, (int (*)()) 0 50*54010Sfujita }; 51*54010Sfujita 52*54010Sfujita struct st_softc { 53*54010Sfujita struct hp_device *sc_hd; 54*54010Sfujita struct scsi_queue sc_dq; 55*54010Sfujita int sc_flags; 56*54010Sfujita short sc_type; /* drive type */ 57*54010Sfujita short sc_punit; /* physical unit (scsi lun) */ 58*54010Sfujita tpr_t sc_ctty; 59*54010Sfujita } st_softc[NST]; 60*54010Sfujita 61*54010Sfujita /* softc flags */ 62*54010Sfujita #define STF_ALIVE 0x0001 63*54010Sfujita #define STF_OPEN 0x0002 64*54010Sfujita #define STF_WMODE 0x0004 65*54010Sfujita #define STF_WRTTN 0x0008 66*54010Sfujita #define STF_CMD 0x0010 67*54010Sfujita #define STF_LEOT 0x0020 68*54010Sfujita #define STF_MOVED 0x0040 69*54010Sfujita 70*54010Sfujita u_char xsense_buff[60]; 71*54010Sfujita 72*54010Sfujita struct scsi_fmt_cdb st_read_cmd = { 6, CMD_READ }; 73*54010Sfujita struct scsi_fmt_cdb st_write_cmd = { 6, CMD_WRITE }; 74*54010Sfujita 75*54010Sfujita struct buf sttab[NST]; 76*54010Sfujita struct buf stbuf[NST]; 77*54010Sfujita 78*54010Sfujita #define stunit(x) (minor(x) & 3) 79*54010Sfujita #define stpunit(x) ((x) & 7) 80*54010Sfujita 81*54010Sfujita #define STDEV_NOREWIND 0x04 82*54010Sfujita 83*54010Sfujita #define STRETRY 2 /* IO retry count */ 84*54010Sfujita 85*54010Sfujita struct st_iostat { 86*54010Sfujita int imax; 87*54010Sfujita int imin; 88*54010Sfujita int omax; 89*54010Sfujita int omin; 90*54010Sfujita }; 91*54010Sfujita 92*54010Sfujita struct st_iostat st_iostat[NST]; 93*54010Sfujita 94*54010Sfujita 95*54010Sfujita /* 96*54010Sfujita * Initialize 97*54010Sfujita */ 98*54010Sfujita 99*54010Sfujita int 100*54010Sfujita stinit(hd) 101*54010Sfujita register struct hp_device *hd; 102*54010Sfujita { 103*54010Sfujita register struct st_softc *sc = &st_softc[hd->hp_unit]; 104*54010Sfujita 105*54010Sfujita sc->sc_hd = hd; 106*54010Sfujita sc->sc_punit = stpunit(hd->hp_flags); 107*54010Sfujita sc->sc_type = stident(sc, hd); 108*54010Sfujita if (sc->sc_type < 0) 109*54010Sfujita return(0); 110*54010Sfujita sc->sc_dq.dq_ctlr = hd->hp_ctlr; 111*54010Sfujita sc->sc_dq.dq_unit = hd->hp_unit; 112*54010Sfujita sc->sc_dq.dq_slave = hd->hp_slave; 113*54010Sfujita sc->sc_dq.dq_driver = &stdriver; 114*54010Sfujita sc->sc_flags = STF_ALIVE; 115*54010Sfujita return(1); 116*54010Sfujita } 117*54010Sfujita 118*54010Sfujita static struct scsi_inquiry inqbuf; 119*54010Sfujita static struct scsi_fmt_cdb inq = { 120*54010Sfujita 6, 121*54010Sfujita CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 122*54010Sfujita }; 123*54010Sfujita 124*54010Sfujita int 125*54010Sfujita stident(sc, hd) 126*54010Sfujita struct st_softc *sc; 127*54010Sfujita struct hp_device *hd; 128*54010Sfujita { 129*54010Sfujita char idstr[32]; 130*54010Sfujita int unit; 131*54010Sfujita register int ctlr, slave; 132*54010Sfujita register int i, stat; 133*54010Sfujita register int tries = 10; 134*54010Sfujita 135*54010Sfujita ctlr = hd->hp_ctlr; 136*54010Sfujita slave = hd->hp_slave; 137*54010Sfujita unit = sc->sc_punit; 138*54010Sfujita 139*54010Sfujita /* 140*54010Sfujita * See if unit exists and is a disk then read block size & nblocks. 141*54010Sfujita */ 142*54010Sfujita while ((stat = scsi_immed_command(ctlr, slave, unit, 143*54010Sfujita &inq, (u_char *)&inqbuf, sizeof(inqbuf))) != 0) { 144*54010Sfujita if (stat < 0 || --tries < 0) 145*54010Sfujita return (-1); 146*54010Sfujita DELAY(1000); 147*54010Sfujita } 148*54010Sfujita 149*54010Sfujita switch (inqbuf.type) { 150*54010Sfujita case 1: /* tape */ 151*54010Sfujita break; 152*54010Sfujita default: /* not a disk */ 153*54010Sfujita printf("stident: inqbuf.type = %d\n", inqbuf.type); 154*54010Sfujita return (-1); 155*54010Sfujita } 156*54010Sfujita 157*54010Sfujita bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28); 158*54010Sfujita for (i = 27; i > 23; --i) 159*54010Sfujita if (idstr[i] != ' ') 160*54010Sfujita break; 161*54010Sfujita idstr[i+1] = 0; 162*54010Sfujita for (i = 23; i > 7; --i) 163*54010Sfujita if (idstr[i] != ' ') 164*54010Sfujita break; 165*54010Sfujita idstr[i+1] = 0; 166*54010Sfujita for (i = 7; i >= 0; --i) 167*54010Sfujita if (idstr[i] != ' ') 168*54010Sfujita break; 169*54010Sfujita idstr[i+1] = 0; 170*54010Sfujita printf("st%d: %s %s rev %s\n", hd->hp_unit, idstr, &idstr[8], 171*54010Sfujita &idstr[24]); 172*54010Sfujita 173*54010Sfujita return(inqbuf.type); 174*54010Sfujita } 175*54010Sfujita 176*54010Sfujita 177*54010Sfujita /* 178*54010Sfujita * Open 179*54010Sfujita */ 180*54010Sfujita 181*54010Sfujita int 182*54010Sfujita stopen(dev, flag, type, p) 183*54010Sfujita dev_t dev; 184*54010Sfujita int flag, type; 185*54010Sfujita struct proc *p; 186*54010Sfujita { 187*54010Sfujita register int unit = stunit(dev); 188*54010Sfujita register struct st_softc *sc = &st_softc[unit]; 189*54010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 190*54010Sfujita int ctlr = sc->sc_dq.dq_ctlr; 191*54010Sfujita int slave = sc->sc_dq.dq_slave; 192*54010Sfujita int stat, retry = 9; 193*54010Sfujita 194*54010Sfujita if (unit >= NST || (sc->sc_flags & STF_ALIVE) == 0) 195*54010Sfujita return(-1); 196*54010Sfujita if (sc->sc_flags & STF_OPEN) 197*54010Sfujita return(-1); 198*54010Sfujita 199*54010Sfujita /* drive ready ? */ 200*54010Sfujita while ((stat = scsi_test_unit_rdy(ctlr, slave, 0)) != 0) { 201*54010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 202*54010Sfujita 203*54010Sfujita if (stat != STS_CHECKCOND) { 204*54010Sfujita printf("st%d: stopen: %s\n", scsi_status(stat)); 205*54010Sfujita return(EIO); 206*54010Sfujita } 207*54010Sfujita 208*54010Sfujita if (retry-- < 0) { 209*54010Sfujita printf("st%d: stopen: %s\n", sense_key(sp->key)); 210*54010Sfujita return(EIO); 211*54010Sfujita } 212*54010Sfujita 213*54010Sfujita DELAY(1000000); 214*54010Sfujita } 215*54010Sfujita 216*54010Sfujita sc->sc_ctty = tprintf_open(p); 217*54010Sfujita 218*54010Sfujita sc->sc_flags |= STF_OPEN; 219*54010Sfujita if (flag & FWRITE) 220*54010Sfujita sc->sc_flags |= STF_WMODE; 221*54010Sfujita sc->sc_flags &= ~STF_MOVED; 222*54010Sfujita 223*54010Sfujita return(0); 224*54010Sfujita } 225*54010Sfujita 226*54010Sfujita /*ARGSUSED*/ 227*54010Sfujita stclose(dev) 228*54010Sfujita dev_t dev; 229*54010Sfujita { 230*54010Sfujita register int unit = stunit(dev); 231*54010Sfujita register struct st_softc *sc = &st_softc[unit]; 232*54010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 233*54010Sfujita int ctlr = sc->sc_hd->hp_ctlr; 234*54010Sfujita int slave = sc->sc_hd->hp_slave; 235*54010Sfujita int stat, retry = 9; 236*54010Sfujita 237*54010Sfujita if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) { 238*54010Sfujita st_write_EOF(dev); 239*54010Sfujita } 240*54010Sfujita 241*54010Sfujita if ((minor(dev) & STDEV_NOREWIND) == 0) { 242*54010Sfujita st_rewind(dev); 243*54010Sfujita } 244*54010Sfujita 245*54010Sfujita sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN); 246*54010Sfujita 247*54010Sfujita tprintf_close(sc->sc_ctty); 248*54010Sfujita 249*54010Sfujita return(0); 250*54010Sfujita } 251*54010Sfujita 252*54010Sfujita /* 253*54010Sfujita * Strategy 254*54010Sfujita */ 255*54010Sfujita 256*54010Sfujita int 257*54010Sfujita ststrategy(bp) 258*54010Sfujita register struct buf *bp; 259*54010Sfujita { 260*54010Sfujita register int unit = stunit(bp->b_dev); 261*54010Sfujita register struct buf *dp = &sttab[unit]; 262*54010Sfujita int s; 263*54010Sfujita 264*54010Sfujita bp->av_forw = NULL; 265*54010Sfujita 266*54010Sfujita s = splbio(); 267*54010Sfujita 268*54010Sfujita if (dp->b_actf == NULL) 269*54010Sfujita dp->b_actf = bp; 270*54010Sfujita else 271*54010Sfujita dp->b_actl->av_forw = bp; 272*54010Sfujita 273*54010Sfujita dp->b_actl = bp; 274*54010Sfujita 275*54010Sfujita if (dp->b_active == 0) { 276*54010Sfujita dp->b_active = 1; 277*54010Sfujita stustart(unit); 278*54010Sfujita } 279*54010Sfujita 280*54010Sfujita splx(s); 281*54010Sfujita } 282*54010Sfujita 283*54010Sfujita int 284*54010Sfujita stustart(unit) 285*54010Sfujita register int unit; 286*54010Sfujita { 287*54010Sfujita register struct st_softc *sc = &st_softc[unit]; 288*54010Sfujita register struct hp_device *hp = sc->sc_hd; 289*54010Sfujita register struct scsi_queue *dq = &sc->sc_dq; 290*54010Sfujita register struct buf *bp = sttab[unit].b_actf; 291*54010Sfujita register struct scsi_fmt_cdb *cmd; 292*54010Sfujita long nblks; 293*54010Sfujita 294*54010Sfujita cmd = bp->b_flags & B_READ ? &st_read_cmd : &st_write_cmd; 295*54010Sfujita cmd->cdb[1] = 1; /* unknown setup */ 296*54010Sfujita 297*54010Sfujita if (bp->b_flags & B_READ) 298*54010Sfujita sc->sc_flags &= ~STF_WRTTN; 299*54010Sfujita else 300*54010Sfujita sc->sc_flags |= STF_WRTTN; 301*54010Sfujita 302*54010Sfujita nblks = bp->b_bcount >> DEV_BSHIFT; 303*54010Sfujita 304*54010Sfujita if (bp->b_bcount % DEV_BSIZE) { 305*54010Sfujita tprintf(sc->sc_ctty, 306*54010Sfujita "st%d: I/O not block aligned %d/%ld\n", 307*54010Sfujita unit, DEV_BSIZE, bp->b_bcount); 308*54010Sfujita 309*54010Sfujita bp->b_flags |= B_ERROR; 310*54010Sfujita bp->b_error = EIO; 311*54010Sfujita 312*54010Sfujita sttab[unit].b_errcnt = 0; 313*54010Sfujita sttab[unit].b_actf = bp->b_actf; 314*54010Sfujita 315*54010Sfujita bp->b_resid = 0; 316*54010Sfujita 317*54010Sfujita biodone(bp); 318*54010Sfujita 319*54010Sfujita if (sttab[unit].b_actf) { 320*54010Sfujita stustart(unit); 321*54010Sfujita } else { 322*54010Sfujita sttab[unit].b_active = 0; 323*54010Sfujita } 324*54010Sfujita } 325*54010Sfujita 326*54010Sfujita *(u_char *)(&cmd->cdb[2]) = (u_char) (nblks >> 16); 327*54010Sfujita *(u_char *)(&cmd->cdb[3]) = (u_char) (nblks >> 8); 328*54010Sfujita *(u_char *)(&cmd->cdb[4]) = (u_char) nblks; 329*54010Sfujita 330*54010Sfujita cmd->cdb[5] = 0; /* unknown setup */ 331*54010Sfujita 332*54010Sfujita sc->sc_flags |= STF_MOVED; 333*54010Sfujita 334*54010Sfujita dq->dq_cdb = cmd; 335*54010Sfujita dq->dq_bp = bp; 336*54010Sfujita dq->dq_flags = 0; /* No Disconnect */ 337*54010Sfujita 338*54010Sfujita if (screq(dq)) 339*54010Sfujita ststart(unit); 340*54010Sfujita } 341*54010Sfujita 342*54010Sfujita int 343*54010Sfujita ststart(unit) 344*54010Sfujita register int unit; 345*54010Sfujita { 346*54010Sfujita register struct st_softc *sc = &st_softc[unit]; 347*54010Sfujita register struct hp_device *hp = sc->sc_hd; 348*54010Sfujita 349*54010Sfujita scstart(hp->hp_ctlr); 350*54010Sfujita } 351*54010Sfujita 352*54010Sfujita /* 353*54010Sfujita * Interrupt 354*54010Sfujita */ 355*54010Sfujita 356*54010Sfujita char * 357*54010Sfujita sense_key(key) 358*54010Sfujita int key; 359*54010Sfujita { 360*54010Sfujita if (key == 0) 361*54010Sfujita return("No Sense"); 362*54010Sfujita else if (key == 2) 363*54010Sfujita return("Not Ready"); 364*54010Sfujita else if (key == 3) 365*54010Sfujita return("Medium Error"); 366*54010Sfujita else if (key == 4) 367*54010Sfujita return("Hardware Error"); 368*54010Sfujita else if (key == 5) 369*54010Sfujita return("Illegal Request"); 370*54010Sfujita else if (key == 6) 371*54010Sfujita return("Unit Attention"); 372*54010Sfujita else if (key == 7) 373*54010Sfujita return("Data Protect"); 374*54010Sfujita else if (key == 8) 375*54010Sfujita return("No Data"); 376*54010Sfujita else if (key == 11) 377*54010Sfujita return("Aborted Command"); 378*54010Sfujita else if (key == 13) 379*54010Sfujita return("Volume Overflow"); 380*54010Sfujita else 381*54010Sfujita return("Unknown Error"); 382*54010Sfujita } 383*54010Sfujita 384*54010Sfujita int 385*54010Sfujita stintr(unit, stat) 386*54010Sfujita register int unit; 387*54010Sfujita int stat; 388*54010Sfujita { 389*54010Sfujita register struct st_softc *sc = &st_softc[unit]; 390*54010Sfujita register struct scsi_xsense *xp = (struct scsi_xsense *) xsense_buff; 391*54010Sfujita register struct scsi_queue *dq = &sc->sc_dq; 392*54010Sfujita register struct buf *bp = dq->dq_bp; 393*54010Sfujita int ctlr = dq->dq_ctlr; 394*54010Sfujita int slave = dq->dq_slave; 395*54010Sfujita 396*54010Sfujita if (bp->b_flags & B_READ) { 397*54010Sfujita st_iostat[unit].imin = MIN(dq->dq_imin, st_iostat[unit].imin); 398*54010Sfujita if (dq->dq_imax > st_iostat[unit].imax) { 399*54010Sfujita st_iostat[unit].imax = dq->dq_imax; 400*54010Sfujita #ifdef ST_IOSTAT 401*54010Sfujita printf("stintr: st%d INPUT MAX = %d, MIN = %d\n", 402*54010Sfujita unit, st_iostat[unit].imax, st_iostat[unit].imin); 403*54010Sfujita #endif 404*54010Sfujita } 405*54010Sfujita } else { 406*54010Sfujita st_iostat[unit].omin = MIN(dq->dq_omin, st_iostat[unit].omin); 407*54010Sfujita if (dq->dq_omax > st_iostat[unit].omax) { 408*54010Sfujita st_iostat[unit].omax = dq->dq_omax; 409*54010Sfujita #ifdef ST_IOSTAT 410*54010Sfujita printf("stintr: st%d OUTPUT MAX = %d, MIN = %d\n", 411*54010Sfujita unit, st_iostat[unit].omax, st_iostat[unit].omin); 412*54010Sfujita #endif 413*54010Sfujita } 414*54010Sfujita } 415*54010Sfujita if (stat < 0) { 416*54010Sfujita bp->b_flags |= B_ERROR; 417*54010Sfujita bp->b_error = EIO; 418*54010Sfujita goto done; 419*54010Sfujita } 420*54010Sfujita 421*54010Sfujita switch (stat) { 422*54010Sfujita /* scsi command completed ok */ 423*54010Sfujita case 0: 424*54010Sfujita bp->b_resid = 0; 425*54010Sfujita break; 426*54010Sfujita 427*54010Sfujita /* more status */ 428*54010Sfujita case STS_CHECKCOND: 429*54010Sfujita scsi_request_sense(ctlr, slave, 0, xp, 8); 430*54010Sfujita #ifdef DEBUG 431*54010Sfujita printf("stintr: xsense_buff[0] = 0x%s\n", hexstr(xsense_buff[0], 2)); 432*54010Sfujita printf("stintr: xsense_buff[2] = 0x%s\n", hexstr(xsense_buff[2], 2)); 433*54010Sfujita printf("stintr: Sense Key = [%s]\n", sense_key(xp->key)); 434*54010Sfujita #endif 435*54010Sfujita if (xp->valid) { 436*54010Sfujita bp->b_resid = (u_long)((xp->info1 << 24) | 437*54010Sfujita (xp->info2 << 16) | 438*54010Sfujita (xp->info3 << 8) | 439*54010Sfujita (xp->info4)); 440*54010Sfujita bp->b_resid <<= DEV_BSHIFT; 441*54010Sfujita } 442*54010Sfujita 443*54010Sfujita if (xp->filemark) { /* End of File */ 444*54010Sfujita tprintf(sc->sc_ctty, "st%d: End of File\n", unit); 445*54010Sfujita bp->b_flags |= B_ERROR; 446*54010Sfujita bp->b_error = EIO; 447*54010Sfujita break; 448*54010Sfujita } 449*54010Sfujita 450*54010Sfujita if (xp->key) { 451*54010Sfujita tprintf(sc->sc_ctty, "st%d: %s\n", unit, sense_key(xp->key)); 452*54010Sfujita bp->b_flags |= B_ERROR; 453*54010Sfujita bp->b_error = EIO; 454*54010Sfujita break; 455*54010Sfujita } 456*54010Sfujita 457*54010Sfujita if (xp->eom) { /* End of TAPE */ 458*54010Sfujita tprintf(sc->sc_ctty, "st%d: End of Tape\n", unit); 459*54010Sfujita bp->b_flags |= B_ERROR; 460*54010Sfujita bp->b_error = ENOSPC; 461*54010Sfujita break; 462*54010Sfujita } 463*54010Sfujita 464*54010Sfujita tprintf(sc->sc_ctty, "st%d: unknown scsi error\n", unit); 465*54010Sfujita bp->b_flags |= B_ERROR; 466*54010Sfujita bp->b_error = EIO; 467*54010Sfujita break; 468*54010Sfujita 469*54010Sfujita default: 470*54010Sfujita printf("st%d: stintr unknown stat 0x%x\n", unit, stat); 471*54010Sfujita break; 472*54010Sfujita } 473*54010Sfujita 474*54010Sfujita done: 475*54010Sfujita sttab[unit].b_errcnt = 0; 476*54010Sfujita sttab[unit].b_actf = bp->b_actf; 477*54010Sfujita 478*54010Sfujita bp->b_resid = 0; 479*54010Sfujita 480*54010Sfujita biodone(bp); 481*54010Sfujita 482*54010Sfujita scfree(&sc->sc_dq); 483*54010Sfujita 484*54010Sfujita if (sttab[unit].b_actf) { 485*54010Sfujita stustart(unit); 486*54010Sfujita } else { 487*54010Sfujita sttab[unit].b_active = 0; 488*54010Sfujita } 489*54010Sfujita } 490*54010Sfujita 491*54010Sfujita 492*54010Sfujita /* 493*54010Sfujita * RAW Device Routines 494*54010Sfujita */ 495*54010Sfujita 496*54010Sfujita 497*54010Sfujita stread(dev, uio) 498*54010Sfujita dev_t dev; 499*54010Sfujita struct uio *uio; 500*54010Sfujita { 501*54010Sfujita int unit = stunit(dev); 502*54010Sfujita 503*54010Sfujita return(physio(ststrategy, &stbuf[unit], dev, B_READ, minphys, uio)); 504*54010Sfujita } 505*54010Sfujita 506*54010Sfujita stwrite(dev, uio) 507*54010Sfujita dev_t dev; 508*54010Sfujita struct uio *uio; 509*54010Sfujita { 510*54010Sfujita int unit = stunit(dev); 511*54010Sfujita 512*54010Sfujita return(physio(ststrategy, &stbuf[unit], dev, B_WRITE, minphys, uio)); 513*54010Sfujita } 514*54010Sfujita 515*54010Sfujita int 516*54010Sfujita stioctl(dev, cmd, data, flag, p) 517*54010Sfujita dev_t dev; 518*54010Sfujita int cmd; 519*54010Sfujita caddr_t data; 520*54010Sfujita int flag; 521*54010Sfujita struct proc *p; 522*54010Sfujita { 523*54010Sfujita return(ENXIO); 524*54010Sfujita } 525*54010Sfujita 526*54010Sfujita struct scsi_fmt_cdb st_cmd; 527*54010Sfujita 528*54010Sfujita st_rewind(dev) 529*54010Sfujita dev_t dev; 530*54010Sfujita { 531*54010Sfujita register int unit = stunit(dev); 532*54010Sfujita register struct st_softc *sc = &st_softc[unit]; 533*54010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 534*54010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 535*54010Sfujita int ctlr, slave, stat; 536*54010Sfujita int retry = 9; 537*54010Sfujita 538*54010Sfujita ctlr = sc->sc_hd->hp_ctlr; 539*54010Sfujita slave = sc->sc_hd->hp_slave; 540*54010Sfujita 541*54010Sfujita cdb->len = 6; 542*54010Sfujita 543*54010Sfujita cdb->cdb[0] = CMD_REWIND; 544*54010Sfujita 545*54010Sfujita cdb->cdb[1] = 1; /* command finished soon */ 546*54010Sfujita 547*54010Sfujita cdb->cdb[2] = 0; 548*54010Sfujita cdb->cdb[3] = 0; 549*54010Sfujita cdb->cdb[4] = 0; 550*54010Sfujita 551*54010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 552*54010Sfujita 553*54010Sfujita rewind: 554*54010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 555*54010Sfujita 556*54010Sfujita if (stat == 0) { 557*54010Sfujita return(1); 558*54010Sfujita } else { 559*54010Sfujita printf("st: rewind error\n"); 560*54010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 561*54010Sfujita printf("st: status = 0x%x, sens key = 0x%x\n", stat, sp->key); 562*54010Sfujita 563*54010Sfujita if (retry > 0) { 564*54010Sfujita DELAY(1000000); 565*54010Sfujita retry--; 566*54010Sfujita goto rewind; 567*54010Sfujita } 568*54010Sfujita 569*54010Sfujita return(0); 570*54010Sfujita } 571*54010Sfujita } 572*54010Sfujita 573*54010Sfujita st_write_EOF(dev) 574*54010Sfujita dev_t dev; 575*54010Sfujita { 576*54010Sfujita register int unit = stunit(dev); 577*54010Sfujita register struct st_softc *sc = &st_softc[unit]; 578*54010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 579*54010Sfujita int ctlr, slave, stat; 580*54010Sfujita int marks = 1; 581*54010Sfujita 582*54010Sfujita ctlr = sc->sc_hd->hp_ctlr; 583*54010Sfujita slave = sc->sc_hd->hp_slave; 584*54010Sfujita 585*54010Sfujita cdb->len = 6; 586*54010Sfujita 587*54010Sfujita cdb->cdb[0] = CMD_WRITE_FILEMARK; 588*54010Sfujita 589*54010Sfujita cdb->cdb[1] = 0; 590*54010Sfujita 591*54010Sfujita cdb->cdb[2] = 0; 592*54010Sfujita cdb->cdb[3] = 0; 593*54010Sfujita cdb->cdb[4] = marks; 594*54010Sfujita 595*54010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 596*54010Sfujita 597*54010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 598*54010Sfujita 599*54010Sfujita if (stat == 0) 600*54010Sfujita return(1); 601*54010Sfujita 602*54010Sfujita printf("st: write EOF error\n"); 603*54010Sfujita 604*54010Sfujita return(0); 605*54010Sfujita } 606*54010Sfujita 607*54010Sfujita /* 608*54010Sfujita * Dump 609*54010Sfujita */ 610*54010Sfujita 611*54010Sfujita int 612*54010Sfujita stdump(dev) 613*54010Sfujita dev_t dev; 614*54010Sfujita { 615*54010Sfujita } 616*54010Sfujita #endif 617