xref: /csrg-svn/sys/hp300/stand/sd.c (revision 54073)
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*54073Shibler  *	@(#)sd.c	7.5 (Berkeley) 06/18/92
1541488Smckusick  */
1641488Smckusick 
1741488Smckusick /*
1841488Smckusick  * SCSI CCS disk driver
1941488Smckusick  */
2041488Smckusick 
21*54073Shibler #include "sys/param.h"
2241488Smckusick #include "saio.h"
2341488Smckusick #include "samachdep.h"
2441488Smckusick 
2545790Sbostic #include "../dev/scsireg.h"
2641488Smckusick 
2741488Smckusick struct	sd_softc {
2841488Smckusick 	char	sc_retry;
2941488Smckusick 	char	sc_alive;
3041488Smckusick 	short	sc_blkshift;
31*54073Shibler } sd_softc[NSCSI][NSD];
3241488Smckusick 
3341488Smckusick int sdpartoff[] = {
3441488Smckusick 	1024,	17408,	0,	17408,
35*54073Shibler 	115712,	218112,	82944,	115712
3641488Smckusick };
3741488Smckusick 
3841488Smckusick #define	SDRETRY		2
3941488Smckusick 
40*54073Shibler sdinit(ctlr, unit)
41*54073Shibler 	int ctlr, unit;
4241488Smckusick {
43*54073Shibler 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
4441488Smckusick 	u_char stat;
4541488Smckusick 	int capbuf[2];
4641488Smckusick 
4741488Smckusick 	/* NB: HP6300 won't boot if next printf is removed (???) - vj */
48*54073Shibler 	printf("sd(%d,%d,0,0): ", ctlr, unit);
49*54073Shibler 	stat = scsi_test_unit_rdy(ctlr, unit);
50*54073Shibler 	if (stat) {
5141488Smckusick 		/* drive may be doing RTZ - wait a bit */
52*54073Shibler 		printf("not ready - ");
5341488Smckusick 		if (stat == STS_CHECKCOND) {
54*54073Shibler 			printf("retrying ... ");
5541488Smckusick 			DELAY(1000000);
56*54073Shibler 			stat = scsi_test_unit_rdy(ctlr, unit);
5741488Smckusick 		}
58*54073Shibler 		if (stat) {
59*54073Shibler 			printf("giving up (stat=%x).\n", stat);
60*54073Shibler 			return (0);
61*54073Shibler 		}
6241488Smckusick 	}
6341488Smckusick 	printf("unit ready.\n");
6441488Smckusick 	/*
6541488Smckusick 	 * try to get the drive block size.
6641488Smckusick 	 */
6741488Smckusick 	capbuf[0] = 0;
6841488Smckusick 	capbuf[1] = 0;
69*54073Shibler 	stat = scsi_read_capacity(ctlr, unit,
70*54073Shibler 				  (u_char *)capbuf, sizeof(capbuf));
71*54073Shibler 	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 
80*54073Shibler sdreset(ctlr, unit)
81*54073Shibler 	int ctlr, unit;
8241488Smckusick {
8341488Smckusick }
8441488Smckusick 
8541488Smckusick sdopen(io)
8641488Smckusick 	struct iob *io;
8741488Smckusick {
88*54073Shibler 	register struct sd_softc *ss;
89*54073Shibler 	int ctlr, unit, part;
9041488Smckusick 
91*54073Shibler 	devconvert(io);
92*54073Shibler 
93*54073Shibler 	ctlr = io->i_adapt;
94*54073Shibler 	if (ctlr >= NSCSI || scsialive(ctlr) == 0)
95*54073Shibler 		return (EADAPT);
96*54073Shibler 	unit = io->i_ctlr;
97*54073Shibler 	if (unit >= NSD)
98*54073Shibler 		return (ECTLR);
99*54073Shibler 	ss = &sd_softc[ctlr][unit];
10041488Smckusick 	if (ss->sc_alive == 0)
101*54073Shibler 		if (sdinit(ctlr, unit) == 0)
102*54073Shibler 			return (ENXIO);
103*54073Shibler 	part = io->i_part;
104*54073Shibler 	if (part >= 8)
105*54073Shibler 		return (EPART);
106*54073Shibler 	io->i_boff = sdpartoff[part];
107*54073Shibler 	return (0);
10841488Smckusick }
10941488Smckusick 
11041488Smckusick sdstrategy(io, func)
11141488Smckusick 	register struct iob *io;
112*54073Shibler 	int func;
11341488Smckusick {
114*54073Shibler 	register int ctlr = io->i_adapt;
115*54073Shibler 	register int unit = io->i_ctlr;
116*54073Shibler 	register struct sd_softc *ss = &sd_softc[ctlr][unit];
11741488Smckusick 	daddr_t blk = io->i_bn >> ss->sc_blkshift;
11841488Smckusick 	u_int nblk = io->i_cc >> ss->sc_blkshift;
119*54073Shibler 	char stat;
12041488Smckusick 
12141488Smckusick 	ss->sc_retry = 0;
12241488Smckusick retry:
12349156Sbostic 	if (func == F_READ)
124*54073Shibler 		stat = scsi_tt_read(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
12541488Smckusick 	else
126*54073Shibler 		stat = scsi_tt_write(ctlr, unit, io->i_ma, io->i_cc, blk, nblk);
12741488Smckusick 	if (stat) {
128*54073Shibler 		printf("sd(%d,%d,%d,%d): block=%x, error=0x%x\n",
129*54073Shibler 		       ctlr, unit, io->i_unit, io->i_part, blk, stat);
13041488Smckusick 		if (++ss->sc_retry > SDRETRY)
13141488Smckusick 			return(-1);
132*54073Shibler 		goto retry;
13341488Smckusick 	}
13441488Smckusick 	return(io->i_cc);
13541488Smckusick }
136