1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Van Jacobson of Lawrence Berkeley Laboratory and the Systems 8 * Programming Group of the University of Utah Computer Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: sd.c 1.2 90/01/23$ 13 * 14 * @(#)sd.c 7.5 (Berkeley) 06/18/92 15 */ 16 17 /* 18 * SCSI CCS disk driver 19 */ 20 21 #include "sys/param.h" 22 #include "saio.h" 23 #include "samachdep.h" 24 25 #include "../dev/scsireg.h" 26 27 struct sd_softc { 28 char sc_retry; 29 char sc_alive; 30 short sc_blkshift; 31 } sd_softc[NSCSI][NSD]; 32 33 int sdpartoff[] = { 34 1024, 17408, 0, 17408, 35 115712, 218112, 82944, 115712 36 }; 37 38 #define SDRETRY 2 39 40 sdinit(ctlr, unit) 41 int ctlr, unit; 42 { 43 register struct sd_softc *ss = &sd_softc[ctlr][unit]; 44 u_char stat; 45 int capbuf[2]; 46 47 /* NB: HP6300 won't boot if next printf is removed (???) - vj */ 48 printf("sd(%d,%d,0,0): ", ctlr, unit); 49 stat = scsi_test_unit_rdy(ctlr, unit); 50 if (stat) { 51 /* drive may be doing RTZ - wait a bit */ 52 printf("not ready - "); 53 if (stat == STS_CHECKCOND) { 54 printf("retrying ... "); 55 DELAY(1000000); 56 stat = scsi_test_unit_rdy(ctlr, unit); 57 } 58 if (stat) { 59 printf("giving up (stat=%x).\n", stat); 60 return (0); 61 } 62 } 63 printf("unit ready.\n"); 64 /* 65 * try to get the drive block size. 66 */ 67 capbuf[0] = 0; 68 capbuf[1] = 0; 69 stat = scsi_read_capacity(ctlr, unit, 70 (u_char *)capbuf, sizeof(capbuf)); 71 if (stat == 0) { 72 if (capbuf[1] > DEV_BSIZE) 73 for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1) 74 ++ss->sc_blkshift; 75 } 76 ss->sc_alive = 1; 77 return (1); 78 } 79 80 sdreset(ctlr, unit) 81 int ctlr, unit; 82 { 83 } 84 85 sdopen(io) 86 struct iob *io; 87 { 88 register struct sd_softc *ss; 89 int ctlr, unit, part; 90 91 devconvert(io); 92 93 ctlr = io->i_adapt; 94 if (ctlr >= NSCSI || scsialive(ctlr) == 0) 95 return (EADAPT); 96 unit = io->i_ctlr; 97 if (unit >= NSD) 98 return (ECTLR); 99 ss = &sd_softc[ctlr][unit]; 100 if (ss->sc_alive == 0) 101 if (sdinit(ctlr, unit) == 0) 102 return (ENXIO); 103 part = io->i_part; 104 if (part >= 8) 105 return (EPART); 106 io->i_boff = sdpartoff[part]; 107 return (0); 108 } 109 110 sdstrategy(io, func) 111 register struct iob *io; 112 int func; 113 { 114 register int ctlr = io->i_adapt; 115 register int unit = io->i_ctlr; 116 register struct sd_softc *ss = &sd_softc[ctlr][unit]; 117 daddr_t blk = io->i_bn >> ss->sc_blkshift; 118 u_int nblk = io->i_cc >> ss->sc_blkshift; 119 char stat; 120 121 ss->sc_retry = 0; 122 retry: 123 if (func == F_READ) 124 stat = scsi_tt_read(ctlr, unit, io->i_ma, io->i_cc, blk, nblk); 125 else 126 stat = scsi_tt_write(ctlr, unit, io->i_ma, io->i_cc, blk, nblk); 127 if (stat) { 128 printf("sd(%d,%d,%d,%d): block=%x, error=0x%x\n", 129 ctlr, unit, io->i_unit, io->i_part, blk, stat); 130 if (++ss->sc_retry > SDRETRY) 131 return(-1); 132 goto retry; 133 } 134 return(io->i_cc); 135 } 136