xref: /original-bsd/sys/tahoe/vba/vdreg.h (revision f43fc9d7)
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  * Computer Consoles Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)vdreg.h	7.7 (Berkeley) 06/28/90
11  */
12 
13 /*
14  * Versabus VDDC/SMDE disk controller definitions.
15  */
16 #define	VDDC_SECSIZE	512	/* sector size for VDDC */
17 #define	VD_MAXSECSIZE	1024	/* max sector size for SMD/E */
18 
19 /*
20  * Controller communications block.
21  */
22 struct vddevice {
23 	u_long	vdcdr;		/* controller device register */
24 	u_long	vdreset;	/* controller reset register */
25 	u_long	vdcsr;		/* control-status register */
26 	long	vdrstclr;	/* reset clear register */
27 	u_short	vdstatus[16];	/* per-drive status register */
28 	u_short	vdicf_status;	/* status change interupt control format */
29 	u_short	vdicf_done;	/* interrupt complete control format */
30 	u_short	vdicf_error;	/* interrupt error control format */
31 	u_short	vdicf_success;	/* interrupt success control format */
32 	u_short	vdtcf_mdcb;	/* mdcb transfer control format */
33 	u_short	vdtcf_dcb;	/* dcb transfer control format */
34 	u_short	vdtcf_trail;	/* trail transfer control format */
35 	u_short	vdtcf_data;	/* data transfer control format */
36 	u_long	vdccf;		/* controller configuration flags */
37 	u_long	vdsecsize;	/* sector size */
38 	u_short	vdfill0;
39 	u_char	vdcylskew;	/* cylinder to cylinder skew factor */
40 	u_char	vdtrackskew;	/* track to track skew factor */
41 	u_long	vdfill1;
42 	u_long	vddfr;		/* diagnostic flag register */
43 	u_long	vddda;		/* diagnostic dump address */
44 };
45 
46 /* controller types */
47 #define	VDTYPE_VDDC	1	/* old vddc controller (smd only) */
48 #define	VDTYPE_SMDE	2	/* new smde controller (smd-e) */
49 
50 /*
51  * Controller status definitions.
52  */
53 #define	CS_SCS	0xf		/* status change source (drive number) */
54 #define	CS_ELC	0x10		/* error on last command */
55 #define	CS_ICC	0x60		/* interupt cause code */
56 #define   ICC_NOI  0x00		/* no interupt */
57 #define   ICC_DUN  0x20		/* no interupt */
58 #define   ICC_ERR  0x40		/* no interupt */
59 #define   ICC_SUC  0x60		/* no interupt */
60 #define	CS_GO	0x80		/* go bit (controller busy) */
61 #define	CS_BE	0x100		/* buss error */
62 #define	CS_BOK	0x4000		/* board ok */
63 #define	CS_SFL	0x8000		/* system fail */
64 #define	CS_LEC	0xff000000	/* last error code */
65 
66 /*
67  * Drive status definitions.
68  */
69 #define	STA_UR	0x1		/* unit ready */
70 #define	STA_OC	0x2		/* on cylinder */
71 #define	STA_SE	0x4		/* seek error */
72 #define	STA_DF	0x8		/* drive fault */
73 #define	STA_WP	0x10		/* write protected */
74 #define	STA_US	0x20		/* unit selected */
75 #define	STA_TYPE	0x300	/* drive type: */
76 #define	STA_SMD		0x000		/* SMD */
77 #define	STA_ESDI	0x100		/* ESDI */
78 
79 /*
80  * Interupt Control Field definitions.
81  */
82 #define	ICF_IPL	0x7		/* interupt priority level */
83 #define	ICF_IEN	0x8		/* interupt enable */
84 #define	ICF_IV	0xff00		/* interupt vector */
85 
86 /*
87  * Transfer Control Format definitions.
88  */
89 #define	TCF_AM	0xff		/* Address Modifier */
90 #define	  AM_SNPDA   0x01	/* Standard Non-Privileged Data Access */
91 #define	  AM_SASA    0x81	/* Standard Ascending Sequential Access */
92 #define	  AM_ENPDA   0xf1	/* Extended Non-Privileged Data Access */
93 #define	  AM_EASA    0xe1	/* Extended Ascending Sequential Access */
94 #define	TCF_BTE	0x800		/* Block Transfer Enable */
95 
96 /*
97  * Controller Configuration Flags.
98  */
99 #define	CCF_STS	0x1		/* sectors per track selectable */
100 #define	CCF_EAV	0x2		/* enable auto vector */
101 #define	CCF_ERR	0x4		/* enable reset register */
102 #define CCF_RFE 0x8		/* recovery flag enable */
103 #define	CCF_XMD	0x60		/* xmd transfer mode (bus size) */
104 #define	  XMD_8BIT  0x20	/*   do only 8 bit transfers */
105 #define	  XMD_16BIT 0x40	/*   do only 16 bit transfers */
106 #define	  XMD_32BIT 0x60	/*   do only 32 bit transfers */
107 #define	CCF_DIU	0x80		/* disable initial update of DCB @cmd start */
108 #define	CCF_BSZ	0x300		/* burst size */
109 #define	  BSZ_16WRD 0x000	/*   16 word transfer burst */
110 #define	  BSZ_12WRD 0x100	/*   12 word transfer burst */
111 #define	  BSZ_8WRD  0x200	/*   8 word transfer burst */
112 #define	  BSZ_4WRD  0x300	/*   4 word transfer burst */
113 #define CCF_SEN	0x400		/* cylinder/track skew enable (for format) */
114 #define	CCF_ENP	0x1000		/* enable parity */
115 #define	CCF_EPE	0x2000		/* enable parity errors */
116 #define	CCF_EDE	0x10000		/* error detection enable */
117 #define	CCF_ECE	0x20000		/* error correction enable */
118 
119 /*
120  * Diagnostic register definitions.
121  */
122 #define	DIA_DC	0x7f		/* dump count mask */
123 #define	DIA_DWR	0x80		/* dump write/read flag */
124 #define	DIA_ARE	0x100		/* auto rebuild enable */
125 #define	DIA_CEN	0x200		/* call enable flag */
126 #define	DIA_KEY	0xAA550000	/* reset enable key */
127 
128 /*
129  * Hardware interface flags, in dcb.devselect and d_devflags
130  */
131 #define VD_ESDI	0x10		/* drive is on ESDI interface */
132 #define	d_devflags	d_drivedata[0]		/* in disk label */
133 
134 /*
135  * Error recovery flags.
136  */
137 #define	VDRF_RTZ	0x0001	/* return to zero */
138 #define	VDRF_OCF	0x0002	/* on cylinder false */
139 #define	VDRF_OSP	0x0004	/* offset plus */
140 #define	VDRF_OSM	0x0008	/* offset minus */
141 #define	VDRF_DSE	0x0080	/* data strobe early */
142 #define	VDRF_DSL	0x0100	/* data strobe late */
143 
144 #define	VDRF_NONE	0
145 #define	VDRF_NORMAL	(VDRF_RTZ|VDRF_OCF|VDRF_OSP|VDRF_OSM|VDRF_DSE|VDRF_DSL)
146 
147 /*
148  * Perform a reset on the controller.
149  */
150 #define	VDRESET(a,t) { \
151 	if ((t) == VDTYPE_SMDE) { \
152 		((struct vddevice *)(a))->vddfr = DIA_KEY|DIA_CEN; \
153 		((struct vddevice *)(a))->vdcdr = (u_long)0xffffffff; \
154 		DELAY(5000000); \
155 	} else { \
156 		((struct vddevice *)(a))->vdreset = 0; \
157 		DELAY(1500000); \
158 	} \
159 }
160 
161 /*
162  * Abort a controller operation.
163  */
164 #define	VDABORT(a,t) { \
165 	if ((t) == VDTYPE_VDDC) { \
166 		movow((a), (VDOP_ABORT&0xffff0000)>>16) ; \
167 		movow((int)(a)+2, VDOP_ABORT&0xffff); \
168 	} else \
169 		((struct vddevice *)(a))->vdcdr = (u_long)VDOP_ABORT; \
170 	DELAY(1000000); \
171 }
172 
173 /*
174  * Start a command.
175  */
176 #define VDGO(a,mdcb,t) {\
177 	if ((t) == VDTYPE_VDDC) { \
178 		movow((a), ((int)(mdcb)&0xffff0000)>>16) ; \
179 		movow((int)((a))+2, (int)(mdcb)&0xffff); \
180 	} else \
181 		((struct vddevice *)(a))->vdcdr = (mdcb); \
182 }
183 
184 /*
185  * MDCB layout.
186  */
187 struct mdcb {
188 	struct	dcb *mdcb_head;		/* first dcb in list */
189 	struct	dcb *mdcb_busy;		/* dcb being processed */
190 	struct	dcb *mdcb_intr;		/* dcb causing interrupt */
191 	long	mdcb_status;		/* status of dcb in mdcb_busy */
192 };
193 
194 /*
195  * DCB definitions.
196  */
197 
198 /*
199  * A disk address.
200  */
201 typedef struct {
202 	u_char	track;			/* all 8 bits */
203 	u_char	sector;			/* all 8  bits */
204 	u_short	cylinder;		/* low order 12 bits */
205 } dskadr;
206 
207 /*
208  * DCB trailer formats.
209  */
210 /* read/write trailer */
211 struct trrw {
212 	u_long	memadr;		/* memory address */
213 	u_long	wcount;		/* 16 bit word count */
214 	dskadr	disk;		/* disk address */
215 };
216 
217 /* scatter/gather trailer */
218 #define	VDMAXPAGES	(MAXPHYS / NBPG)
219 struct trsg {
220 	struct	trrw start_addr;
221 	struct addr_chain {
222 		u_long	nxt_addr;
223 		u_long	nxt_len;
224 	} addr_chain[VDMAXPAGES + 1];
225 };
226 
227 /* seek trailer format */
228 struct trseek {
229 	dskadr	skaddr;
230 };
231 
232 /* format trailer */
233 struct trfmt {
234 	char	*addr;		/* data buffer to be filled on sector*/
235 	long	nsectors;	/* # of sectors to be formatted */
236 	dskadr	disk;		/* disk physical address info */
237 	dskadr  hdr;		/* header address info */
238 };
239 
240 /* reset/configure trailer */
241 struct treset {
242 	long	ncyl;		/* # cylinders */
243 	long	nsurfaces;	/* # surfaces */
244 	long	nsectors;	/* # sectors */
245 	long	slip_sec;	/* # of slip sectors */
246 	long	recovery;	/* recovery flags */
247 };
248 
249 /* ident trailer */
250 struct trid {
251 	long	name;
252 	long	rev;
253 	long	date;
254 };
255 
256 /*
257  * DCB layout.
258  */
259 struct dcb {
260 	struct	dcb *nxtdcb;	/* next dcb */
261 	short	intflg;		/* interrupt settings and flags */
262 	short	opcode;		/* DCB command code etc... */
263 	long	operrsta;	/* error & status info */
264 	short	fill;		/* not used */
265 	char	devselect;	/* drive selection */
266 	char	trailcnt;	/* trailer Word Count */
267 	long	err_memadr;	/* error memory address */
268 	u_char	err_code;	/* error codes for SMD/E */
269 	char	fill2;		/* not used */
270 	short	err_wcount;	/* error word count */
271 	char	err_trk;	/* error track/sector */
272 	char	err_sec;	/* error track/sector */
273 	short	err_cyl;	/* error cylinder adr */
274 	union {
275 		struct	trid idtrail;	/* ident command trailer */
276 		struct	trseek sktrail;	/* seek command trailer */
277 		struct	trsg sgtrail;	/* scatter/gather trailer */
278 		struct	trrw rwtrail;	/* read/write trailer */
279 		struct	trfmt fmtrail;	/* format trailer */
280 		struct	treset rstrail;	/* reset/configure trailer */
281 	} trail;
282 };
283 
284 /*
285  * smaller DCB with seek trailer only (no scatter-gather).
286  */
287 struct skdcb {
288 	struct	dcb *nxtdcb;	/* next dcb */
289 	short	intflg;		/* interrupt settings and flags */
290 	short	opcode;		/* DCB command code etc... */
291 	long	operrsta;	/* error & status info */
292 	short	fill;		/* not used */
293 	char	devselect;	/* drive selection */
294 	char	trailcnt;	/* trailer Word Count */
295 	long	err_memadr;	/* error memory address */
296 	u_char	err_code;	/* error codes for SMD/E */
297 	char	fill2;		/* not used */
298 	short	err_wcount;	/* error word count */
299 	char	err_trk;	/* error track/sector */
300 	char	err_sec;	/* error track/sector */
301 	short	err_cyl;	/* error cylinder adr */
302 	union {
303 		struct	trseek sktrail;	/* seek command trailer */
304 	} trail;
305 };
306 
307 /*
308  * DCB command codes.
309  */
310 #define	VDOP_RD		0x80		/* read data */
311 #define	VDOP_FTR	0xc0		/* full track read */
312 #define	VDOP_RAS	0x90		/* read and scatter */
313 #define	VDOP_RDRAW	0x600		/* read unformatted disk sector */
314 #define	VDOP_CMP	0xa0		/* compare */
315 #define	VDOP_FTC	0xe0		/* full track compare */
316 #define	VDOP_RHDE	0x180		/* read header, data & ecc */
317 #define	VDOP_WD		0x00		/* write data */
318 #define	VDOP_FTW	0x40		/* full track write */
319 #define	VDOP_WTC	0x20		/* write then compare */
320 #define	VDOP_FTWTC	0x60		/* full track write then compare */
321 #define	VDOP_GAW	0x10		/* gather and write */
322 #define	VDOP_WDE	0x100		/* write data & ecc */
323 #define	VDOP_FSECT	0x900		/* format sector */
324 #define	VDOP_GWC	0x30		/* gather write & compare */
325 #define	VDOP_START	0x800		/* start drives */
326 #define	VDOP_RELEASE	0xa00		/* stop drives */
327 #define	VDOP_SEEK	0xb00		/* seek */
328 #define	VDOP_INIT	0xc00		/* initialize controller */
329 #define	VDOP_DIAG	0xd00		/* diagnose (self-test) controller */
330 #define	VDOP_CONFIG	0xe00		/* reset & configure drive */
331 #define	VDOP_STATUS	0xf00		/* get drive status */
332 #define	VDOP_IDENT	0x700		/* identify controller */
333 #define	VDOP_PROBE	0x500		/* probe drives and update status */
334 
335 #define	VDOP_ABORT	0x80000000	/* abort current command */
336 
337 /*
338  * DCB status definitions.
339  */
340 #define	DCBS_HCRC	0x00000001	/* header crc error */
341 #define	DCBS_HCE	0x00000002	/* header compare error */
342 #define	DCBS_WPT	0x00000004	/* drive write protected */
343 #define	DCBS_CHE	0x00000008	/* controller hardware error */
344 #define	DCBS_SKI	0x00000010	/* seek incomplete */
345 #define	DCBS_UDE	0x00000020	/* uncorrectable data error */
346 #define	DCBS_OCYL	0x00000040	/* off cylinder */
347 #define	DCBS_NRDY	0x00000080	/* drive not ready */
348 #define	DCBS_ATA	0x00000100	/* alternate track accessed */
349 #define	DCBS_SKS	0x00000200	/* seek started */
350 #define	DCBS_IVA	0x00000400	/* invalid disk address error */
351 #define	DCBS_NEM	0x00000800	/* non-existant memory error */
352 #define	DCBS_DPE	0x00001000	/* memory data parity error */
353 #define	DCBS_DCE	0x00002000	/* data compare error */
354 #define	DCBS_DDI	0x00004000	/* ddi ready */
355 #define	DCBS_OAB	0x00008000	/* operation aborted */
356 #define	DCBS_DSE	0x00010000	/* data strobe early */
357 #define	DCBS_DSL	0x00020000	/* data strobe late */
358 #define	DCBS_TOP	0x00040000	/* track offset plus */
359 #define	DCBS_TOM	0x00080000	/* track offset minus */
360 #define	DCBS_CCD	0x00100000	/* controller corrected data */
361 #define	DCBS_HARD	0x00200000	/* hard error */
362 #define	DCBS_SOFT	0x00400000	/* soft error (retry succesful) */
363 #define	DCBS_ERR	0x00800000	/* composite error */
364 #define DCBS_IVC	0x01000000	/* invalid command error */
365 /* bits 24-27 unused */
366 #define	DCBS_BSY	0x10000000	/* controller busy */
367 #define	DCBS_ICC	0x60000000	/* interrupt cause code */
368 #define	DCBS_INT	0x80000000	/* interrupt generated for this dcb */
369 
370 #define	VDERRBITS	"\20\1HCRC\2HCE\3WPT\4CHE\5DSKI\6UDE\7OCYL\10NRDY\
371 \11ATA\12SKS\13IVA\14NEM\15DPE\16DCE\17DDI\20OAB\21DSE\22DSL\23TOP\24TOM\
372 \25CCD\26HARD\27SOFT\30ERR\31IVC\35ABORTED\36FAIL\37COMPLETE\40STARTED"
373 
374 /* drive related errors */
375 #define	VDERR_DRIVE	(DCBS_SKI|DCBS_OCYL|DCBS_NRDY|DCBS_IVA)
376 /* controller related errors */
377 #define	VDERR_CTLR	(DCBS_CHE|DCBS_OAB|DCBS_IVC|DCBS_NEM)
378 /* potentially recoverable errors */
379 #define	VDERR_RETRY \
380     (VDERR_DRIVE|VDERR_CTLR|DCBS_DCE|DCBS_DPE|DCBS_HCRC|DCBS_HCE)
381 /* uncorrected data errors */
382 #define	VDERR_HARD	(VDERR_RETRY|DCBS_WPT|DCBS_UDE)
383 
384 /*
385  * DCB status codes.
386  */
387 #define	DCBS_ABORT	0x10000000	/* dcb aborted */
388 #define	DCBS_FAIL	0x20000000	/* dcb unsuccesfully completed */
389 #define	DCBS_DONE	0x40000000	/* dcb complete */
390 #define	DCBS_START	0x80000000	/* dcb started */
391 
392 /*
393  * DCB interrupt control.
394  */
395 #define	DCBINT_NONE	0x0		/* don't interrupt */
396 #define	DCBINT_ERR	0x2		/* interrupt on error */
397 #define	DCBINT_SUC	0x1		/* interrupt on success */
398 #define	DCBINT_DONE	(DCBINT_ERR|DCBINT_SUC)
399 #define	DCBINT_PBA	0x4		/* proceed before acknowledge */
400 
401 /*
402  * Sector formats.
403  */
404 typedef union {
405 	struct {
406 		dskadr	hdr_addr;
407 		short	smd_crc;
408 	} smd;
409 	struct {
410 		dskadr	physical;
411 		dskadr	logical;
412 		long	smd_e_crc;
413 	} smd_e;
414 } fmt_hdr;
415 
416 /* Sector Header bit assignments */
417 #define	VDMF	0x8000		/* Manufacturer Fault 1=good sector */
418 #define	VDUF	0x4000		/* User Fault 1=good sector */
419 #define	VDALT	0x2000		/* Alternate Sector 1=alternate */
420 #define	VDWPT	0x1000		/* Write Protect 1=Read Only Sector */
421 
422 /* input register assignments for DIOCWFORMAT ioctl */
423 #define	dk_op		df_reg[0]	/* opcode */
424 #define	dk_althdr	df_reg[1]	/* alt. sect. dskadr, in an int! */
425 #define	dk_fmtflags	df_reg[2]	/* header format flags */
426 
427 /* output register assignments for DIOCWFORMAT ioctl */
428 #define	dk_operrsta	df_reg[0]	/* dcb operrsta */
429 #define	dk_ecodecnt	df_reg[1]	/* smd-e ecode and error word count */
430 #define	dk_ecode(ecodecnt)	((u_long)(ecodecnt) >> 2)
431 #define	dk_errcnt(ecodecnt)	(((ecodecnt) & 0xffff) << 1)
432 #define	dk_erraddr	df_reg[2]	/* error dskadr, in an int! */
433