xref: /csrg-svn/sys/hp300/stand/sd.c (revision 56510)
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  *
1241488Smckusick  * from: Utah $Hdr: sd.c 1.2 90/01/23$
1341488Smckusick  *
14*56510Sbostic  *	@(#)sd.c	7.7 (Berkeley) 10/11/92
1541488Smckusick  */
1641488Smckusick 
1741488Smckusick /*
1841488Smckusick  * SCSI CCS disk driver
1941488Smckusick  */
2041488Smckusick 
21*56510Sbostic #include <sys/param.h>
22*56510Sbostic #include <stand/saio.h>
23*56510Sbostic #include <hp300/stand/samachdep.h>
2441488Smckusick 
25*56510Sbostic #include <hp300/dev/scsireg.h>
2641488Smckusick 
2741488Smckusick struct	sd_softc {
2841488Smckusick 	char	sc_retry;
2941488Smckusick 	char	sc_alive;
3041488Smckusick 	short	sc_blkshift;
3154073Shibler } sd_softc[NSCSI][NSD];
3241488Smckusick 
3341488Smckusick int sdpartoff[] = {
3441488Smckusick 	1024,	17408,	0,	17408,
3554073Shibler 	115712,	218112,	82944,	115712
3641488Smckusick };
3741488Smckusick 
3841488Smckusick #define	SDRETRY		2
3941488Smckusick 
4054073Shibler sdinit(ctlr, unit)
4154073Shibler 	int ctlr, unit;
4241488Smckusick {
4354073Shibler 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
4441488Smckusick 	u_char stat;
4541488Smckusick 	int capbuf[2];
4641488Smckusick 
4754073Shibler 	stat = scsi_test_unit_rdy(ctlr, unit);
4854073Shibler 	if (stat) {
4941488Smckusick 		/* drive may be doing RTZ - wait a bit */
5041488Smckusick 		if (stat == STS_CHECKCOND) {
5141488Smckusick 			DELAY(1000000);
5254073Shibler 			stat = scsi_test_unit_rdy(ctlr, unit);
5341488Smckusick 		}
5454073Shibler 		if (stat) {
5555899Shibler 			printf("sd(%d,%d,0,0): init failed (stat=%x)\n",
5655899Shibler 			       ctlr, unit, stat);
5754073Shibler 			return (0);
5854073Shibler 		}
5941488Smckusick 	}
6041488Smckusick 	/*
6141488Smckusick 	 * try to get the drive block size.
6241488Smckusick 	 */
6341488Smckusick 	capbuf[0] = 0;
6441488Smckusick 	capbuf[1] = 0;
6554073Shibler 	stat = scsi_read_capacity(ctlr, unit,
6654073Shibler 				  (u_char *)capbuf, sizeof(capbuf));
6754073Shibler 	if (stat == 0) {
6841488Smckusick 		if (capbuf[1] > DEV_BSIZE)
6941488Smckusick 			for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1)
7041488Smckusick 				++ss->sc_blkshift;
7141488Smckusick 	}
7241488Smckusick 	ss->sc_alive = 1;
7341488Smckusick 	return (1);
7441488Smckusick }
7541488Smckusick 
7654073Shibler sdreset(ctlr, unit)
7754073Shibler 	int ctlr, unit;
7841488Smckusick {
7941488Smckusick }
8041488Smckusick 
8141488Smckusick sdopen(io)
8241488Smckusick 	struct iob *io;
8341488Smckusick {
8454073Shibler 	register struct sd_softc *ss;
8554073Shibler 	int ctlr, unit, part;
8641488Smckusick 
8754073Shibler 	devconvert(io);
8854073Shibler 
8954073Shibler 	ctlr = io->i_adapt;
9054073Shibler 	if (ctlr >= NSCSI || scsialive(ctlr) == 0)
9154073Shibler 		return (EADAPT);
9254073Shibler 	unit = io->i_ctlr;
9354073Shibler 	if (unit >= NSD)
9454073Shibler 		return (ECTLR);
9554073Shibler 	ss = &sd_softc[ctlr][unit];
9641488Smckusick 	if (ss->sc_alive == 0)
9754073Shibler 		if (sdinit(ctlr, unit) == 0)
9854073Shibler 			return (ENXIO);
9954073Shibler 	part = io->i_part;
10054073Shibler 	if (part >= 8)
10154073Shibler 		return (EPART);
10254073Shibler 	io->i_boff = sdpartoff[part];
10354073Shibler 	return (0);
10441488Smckusick }
10541488Smckusick 
10641488Smckusick sdstrategy(io, func)
10741488Smckusick 	register struct iob *io;
10854073Shibler 	int func;
10941488Smckusick {
11054073Shibler 	register int ctlr = io->i_adapt;
11154073Shibler 	register int unit = io->i_ctlr;
11254073Shibler 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
11341488Smckusick 	daddr_t blk = io->i_bn >> ss->sc_blkshift;
11441488Smckusick 	u_int nblk = io->i_cc >> ss->sc_blkshift;
11554073Shibler 	char stat;
11641488Smckusick 
11755899Shibler 	if (io->i_cc == 0)
11855899Shibler 		return(0);
11955899Shibler 
12041488Smckusick 	ss->sc_retry = 0;
12141488Smckusick retry:
12249156Sbostic 	if (func == F_READ)
12354073Shibler 		stat = scsi_tt_read(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
12441488Smckusick 	else
12554073Shibler 		stat = scsi_tt_write(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
12641488Smckusick 	if (stat) {
12754073Shibler 		printf("sd(%d,%d,%d,%d): block=%x, error=0x%x\n",
12854073Shibler 		       ctlr, unit, io->i_unit, io->i_part, blk, stat);
12941488Smckusick 		if (++ss->sc_retry > SDRETRY)
13041488Smckusick 			return(-1);
13154073Shibler 		goto retry;
13241488Smckusick 	}
13341488Smckusick 	return(io->i_cc);
13441488Smckusick }
135