xref: /original-bsd/sys/vax/vax/mscpvar.h (revision 4d072710)
1 /*
2  * Copyright (c) 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Chris Torek.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the University of California, Berkeley.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  *	@(#)mscpvar.h	7.2 (Berkeley) 07/09/88
21  */
22 
23 /*
24  * MSCP generic driver configuration
25  */
26 
27 /*
28  * Enabling MSCP_PARANOIA makes the response code perform various checks
29  * on the hardware.  (Right now it verifies only the buffer pointer in
30  * mscp_cmdref.)
31  *
32  * Enabling AVOID_EMULEX_BUG selects an alternative method of identifying
33  * transfers in progress, which gets around a rather peculiar bug in the
34  * SC41/MS.  Enabling MSCP_PARANOIA instead should work, but will cause
35  * `extra' Unibus resets.
36  *
37  * Either of these flags can simply be included as an `options' line in
38  * your configuration file.
39  */
40 
41 /* #define MSCP_PARANOIA */
42 /* #define AVOID_EMULEX_BUG */
43 
44 /*
45  * Per driver information.
46  *
47  * md_ndpc sets the maximum unit number allowed in response packets.
48  * md_nunits is the number of drives attached to all controllers.
49  * md_unitshift is the divisor for converting a minor device number
50  * to a unit index for the device queues in md_utab.
51  *
52  * The routines are called from the generic response dispatcher.
53  * THE FOLLOWING IS OUT OF DATE
54  * The first three (dgram, ctlrdone, and unconf) get passed a pointer
55  * to the uba_ctlr and to the packet; the rest get a pointer to the
56  * uba_device and to the packet (`um, mp' and `ui, mp' respectively).
57  * The routines unconf, online, gotstatus, and ioerr are functions
58  * and should return one of the values given below.  In addition,
59  * the ioerr and bb routines get a third argument, `bp': a pointer
60  * to the buffer describing the transfer in error.
61  * END OUT OF DATE
62  */
63 struct mscp_driver {
64 	int	md_ndpc;		/* number of drives per ctlr */
65 	int	md_nunits;		/* total number drives (all ctlrs) */
66 	int	md_unitshift;		/* device number to unit: >> count */
67 	struct	buf *md_utab;		/* pointer to device queues */
68 	struct	disklabel *md_lab;	/* pointer to devicee disklabels */
69 	struct	uba_device **md_dinfo;	/* pointer to device info */
70 	int	(*md_dgram)();		/* error datagram */
71 	int	(*md_ctlrdone)();	/* controller operation complete */
72 	int	(*md_unconf)();		/* response from unconfigured drive */
73 	int	(*md_iodone)();		/* normal I/O is done */
74 	int	(*md_online)();		/* drive on line */
75 	int	(*md_gotstatus)();	/* got unit status */
76 	int	(*md_replace)();	/* replace done */
77 	int	(*md_ioerr)();		/* read or write failed */
78 	int	(*md_bb)();		/* B_BAD io done */
79 	char	*md_mname;		/* name of controllers */
80 	char	*md_dname;		/* name of drives */
81 };
82 
83 /*
84  * Return values from functions.
85  * MSCP_RESTARTED is peculiar to I/O errors.
86  */
87 #define	MSCP_DONE	0		/* all ok */
88 #define	MSCP_FAILED	1		/* no go */
89 #define	MSCP_RESTARTED	2		/* transfer restarted */
90 
91 /*
92  * Ring information, per ring (one each for commands and responses).
93  */
94 struct mscp_ri {
95 	int	mri_size;		/* ring size */
96 	int	mri_next;		/* next (expected|free) */
97 	long	*mri_desc;		/* base address of descriptors */
98 	struct	mscp *mri_ring;		/* base address of packets */
99 };
100 
101 /*
102  * Per device information.
103  *
104  * mi_ip is a pointer to the inverting pointers (things that get `ui's
105  * given unit numbers) FOR THIS CONTROLLER (NOT the whole set!).
106  *
107  * mi_wtab holds a queue of those transfers that were started but have
108  * not yet finished.  Other Unibus drivers do not need this as they hand
109  * out requests one at a time.  MSCP devices, however, take a slew of
110  * requests and pick their own order to execute them.  This means that
111  * we have to have a place to move transfers that were given to the
112  * controller, so we can tell those apart from those that have not yet
113  * been handed out; mi_wtab is that place.
114  */
115 struct mscp_info {
116 	struct	mscp_driver *mi_md;	/* pointer to driver info */
117 	int	mi_ctlr;		/* controller index */
118 	struct	buf *mi_tab;		/* pointer to ctlr's drive queue */
119 	struct	uba_device **mi_ip;	/* pointer to inverting pointers */
120 	struct	mscp_ri mi_cmd;		/* MSCP command ring info */
121 	struct	mscp_ri mi_rsp;		/* MSCP response ring info */
122 	short	mi_credits;		/* transfer credits */
123 	char	mi_wantcmd;		/* waiting for command packet */
124 	char	mi_wantcredits;		/* waiting for transfer credits */
125 	struct	buf mi_wtab;		/* transfer wait queue */
126 #ifdef AVOID_EMULEX_BUG
127 #define	AEB_MAX_BP	32		/* max pend xfers (power of 2) XXX */
128 	struct	buf *mi_bp[AEB_MAX_BP];	/* xfer no. to buffer */
129 	u_int	mi_nextbp;		/* generates unique xfer no's */
130 	int	mi_ok;			/* for error rate statistics */
131 #endif AVOID_EMULEX_BUG
132 };
133 
134 /*
135  * We have run out of credits when mi_credits is <= MSCP_MINCREDITS.
136  * It is still possible to issue one command in this case, but it must
137  * not be a data transfer.  E.g., `get command status' or `abort command'
138  * is legal, while `read' is not.
139  */
140 #define	MSCP_MINCREDITS	1
141 
142 /*
143  * Flags for mscp_getcp().
144  */
145 #define	MSCP_WAIT	1
146 #define	MSCP_DONTWAIT	0
147 
148 struct	mscp *mscp_getcp();	/* get a command packet */
149 
150 /*
151  * Unit flags
152  */
153 #define	UNIT_ONLINE	0x01	/* drive is on line */
154 #define	UNIT_HAVESTATUS	0x02	/* got unit status */
155 #define	UNIT_REQUEUE	0x04	/* requeue after response */
156 
157 /*
158  * Handle a command ring transition: wake up sleepers for command packets.
159  * This is too simple to bother with a function call.
160  */
161 #define	MSCP_DOCMD(mi) { \
162 	if ((mi)->mi_wantcmd) { \
163 		(mi)->mi_wantcmd = 0; \
164 		wakeup((caddr_t) &(mi)->mi_wantcmd); \
165 	} \
166 }
167 
168 /*
169  * The following macro appends a buffer to a drive queue or a drive to
170  * a controller queue, given the name of the forward link.  Use as
171  * `APPEND(dp, &um->um_tab, b_forw)' or `APPEND(bp, dp, av_forw)',
172  * where `bp' is a transfer request, `dp' is a drive queue, and `um_tab'
173  * is a controller queue.  (That is, the forward link for controller
174  * queues is `b_forw'; for drive queues, it is `av_forw'.)
175  */
176 #define	APPEND(bp, queue, link) { \
177 	(bp)->link = NULL; \
178 	if ((queue)->b_actf == NULL) \
179 		(queue)->b_actf = (bp); \
180 	else \
181 		(queue)->b_actl->link = (bp); \
182 	(queue)->b_actl = (bp); \
183 }
184