/* * 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 */