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