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