141488Smckusick /* 241488Smckusick * Copyright (c) 1988 University of Utah. 341488Smckusick * Copyright (c) 1990 The Regents of the University of California. 441488Smckusick * All rights reserved. 541488Smckusick * 641488Smckusick * This code is derived from software contributed to Berkeley by 741488Smckusick * Van Jacobson of Lawrence Berkeley Laboratory and the Systems 841488Smckusick * Programming Group of the University of Utah Computer Science Department. 941488Smckusick * 1041488Smckusick * %sccs.include.redist.c% 1141488Smckusick * 1257299Shibler * from: Utah $Hdr: sd.c 1.9 92/12/21$ 1341488Smckusick * 14*60329Smckusick * @(#)sd.c 7.9 (Berkeley) 05/24/93 1541488Smckusick */ 1641488Smckusick 1741488Smckusick /* 1841488Smckusick * SCSI CCS disk driver 1941488Smckusick */ 2041488Smckusick 2156510Sbostic #include <sys/param.h> 2257299Shibler #include <sys/disklabel.h> 23*60329Smckusick #include <stand.att/saio.h> 2456510Sbostic #include <hp300/stand/samachdep.h> 2541488Smckusick 2656510Sbostic #include <hp300/dev/scsireg.h> 2741488Smckusick 2857299Shibler struct disklabel sdlabel; 2957299Shibler 3057299Shibler struct sdminilabel { 3157299Shibler u_short npart; 3257299Shibler u_long offset[MAXPARTITIONS]; 3357299Shibler }; 3457299Shibler 3541488Smckusick struct sd_softc { 3641488Smckusick char sc_retry; 3741488Smckusick char sc_alive; 3841488Smckusick short sc_blkshift; 3957299Shibler struct sdminilabel sc_pinfo; 4054073Shibler } sd_softc[NSCSI][NSD]; 4141488Smckusick 4241488Smckusick #define SDRETRY 2 4341488Smckusick 4454073Shibler sdinit(ctlr, unit) 4554073Shibler int ctlr, unit; 4641488Smckusick { 4754073Shibler register struct sd_softc *ss = &sd_softc[ctlr][unit]; 4841488Smckusick u_char stat; 4941488Smckusick int capbuf[2]; 5041488Smckusick 5154073Shibler stat = scsi_test_unit_rdy(ctlr, unit); 5254073Shibler if (stat) { 5341488Smckusick /* drive may be doing RTZ - wait a bit */ 5441488Smckusick if (stat == STS_CHECKCOND) { 5541488Smckusick DELAY(1000000); 5654073Shibler stat = scsi_test_unit_rdy(ctlr, unit); 5741488Smckusick } 5854073Shibler if (stat) { 5955899Shibler printf("sd(%d,%d,0,0): init failed (stat=%x)\n", 6055899Shibler ctlr, unit, stat); 6154073Shibler return (0); 6254073Shibler } 6341488Smckusick } 6441488Smckusick /* 6541488Smckusick * try to get the drive block size. 6641488Smckusick */ 6741488Smckusick capbuf[0] = 0; 6841488Smckusick capbuf[1] = 0; 6954073Shibler stat = scsi_read_capacity(ctlr, unit, 7054073Shibler (u_char *)capbuf, sizeof(capbuf)); 7154073Shibler if (stat == 0) { 7241488Smckusick if (capbuf[1] > DEV_BSIZE) 7341488Smckusick for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1) 7441488Smckusick ++ss->sc_blkshift; 7541488Smckusick } 7641488Smckusick ss->sc_alive = 1; 7741488Smckusick return (1); 7841488Smckusick } 7941488Smckusick 8054073Shibler sdreset(ctlr, unit) 8154073Shibler int ctlr, unit; 8241488Smckusick { 8341488Smckusick } 8441488Smckusick 8557299Shibler #ifdef COMPAT_NOLABEL 8657299Shibler struct sdminilabel defaultpinfo = { 8757299Shibler 8, 8857299Shibler { 1024, 17408, 0, 17408, 115712, 218112, 82944, 115712 } 8957299Shibler }; 9057299Shibler #endif 9157299Shibler 9257299Shibler sdgetinfo(io) 9357299Shibler register struct iob *io; 9457299Shibler { 9557299Shibler struct sd_softc *ss = &sd_softc[io->i_adapt][io->i_ctlr]; 9657299Shibler register struct sdminilabel *pi = &ss->sc_pinfo; 9757299Shibler register struct disklabel *lp = &sdlabel; 9857299Shibler char *msg, *readdisklabel(); 9957299Shibler int sdstrategy(), i; 10057299Shibler 10157299Shibler bzero((caddr_t)lp, sizeof *lp); 10257299Shibler lp->d_secsize = (DEV_BSIZE << ss->sc_blkshift); 10357299Shibler msg = readdisklabel(io, sdstrategy, lp); 10457299Shibler if (msg) { 10557299Shibler printf("sd(%d,%d,%d,%d): WARNING: %s, ", 10657299Shibler io->i_adapt, io->i_ctlr, io->i_unit, io->i_part, msg); 10757299Shibler #ifdef COMPAT_NOLABEL 10857299Shibler printf("using old default partitioning\n"); 10957299Shibler *pi = defaultpinfo; 11057299Shibler #else 11157299Shibler printf("defining `c' partition as entire disk\n"); 11257299Shibler pi->npart = 3; 11357299Shibler pi->offset[0] = pi->offset[1] = -1; 11457299Shibler pi->offset[2] = 0; 11557299Shibler #endif 11657299Shibler } else { 11757299Shibler pi->npart = lp->d_npartitions; 11857299Shibler for (i = 0; i < pi->npart; i++) 11957299Shibler pi->offset[i] = lp->d_partitions[i].p_size == 0 ? 12057299Shibler -1 : lp->d_partitions[i].p_offset; 12157299Shibler } 12257299Shibler return(1); 12357299Shibler } 12457299Shibler 12541488Smckusick sdopen(io) 12641488Smckusick struct iob *io; 12741488Smckusick { 12854073Shibler register struct sd_softc *ss; 12954073Shibler int ctlr, unit, part; 13041488Smckusick 13154073Shibler devconvert(io); 13254073Shibler 13354073Shibler ctlr = io->i_adapt; 13454073Shibler if (ctlr >= NSCSI || scsialive(ctlr) == 0) 13554073Shibler return (EADAPT); 13654073Shibler unit = io->i_ctlr; 13754073Shibler if (unit >= NSD) 13854073Shibler return (ECTLR); 13954073Shibler ss = &sd_softc[ctlr][unit]; 14057299Shibler if (ss->sc_alive == 0) { 14154073Shibler if (sdinit(ctlr, unit) == 0) 14254073Shibler return (ENXIO); 14357299Shibler if (sdgetinfo(io) == 0) 14457299Shibler return (ERDLAB); 14557299Shibler } 14654073Shibler part = io->i_part; 14757299Shibler if (part >= ss->sc_pinfo.npart || ss->sc_pinfo.offset[part] == -1) 14854073Shibler return (EPART); 14957299Shibler io->i_boff = ss->sc_pinfo.offset[part]; 15054073Shibler return (0); 15141488Smckusick } 15241488Smckusick 15341488Smckusick sdstrategy(io, func) 15441488Smckusick register struct iob *io; 15554073Shibler int func; 15641488Smckusick { 15754073Shibler register int ctlr = io->i_adapt; 15854073Shibler register int unit = io->i_ctlr; 15954073Shibler register struct sd_softc *ss = &sd_softc[ctlr][unit]; 16041488Smckusick daddr_t blk = io->i_bn >> ss->sc_blkshift; 16141488Smckusick u_int nblk = io->i_cc >> ss->sc_blkshift; 16254073Shibler char stat; 16341488Smckusick 16455899Shibler if (io->i_cc == 0) 16555899Shibler return(0); 16655899Shibler 16741488Smckusick ss->sc_retry = 0; 16841488Smckusick retry: 16949156Sbostic if (func == F_READ) 17054073Shibler stat = scsi_tt_read(ctlr, unit, io->i_ma, io->i_cc, blk, nblk); 17141488Smckusick else 17254073Shibler stat = scsi_tt_write(ctlr, unit, io->i_ma, io->i_cc, blk, nblk); 17341488Smckusick if (stat) { 17454073Shibler printf("sd(%d,%d,%d,%d): block=%x, error=0x%x\n", 17554073Shibler ctlr, unit, io->i_unit, io->i_part, blk, stat); 17641488Smckusick if (++ss->sc_retry > SDRETRY) 17741488Smckusick return(-1); 17854073Shibler goto retry; 17941488Smckusick } 18041488Smckusick return(io->i_cc); 18141488Smckusick } 182