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