132391Sbostic /* 237098Sbostic * Copyright (c) 1988 The Regents of the University of California. 337098Sbostic * All rights reserved. 432391Sbostic * 537098Sbostic * This code is derived from software contributed to Berkeley by 637098Sbostic * Harris Corp. 737098Sbostic * 8*44534Sbostic * %sccs.include.redist.c% 937098Sbostic * 10*44534Sbostic * @(#)hdreg.h 7.4 (Berkeley) 06/28/90 1132391Sbostic */ 1232391Sbostic 1337098Sbostic #ifndef COMPAT_42 1437098Sbostic #define COMPAT_42 1537098Sbostic #endif 1637098Sbostic 1733166Sbostic #define HDC_READ 0 1833166Sbostic #define HDC_WRITE 1 1937098Sbostic 2033166Sbostic #define HDC_MAXBUS 2 /* max# buses */ 2133166Sbostic #define HDC_MAXCTLR 21 /* max# hdc controllers per bus */ 2233166Sbostic #define HDC_MAXDRIVE 4 /* max# drives per hdc controller */ 2337098Sbostic #define HDC_MAXMCBS 32 /* max# mcb's the hdc can handle */ 2437098Sbostic #define HDC_MAXCHAIN 64 /* max# of data chains */ 2537098Sbostic #define HDC_MAXBC 64*1024 /* max# byte count per data chain */ 2637098Sbostic #define HDC_MAXFLAWS 8000 /* max# flaws per hdc disk */ 2737098Sbostic 2833166Sbostic #define HDC_SPB 2 /* sectors per block for hdc's */ 2933166Sbostic #define HDC_VDATA_SIZE 16 /* vendor data size (long words) */ 3037098Sbostic 3137098Sbostic #define HDC_REG(x) (hd->reg->x) /* set an HDC register */ 3232391Sbostic /* number of blocks per dump record */ 3337098Sbostic #define HDC_DUMPSIZE (HDC_MAXBC/DEV_BSIZE*HDC_MAXCHAIN) 3432391Sbostic 3532391Sbostic /* 3637098Sbostic * These are the 4 hdc i/o register addresses. Writing to "master_mcb" 3737098Sbostic * tells the hdc controller where the master mcb is and initiates hdc 3837098Sbostic * operation. The hdc then reads the master mcb and all new mcb's in the 3937098Sbostic * active mcb queue. Writing to "module_id" causes the hdc to return the 4037098Sbostic * hdc's module id word in the location specified by the address written 4137098Sbostic * into the register. "soft_reset" causes orderly shutdown of HDC; it's 4237098Sbostic * unclear from the manual what "hard_reset" does, but it should never be 4337098Sbostic * used as use while the HDC is active may cause format errors. 4432391Sbostic */ 4537098Sbostic struct registers { 4637098Sbostic u_long master_mcb, /* set the master mcb address */ 4737098Sbostic module_id, /* returns hdc's module id (hdc_mid) */ 4837098Sbostic soft_reset, /* shut down the hdc */ 4937098Sbostic hard_reset; /* send a system reset to the hdc */ 5037098Sbostic }; 5132391Sbostic 5232391Sbostic /* 5337098Sbostic * Definition for the module id returned by the hdc when "module_id" 5437098Sbostic * is written to. The format is defined by the hdc microcode. 5532391Sbostic */ 5637098Sbostic #define HID_HDC 0x01 /* hvme_id for HDC */ 5737098Sbostic #define HDC_MID HID_HDC /* module id code for hdc's */ 5837098Sbostic struct module_id { 5937098Sbostic u_char module_id, /* module id; hdc's return HDC_MID */ 6037098Sbostic reserved, 6137098Sbostic code_rev, /* micro-code rev#; FF= not loaded */ 6237098Sbostic fit; /* FIT test result; FF= no error */ 6337098Sbostic }; 6432391Sbostic 6532391Sbostic /* 6637098Sbostic * This structure defines the mcb's. A portion of this structure is used 6737098Sbostic * only by the software. The other portion is set up by software and sent 6837098Sbostic * to the hdc firmware to perform an operation; the order of this part of 6937098Sbostic * the mcb is determined by the controller firmware. 7032391Sbostic * 7137098Sbostic * "context" is the software context word. The hdc firmware copies the 7237098Sbostic * contents of this word to the master mcb whenever the mcb has been 7337098Sbostic * completed. The virtual address of the mcb is usually saved here. 7432391Sbostic * 7537098Sbostic * "forw_phaddr" forms a linked list of mcbs. The addresses are physical 7632391Sbostic * since they are used by the hdc firmware. 7732391Sbostic * 7837098Sbostic * Bits in device control word #1 define the hdc command and control the 7937098Sbostic * operation of the hdc. Bits in device control word #2 define the disk 8037098Sbostic * sector address for the operation defined in control word #1. 8132391Sbostic */ 8237098Sbostic #define LWC_DATA_CHAIN 0x80000000 /* mask for data chain bit in wcount */ 8337098Sbostic struct mcb { 8437098Sbostic u_long forw_phaddr; /* phys address of next mcb */ 8537098Sbostic u_int priority : 8, /* device control word #1 */ 8637098Sbostic interrupt : 1, /* " */ 8737098Sbostic drive : 7, /* " */ 8837098Sbostic command : 16, /* " (see HCMD_) */ 8937098Sbostic cyl : 13, /* device control word #2 */ 9037098Sbostic head : 9, /* " */ 9137098Sbostic sector : 10; /* " */ 9237098Sbostic u_long r1, r2, 9337098Sbostic context; /* software context word */ 9437098Sbostic struct chain { 9537098Sbostic long wcount, /* word count */ 9637098Sbostic memadr; /* transfer address */ 9737098Sbostic } chain[HDC_MAXCHAIN]; /* data chain */ 9833166Sbostic }; 9933166Sbostic /* defines for the "command"s */ 10033166Sbostic #define HCMD_STATUS 0x40 /* command: read drive status */ 10133166Sbostic #define HCMD_READ 0x60 /* command: read data */ 10237098Sbostic #define HCMD_VENDOR 0x6a /* command: read vendor data */ 10337098Sbostic #define HCMD_VERIFY 0x6d /* command: verify a track */ 10433166Sbostic #define HCMD_WRITE 0x70 /* command: write data */ 10537098Sbostic #define HCMD_FORMAT 0x7e /* command: format a track */ 10637098Sbostic #define HCMD_CERTIFY 0x7f /* command: certify a track */ 10737098Sbostic #define HCMD_WCS 0xd0 /* command: write control store */ 10832391Sbostic 10932391Sbostic /* 11032391Sbostic * This structure defines the master mcb - one per hdc controller. 11132391Sbostic * The order of this structure is determined by the controller firmware. 11232391Sbostic * "R" and "W" indicate read-only and write-only. 11332391Sbostic * 11432391Sbostic * Bits in the module control long word, "mcl", control the invocation of 11532391Sbostic * operations on the hdc. 11632391Sbostic * 11737098Sbostic * The hdc operates in queued mode or immediate mode. In queued mode, it 11837098Sbostic * grabs new mcb's, prioritizes them, and adds them to its queue; it knows 11937098Sbostic * if we've added any mcb's by checking forw_phaddr to see if any are 12037098Sbostic * linked off of there. 12132391Sbostic * 12232391Sbostic * Bits in the master mcb's status word, "mcs", indicate the status 12337098Sbostic * of the last-processed mcb. The MCS_ definitions define these bits. 12432391Sbostic * This word is set to zero when the mcb queue is passed to the hdc 12532391Sbostic * controller; the hdc controller then sets bits in this word. 12632391Sbostic * We cannot modify the mcb queue until the hdc has completed an mcb 12732391Sbostic * (the hdc sets the MCS_Q_DONE bit). 12832391Sbostic * 12932391Sbostic * The "context" word is copied from the context word of the completed 13037098Sbostic * mcb. It is currently the virtual pointer to the completed mcb. 13132391Sbostic */ 13233166Sbostic /* definition of master mcb "mcl" */ 13333166Sbostic #define MCL_QUEUED 0x00000010 /* start queued execution of mcb's */ 13433166Sbostic #define MCL_IMMEDIATE 0x00000001 /* start immediate xqt of an mcb */ 13533166Sbostic /* definition of master mcb "mcs" */ 13633166Sbostic #define MCS_DONE 0x00000080 /* an mcb is done; status is valid */ 13733166Sbostic #define MCS_FATALERROR 0x00000002 /* a fatal error occurred */ 13833166Sbostic #define MCS_SOFTERROR 0x00000001 /* a recoverable error occurred */ 13932391Sbostic 14037098Sbostic struct master_mcb { 14137098Sbostic u_long mcw, /* W module control word (MCL_) */ 14237098Sbostic interrupt, /* W interrupt acknowledge word */ 14337098Sbostic forw_phaddr, /* W physical address of first mcb */ 14437098Sbostic r1, r2, 14537098Sbostic mcs, /* R status for last completed mcb */ 14637098Sbostic cmcb_phaddr, /* W physical addr of completed mcb */ 14737098Sbostic context, /* W software context word */ 14837098Sbostic #define HDC_XSTAT_SIZE 128 /* size of extended status (lwords) */ 14937098Sbostic xstatus[HDC_XSTAT_SIZE];/* R xstatus of last mcb */ 15037098Sbostic }; 15137098Sbostic 15232391Sbostic /* 15337098Sbostic * This structure defines the information returned by the hdc controller for 15437098Sbostic * a "read drive status" (HCMD_STATUS) command. The format of this structure 15537098Sbostic * is determined by the hdc firmware. r[1-11] are reserved for future use. 15632391Sbostic */ 15733166Sbostic /* defines for drive_stat drs word */ 15833166Sbostic #define DRS_FAULT 0x00000080 /* drive is reporting a fault */ 15933166Sbostic #define DRS_RESERVED 0x00000040 /* drive is reserved by other port */ 16033166Sbostic #define DRS_WRITE_PROT 0x00000020 /* drive is write protected */ 16133166Sbostic #define DRS_ON_CYLINDER 0x00000002 /* drive heads are not moving now */ 16233166Sbostic #define DRS_ONLINE 0x00000001 /* drive is available for operation */ 16332391Sbostic 16437098Sbostic struct status { 16537098Sbostic u_long drs, /* drive status (see DRS_) */ 16637098Sbostic r1, r2, r3; 16737098Sbostic u_short max_cyl, /* max logical cylinder address */ 16837098Sbostic max_head, /* max logical head address */ 16937098Sbostic r4, 17037098Sbostic max_sector, /* max logical sector address */ 17137098Sbostic def_cyl, /* definition track cylinder address */ 17237098Sbostic def_cyl_count, /* definition track cylinder count */ 17337098Sbostic diag_cyl, /* diagnostic track cylinder address */ 17437098Sbostic diag_cyl_count, /* diagnostic track cylinder count */ 17537098Sbostic max_phys_cyl, /* max physical cylinder address */ 17637098Sbostic max_phys_head, /* max physical head address */ 17737098Sbostic r5, 17837098Sbostic max_phys_sector, /* max physical sector address */ 17937098Sbostic r6, 18037098Sbostic id, /* drive id (drive model) */ 18137098Sbostic r7, 18237098Sbostic bytes_per_sec, /* bytes/sector -vendorflaw conversn */ 18337098Sbostic r8, 18437098Sbostic rpm; /* disk revolutions per minute */ 18537098Sbostic u_long r9, r10, r11; 18637098Sbostic }; 18737098Sbostic 18837098Sbostic #ifdef COMPAT_42 18937098Sbostic #define GB_ID "geometry" 19037098Sbostic #define GB_ID_LEN sizeof(GB_ID)-1 19137098Sbostic #define GB_MAXPART 8 19237098Sbostic #define GB_VERSION 1 19337098Sbostic 19437098Sbostic #define HDC_DEFPART GB_MAXPART-1 /* partition# of def and diag cyls */ 19537098Sbostic #define BPS 512 /* bytes per sector */ 19637098Sbostic 19732391Sbostic /* 19837098Sbostic * Geometry Block: 19937098Sbostic * 20037098Sbostic * The geometry block defines partition offsets and information about the 20137098Sbostic * flaw maps on the flaw map track. It resides on the first sector of the 20237098Sbostic * flaw map track. This structure is also used by vddc disk controllers. 20337098Sbostic * In this case, the block resides at sector 0 of the disk. 20437098Sbostic * 20537098Sbostic * The geometry_sector structure defines the sector containing the geometry 20637098Sbostic * block. This sector is checksumed independent of the geometry information. 20737098Sbostic * The fields in these structured which should never be moved are the id and 20837098Sbostic * version fields in the geometry_block structure and the checksum field in 20937098Sbostic * the geometry_sector structure. This will provide for easy extensions in 21037098Sbostic * the future. 21132391Sbostic */ 21232391Sbostic 21337098Sbostic #define DRIVE_TYPE flaw_offset /* For VDDC Geometry Blocks Only */ 21437098Sbostic 21532391Sbostic typedef struct { 21637098Sbostic char id[GB_ID_LEN]; /* identifies the geometry block */ 21737098Sbostic long version, /* geometry block version number */ 21837098Sbostic flaw_offset, /* flaw map byte offset in partition7 */ 21937098Sbostic flaw_size, /* harris flaw map size in bytes */ 22037098Sbostic flaw_checksum, /* sum of bytes in harris flaw map */ 22137098Sbostic unused[3]; /* --- available for use */ 22237098Sbostic struct par_tab { 22337098Sbostic long start, /* starting 1K block number */ 22437098Sbostic length; /* partition size in 1K blocks */ 22537098Sbostic } partition[GB_MAXPART]; /* partition definitions */ 22637098Sbostic } geometry_block; 22732391Sbostic 22837098Sbostic typedef struct { 22937098Sbostic geometry_block geometry_block; /* disk geometry */ 23037098Sbostic char filler[BPS - sizeof(geometry_block) - sizeof(long)]; 23137098Sbostic long checksum; /* sector checksum */ 23237098Sbostic } geometry_sector; 23337098Sbostic 23432391Sbostic /* 23537098Sbostic * GB_CHECKSUM: 23637098Sbostic * 23737098Sbostic * This macro computes the checksum for the geometry sector and returns the 23837098Sbostic * value. Input to this macro is a pointer to the geometry_sector. Pretty 23937098Sbostic * useless, should at least have done an XOR. 24032391Sbostic */ 24137098Sbostic #define GB_CHECKSUM(_gs_ptr, _checksum) { \ 24237098Sbostic register u_char *_ptr; \ 24337098Sbostic register u_long _i, _xsum; \ 24437098Sbostic _xsum = 0; \ 24537098Sbostic _ptr = (u_char *)(_gs_ptr); \ 24637098Sbostic for (_i = 0; _i < (sizeof(geometry_sector) - sizeof(long)); _i++) \ 24737098Sbostic _xsum += * _ptr++; \ 24837098Sbostic _checksum = _xsum; \ 24937098Sbostic } 25037098Sbostic #endif /* COMPAT_42 */ 251