#sccs "@(#)uts/kern/sys:gdisk.h 1.4" /* Convergent Technologies - System V - May 1983 */ #ifndef gdisk_h #define gdisk_h #include "sys/buf.h" #include "sys/iobuf.h" #define FALSE 0 #define TRUE 0xff #define DISKS 3 /* the number of disks on s4 */ #define MINIDENSITY 2 /* s4 floppy disks are double density */ #define GDRETRIES 15 /* 15 retries to recover operation */ #define GAPSZ 36 /* size of gap1 and gap3 for format */ /* defines for manipulating the minor node number */ #define DRVSHIFT 4 /* slice number occupies the ls 4 bits */ #define DRVMSK 3 /* drive number is 2 bits */ #define SLCMSK 0xF /* slice number is 4 bits */ #define MAXSLICE 16 /* maximum number of slices */ /* bit ops to isolate fields in minor number */ #define gddrive(X) ((X>>DRVSHIFT)&DRVMSK) #define gdslice(X) (X&SLCMSK) /* * data describing disk specific information held in the VHB and then * loaded into the gdsw table */ struct gdswprt { char name[6]; /* printf name */ ushort cyls; /* the number of cylinders for this disk */ ushort heads; /* number of heads per cylinder */ ushort psectrk; /* number of physical sectors per track */ ushort pseccyl; /* number of physical sectors per cylinder */ char flags; /* floppy density and high tech drive flags */ char step; /* stepper motor rate to controller */ ushort sectorsz; /* physical sector size in bytes */ }; /* flags in gdswprt */ #define FPDENSITY 0x01 /* 0=single 1=double density */ #define FPMIXDENS 0x02 /* 0=all tracks are the same density 1= cylinder zero is single density */ #define HITECH 0x04 /* 0= reduced write current is valid, 1= head select bit 3 is valid */ #define NEWPARTTAB 0x08 /* 0= old style partition table, 1= new style partition table */ /* disk slice table */ struct partit{ /* partition table */ union { uint strk; /* start track number (new style) */ struct { ushort strk; /* start track # */ ushort nsecs; /* # logical blocks available to user */ } old; } sz; }; /* disk slice table in memory */ struct mpartit{ /* partition table */ uint strk; /* start track # */ uint nsecs; /* # of logical sectors available to user */ }; /* bad block cell on disk */ struct bbcell { ushort cyl; /* the cylinder of the bad block */ ushort badblk; /* the physical sector address of the bad block within the cylinder cyl */ ushort altblk; /* track number of alternate */ ushort nxtind; /* index into the cell array for next bad block cell for this cylinder */ }; /* bad block cell in memory */ struct bbmcell { ushort badblk; /* the physical sector address of the bad block within the cylinder cyl */ ushort altblk; /* track number of alternate */ char nxtind; /* index into the cell array for next bad block cell for this cylinder */ }; /* internal switch for various disk parameters and device specific routines */ /* table initialization is in gdtab.c */ /* indexed into by gddtab[n].btype */ struct gdsw { uint v_flags; /* flags for this drive/disk */ struct gdswprt dsk; /* disk specific information */ ushort curcyl; /* current cylinder number */ ushort reqcyl; /* cylinder number required for this transfer */ ushort sectrk; /* actual number of physical data sectors in the logical map per track. i.e omitting the alternate sectors located in the 17th sector of each track */ ushort seccyl; /* actual number of physical data sectors in the logical map per cylinder. i.e omitting the alternate sectors located in the 17th sector of each track */ ushort DMAto; /* max duration of a disk operation (1/4 sec units) */ int (*intr)(); int (*start)(); /* more volume home block information */ ushort szbbq; /* size of bad block cylinder index */ ushort szbb; /* size of bad block table */ char *bbq; /* bad block cylinder index */ struct bbmcell *bb; /* bad block table */ struct mpartit partab[MAXSLICE]; /* partition table */ }; #define MNAMSZ 40 /* max length of name including null terminator */ struct mntnam { char name[MNAMSZ]; /* full path name of mount point */ }; /* volume home block on disk */ struct vhbd { uint magic; /* S4 disk format code */ int chksum; /* adjustment so that the 32 bit sum starting from magic for 512 bytes sums to -1 */ struct gdswprt dsk; /* specific description of this disk */ struct partit partab[MAXSLICE]; /* partition table */ struct resdes{ /* reserved area special files */ daddr_t blkstart; /* start logical block # */ ushort nblocks; /* length in logical blocks (zero implies not present) */ } resmap[8]; /* resmap consists of the following entries: * loader area * bad block table * dump area * down load image file * Bootable program, size determined by a.out format. nblocks=1. */ char fpulled; /* dismounted last time? */ struct mntnam mntname[MAXSLICE]; /* names for auto mounting. null string means no auto mount */ long time; /* time last came on line */ short cpioMagic, /* for cpio backup, restore */ setMagic, cpioVol; }; #define VHBMAGIC 0x55515651 /* magic number in disk vhb */ /* indexes into resmap */ #define INDLOADER 0 #define INDBBTBL 1 #define INDDUMP 2 #define INDDOWNLOAD 3 #define INDBOOT 4 /* values for hwtype */ #define HD 0 /* Winchester */ #define HD2 1 /* Second winchester */ #define SY 1 /* Syquest */ #define FD 2 /* floppy */ /* values of flag bits in v_flags */ #define F_OPENED 0x0001 /* set when the first open is performed for any slice on this disk, cleared when the drive goes off line - indicates an attempt has been made to read the vhb */ #define F_CT_FMT 0x0002 /* a valid vhb has been read for this disk, this implies logical block=1024 bytes and bad block handling */ #define F_READY 0x0004 /* ready from controller */ #define F_PULLED 0x0008 /* disk was removed without permission last time, produces warning on open */ #define PHYS_ADDR 0x0010 /* alien disk. gdswprt supplied via ioctl. the flag is set by ioctl for reading non standard floppies. cleared by close. slice 0 is the only valid one */ /* in this mode the offset number is the physical sector number <<10, whether sector size is 1024, 512, 256 or 128. count is still the number of bytes. */ #define F_MAYREMOVE 0x0020 /* the drive may go off line */ #define WR_PROT 0x0040 /* set after each transfer. 1=write protected disk. 0=not protected */ #define F_FMT 0x0080 /* True while formatting a disk */ #define F_NORETRY 0x0100 /* no retry bit - set by GDRETRY ioctl */ #define F_LOCK 0x0200 /* Floppy lock bit */ /* bad block table */ /* * On the disk the bad block table consists of an array of cells, one per * used alternate physical sector. * cyl is the cylinder containing the bad block badblk. * badblk is the physical sector address (within the cylinder cyl) * of a bad block. * altblk is the location of the alternate physical sector. It is * specified as the track number since the alternate sector is * always the last sector of a track. * nxtind is a chain of bad blocks on the same cylinder. The number is * the index into this array of bad block cells. A value of zero * means the end of the chain for this cylinder. The zero'th * entry is not used, other than to hold the count of used cells). * * * In memory a similar array will be held in the appropriate gdbtab * together with an array containing an entry for each cylinder which * holds the index into the above array of cells for the head for that * cylinder. * This means that a zero entry indicates no bad blocks on that cylinder. * * This mechanism implies a maximum of 255 bad blocks per disk which is * adequate for disks upto the 250 Mbyte range. * The bad block table is held as a chained set of logical blocks on * track zero. Each block can hold 256 entries. * The first bad block cell in each logical block of the bad block table * contains a chksum (in cyl and badblk) for the 1024 byte block, it is * a 32 bit sum which sums to -1. altblk contains the logical block * number of the next block in the bad block table, zero=end. * On a disk with an odd number of sectors per track, the last sector * is removed from the logical mapping and is used as an alternate area. * * Bad block handling is disabled on floppies. */ #define HDMAXBADBLK 128 /* only support maximum of 128 bad blocks */ #define HDMAXCYL 1400 /* support a maximum of 1400 cylinders */ #define FPMAXBADBLK 0 /* no bad block support on floppies */ #define FPMAXCYL 0 /* no bad block support on floppies */ /* this structure contains the relevant information about the transfer * currently in progress. */ struct driver { /* ******* d_flags + ctl are accessed by assembly code in trap.s ******* */ /* ******* do not change their sizes, locations or contents without **** */ /* ******* checking their use in trap.s. ***** */ ushort d_flags; /* driver flags */ char ctl; /* controller number */ char retries; /* number of retries remaining for this operation before we give up */ int fd_timer; /* fd motor on timer */ ushort timer; /* timer for operation completion */ struct xfrinfo x; /* details of the current required transfer */ struct xfrinfo rpt; /* details of the current real transfer */ /* information for repeating a transfer (needed because of bad blocks) */ ushort rptcyl; ushort rpttrk; ushort rptsec; ushort rpttcnt; dev_t disk; /* current device for transfer */ int xfrcnt; /* count of characters transferred so far */ union { /* holds virtual address in Kernel address */ caddr_t b_addr; /* space that is mapped to correspond with */ struct { /* the address in bp->a_un */ ushort high; ushort low; } addr; } c_un; ushort rpts; /* total transfers for complete request */ }; /* values in d_flags */ #define F_ACTIVE (ushort)0x0001 /* driver operation in progress */ #define F_DMAON (ushort)0x0002 /* DMA operation in progress */ #define F_SEEKING (ushort)0x0004 /* seek operation in progress */ #define FDMTRON (ushort)0x0008 /* floppy motor is on + up to speed */ #define FDMTRSTRT (ushort)0x0010 /* the floppy motor has been started but is not up to speed yet */ #define FDCHECKED (ushort)0x0020 /* set when floppy has been verified as still being the same one that was on line before the motor was turned off */ #define MAYGETFDINT (ushort)0x0040 /* on reseting the floppy the 2797 may or may not choose to give an interrupt, so be prepared to discard it */ #define FDSPECIALRD (ushort)0x0080 /* a read of the vhb from dismount caused a special read to be be performed in the disk driver while checking if the floppy had been changed */ #define FDNEWQ (ushort)0x0100 /* new disk maybe so use recal to establish head position */ #define FD_TIMEOUT (ushort)0x0200 /* a timeout occurred on a floppy transfer, floppy not in or in backwards - so terminate with error*/ #define F_NOTOUCH (ushort)0x0400 /* Used by gfdchk to determine the safety in polling disk controller */ #define F_MSG (ushort)0x0800 /* To avoid multiple eprintfs in gfpchk */ #define F_HD_DMA (ushort)0x1000 #define F_FD_DMA (ushort)0x2000 /* values in ctl (supplied from assembly interrupt code) */ #define WD2797 1 #define WD1010 0 #define BIU 2 extern struct driver gdreal; extern struct gdsw gdsw[]; extern struct iotime gdstat[]; extern struct iobuf gdtab, gdutab[]; extern char gdourunflg; /* flag indicating disk over/under run */ extern ushort dcr_save; /* Image of disk control register. */ extern char dma_flag; /* TRUE when dma is enabled */ #define GDPRI (PZERO - 3) /* * Internal commands */ #define CMD_READ ((char)0) #define CMD_WRITE ((char)1) #define CMD_FORMAT ((char)2) /* * Command information for WD1010. */ #define H_ERRFLAGS 0x01 #define H_PRECOMP 0x01 #define H_SECCNT 0x02 #define H_SECNUM 0x03 #define H_CYLLOW 0x04 #define H_CYLHIGH 0x05 #define H_SDH 0x06 #define H_COMMANDREG 0x07 #define H_STATUSREG 0x07 #define HDMASK 0x0007 /* 3 bits for head size */ #define W_RESTORE 0x0010 /* restore command */ #define W_SEEK 0x0070 /* seek command */ #define W_READ 0x0020 /* read sector command */ #define W_WRITE 0x0030 /* write sector command */ #define W_SCANID 0x0040 /* scan id command */ #define W_WR_FORMAT 0x0050 /* write format command */ #define W_RATEMSK 0x000F /* LS 4 bits of restore/seek command = rate */ #define W_MULT 0x0004 /* multi sector transfer flag for read/write */ #define W_INTEOC 0x0008 /* interrupt at end of command (read only) */ #define W_NORETRY 0x0001 /* Disable automatic retries */ /* * Status information for WD1010. */ #define W_ERR 0x0001 /* logical or of bits in the error register */ #define W_CIP 0x0002 /* 1= command in progress */ #define W_DRQ 0x0008 /* 1= data request outstanding */ #define W_SEKCMP 0x0010 /* 1= seek complete */ #define W_WRFLT 0x0020 /* 1= write fault */ #define W_RDY 0x0040 /* 1= ready,frozen on error until status read */ #define W_BUSY 0x0080 /* 1= WD1010 is accessing the disk */ /* * Error status information for the WD1010. */ #define W_BBD 0x0080 /* bad block detected (not used) */ #define W_CRC 0x0040 /* 1= CRC error */ #define W_ID 0x0010 /* 1= id not found */ #define W_ABC 0x0004 /* 1= aborted command */ #define W_TK 0x0002 /* 1= restore command did not find track zero */ /* * Command information for the WD2797. */ #define F_COMMANDREG 0x00 #define F_STATUSREG 0x00 #define F_TRACKREG 0x01 #define F_SECTORREG 0x02 #define F_DATAREG 0x03 #define F_RESTORE 0x0000 /* restore command */ #define F_SEEK 0x0010 /* seek command */ #define F_STEP 0x0020 /* step command */ #define F_STEPIN 0x0040 /* step-in command */ #define F_STEPOUT 0x0060 /* step-out command */ #define F_READ 0x0080 /* read sector command */ #define F_WRITE 0x00a0 /* write sector command */ #define F_READADR 0x00c0 /* read address command */ #define F_READTRK 0x00e0 /* read track command */ #define F_WRITETRK 0x00f0 /* write track command */ #define F_FORCEINT 0x00d0 /* force interrupt command */ #define LOADHEAD 0x0008 /* 1= load head at beginning (restore,seek,step, step-in, step-out) */ #define VERIFYTRK 0x0004 /* 1= verify on destination track (restore,seek, step, step-in, step-out) */ #define STEPMSK 0x0003 /* stepping motor rate (restore,seek, step, step-in, step-out) */ #define F_UPDTRKRG 0x0010 /* 1= update track register (step, step-in, step-out) */ #define F_MULT 0x0010 /* 1= multiple record flag(read/write sector) */ #define F_LENGTH 0x0008 /* 1= lsb sector length in sector id field means 00=128 01=256 10=512 11=1024 (read/write sector) */ #define F_15MSDLY 0x0004 /* 1= 15MS delay(30 MS for 1MHZ) (read/write sector, read/write track and read address) */ #define F_UPDATESSO 0x0002 /* 1= update SSO to 1 (read/write sector, read/write track and read address) */ #define F_D_A_MRK 0x0001 /* data address mark (write sector) */ #define F_INT0 0x0001 /* force interrupt on not ready to ready transition. (force interrupt) */ #define F_INT1 0x0002 /* force interrupt on ready to not ready transition. (force interrupt) */ #define F_INT2 0x0004 /* force interrupt on index pulse. (force interrupt) */ #define F_INT3 0x0008 /* force interrupt immediately (requires reset). (force interrupt) */ #define F_INT_NO 0x0000 /* terminate with no interrupt.(force interrupt) /* * Status information for the WD2797. */ #define F_BUSY 0x0001 /* 1= command under execution */ #define F_DRQ 0x0002 /* 1= data request line */ #define F_LOSTDATA 0x0004 /* 1= CPU didn't respond to DRQ */ #define F_CRCERR 0x0008 /* 1= error in one or more id fields or an error in the data field */ #define F_RECNF 0x0010 /* 1= requested side,track, sector not found */ #define F_SEEKERR 0x0010 /* 1= seek error */ #define F_RECTYP 0x0020 /* 1= deleted data mark else data mark, on read. forced to zero on write. */ #define F_WRPROT 0x0040 /* 1= indicates a protected disk on write, not used on read */ #define F_NOTRDY 0x0080 /* 1= drive not ready */ #define F_TRK0 0x0004 /* 1= heads on track zero */ /* * down load file index. */ #define DLDSZ 256 struct dldent { short d_strt; /* block displacement from down load index */ short d_sz; /* # of blocks for this entry */ }; struct dldind { struct dldent dldent[DLDSZ]; }; /* GDSETOUCH */ /* gdsetouch sets the NOTOUCH flag. */ #define gdsetouch(flag)\ {\ gdreal.d_flags |= ( F_NOTOUCH | flag );\ } /* GDCLRTOUCH */ /* gdclrtouch clears the NOTOUCH flag, and wakes up any processes * waiting for the controller. */ #define gdclrtouch( flag )\ {\ gdreal.d_flags &= ~( F_NOTOUCH | flag );\ wakeup( (caddr_t)DISK_CNTRL );\ } #endif gdisk_h