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*49156Sbostic * @(#)sd.c 7.4 (Berkeley) 05/05/91 1541488Smckusick */ 1641488Smckusick 1741488Smckusick /* 1841488Smckusick * SCSI CCS disk driver 1941488Smckusick */ 2041488Smckusick 21*49156Sbostic #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; 3141488Smckusick } sd_softc[NSD]; 3241488Smckusick 3341488Smckusick int sdpartoff[] = { 3441488Smckusick 1024, 17408, 0, 17408, 3541488Smckusick 115712, 218112, 82944, 0 3641488Smckusick }; 3741488Smckusick 3841488Smckusick #define SDRETRY 2 3941488Smckusick 4041488Smckusick sdinit(unit) 4141488Smckusick register int unit; 4241488Smckusick { 4341488Smckusick register struct sd_softc *ss; 4441488Smckusick u_char stat; 4541488Smckusick int capbuf[2]; 4641488Smckusick 4741488Smckusick if (unit > NSD) 4841488Smckusick return (0); 4941488Smckusick ss = &sd_softc[unit]; 5041488Smckusick /* NB: HP6300 won't boot if next printf is removed (???) - vj */ 5141488Smckusick printf("sd%d: ", unit); 5241488Smckusick if ((stat = scsi_test_unit_rdy(unit)) == 0) { 5341488Smckusick /* drive may be doing RTZ - wait a bit */ 5441488Smckusick printf("not ready - retrying ... "); 5541488Smckusick if (stat == STS_CHECKCOND) { 5641488Smckusick DELAY(1000000); 5741488Smckusick if (scsi_test_unit_rdy(unit) == 0) { 5841488Smckusick printf("giving up.\n"); 5941488Smckusick return (0); 6041488Smckusick } 6141488Smckusick } 6241488Smckusick } 6341488Smckusick printf("unit ready.\n"); 6441488Smckusick /* 6541488Smckusick * try to get the drive block size. 6641488Smckusick */ 6741488Smckusick capbuf[0] = 0; 6841488Smckusick capbuf[1] = 0; 6941488Smckusick if (scsi_read_capacity(unit, (u_char *)capbuf, sizeof(capbuf)) != 0) { 7041488Smckusick if (capbuf[1] > DEV_BSIZE) 7141488Smckusick for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1) 7241488Smckusick ++ss->sc_blkshift; 7341488Smckusick } 7441488Smckusick ss->sc_alive = 1; 7541488Smckusick return (1); 7641488Smckusick } 7741488Smckusick 7841488Smckusick sdreset(unit) 7941488Smckusick { 8041488Smckusick } 8141488Smckusick 8241488Smckusick sdopen(io) 8341488Smckusick struct iob *io; 8441488Smckusick { 8541488Smckusick register int unit = io->i_unit; 8641488Smckusick register struct sd_softc *ss = &sd_softc[unit]; 8741488Smckusick struct sdinfo *ri; 8841488Smckusick 8941488Smckusick if (scsialive(unit) == 0) 9041488Smckusick _stop("scsi controller not configured"); 9141488Smckusick if (ss->sc_alive == 0) 9241488Smckusick if (sdinit(unit) == 0) 9341488Smckusick _stop("sd init failed"); 9441488Smckusick if (io->i_boff < 0 || io->i_boff > 7) 9541488Smckusick _stop("sd bad minor"); 9641488Smckusick io->i_boff = sdpartoff[io->i_boff]; 9741488Smckusick } 9841488Smckusick 9941488Smckusick sdstrategy(io, func) 10041488Smckusick register struct iob *io; 10141488Smckusick register int func; 10241488Smckusick { 10341488Smckusick register int unit = io->i_unit; 10441488Smckusick register struct sd_softc *ss = &sd_softc[unit]; 10541488Smckusick char stat; 10641488Smckusick daddr_t blk = io->i_bn >> ss->sc_blkshift; 10741488Smckusick u_int nblk = io->i_cc >> ss->sc_blkshift; 10841488Smckusick 10941488Smckusick ss->sc_retry = 0; 11041488Smckusick retry: 111*49156Sbostic if (func == F_READ) 11241488Smckusick stat = scsi_tt_read(unit, io->i_ma, io->i_cc, blk, nblk); 11341488Smckusick else 11441488Smckusick stat = scsi_tt_write(unit, io->i_ma, io->i_cc, blk, nblk); 11541488Smckusick if (stat) { 11642377Smckusick printf("sd(%d,?) err: 0x%x\n", unit, stat); 11741488Smckusick if (++ss->sc_retry > SDRETRY) 11841488Smckusick return(-1); 11941488Smckusick else 12041488Smckusick goto retry; 12141488Smckusick } 12241488Smckusick return(io->i_cc); 12341488Smckusick } 124