1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * All advertising materials mentioning features or use of this software 10 * must display the following acknowledgement: 11 * This product includes software developed by the University of 12 * California, Lawrence Berkeley Laboratories. 13 * 14 * %sccs.include.redist.c% 15 * 16 * @(#)scsivar.h 8.1 (Berkeley) 06/10/93 17 * 18 * from: $Header: scsivar.h,v 1.7 92/12/02 03:54:05 torek Exp $ (LBL) 19 */ 20 21 /* 22 * SCSI variables. 23 * 24 * Each SCSI Host Bus Adapter (hba) has: 25 * a target queue head and tail 26 * eight targets (for units to enqueue on) 27 * a list of all units on all targets 28 * its target number (the number cpu uses in initiating requests) 29 * a driver 30 * Each SCSI target has: 31 * a forward link so that it can sit on a SCSI host bus adapter queue 32 * a unit queue head and tail 33 * Each SCSI unit has: 34 * a forward link so that it can sit on a SCSI target queue 35 * a driver 36 * an hba & driver (so that we need not chase parent pointers) 37 */ 38 39 /* 40 * Downcalls. These are usually made from hba to unit, but can be 41 * hba->target->unit (when there are multiple units on a target). 42 */ 43 /* device go function (`you got bus') */ 44 typedef void (*scdgo_fn) __P((struct device *, struct scsi_cdb *)); 45 46 /* intr function (`you no got bus no more') */ 47 typedef void (*scintr_fn) __P((struct device *, int stat, int resid)); 48 49 /* 50 * Upcalls. These are usually made from unit to hba, but can be 51 * unit->target->hba. 52 */ 53 /* bus alloc function (`please get me bus') */ 54 struct sq; struct buf; 55 typedef void (*scstart_fn) __P((struct device *, struct sq *, struct buf *, 56 scdgo_fn, struct device *)); 57 58 /* bus go function (`I have bus and I set up cmd, so start it up') */ 59 typedef int (*scbusgo_fn) __P((struct device *, int targ, 60 scintr_fn, struct device *, 61 struct buf *, int pad)); 62 63 /* bus release function (`I have bus but do not need it after all') */ 64 typedef void (*scbusrel_fn) __P((struct device *)); 65 66 /* 67 * SCSI Queue. This is an element in a queue of devices (targets 68 * and/or units) waiting for the bus. 69 */ 70 struct sq { 71 struct sq *sq_forw; /* forward link */ 72 struct buf *sq_bp; /* buffer for transfer */ 73 scdgo_fn sq_dgo; /* device-go to call when got bus */ 74 struct device *sq_dev; /* device argument to sq_dgo */ 75 }; 76 77 struct hba_softc { 78 struct device hba_dev; /* generic part */ 79 struct sq *hba_head, *hba_tail;/* io queue (u's/t's wanting bus) */ 80 char hba_busy; /* true => will inspect qhead later */ 81 struct targ *hba_targets[8]; /* the 8 possible targets */ 82 struct hbadriver *hba_driver; /* hba driver */ 83 scintr_fn hba_intr; /* current interrupt function */ 84 struct device *hba_intrdev; /* arg 0 for hba_intr */ 85 }; 86 87 struct targ { 88 struct device t_dev; /* generic part */ 89 struct sq t_forw; /* forward link, etc, on hba queue */ 90 struct sq *t_head, *t_tail; /* io queue */ 91 char t_busy; /* true => will inspect qhead later */ 92 char t_targ; /* target number */ 93 char t_nunits; /* count of live units */ 94 char t_firstunit; /* the first live unit */ 95 struct unit *t_units[8]; /* the 8 possible units */ 96 scintr_fn t_intr; /* current interrupt function */ 97 struct device *t_intrdev; /* arg 0 for t_intr */ 98 }; 99 100 /* since a unit may be a disk, tape, etc., it has only pointer to dev */ 101 struct unit { 102 struct device *u_dev; /* backpointer to generic */ 103 int u_unit; /* unit number on target */ 104 scstart_fn u_start; /* upcall to get bus */ 105 scbusgo_fn u_go; /* upcall to use bus */ 106 scbusrel_fn u_rel; /* upcall to release bus early */ 107 struct device *u_updev; /* device for upcalls */ 108 struct sq u_forw; /* forward link on target or hba q */ 109 struct unitdriver *u_driver; /* unit driver */ 110 /* the following three fields are copied from target & hba, for quick lookup */ 111 int u_targ; /* target number */ 112 struct hba_softc *u_hba; /* hba, from parent */ 113 struct hbadriver *u_hbd; /* hba driver, from parent */ 114 }; 115 116 /* 117 * SCSI hba driver. 118 */ 119 struct hbadriver { 120 /* immediate command; should not depend on receiving interrupts */ 121 int (*hd_icmd) __P((struct hba_softc *, int targ, 122 struct scsi_cdb *cmd, 123 caddr_t addr, int len, int rw)); 124 /* crash dump: like icmd(B_WRITE), but possibly from physmem */ 125 int (*hd_dump) __P((struct hba_softc *, int targ, 126 struct scsi_cdb *cmd, caddr_t addr, int len)); 127 scstart_fn hd_start; /* allocate DMA & bus */ 128 scbusgo_fn hd_go; /* start DMA xfer on bus */ 129 scbusrel_fn hd_rel; /* release bus early */ 130 void (*hd_reset) __P((struct hba_softc *, int)); 131 }; 132 133 /* 134 * SCSI unit driver (`downcalls' from hba to unit). 135 */ 136 struct unitdriver { 137 void (*ud_reset) __P((struct unit *)); /* SCSI bus reset */ 138 }; 139 140 /* 141 * The generic SCSI target probe code passes the following to 142 * unit configuration `match' routines. 143 */ 144 struct scsi_attach_args { 145 int sa_targ; /* target number */ 146 int sa_unit; /* unit number */ 147 int sa_req_status; /* status from REQUEST SENSE */ 148 struct scsi_sense sa_sn; /* contents from same */ 149 int sa_inq_status; /* status from INQUIRY command */ 150 struct scsi_inquiry sa_si; /* contents from same */ 151 }; 152 153 /* 154 * The SCSICMDLEN macro gives the SCSI-standard-defined length of 155 * a given SCSI command. This is 0 if the command is in an undefined 156 * group (see scsi.h). 157 */ 158 extern const char scsicmdlen[8]; 159 #define SCSICMDLEN(cmd) scsicmdlen[(cmd) >> 5] 160 161 /* 162 * The SCSIMSGLEN macro gives the SCSI-standard-defined length of 163 * a given SCSI message byte. This is -1 if the message byte is 164 * undefined, -3 if it is an identify, -2 for an extended message, 165 * 0 if it is normal completion, otherwise positive. 166 */ 167 #define SMLEN_IDENTIFY -3 168 #define SMLEN_EXTENDED -2 169 #define SMLEN_UNDEF -1 170 #define SMLEN_DONE 0 171 extern const signed char scsimsglen[0x24]; 172 #define SCSIMSGLEN(msg) ((msg) & MSG_IDENTIFY ? SMLEN_IDENTIFY : \ 173 (msg) > 0x24 ? SMLEN_UNDEF : scsimsglen[msg]) 174 175 /* 176 * Declarations for exported functions in scsi_subr.c 177 */ 178 int scsi_test_unit_ready __P((struct hba_softc *, int targ, int unit)); 179 int scsi_request_sense __P((struct hba_softc *, int, int, caddr_t, int)); 180 void scsi_hbaattach __P((struct hba_softc *)); 181 void scsi_establish __P((struct unit *, struct device *, int)); 182 void scsi_printinq __P((struct scsi_inquiry *)); 183 void scsi_inq_ansi __P((struct scsi_inq_ansi *, char *, char *, char *)); 184 void scsi_reset_units __P((struct hba_softc *)); 185 186 #define SCSI_FOUNDTARGET(hba, targ) { \ 187 extern int scsi_targprint(void *, char *); \ 188 int _t = targ; \ 189 config_found(&(hba)->hba_dev, (void *)&_t, scsi_targprint); \ 190 } 191