xref: /csrg-svn/sys/hp300/stand/sd.c (revision 63165)
141488Smckusick /*
241488Smckusick  * Copyright (c) 1988 University of Utah.
3*63165Sbostic  * Copyright (c) 1990, 1993
4*63165Sbostic  *	The Regents of the University of California.  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*63165Sbostic  *	@(#)sd.c	8.1 (Berkeley) 06/10/93
1541488Smckusick  */
1641488Smckusick 
1741488Smckusick /*
1841488Smckusick  * SCSI CCS disk driver
1941488Smckusick  */
2041488Smckusick 
2156510Sbostic #include <sys/param.h>
2257299Shibler #include <sys/disklabel.h>
2360329Smckusick #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 
sdinit(ctlr,unit)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 
sdreset(ctlr,unit)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 
sdgetinfo(io)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 
sdstrategy(io,func)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