fdc.h revision ca925f54ccacc64abb1dc147c736397a9ccaab0e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_FDC_H
#define _SYS_FDC_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef OTYPCNT
#define OTYPCNT 5
#endif
typedef struct xlate_tbl {
int value;
uchar_t code;
} xlate_tbl_t;
/*
* the floppy disk minor device number is interpreted as follows:
*
* 7 6 5 4 3 2 1 0
* +---------+-----+
* | drive | part|
* +---------+-----+
* where:
* drive = instance
* part = partition
*/
/*
* Macros for partition/drive from floppy device number,
* plus other manifest defines....
*/
#define PARTITION(x) (getminor(x) & 7)
#define DRIVE(x) (getminor(x) >> 3)
#define FDUNIT(x) ((x) & 3) /* unit on controller */
#define FDCTLR(x) ((x) >> 2) /* controller instance */
#define NFDUN 4
/*
* Floppy drive / diskette type numbers.
*/
#define FMT_5H 0
#define FMT_5Q 1
#define FMT_5D9 2
#define FMT_5D8 3
#define FMT_5D4 4
#define FMT_5D16 5
#define FMT_3E 6
#define FMT_3H 7
#define FMT_3I 8
#define FMT_3M 9
#define FMT_3D 10
#define FMT_AUTO 11
#define FMT_MAX 11
#define FMT_UNKWN 11
/*
* Mini- and Micro- Diskettes Attributes Structure
*/
struct fdattr {
ushort_t fda_rotatespd; /* rotational speed */
ushort_t fda_intrlv; /* interleave factor */
uchar_t fda_gapl; /* gap 3 length */
uchar_t fda_gapf; /* gap 3 length for format */
};
/*
* Miscellaneous
*/
#define FDWRITE 0 /* for fdrw() flag */
#define FDREAD 1 /* for fdrw() flag */
#define FDRDONE 86 /* . read with no retries */
/*
* Per floppy-drive / diskette state structure
*/
struct fdisk {
struct fcu_obj *d_obj;
int d_media; /* drive media capacities */
struct kstat *d_iostat; /* pointer to iostat statistics */
int d_bpsshf; /* shift count for bytes to sector */
ksema_t d_ocsem; /* sem for serializing opens/closes */
struct buf *d_actf; /* head of wait list */
struct buf *d_actl; /* tail of wait list */
struct buf *d_current; /* currently active buf */
struct partition d_part[NDKMAP]; /* partitions descriptions */
/*
* Regular open type flags.
* Open types BLK, MNT, CHR, SWP assumed to be values 0-3.
*/
ulong_t d_regopen[OTYPCNT - 1];
ulong_t d_lyropen[NDKMAP]; /* Layered open counters */
/*
* Exclusive open flags (per partition).
*
* The rules are that in order to open a partition exclusively,
* the partition must be completely closed already. Once any
* partition of the device is opened exclusively, no other open
* on that partition may succeed until the partition is closed.
*/
ulong_t d_exclmask; /* set to indicate exclusive open */
/*
* Current drive characteristics type.
* If -1, then it was set via an ioctl. Note that a close
* and then an open loses the ioctl set characteristics.
*/
signed char d_curfdtype;
uchar_t d_deffdtype;
uchar_t d_bsec; /* encoded bytes_per_sector */
uchar_t d_drate; /* encoded data_rate */
uchar_t d_motor; /* motor-on bit */
uchar_t d_hutsrt; /* encoded head unload & step_rate */
uchar_t d_hlt; /* encoded head load time */
uchar_t d_dtl; /* dtl code */
int d_media_timeout; /* media detection timeout */
timeout_id_t d_media_timeout_id; /* media detection timeout id */
enum dkio_state d_media_state; /* up-to-date media state */
int d_ejected;
kcondvar_t d_statecv; /* condition var for media state */
ulong_t d_vtoc_bootinfo[3]; /* from label */
ulong_t d_vtoc_version;
time_t d_vtoc_timestamp[NDKMAP];
char d_vtoc_volume[LEN_DKL_VVOL];
char d_vtoc_asciilabel[LEN_DKL_ASCII];
};
/* a place to keep some statistics on what's going on */
struct fdstat {
/* first operations */
int rd; /* count reads */
int wr; /* count writes */
int recal; /* count recalibrates */
int form; /* count format_tracks */
int other; /* count other ops */
/* then errors */
int reset; /* count resets */
int to; /* count timeouts */
int run; /* count overrun/underrun */
int de; /* count data errors */
int bfmt; /* count bad format errors */
};
/*
* floppy disk command and status block.
*
* Needed to execute a command. Since the floppy chip is
* single threaded with respect to having only one drive
* active at a time, this block of information is only
* valid for the length of a command and gets rewritten
* for each command.
*/
enum fxstate {
FXS_START,
FXS_MTRON,
FXS_RCAL,
FXS_DKCHGX,
FXS_RESTART,
FXS_RESEEK,
FXS_SEEK,
FXS_HDST,
FXS_RDID,
FXS_DOIT,
FXS_DOWT,
FXS_KILL,
FXS_RESET,
FXS_END
};
enum fmtrstate {
FMS_OFF,
FMS_START,
FMS_KILLST,
FMS_ON,
FMS_DELAY,
FMS_IDLE
};
enum fmtrinput {
FMI_TIMER,
FMI_STARTCMD,
FMI_RSTARTCMD,
FMI_DELAYCMD,
FMI_IDLECMD
};
struct fdcsb {
struct buf *csb_bufp; /* associated buf */
ddi_dma_handle_t csb_dmahandle;
int csb_handle_bound; /* DMA handle has been bound */
uint_t csb_dmacookiecnt; /* number of DMA cookies */
uint_t csb_dmacurrcookie; /* current cookie number */
uint_t csb_dmawincnt; /* number of DMA windows */
uint_t csb_dmacurrwin; /* current DMA window */
ddi_dma_cookie_t csb_dmacookie;
enum fxstate csb_xstate; /* Current execution state */
enum fxstate csb_oldxs; /* old execution state */
uchar_t csb_npcyl; /* new physical cylinder number */
uchar_t csb_drive; /* floppy unit number */
uchar_t csb_ncmds; /* how many command bytes to send */
uchar_t csb_nrslts; /* number of result bytes gotten */
uchar_t csb_opflags; /* opflags, see below */
uchar_t csb_timer; /* op timer, in 0.1 sec */
uchar_t csb_maxretry; /* maximum retries this operation */
uchar_t csb_retrys; /* how may retrys done so far */
uchar_t csb_ourtrys; /* how may over/underrun retrys done so far */
uchar_t csb_status; /* status returned from hwintr */
uchar_t csb_cmdstat; /* if 0 then success, else failure */
uchar_t csb_cmd[10]; /* command to send to chip */
uchar_t csb_rslt[10]; /* results from chip */
};
/*
* defines for csb_opflags
*/
#define CSB_OFINRPT 0x01 /* generates an interrupt */
#define CSB_OFDMARD 0x02 /* uses DMA for reading */
#define CSB_OFDMAWT 0x04 /* uses DMA for writing */
#define CSB_OFRESLT 0x08 /* generates results */
#define CSB_OFRAWIOCTL 0x10 /* raw i/o control */
#define CSB_CMDTO 0x01
#define CSB_CMDDMA 0x03
#define CSB_CMDNGNR 0x07
/*
* 82077AA Controller modes
*/
enum fdcmode077 {
FDCMODE_AT,
FDCMODE_PS2, /* not supported */
FDCMODE_30
};
/*
* Per controller data
*/
struct fdcntlr {
kmutex_t c_lock; /* controller mutex */
kmutex_t c_dorlock; /* digital_output_register mutex */
kcondvar_t c_iocv; /* condition var for I/O done */
ksema_t c_selsem; /* sem for select unit */
boolean_t c_suspended; /* if DDI_SUSPENDed */
dev_info_t *c_dip;
int c_number; /* logical controller number */
int c_regbase; /* base i/o address */
int c_dmachan; /* DMA channel number */
int c_intprio; /* interrupt priority */
int c_intvec; /* interrupt vector num */
int c_chip;
enum fdcmode077 c_mode; /* 82077 controller mode */
ulong_t c_flags; /* state information */
struct kstat *c_intrstat; /* interrupt stats pointer */
struct fdstat fdstats; /* statistics */
ddi_iblock_cookie_t c_iblock; /* returned from ddi_add_intr */
ddi_idevice_cookie_t c_idevice; /* returned from ddi_add_intr */
int c_curunit; /* current/last selected unit */
timeout_id_t c_timeid; /* watchdog timer id */
struct fcu_obj *c_unit[NFDUN]; /* slave on controller */
timeout_id_t c_motort[NFDUN]; /* motor timer id */
enum fmtrstate c_mtrstate[NFDUN];
int c_curpcyl[NFDUN]; /* current physical cylinder */
signed char c_sekdir[NFDUN]; /* direction of last seek */
struct fdcsb c_csb; /* current csb */
/*
* floppy controller register values
*/
uchar_t c_digout;
uchar_t c_drate; /* only 82072 and 82077AA controllers */
uchar_t c_config; /* DSR on PC/AT with 8272A */
uchar_t c_mstat;
uchar_t c_data;
uchar_t c_digin;
uchar_t c_bsec; /* encoded bytes_per_sector */
uchar_t c_hutsrt; /* encoded head unload & step_rate */
uchar_t c_hlt; /* encoded head load time */
};
/*
* Controller flags
*/
#define FCFLG_BUSY 0x01 /* operation in progress */
#define FCFLG_WANT 0x02 /* csb structure wanted */
#define FCFLG_WAITMR 0x10 /* waiting for motor to start I/O */
#define FCFLG_WAITING 0x20 /* waiting on I/O completion */
#define FCFLG_TIMEOUT 0x80 /* the current operation just timed out */
#define FCFLG_DSOUT 0x100 /* DENSEL ouput is in use for speed ctl */
#define FCFLG_3DMODE 0x800 /* ctlr is 3D Mode capable */
/*
* FDC operations
*/
struct fcobjops {
int (*fco_abort)(); /* controller abort */
int (*fco_dkinfo)(); /* get disk controller info */
int (*fco_select)(); /* select / deselect unit */
int (*fco_getchng)(); /* get media change */
int (*fco_resetchng)(); /* reset media change */
int (*fco_rcseek)(); /* recal / seek */
int (*fco_rwbuf)(); /* read /write request */
int (*fco_rw)(); /* read /write sector */
int (*fco_format)(); /* format track */
int (*fco_rwioctl)(); /* raw ioctl */
};
/*
* FDC unit object
*/
struct fcu_obj {
ulong_t fj_flags; /* state information */
kmutex_t fj_lock; /* unit mutex */
caddr_t fj_data;
struct fd_drive *fj_drive; /* pointer to drive characteristics */
struct fd_char *fj_chars; /* ptr to diskette characteristics */
struct fdattr *fj_attr; /* additional diskette attributes */
dev_info_t *fj_dip;
ushort_t fj_rotspd; /* rotational speed */
ulong_t fj_unit;
struct fcobjops *fj_ops;
struct fdcntlr *fj_fdc;
ddi_iblock_cookie_t *fj_iblock;
};
/* unit flags (state info) */
#define FUNIT_DRVATCH 0x001 /* this is drive present */
#define FUNIT_WPROT 0x004 /* diskette is read only */
#define FUNIT_CHAROK 0x010 /* characteristics are known */
#define FUNIT_LABELOK 0x020 /* label was read from disk */
#define FUNIT_UNLABELED 0x040 /* no label using default */
#define FUNIT_CHANGED 0x100 /* diskette was changed after open */
#define FUNIT_CHGDET 0x200 /* diskette removal was detected */
#define FUNIT_3DMODE 0x4000 /* unit is in fast speed mode */
#define FUNIT_BUSY 0x8000 /* unit is busy */
#ifdef _VPIX
#define DRV_NONE 0x00
#define DRV_DBL 0x01
#define DRV_QUAD 0x02
#define DRV_720 0x04 /* LOW_35 gets changed to this for or'ing */
#define DRV_144 0x08 /* HI35 gets changed to this for or'ing */
/* ioctl numbers used by VPIX */
#define FIOC ('F'<<8)
#define F_DTYP (FIOC|60) /* returns fd_drvtype */
#define F_FCR (FIOC|61) /* output to Floppy Control Register */
#define F_DOR (FIOC|62) /* output to Digital Output Register */
#define F_RAW (FIOC|63) /* general raw controller interface */
#endif
#ifdef __cplusplus
}
#endif
#endif /* !_SYS_FDC_H */