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

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


/*  $Header:dio.h 12.0$ */
/*  $ACIS:dio.h 12.0$ */


#define SECSIZE 512
#define DISK 0x13

#define DISKOP_RESET    0x00	/* reset the drive */
#define DISKOP_STATUS   0x01	/* get drive status */
#define DISKOP_READ     0x02	/* read request */
#define DISKOP_WRITE    0x03	/* write request */
#define DISKOP_VERIFY   0x04	/* verify request */
#define DISKOP_FORMAT   0x05	/* format request */
#define DISKOP_SMT      0x18	/* set media type for diskette format */

/* following are for optical disk drive */
#define DISKOP_OPEN     0x10    /* open disk */
#define DISKOP_CLOSE    0x11    /* close disk */

#define BBT_DIO 0x70
#define HD_RETRY_COUNT 5
#define FLOPPY_RETRY_COUNT 10
#define HD_STATUS_REG 0x1F7
#define HD_ERROR_REG  0x1F1
#define HD_SEC_CNT    0x1F2


#define DSDD 0x1		/* Double Sided Diskette drive */
#define HCDD 0x2		/* High Capacity Diskette drive */
#define PSDDLO 0x3		/* 720Kb 3.5 Diskette Drive */
#define PSDDHI 0x4		/* 1.44MB 3.5 Diskette Drive */

#define XTRACTCYL(C,S) ((u_short) ((((S) & 0xc0) << 2) | LOBYTE(C)))

#ifndef ABIOS
#define ISFLOPPY(drive) ((drive) < 128)

#define RESET(drive) io(DISKOP_RESET,drive, 0, 0, 0, 0, NULL)
#define DMAERROR(rc) ((rc & 0x00ff) == 0x0008)
#define BOOTRETRY 10		/* Number of times we try to read disk in
				 * loadboot */

#define BOOTCYLS 0		/* Number of cylinders used by boot record */

#else /* ABIOS */
/*
 * ABIOS hard disk request block
 */
/* read param block */
struct Hd_device_params {
	u_short		Sectors_per_track;		/* OUT */
	u_short		Bytes_per_sector;		/* OUT */
#define	HD_GET_SECT_SIZE(x)	((x)*256)
	u_short		Device_control;			/* OUT */
#define HD_FORMAT_SUPPORT	0x1800
#define HD_NO_FORMAT		0x0000
#define HD_TRACK_FORMAT		0x0800
#define HD_UNIT_FORMAT		0x1000
#define HD_BOTH_FORMAT		0x1800
#define HD_GET_FORMAT(x)	((x)& HD_FORMAT_SUPPORT)
#define HD_ST506		0x0400
#define HD_CONCURRENT		0x0200
#define HD_EJECTABLE		0x0100
#define HD_SEQUENTIAL		0x0080
#define HD_LOCKABLE		0x0040
#define HD_READABLE		0x0020
#define HD_CACHES		0x0010
#define HD_WRITE_MANY		0x0008
#define HD_CHANGE_SUPPORT	0x0004
	u_short		Reserved1;
	u_long		Number_cylinders;		/* OUT */
	u_char		Number_heads;			/* OUT */
	u_char		Max_retries;			/* OUT */
	u_short		Reserved2;
	u_long		Max_block_number;		/* OUT */
	u_long		Reserved3;
	u_short		Reserved4;
	u_short		Max_transfer;			/* OUT */
};
#define hr_sectors_per_track	un.hd_device_params.Sectors_per_track
#define hr_bytes_per_sector	un.hd_device_params.Bytes_per_sector
#define hr_device_control	un.hd_device_params.Device_control
#define hr_number_cylinders	un.hd_device_params.Number_cylinders
#define hr_number_heads		un.hd_device_params.Number_heads
#define hr_max_retries		un.hd_device_params.Max_retries
#define hr_max_block_number	un.hd_device_params.Max_block_number
#define hr_max_transfer		un.hd_device_params.Max_transfer

/* read,write,write verify,read verify */
struct Hd_transfer {
	u_short		Reserved1;
	char far	*Log_addr;			/* IN */
	u_short		Reserved2[2];
	char far	*Phys_addr;			/* IN */
	u_short		Reserved3;
	u_long		Relative_block_addr;		/* IN */
	u_long		Reserved4;
	u_long		Delay_time;			/* OUT */
	u_short		Number_of_blocks;		/* IN/OUT */
	u_char		Transfer_flags;			/* IN */
#define	HD_NO_CACHE	0
#define HD_CACHE	1
	u_short		Soft_error;			/* OUT */
};
#define hr_log_addr		un.hd_transfer.Log_addr
#define hr_phys_addr		un.hd_transfer.Phys_addr
#define hr_block		un.hd_transfer.Relative_block_addr
#define hr_delay_time		un.hd_transfer.Delay_time
#define hr_number_of_blocks	un.hd_transfer.Number_of_blocks	/* IN */
#define hr_blocks_transfered	hr_number_of_blocks		/* OUT */
#define hr_transfer_flags	un.hd_transfer.Transfer_flags
#define hr_soft_error		un.hd_transfer.Soft_error

#define HDSTAGED	0x7ff
#define HD_INV_FUNCTION	0xff
#define INV_FUNCTION	0x01
#define HD_WRITE_VERIFY 0x0a
#define HD_VERIFY	0x0b

struct Hdrequest	{
	struct Request_header	request_header;
	/* Service Specific */
	union {
		struct Logical_id_params	logical_id_params;
		struct Hd_device_params		hd_device_params;
		struct Hd_transfer		hd_transfer;
		/*
		 * reserve the scratch space the ABIOS driver needs
		 * (should be dynamically allocated in hdinit).
		 */
		char	dummy[128];
	} un;
};
/*
 * ABIOS hard disk request block
 */
/* read param block */
struct Fd_device_params {
	u_short		Sectors_per_track;		/* OUT */
	u_short		Bytes_per_sector;		/* OUT */
#define	FD_GET_SECT_SIZE(x)	((x)*256)
	u_short		Device_control;			/* OUT */
#define FD_RECALIBRATE		0x0008
#define FD_CONCURRENT		0x0004
#define FD_UNIT_FORMAT		0x0002
#define FD_CHANGE_SUPPORT	0x0001
	u_short		Media_type;			/* OUT */
#define FD_3_1440K	0x04
#define FD_5_360K	0x01
	u_long		Reserved1;
	u_long		Motor_off;			/* OUT */
	u_long		Motor_on;			/* OUT */
	u_short		Reserved2;
	u_short		Number_cylinders;		/* OUT */
	u_short		Reserved3;
	u_char		Number_heads;			/* OUT */
	u_char		Max_retries;			/* OUT */
	u_char		Format_fill_byte;		/* OUT */
	u_long		Head_settle_time;		/* OUT */
	u_char		RW_gap_length;			/* OUT */
	u_char		Format_gap_length;		/* OUT */
	u_char		Data_length;			/* OUT */
};
#define fr_sectors_per_track	un.fd_device_params.Sectors_per_track
#define fr_bytes_per_sector	un.fd_device_params.Bytes_per_sector
#define fr_device_control	un.fd_device_params.Device_control
#define fr_media_type		un.fd_device_params.Media_type
#define fr_motor_off		un.fd_device_params.Motor_off
#define fr_motor_on		un.fd_device_params.Motor_on
#define fr_number_cylinders	un.fd_device_params.Number_cylinders
#define fr_number_heads		un.fd_device_params.Number_heads
#define fr_max_retries		un.fd_device_params.Max_retries
#define fr_format_fill_byte	un.fd_device_params.Format_fill_byte
#define fr_head_settle_time	un.fd_device_params.Head_settle_time
#define fr_rw_gap_length	un.fd_device_params.RW_gap_length
#define fr_format_gap_length	un.fd_device_params.Format_gap_length
#define fr_data_length		un.fd_device_params.Data_length

/* read,write,write verify,read verify */
struct Fd_transfer {
	u_short		Reserved1;
	char far	*Log_addr;			/* IN */
	u_short		Reserved2[2];
	char far	*Phys_addr;			/* IN */
	u_short		Reserved3;
	u_long		Delay_time;			/* OUT */
	u_short		Number_of_blocks;		/* IN/OUT */
	u_short		Cylinder;			/* IN */
	u_short		Reserved4;
	u_short		Head;				/* IN */
	u_char		Reserved5[5];
	u_short		Sector;				/* IN */
};
#define fr_log_addr		un.fd_transfer.Log_addr
#define fr_phys_addr		un.fd_transfer.Phys_addr
#define fr_cylinder		un.fd_transfer.Cylinder
#define fr_head			un.fd_transfer.Head
#define fr_sector		un.fd_transfer.Sector
#define fr_delay_time		un.fd_transfer.Delay_time
#define fr_number_of_blocks	un.fd_transfer.Number_of_blocks	/* IN */
#define fr_blocks_transfered	fr_number_of_blocks		/* OUT */
/* used for format */
#define fr_sub_function		fr_number_of_blocks		/* IN */
#define fr_reserved_1		un.fd_transfer.Reserved1
#define fr_reserved_2		un.fd_transfer.Reserved2[0]
#define fr_reserved_3		un.fd_transfer.Reserved2[1]
#define fr_reserved_4		un.fd_transfer.Reserved3

#define FDSTAGED	0x7ff
#define FD_INV_FUNCTION	0xff
#define INV_FUNCTION	0x01
#define FD_FORMAT	0x0a
#define FD_VERIFY	0x0b
#define FD_READ_MEDIA	0x0c
#define FD_MOTOR_OFF	0x0f

struct Fdrequest	{
	struct Request_header	request_header;
	/* Service Specific */
	union {
		struct Logical_id_params	logical_id_params;
		struct Fd_device_params		fd_device_params;
		struct Fd_transfer		fd_transfer;
		/*
		 * reserve the scratch space the ABIOS driver needs
		 * (should be dynamically allocated in fdinit).
		 */
		char	dummy[128];
	} un;
};
#endif /* ABIOS */
