home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OpenStep 4.2J (Developer)
/
os42jdev.iso
/
NextDeveloper
/
Headers
/
bsd
/
dev
/
fd_extern.h
< prev
next >
Wrap
Text File
|
1997-04-27
|
19KB
|
699 lines
/* @(#)fd_extern.h 2.0 01/25/90 (c) 1990 NeXT
*
* fd_vars.h -- Externally used data structures and constants for Floppy
* Disk driver
*
* KERNEL VERSION
*
* HISTORY
* 13-May-94 Dean Reece
* Added define and struct for FDIOCGCAPLIST to return possible
* format densities. Enables workspace to build a menu.
* 20-Mar-91 Doug Mitchell
* Made #importing pmap.h and vm_map.h dependent on #ifdef KERNEL.
* 25-Jan-90 Doug Mitchell at NeXT
* Created.
*
*/
#ifndef _FDEXTERN_
#define _FDEXTERN_
#import <sys/types.h>
#import <sys/ioctl.h>
#import <mach/boolean.h>
#import <mach/vm_param.h>
#define FD_CMDSIZE 0x10 /* max size of command passed to
* controller */
#define FD_STATSIZE 0x10 /* max size of status array returned
* from controller */
#define FD_MAX_CAP_LIST 8
typedef int fd_return_t; /* see FDR_xxx, below */
struct fd_drive_stat {
u_char media_id:2, /* media type currently inserted. See
* FD_MID_xxx, below. */
motor_on:1, /* state of motor at I/O complete
* 1 = on; 0 = off */
write_prot:1, /* write protect 1 = Write Protected */
drive_present:1,
rsvd1:3; /* reserved */
};
/*
* Format Capacity List struct. Returned by FDIOCGCAPLIST ioctl as a list
* of possible format capacities. Entries are possible capacities
* in 1k (1024) units. List is null terminated, so the useful size is
* (FD_MAX_CAP_LIST - 1).
*/
struct fd_cap_list {
int capacity[FD_MAX_CAP_LIST];
};
/*
* I/O request struct. Used in DKIOCREQ ioctl to specify one command sequence
* to be executed.
*/
struct fd_ioreq {
/*
* inputs to driver:
*/
u_char density; /* see FD_DENS_xxx, below */
int timeout; /* I/O timeout in milliseconds. Used
* in FDCMD_CMD_XFR commands only. */
int command; /* see FDCMD_xxx, below */
u_char cmd_blk[FD_CMDSIZE];
/* actual command bytes */
u_int num_cmd_bytes; /* expected # of bytes in cmd_blk[] to
* transfer */
caddr_t addrs; /* source/dest of data */
u_int byte_count; /* max # of data bytes to move */
u_char stat_blk[FD_STATSIZE];
/* status returned from controller */
u_int num_stat_bytes; /* number of status bytes to transfer
* to stat_blk[] */
int flags; /* see FD_IOF_xxx, below */
/*
* outputs from driver:
*/
fd_return_t status; /* FDR_SUCCESS, etc. */
u_int cmd_bytes_xfr; /* # of command bytes actually moved */
u_int bytes_xfr; /* # of data bytes actually moved */
u_int stat_bytes_xfr; /* # if status bytes moved to
* stat_blk[] */
struct fd_drive_stat drive_stat; /* media ID, etc. */
/*
* used internally by driver
*/
struct pmap *pmap; /* DMA is mapped by this */
struct vm_map *map; /* map of requestor's task */
u_char unit; /* drive # (relative to controller) */
};
typedef struct fd_ioreq fdIoReq_t;
typedef struct fd_ioreq *fd_ioreq_t;
/*
* fd_ioreq.command values
*/
#define FDCMD_BAD 0x00 /* not used */
#define FDCMD_CMD_XFR 0x01 /* transfer command in fd_ioreq.cmd_blk
*/
#define FDCMD_EJECT 0x02 /* eject disk */
#define FDCMD_MOTOR_ON 0x03 /* motor on */
#define FDCMD_MOTOR_OFF 0x04 /* motor off */
#define FDCMD_GET_STATUS 0x05 /* Get status (media ID, motor state,
* write protect) */
/*
* fd_ioreq.density values. Some routines rely on these being in
* cardinal order...
*/
#define FD_DENS_NONE 0 /* unformatted */
#define FD_DENS_1 1 /* 1 MByte/disk unformatted */
#define FD_DENS_2 2 /* 2 MByte/disk unformatted */
#define FD_DENS_4 3 /* 4 MByte/disk unformatted */
#if i386
#define FD_DENS_DEFAULT FD_DENS_2
#else
#define FD_DENS_DEFAULT FD_DENS_4
#endif
/*
* fd_ioreq.flags values
*/
#define FD_IOF_DMA_DIR 0x00000002
#define FD_IOF_DMA_RD 0x00000002 /* DMA direction = device to
* host */
#define FD_IOF_DMA_WR 0x00000000 /* DMA direction = host to
* device */
/*
* fdr_return_t values
*/
#define FDR_SUCCESS 0 /* OK */
#define FDR_TIMEOUT 1 /* fd_ioreq.timeout exceeded */
#define FDR_MEMALLOC 2 /* couldn't allocate memory */
#define FDR_MEMFAIL 3 /* memory transfer error */
#define FDR_REJECT 4 /* bad field in fd_ioreq */
#define FDR_BADDRV 5 /* drive not present */
#define FDR_DATACRC 6 /* media error - data CRC */
#define FDR_HDRCRC 7 /* media error - header CRC */
#define FDR_MEDIA 8 /* misc. media error */
#define FDR_SEEK 9 /* seek error */
#define FDR_BADPHASE 10 /* controller changed phase
* unexpectedly */
#define FDR_DRIVE_FAIL 11 /* Basic Drive Failure */
#define FDR_NOHDR 12 /* Header Not Found */
#define FDR_WRTPROT 13 /* Disk Write Protected */
#define FDR_NO_ADDRS_MK 14 /* Missing Address Mark */
#define FDR_CNTRL_MK 15 /* Missing Control Mark */
#define FDR_NO_DATA_MK 16 /* Missing Data Mark */
#define FDR_CNTRL_REJECT 17 /* controller rejected command */
#define FDR_CNTRLR 18 /* Controller Handshake Error */
#define FDR_DMAOURUN 19 /* DMA Over/underrun */
#define FDR_VOLUNAVAIL 20 /* Requested Volume not available */
#define FDR_ALIGN 21 /* DMA alignment error */
#define FDR_DMA 22 /* DMA error */
#define FDR_SPURIOUS 23 /* spurious interrupt */
/*
* fd_drive_stat.media_id values
*/
#define FD_MID_NONE 0 /* no disk inserted */
#define FD_MID_1MB 3 /* 1 MByte unformatted */
#define FD_MID_2MB 2 /* 2 MByte unformatted */
#define FD_MID_4MB 1 /* 4 MBytes unformatted */
#if i386 || hppa
#define FD_MID_DEFAULT FD_MID_2MB
#ifdef KERNEL /* Maximum Number of bytes of data
that can be transfered via DMA
using FDIOCREQ ioctl command
*/
#define FD_MAX_DMA_SIZE PAGE_SIZE
#else
#define FD_MAX_DMA_SIZE vm_page_size
#endif KERNEL
#endif i386 || hppa
/*
* ioctl's specific to floppy disk
*/
#define FDIOCREQ _IOWR('f', 0, struct fd_ioreq) /* cmd request */
#define FDIOCGFORM _IOR ('f', 1, struct fd_format_info)
/* get format */
#define FDIOCSDENS _IOW ('f', 2, int) /* set density */
#define FDIOCSSIZE _IOW ('f', 3, int) /* set sector size */
#define FDIOCSGAPL _IOW ('f', 4, int) /* set Gap 3 length */
#define FDIOCRRW _IOWR('f', 5, struct fd_rawio) /* raw read/write */
#define FDIOCSIRETRY _IOW ('f', 6, int) /* set inner retry loop
* count */
#define FDIOCGIRETRY _IOR ('f', 7, int) /* get inner retry loop
* count */
#define FDIOCSORETRY _IOW ('f', 8, int) /* set outer retry loop
* count */
#define FDIOCGORETRY _IOR ('f', 9, int) /* get outer retry loop
* count */
#define FDIOCGCAPLIST _IOR ('f', 10, struct fd_cap_list)
/* get list of possible format capacities */
/*
* software registers passed to controller during command sequences
*/
struct fd_rw_cmd {
/*
* 9 command bytes passed at start of read/write data
*/
#if __LITTLE_ENDIAN__
u_char opcode:5,
sk:1, /* skip sectors with deleted AM */
mfm:1, /* MFM encoding */
mt:1; /* multi track */
u_char drive_sel:2, /* drive select */
hds:1, /* head select */
rsvd1:5; /* reserved */
u_char cylinder;
u_char head;
u_char sector;
u_char sector_size; /* 'n' in the Intel spec. */
u_char eot; /* sector # at end of track */
u_char gap_length; /* gap length */
u_char dtl; /* special sector size */
#elif __BIG_ENDIAN__
u_char mt:1, /* multitrack */
mfm:1, /* MFM encoding */
sk:1, /* skip sectors with deleted AM */
opcode:5;
u_char rsvd1:5, /* reserved */
hds:1, /* head select */
drive_sel:2; /* drive select */
u_char cylinder;
u_char head;
u_char sector;
u_char sector_size; /* 'n' in the Intel spec. */
u_char eot; /* sector # at end of track */
u_char gap_length; /* gap length */
u_char dtl; /* special sector size */
#else
#error Floppy command / data structures are compiler sensitive
#endif
};
#define SIZEOF_RW_CMD 9 /* compiler yields 9 as sizeof this
* struct */
struct fd_rw_stat {
/*
* 7 status bytes passed at completion of read/write data
*/
u_char stat0;
u_char stat1;
u_char stat2;
u_char cylinder;
u_char head;
u_char sector;
u_char sector_size; /* 'n' in the Intel spec. */
};
#define SIZEOF_RW_STAT 7
struct fd_int_stat {
/*
* result of Sense Interrupt Status command
*/
u_char stat0;
u_char pcn; /* present cylinder & */
};
struct fd_seek_cmd {
/*
* Seek command. Uses Sense Interrupt Status to get results.
*/
#if __LITTLE_ENDIAN__
u_char opcode:6, /* will be FCCMD_SEEK */
dir:1, /* 1 == towards spindle for
relative seek*/
relative:1; /* 1 = relative */
u_char drive_sel:2, /* drive select */
hds:1, /* head select */
rsvd1:5; /* reserved */
u_char cyl; /* cylinder # or offset */
#elif __BIG_ENDIAN__
u_char relative:1, /* 1 = relative */
dir:1, /* 1 == towards spindle */
opcode:6; /* will be FCCMD_SEEK */
u_char rsvd1:5, /* reserved */
hds:1, /* head select */
drive_sel:2; /* drive select */
u_char cyl; /* cylinder # or offset */
#else
#error Floppy command / data structures are compiler sensitive
#endif
};
#define SEEK_DIR_IN 1 /* seek towards spindle */
#define SEEK_DIR_OUT 0 /* seek away from spindle */
#define SIZEOF_SEEK_CMD 3
struct fd_recal_cmd {
/*
* Recalibrate command. Uses Sense Interrupt Status to get results.
*/
u_char opcode; /* will be FCCMD_RECAL */
#if __LITTLE_ENDIAN__
u_char drive_sel:2, /* drive select */
rsvd1:6; /* reserved */
#elif __BIG_ENDIAN__
u_char rsvd1:6, /* reserved */
drive_sel:2; /* drive select */
#else
#error Floppy command / data structures are compiler sensitive
#endif
};
struct fd_configure_cmd {
/*
* configure command. No result bytes are returned.
*/
u_char opcode; /* will be FCCMD_CONFIGURE */
u_char rsvd1; /* must be 0 */
u_char conf_2; /* EIS, EFIFO, etc. */
u_char pretrk; /* write precomp track # */
};
/*
* configure command fields
*/
#define CF2_EIS 0x40 /* enable implied seek */
#define CF2_EFIFO 0x20 /* enable FIFO. True Low. */
#define CF2_DPOLL 0x10 /* disable polling */
#define CF2_FIFO_DEFAULT 0x08 /* OUR default FIFO threshold */
#define CF_PRETRACK 0x00 /* OUR default precom track */
#define I82077_FIFO_SIZE 0x10 /* size of FIFO */
struct fd_specify_cmd {
/*
* Specify command. No result bytes are returned.
*/
u_char opcode; /* will be FCCMD_SPECIFY */
#if __LITTLE_ENDIAN__
u_char hut:4, /* head unload time */
srt:4; /* step rate */
u_char nd:1, /* Non-DMA mode */
hlt:7; /* head load time */
#elif __BIG_ENDIAN__
u_char srt:4, /* step rate */
hut:4; /* head unload time */
u_char hlt:7, /* head load time */
nd:1; /* Non-DMA mode */
#else
#error Floppy command / data structures are compiler sensitive
#endif
};
#define SIZEOF_SPECIFY_CMD 3
struct fd_readid_cmd {
/*
* Read ID command. Returns status in an fd_rw_stat.
*/
#if __LITTLE_ENDIAN__
u_char opcode:6, /* Will be FCCMD_READID */
mfm:1,
rsvd1:1;
u_char drive_sel:2, /* drive select */
hds:1, /* head select */
rsvd2:5; /* reserved */
#elif __BIG_ENDIAN__
u_char rsvd1:1,
mfm:1,
opcode:6; /* Will be FCCMD_READID */
u_char rsvd2:5, /* reserved */
hds:1, /* head select */
drive_sel:2; /* drive select */
#else
#error Floppy command / data structures are compiler sensitive
#endif
};
struct fd_perpendicular_cmd {
u_char opcode; /* will be FCCMD_PERPENDICULAR */
#if __LITTLE_ENDIAN__
u_char gap:1,
wgate:1,
rsvd1:6; /* must be 0 */
#elif __BIG_ENDIAN__
u_char rsvd1:6, /* must be 0 */
wgate:1,
gap:1;
#else
#error Floppy command / data structures are compiler sensitive
#endif
};
struct fd_format_cmd {
/*
* Format track command. Returns status in an fd_rw_stat
* (with undefined address fields).
*/
#if __LITTLE_ENDIAN__
u_char opcode:6, /* will be FCCMD_FORMAT */
mfm:1,
rsvd1:1;
u_char drive_sel:2, /* drive select */
hds:1, /* head select */
rsvd2:5; /* reserved */
#elif __BIG_ENDIAN__
u_char rsvd1:1,
mfm:1,
opcode:6; /* will be FCCMD_FORMAT */
u_char rsvd2:5, /* reserved */
hds:1, /* head select */
drive_sel:2; /* drive select */
#else
#error Floppy command / data structures are compiler sensitive
#endif
u_char n; /* sector size (2**n * 128 = sect_size)
*/
u_char sects_per_trk;
u_char gap_length;
u_char filler_data; /* data field written with this byte */
};
struct fd_sense_drive_status_cmd {
/*
* returns one result byte which is basically status register 3
*/
u_char opcode; /* will be FCCMD_DRIVE_STATUS */
#if __LITTLE_ENDIAN__
u_char drive_sel:2, /* drive select */
hds:1, /* head select */
resvd2:5; /* always zero */
#elif __BIG_ENDIAN__
u_char resvd2:5, /* always zero */
hds:1, /* head select */
drive_sel:2; /* drive select */
#else
#error Floppy command / data structures are compiler sensitive
#endif
};
/*
* software register values
*/
/*
* cmd (command byte). Not all of these opcodes are used with the fd_rw_cmd
* struct...
*/
#define FCCMD_OPCODE_MASK 0x1F
#define FCCMD_MULTITRACK 0x80
#define FCCMD_MFM 0x40 /* MFM flag */
#define FCCMD_SK 0x20 /* skip flag */
#define FCCMD_READ 0x06
#define FCCMD_READ_DELETE 0x0C
#define FCCMD_WRITE 0x05
#define FCCMD_WRITE_DELETE 0x09
#define FCCMD_READ_TRACK 0x02
#define FCCMD_VERIFY 0x16
#define FCCMD_VERSION 0x10
#define FCCMD_FORMAT 0x0D
#define FCCMD_RECAL 0x07
#define FCCMD_INTSTAT 0x08 /* sense interrupt status */
#define FCCMD_SPECIFY 0x03
#define FCCMD_DRIVE_STATUS 0x04
#define FCCMD_SEEK 0x0F
#define FCCMD_CONFIGURE 0x13
#define FCCMD_DUMPREG 0x0E
#define FCCMD_READID 0x0A /* Read ID */
#define FCCMD_PERPENDICULAR 0x12 /* perpendicular recording mode
*/
/*
* rws_stat0 (status register 0)
*/
#define SR0_INTCODE 0xC0 /* interrupt code - see INTCODE_xxx */
#define INTCODE_COMPLETE 0x00 /* normal I/O complete */
#define INTCODE_ABNORMAL 0x40 /* abnormal termination */
#define INTCODE_INVALID 0x80 /* Invalid command */
#define INTCODE_POLL_TERM 0xC0 /* abnormal termination caused by
* polling */
#define SR0_SEEKEND 0x20 /* Seek End */
#define SR0_EQ_CHECK 0x10 /* Equipment check (recal failed,
* seek beyond track 0, etc.) */
#define SR0_HEAD 0x04 /* current head address */
#define SR0_DRVSEL 0x03
#define SR0_DRVSEL1 0x02 /* Drive Select 1 */
#define SR0_DRVSEL0 0x01 /* Drive Select 0 */
/*
* rws_stat1 (status register 1)
*/
#define SR1_EOCYL 0x80 /* end of cylinder */
#define SR1_CRCERR 0x20 /* data or ID CRC error */
#define SR1_OURUN 0x10 /* DMA over/underrun */
#define SR1_NOHDR 0x04 /* Header Not Found */
#define SR1_NOT_WRT 0x02 /* Not writable */
#define SR1_MISS_AM 0x01 /* Missing Address mark */
/*
* rws_stat2 (status register 2)
*/
#define SR2_CNTRL_MK 0x40 /* control mark */
#define SR2_DATACRC 0x20 /* Data CRC error */
#define SR2_WRONG_CYL 0x10 /* wrong cylinder */
#define SR2_BAD_CYL 0x02 /* Bad cylinder */
#define SR2_MISS_AM 0x01 /* missing data mark */
/*
* rws_stat3 (status register 3)
*/
#define SR3_WP 0x40 /* write protected */
#define SR3_TRACK0 0x10 /* Track 0 */
#define SR3_HEAD 0x04 /* Head # */
#define SR3_DRVSEL1 0x02 /* same as status register 0?? */
#define SR3_DEVSEL0 0x01
/*
* disk info - maps media_id to tracks_per_cyl and num_cylinders.
*/
struct fd_disk_info {
u_int media_id; /* FD_MID_1MB, etc. */
u_char tracks_per_cyl; /* # of heads */
u_int num_cylinders;
u_int max_density; /* maximum legal density.
* (FD_DENS_1, etc.) */
};
/*
* sector size info - maps sector size to 82077 sector size code and
* gap3 length. Note that the controller must be programmed for different
* gap3 size when formatting as opposed to reading or writing. Since gap3
* sizes may be dependent on the actual disk hardware, the fmt gap is
* maintained here to avoid requiring the formatter to determine
* the disk device type.
*/
struct fd_sectsize_info {
u_int sect_size; /* in bytes */
u_char n; /* 82077 sectsize code */
u_int sects_per_trk; /* physical sectors per trk */
u_char rw_gap_length; /* Gap 3 for rw cmds */
u_char fmt_gap_length; /* Gap 3 for fmt cmds */
};
typedef struct fd_sectsize_info fd_sectsize_info_t;
/*
* density info - maps density to capacity. Note that a disk may be formatted
* with a lower density than its max possible density.
*/
struct fd_density_info {
u_int density; /* FD_DENS_1, etc. */
u_int capacity; /* in bytes */
boolean_t mfm; /* TRUE = MFM encoding */
};
typedef struct fd_density_info fd_density_info_t;
/*
* disk format info. Used with ioctl(FDIOCGFORM).
*/
struct fd_format_info {
/*
* the disk_info struct is always valid as long as a disk is
* inserted.
*/
struct fd_disk_info disk_info;
int flags; /* See FFI_xxx, below */
/*
* the remainder is only valid if (flags & FFI_FORMATTED) is true.
*/
struct fd_density_info density_info;
struct fd_sectsize_info sectsize_info;
u_int total_sects; /* total # of sectors on
* disk */
};
/*
* fd_format_info.flags fields
*/
#define FFI_FORMATTED 0x00000001 /* known disk format */
#define FFI_LABELVALID 0x00000002 /* Valid NeXT file system label
* present */
#define FFI_WRITEPROTECT 0x00000004 /* disk is write protected */
struct format_data {
/*
* one of these per sector. A Format command involves DMA'ing one of
* these for each sector on a track. The format command is executed
* with a FDIOCREQ ioctl.
*/
u_char cylinder;
u_char head;
u_char sector;
u_char n; /* as in sector_size = 2**n * 128 */
};
/*
* result of FCCMD_DUMPREG command
*/
struct fd_82077_regs {
u_char pcn[4]; /* cylinder # for drives 0..3 */
u_char srt:4,
hut:4;
u_char hlt:7,
nd:1;
u_char sc_eot;
u_char rsvd1;
u_char rsvd2:1,
eis:1,
efifo:1,
poll:1,
fifothr:4;
u_char pretrk;
};
/*
* Used for FDIOCRRW - raw disk I/O
* -- no bad block mapping
* -- no label required
* -- no front porch
* -- block size = physical sector size
*/
struct fd_rawio {
/*
* Passed to driver
*/
u_int sector;
u_int sector_count;
caddr_t dma_addrs;
boolean_t read; /* TRUE = read; FALSE = write */
/*
* Returned from driver
*/
fd_return_t status; /* FDR_xxx (see above) */
u_int sects_xfr; /* sectors actually moved */
};
/*
* misc. hardware constants
*/
#define NUM_FD_HEADS 2 /* number of tracks/cylinder */
#define NUM_FD_CYL 80 /* cylinders/disk (is this actually a
* constant for all densities?) */
#define FD_PARK_TRACK 79 /* track to which to seek before
* eject */
#define NUM_UNITS 4 /* max # of drives per controller */
#endif _FDEXTERN_