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