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.1 (Berkeley) 05/08/90 15 */ 16 17 /* 18 * SCSI CCS disk driver 19 */ 20 21 #include "saio.h" 22 #include "samachdep.h" 23 24 #include "../hpdev/scsireg.h" 25 26 struct sd_softc { 27 char sc_retry; 28 char sc_alive; 29 short sc_blkshift; 30 } sd_softc[NSD]; 31 32 int sdpartoff[] = { 33 1024, 17408, 0, 17408, 34 115712, 218112, 82944, 0 35 }; 36 37 #define SDRETRY 2 38 39 sdinit(unit) 40 register int unit; 41 { 42 register struct sd_softc *ss; 43 u_char stat; 44 int capbuf[2]; 45 46 if (unit > NSD) 47 return (0); 48 ss = &sd_softc[unit]; 49 /* NB: HP6300 won't boot if next printf is removed (???) - vj */ 50 printf("sd%d: ", unit); 51 if ((stat = scsi_test_unit_rdy(unit)) == 0) { 52 /* drive may be doing RTZ - wait a bit */ 53 printf("not ready - retrying ... "); 54 if (stat == STS_CHECKCOND) { 55 DELAY(1000000); 56 if (scsi_test_unit_rdy(unit) == 0) { 57 printf("giving up.\n"); 58 return (0); 59 } 60 } 61 } 62 printf("unit ready.\n"); 63 /* 64 * try to get the drive block size. 65 */ 66 capbuf[0] = 0; 67 capbuf[1] = 0; 68 if (scsi_read_capacity(unit, (u_char *)capbuf, sizeof(capbuf)) != 0) { 69 if (capbuf[1] > DEV_BSIZE) 70 for (; capbuf[1] > DEV_BSIZE; capbuf[1] >>= 1) 71 ++ss->sc_blkshift; 72 } 73 ss->sc_alive = 1; 74 return (1); 75 } 76 77 sdreset(unit) 78 { 79 } 80 81 sdopen(io) 82 struct iob *io; 83 { 84 register int unit = io->i_unit; 85 register struct sd_softc *ss = &sd_softc[unit]; 86 struct sdinfo *ri; 87 88 if (scsialive(unit) == 0) 89 _stop("scsi controller not configured"); 90 if (ss->sc_alive == 0) 91 if (sdinit(unit) == 0) 92 _stop("sd init failed"); 93 if (io->i_boff < 0 || io->i_boff > 7) 94 _stop("sd bad minor"); 95 io->i_boff = sdpartoff[io->i_boff]; 96 } 97 98 sdstrategy(io, func) 99 register struct iob *io; 100 register int func; 101 { 102 register int unit = io->i_unit; 103 register struct sd_softc *ss = &sd_softc[unit]; 104 char stat; 105 daddr_t blk = io->i_bn >> ss->sc_blkshift; 106 u_int nblk = io->i_cc >> ss->sc_blkshift; 107 108 ss->sc_retry = 0; 109 retry: 110 if (func == READ) 111 stat = scsi_tt_read(unit, io->i_ma, io->i_cc, blk, nblk); 112 else 113 stat = scsi_tt_write(unit, io->i_ma, io->i_cc, blk, nblk); 114 if (stat) { 115 printf("sd(%d,?) err: 0x%x", unit, stat); 116 if (++ss->sc_retry > SDRETRY) 117 return(-1); 118 else 119 goto retry; 120 } 121 return(io->i_cc); 122 } 123