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