/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986,1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:hdconfig.h 12.0$ */
/* $ACIS:hdconfig.h 12.0$ */
/* $Source: /ibm/acis/usr/sys/caio/RCS/hdconfig.h,v $ */

#if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsidhdconfig = "$Header:hdconfig.h 12.0$";
#endif

#ifndef CONFIG_BLOCK

#define CONFIG_BLOCK	1		/* block where configuration is */
#define CONFIG_BLOCK2(sectors)	((sectors)+13)		/* second block where configuration is */
#define BOOT_BLOCK	0		/* block for boot information */
#define CONFIG_MAGIC	0xF8E9DACB 	/* configuration record magic # */
/*
 * hard disk configuration format 
 */
struct hdconfig
{				/* manufacturers configuration record */
int	conf_magic;		/* 0: always 0xF8E9DACB */
int	conf_sectorcount;	/* 4: number of sectors on device */
short	conf_landing;		/* 8: reserved */
char	conf_interleave;	/* 10: interleave */
char	conf_sectsize;		/* 11: sectors size 02 = 512 */
short	conf_lastcyl;		/* 12: last data cylinder */
char	conf_lasttrack;		/* 14: last head number */
char	conf_lastsect;		/* 15: last sector number */
char	conf_precomp;		/* 16: precomp or 0xff */
#define NOPCMP	0xff
char	conf_status;		/* 17: used by loadable post */
short	conf_maxcyl;		/* 18: last physical cyl */
#define conf_ce_cyl conf_maxcyl
short	conf_end_of_life;	/* 20: max # bad blocks */
struct seek_curve {
	short seek_x;		/* x position (cylinders?) */
	short seek_y;		/* y position (milliseconds?) */
	short seek_slope;	/* slope millseconds/cylinder?) */
} conf_seek[5];			/* 22-51: seek curve characeristics */
short	conf_size;		/* approximate # megabytes */
char	conf_mfr;		/* mfr code */
char	conf_adapter;		/* 55: adapter type */
#define HD_ADAPTER_AT		0x00
#define HD_ADAPTER_ESDI		0x01
#define HD_ADAPTER_HESDI	0x02
short	conf_srn;		/* 56-57: service request num */
char	conf_label;		/* 58: ascii drive type id */
char	conf_skew;		/* 59: head switch sector skewing */
short	conf_hidmax;		/* 60-61: max # hidden defects */
char	conf_fill1[256-62];	/* fill up to halfway */
char	conf_name[8];		/* 256-263: name of disk (ACIS) */
char	conf_fill2[512-264];	/* fill up to the end */
				/* 512: total size */
} ;

struct hdcfg {	/* short form: has minimum needed to generate an hdconfig */
	char	cfg_interleave;		/* interleave */
	char	cfg_lasttrack;		/* last head number */
	char	cfg_lastsect;		/* last sector number */
	char	cfg_precomp;		/* precomp or 0xff */
	short	cfg_maxcyl;		/* last physical cyl */
	short	cfg_end_of_life;	/* max # of bad blocks */
	struct seek_curve cfg_seek[5];	/* seek curve characeristics */
	short	cfg_size;		/* approximate # megabytes */
	char	cfg_mfr;		/* mfr code */
	char	cfg_adapter;		/* adapter type */
	short	cfg_srn;		/* service request num */
	char	*cfg_name;		/* name of disk (ACIS) */
	char	cfg_skew;		/* # sectors skewed per track */
	short	cfg_hidmax;		/* max # of hidden blocks */
} ;
#define	CFG_M40	{2, 4, 17, 255, 1023, 0, {{0x14, 0x14cd, 0x13d}, {0x3c, 0x2500, 0x69}, {0x64, 0x2a00, 0x5a}, {0xc8, 0x3233, 0x3f}, {0, 0x4100, 0x29}}, 0x40, 2, 0, 0, "hd40m", 0, 0}
#define	CFG_R40	{2, 6, 17,  75,  732, 0x15e, {{0x19, 0x1f9a, 0x20e}, {0x37, 0x3b33, 0x87}, {0x64, 0x5100, 0x63}, {0xc8, 0x5300, 0x60}, {0, 0x7400, 0x31}}, 0x40, 1, 0, 0, "hd40r", 0, 0}
#define	CFG_C70	{2, 8, 17, 255,  924, 0, {{0xa, 0xf33, 0x239}, {0x19, 0x1ccd, 0xd4}, {0x32, 0x2666, 0x66}, {0x64, 0x2d9a, 0x41}, {0, 0x3200, 0x33}}, 0x70, 2, 0, 0, "hd70c", 0, 0}
#define	CFG_E70	{1, 6, 35, 255,  582, 0x230, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, 0x70, 3, 2, 0x3737, "hd70e", 0, 0}
#define	CFG_M70	{2, 7, 17, 255, 1023, 0, {{0x14, 0x14cd, 0x13d}, {0x3c, 0x2500, 0x69}, {0x64, 0x2a00, 0x5a}, {0xc8, 0x3233, 0x3f}, {0, 0x4100, 0x29}}, 0x70, 1, 0, 0, "hd70m", 0, 0}
#define	CFG_R70	{4, 6, 36, 255,  565, 0x230, {{0x14, 0x22cd, 0x100}, {0x32, 0x2a00, 0xab}, {0x64, 0x3466, 0x71}, {0xc8, 0x4200, 0x51}, {0, 0x4c00, 0x43}}, 0x70, 2, 1, 0, "hd70r", 0, 0}
#define	CFG_E114 {1, 6, 35, 255,  914, 0xb7, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, 0x114, 1, 2, 0x3736, "hd114e", 7, 0x384}
#define	CFG_E310 {1, 14, 33, 255,  1224, 0x12c, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, 0x310, 1, 2, 0x3531, "hd310e", 8, 0x8ca}
#define	CFG_H310 {1, 14, 34, 255,  1189, 0x109, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, 0x310, 8, 2, 0x3731, "hd310h", 0, 0x8ca}

#define BAD_BLOCK_START	8	/* start of bad block table (BBT) */
#ifdef ATR
#define MAXBADBLKS	100		/* max number of BBT entries */
#else
#define MAXBADBLKS	1000	/* max number of BBT entries */
#endif ATR

struct hdbad {
char hddefect[6];	/* "DEFECT" 	*/
short	hdcount;	/* count of entries in table */
struct hdmap {
	unsigned hdreason:8,	/* the reason block was unusable */
		hdbad:24;	/* the bad block number */
	int	hdgood;		/* the good block number */
	} hdmap[MAXBADBLKS];	/* the table of bad to good blocks */
} ;			/* the drives bad sector maps */

#define HDREASON_MFR	0x00	/* vendor found defect */
#define HDREASON_SURF	0xaa	/* surface verification found defect */
#define HDREASON_SYS	0xbb	/* operating system found defect */
#define HDREASON_MAN	0xcc	/* manufacturing found defect */

struct hdbadtmp {		/* like hdmap but with only 1 entry defined */
char hddefect[6];		/* "DEFECT" 	*/
short	hdcount;		/* count of entries in table */
struct hdmap hdmap[1];		/* the table of bad to good blocks */
} ;				/* the drives bad sector maps */

#define HID_DEFECT_HEAD	1	/* these define where the Hidden */
#define HID_DEFECT_SECT	18	/* 	Defect Table (HDT) starts */
#define MAXHIDBLKS	510	/* max number HDT entries */

struct hdhid {
	char hidden[6];		/* "HIDDEN" */
	short count;		/* # entries in table */
	struct hidmap {
		unsigned cyl : 16;	/* hidden bad block cylinder # */
		unsigned trk : 8;	/* hidden bad block track # (head #) */
		unsigned sec : 8;	/* hidden bad block sector # */
	} hidmap[MAXHIDBLKS];
} ;
#define IGNORE_HID 0xffffffff	/* deleted hidmap entry */

struct boothdr {
char	boot_ibma[4];		/* 0: IBMA in EBCDIC */
long	boot_check;		/* 4: reserved */
short	boot_lastcyl;		/* 8: last available cyl number */
char	boot_lasttrack;		/* 10: last track number */
char	boot_lastsect;		/* 11: last sector number */
short	boot_sectorsize;	/* 12-13: block/sector size (bytes) */
char	boot_reserved1[4];	/* 14-18: reserved */
char	boot_interleave;	/* 19: interleave factor */
char	boot_reserved2[3];	/* 20-23: reserved */
int	boot_sectorcount;	/* 24-27: disk size */
long	boot_formatdate;	/* 28-31: reserved */
short	boot_cyl;		/* 32-33: cyl number of boot */
char	boot_track;		/* 34: track number of boot */
char	boot_sector;		/* 35: sector to boot */
long	boot_length;		/* 36-39: length in sectors */
long	boot_entry;		/* 40-43: entry point */
long	boot_vrmminidisk;	/* 44-47: block number of vrm minidisk */
long	boot_llp;		/* 48-51: Loadlist processor block number */
long	boot_vrmlength;		/* 52-55: length of VRM minidisk */
char	boot_fill[512-56];	/* reserved */
} ;

/* predicate to test if a valid bad block table exists */
#define BAD_BLOCK_TABLE_OK(hdb) !((hdb)->hddefect[0] != 'D' || (hdb)->hddefect[1] != 'E' || \
	    (hdb)->hddefect[2] != 'F' || (hdb)->hddefect[3] != 'E' || \
	    (hdb)->hddefect[4] != 'C' || (hdb)->hddefect[5] != 'T' || \
	    (hdb)->hdcount < 0 || (hdb)->hdcount >= MAXBADBLKS) 

/* predicate to test if a valid hidden defect table exists */
#define HIDDEN_DEFECT_TABLE_OK(HD) !((HD)->hidden[0] != 'H' || (HD)->hidden[1] != 'I' || \
			    (HD)->hidden[2] != 'D' || (HD)->hidden[3] != 'D' || \
			    (HD)->hidden[4] != 'E' || (HD)->hidden[5] != 'N' || \
			    (HD)->count < 0 || (HD)->count >= MAXHIDBLKS)

/*
 * the following defines and structures relate to the VRM 
 * minidisk directory 
 */

#define ENDLIST -1	/* end of list marker */
#define START_BLOCK(sectors)	((sectors)*4)	/* start of allocatable space */
#define START_BLOCK_PS2ESDI(sectors)	16	/* start of allocatable space */

struct miniheader {
	long number;		/* number of entries */
	long level;		/* revision level */
	short unused;		/* index of next unused entry */
	short lastused;		/* index of entry most recently used */
	short first;		/* first entry */
	short last;		/* last entry index */
	long bad_block;		/* first bad block */
	long bad_size;		/* number of bad blocks */
	long unused2;		/* reserved */
	long unused3;		/* reserved */
};

struct minidisk {
	short previous;		/* 0 link to previous entry */
	short next;		/* 2 line to next entry */
	char name[4];		/* 4 name of minidisk */
	unsigned :32;		/* 8 */
	long date;		/* 12 the date of creation */
	short iodn;		/* 16 the IODN used */
#define nextfree iodn		/* 	hokey way of doing it! */
	char blocksize;		/* 18 filesystem block size (bits 0-3) */
#define BLOCK_512	0
#define BLOCK_1024	1
#define BLOCK_2048	3
	char type;		/* 19 type flags */
#define TYPE_RESERVED	0x80	/* reserved */
#define TYPE_NOBADBLOCK	0x40	/* no bad block forwarding on this disk */
#define TYPE_PAGE	0x20	/* pageing space */
#define TYPE_FILE	0x10	/* AIX file system */
#define TYPE_AIX	0x08	/* AIX system minidisk */
#define TYPE_PC		0x04	/* coprocessor disk */
#define TYPE_VRM	0x02	/* VRM */
#define TYPE_IPL	0x01	/* IPL'able */
	long unused;		/* 20 */
	long start;		/* 24 start block of partition */
	long size;		/* 28 size of partition */
				/* 32 total length */
};
#define ISFREE(disk) ((disk)->iodn == 0)

#ifdef KERNEL
#define MAXDISKS 23		/* keep size down for kernel use */
#else
#define MAXDISKS 47		/* actual minidisk size */
#endif KERNEL

#define MINIDISK_BLOCK	3	/* starting block number of minidisk */
#define MINIDISK_BLOCK2(sectors)	((sectors)+14)	/* starting block number of minidisk copy */
#define MINIDISK_BLOCK2_PS2ESDI(sectors)	13	/* starting block number of minidisk copy */
#define BLOCK_SIZE	512
#define ROUND(a,b) (a+b-1)/b*b	/* round up to next unit of b */

struct minidirectory {
struct miniheader header;
struct minidisk minidisk[MAXDISKS];
};

#ifdef ATR
struct diskinfo 		/* a nice structure to hold disk info */
  {
  ushort ncpd;			/* number of cylinders per drive */
  ushort ntpc;  		/* number of tracks per cylinder */          
  ushort pcmp;  		/* write pre-compensation cylinder */
  };


/* Defines for hdinfo */

/* flag defines */	
#define	HDINFO_PRESENT	0x0001	/* drive present */
#define	HDINFO_BADBLOCK	0x0002	/* bad block table read succesfully */
#define	HDINFO_42PART	0x0004	/* valid 4.3 parttion present */
#define	HDINFO_NOBRPT	0x0010	/* no boot record partition table */


#define BLOCK_SIZE 512
#define BOOTRECORD_BLOCK 0
#define BRPT_OFFSET 446
#endif ATR

#define NPART	8		

struct partab {

	daddr_t len;		       /* # of blocks in partition */
	int start;		       /* starting cylinder of partition */

};

#endif CONFIG_BLOCK
