xref: /csrg-svn/sys/dev/scsi/scsivar.h (revision 54880)
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