1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_FDC_H 27 #define _SYS_FDC_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #ifndef OTYPCNT 34 #define OTYPCNT 5 35 #endif 36 37 typedef struct xlate_tbl { 38 int value; 39 uchar_t code; 40 } xlate_tbl_t; 41 42 /* 43 * the floppy disk minor device number is interpreted as follows: 44 * 45 * 7 6 5 4 3 2 1 0 46 * +---------+-----+ 47 * | drive | part| 48 * +---------+-----+ 49 * where: 50 * drive = instance 51 * part = partition 52 */ 53 /* 54 * Macros for partition/drive from floppy device number, 55 * plus other manifest defines.... 56 */ 57 58 #define PARTITION(x) (getminor(x) & 7) 59 #define DRIVE(x) (getminor(x) >> 3) 60 #define FDUNIT(x) ((x) & 3) /* unit on controller */ 61 #define FDCTLR(x) ((x) >> 2) /* controller instance */ 62 #define NFDUN 4 63 64 65 /* 66 * Floppy drive / diskette type numbers. 67 */ 68 #define FMT_5H 0 69 #define FMT_5Q 1 70 #define FMT_5D9 2 71 #define FMT_5D8 3 72 #define FMT_5D4 4 73 #define FMT_5D16 5 74 #define FMT_3E 6 75 #define FMT_3H 7 76 #define FMT_3I 8 77 #define FMT_3M 9 78 #define FMT_3D 10 79 #define FMT_AUTO 11 80 #define FMT_MAX 11 81 #define FMT_UNKWN 11 82 83 84 /* 85 * Mini- and Micro- Diskettes Attributes Structure 86 */ 87 struct fdattr { 88 ushort_t fda_rotatespd; /* rotational speed */ 89 ushort_t fda_intrlv; /* interleave factor */ 90 91 uchar_t fda_gapl; /* gap 3 length */ 92 uchar_t fda_gapf; /* gap 3 length for format */ 93 }; 94 95 /* 96 * Miscellaneous 97 */ 98 #define FDWRITE 0 /* for fdrw() flag */ 99 #define FDREAD 1 /* for fdrw() flag */ 100 #define FDRDONE 86 /* . read with no retries */ 101 102 /* 103 * Per floppy-drive / diskette state structure 104 */ 105 106 struct fdisk { 107 struct fcu_obj *d_obj; 108 int d_media; /* drive media capacities */ 109 struct kstat *d_iostat; /* pointer to iostat statistics */ 110 int d_bpsshf; /* shift count for bytes to sector */ 111 112 ksema_t d_ocsem; /* sem for serializing opens/closes */ 113 114 struct buf *d_actf; /* head of wait list */ 115 struct buf *d_actl; /* tail of wait list */ 116 struct buf *d_current; /* currently active buf */ 117 struct partition d_part[NDKMAP]; /* partitions descriptions */ 118 119 /* 120 * Regular open type flags. 121 * Open types BLK, MNT, CHR, SWP assumed to be values 0-3. 122 */ 123 ulong_t d_regopen[OTYPCNT - 1]; 124 ulong_t d_lyropen[NDKMAP]; /* Layered open counters */ 125 126 /* 127 * Exclusive open flags (per partition). 128 * 129 * The rules are that in order to open a partition exclusively, 130 * the partition must be completely closed already. Once any 131 * partition of the device is opened exclusively, no other open 132 * on that partition may succeed until the partition is closed. 133 */ 134 ulong_t d_exclmask; /* set to indicate exclusive open */ 135 136 /* 137 * Current drive characteristics type. 138 * If -1, then it was set via an ioctl. Note that a close 139 * and then an open loses the ioctl set characteristics. 140 */ 141 signed char d_curfdtype; 142 uchar_t d_deffdtype; 143 144 uchar_t d_bsec; /* encoded bytes_per_sector */ 145 uchar_t d_drate; /* encoded data_rate */ 146 uchar_t d_motor; /* motor-on bit */ 147 148 uchar_t d_hutsrt; /* encoded head unload & step_rate */ 149 uchar_t d_hlt; /* encoded head load time */ 150 uchar_t d_dtl; /* dtl code */ 151 152 int d_media_timeout; /* media detection timeout */ 153 timeout_id_t d_media_timeout_id; /* media detection timeout id */ 154 enum dkio_state d_media_state; /* up-to-date media state */ 155 int d_ejected; 156 kcondvar_t d_statecv; /* condition var for media state */ 157 158 ulong_t d_vtoc_bootinfo[3]; /* from label */ 159 ulong_t d_vtoc_version; 160 time_t d_vtoc_timestamp[NDKMAP]; 161 char d_vtoc_volume[LEN_DKL_VVOL]; 162 char d_vtoc_asciilabel[LEN_DKL_ASCII]; 163 }; 164 165 166 /* a place to keep some statistics on what's going on */ 167 struct fdstat { 168 /* first operations */ 169 int rd; /* count reads */ 170 int wr; /* count writes */ 171 int recal; /* count recalibrates */ 172 int form; /* count format_tracks */ 173 int other; /* count other ops */ 174 175 /* then errors */ 176 int reset; /* count resets */ 177 int to; /* count timeouts */ 178 int run; /* count overrun/underrun */ 179 int de; /* count data errors */ 180 int bfmt; /* count bad format errors */ 181 }; 182 183 /* 184 * floppy disk command and status block. 185 * 186 * Needed to execute a command. Since the floppy chip is 187 * single threaded with respect to having only one drive 188 * active at a time, this block of information is only 189 * valid for the length of a command and gets rewritten 190 * for each command. 191 */ 192 193 enum fxstate { 194 FXS_START, 195 FXS_MTRON, 196 FXS_RCAL, 197 FXS_DKCHGX, 198 FXS_RESTART, 199 FXS_RESEEK, 200 FXS_SEEK, 201 FXS_HDST, 202 FXS_RDID, 203 FXS_DOIT, 204 FXS_DOWT, 205 FXS_KILL, 206 FXS_RESET, 207 FXS_END 208 }; 209 210 enum fmtrstate { 211 FMS_OFF, 212 FMS_START, 213 FMS_KILLST, 214 FMS_ON, 215 FMS_DELAY, 216 FMS_IDLE 217 }; 218 219 enum fmtrinput { 220 FMI_TIMER, 221 FMI_STARTCMD, 222 FMI_RSTARTCMD, 223 FMI_DELAYCMD, 224 FMI_IDLECMD 225 }; 226 227 struct fdcsb { 228 struct buf *csb_bufp; /* associated buf */ 229 ddi_dma_handle_t csb_dmahandle; 230 int csb_handle_bound; /* DMA handle has been bound */ 231 uint_t csb_dmacookiecnt; /* number of DMA cookies */ 232 uint_t csb_dmacurrcookie; /* current cookie number */ 233 uint_t csb_dmawincnt; /* number of DMA windows */ 234 uint_t csb_dmacurrwin; /* current DMA window */ 235 ddi_dma_cookie_t csb_dmacookie; 236 enum fxstate csb_xstate; /* Current execution state */ 237 enum fxstate csb_oldxs; /* old execution state */ 238 uchar_t csb_npcyl; /* new physical cylinder number */ 239 uchar_t csb_drive; /* floppy unit number */ 240 uchar_t csb_ncmds; /* how many command bytes to send */ 241 uchar_t csb_nrslts; /* number of result bytes gotten */ 242 uchar_t csb_opflags; /* opflags, see below */ 243 uchar_t csb_timer; /* op timer, in 0.1 sec */ 244 uchar_t csb_maxretry; /* maximum retries this operation */ 245 uchar_t csb_retrys; /* how may retrys done so far */ 246 uchar_t csb_ourtrys; /* how may over/underrun retrys done so far */ 247 uchar_t csb_status; /* status returned from hwintr */ 248 uchar_t csb_cmdstat; /* if 0 then success, else failure */ 249 uchar_t csb_cmd[10]; /* command to send to chip */ 250 uchar_t csb_rslt[10]; /* results from chip */ 251 }; 252 253 /* 254 * defines for csb_opflags 255 */ 256 #define CSB_OFINRPT 0x01 /* generates an interrupt */ 257 #define CSB_OFDMARD 0x02 /* uses DMA for reading */ 258 #define CSB_OFDMAWT 0x04 /* uses DMA for writing */ 259 #define CSB_OFRESLT 0x08 /* generates results */ 260 #define CSB_OFRAWIOCTL 0x10 /* raw i/o control */ 261 262 #define CSB_CMDTO 0x01 263 #define CSB_CMDDMA 0x03 264 #define CSB_CMDNGNR 0x07 265 266 267 /* 268 * 82077AA Controller modes 269 */ 270 enum fdcmode077 { 271 FDCMODE_AT, 272 FDCMODE_PS2, /* not supported */ 273 FDCMODE_30 274 }; 275 276 /* 277 * Per controller data 278 */ 279 280 struct fdcntlr { 281 kmutex_t c_lock; /* controller mutex */ 282 kmutex_t c_dorlock; /* digital_output_register mutex */ 283 kcondvar_t c_iocv; /* condition var for I/O done */ 284 ksema_t c_selsem; /* sem for select unit */ 285 boolean_t c_suspended; /* if DDI_SUSPENDed */ 286 287 dev_info_t *c_dip; 288 int c_number; /* logical controller number */ 289 int c_regbase; /* base i/o address */ 290 int c_dmachan; /* DMA channel number */ 291 int c_intprio; /* interrupt priority */ 292 int c_intvec; /* interrupt vector num */ 293 int c_chip; 294 enum fdcmode077 c_mode; /* 82077 controller mode */ 295 296 ulong_t c_flags; /* state information */ 297 struct kstat *c_intrstat; /* interrupt stats pointer */ 298 struct fdstat fdstats; /* statistics */ 299 300 ddi_iblock_cookie_t c_iblock; /* returned from ddi_add_intr */ 301 ddi_idevice_cookie_t c_idevice; /* returned from ddi_add_intr */ 302 303 int c_curunit; /* current/last selected unit */ 304 timeout_id_t c_timeid; /* watchdog timer id */ 305 306 struct fcu_obj *c_unit[NFDUN]; /* slave on controller */ 307 timeout_id_t c_motort[NFDUN]; /* motor timer id */ 308 enum fmtrstate c_mtrstate[NFDUN]; 309 int c_curpcyl[NFDUN]; /* current physical cylinder */ 310 signed char c_sekdir[NFDUN]; /* direction of last seek */ 311 312 struct fdcsb c_csb; /* current csb */ 313 314 /* 315 * floppy controller register values 316 */ 317 uchar_t c_digout; 318 uchar_t c_drate; /* only 82072 and 82077AA controllers */ 319 uchar_t c_config; /* DSR on PC/AT with 8272A */ 320 uchar_t c_mstat; 321 uchar_t c_data; 322 uchar_t c_digin; 323 324 uchar_t c_bsec; /* encoded bytes_per_sector */ 325 uchar_t c_hutsrt; /* encoded head unload & step_rate */ 326 uchar_t c_hlt; /* encoded head load time */ 327 }; 328 329 /* 330 * Controller flags 331 */ 332 #define FCFLG_BUSY 0x01 /* operation in progress */ 333 #define FCFLG_WANT 0x02 /* csb structure wanted */ 334 #define FCFLG_WAITMR 0x10 /* waiting for motor to start I/O */ 335 #define FCFLG_WAITING 0x20 /* waiting on I/O completion */ 336 #define FCFLG_TIMEOUT 0x80 /* the current operation just timed out */ 337 #define FCFLG_DSOUT 0x100 /* DENSEL ouput is in use for speed ctl */ 338 #define FCFLG_3DMODE 0x800 /* ctlr is 3D Mode capable */ 339 340 341 /* 342 * FDC operations 343 */ 344 345 struct fcobjops { 346 int (*fco_abort)(); /* controller abort */ 347 int (*fco_dkinfo)(); /* get disk controller info */ 348 349 int (*fco_select)(); /* select / deselect unit */ 350 int (*fco_getchng)(); /* get media change */ 351 int (*fco_resetchng)(); /* reset media change */ 352 int (*fco_rcseek)(); /* recal / seek */ 353 int (*fco_rwbuf)(); /* read /write request */ 354 int (*fco_rw)(); /* read /write sector */ 355 int (*fco_format)(); /* format track */ 356 int (*fco_rwioctl)(); /* raw ioctl */ 357 }; 358 359 /* 360 * FDC unit object 361 */ 362 363 struct fcu_obj { 364 ulong_t fj_flags; /* state information */ 365 kmutex_t fj_lock; /* unit mutex */ 366 caddr_t fj_data; 367 struct fd_drive *fj_drive; /* pointer to drive characteristics */ 368 struct fd_char *fj_chars; /* ptr to diskette characteristics */ 369 struct fdattr *fj_attr; /* additional diskette attributes */ 370 dev_info_t *fj_dip; 371 ushort_t fj_rotspd; /* rotational speed */ 372 ulong_t fj_unit; 373 struct fcobjops *fj_ops; 374 struct fdcntlr *fj_fdc; 375 ddi_iblock_cookie_t *fj_iblock; 376 }; 377 378 /* unit flags (state info) */ 379 #define FUNIT_DRVATCH 0x001 /* this is drive present */ 380 #define FUNIT_WPROT 0x004 /* diskette is read only */ 381 #define FUNIT_CHAROK 0x010 /* characteristics are known */ 382 #define FUNIT_LABELOK 0x020 /* label was read from disk */ 383 #define FUNIT_UNLABELED 0x040 /* no label using default */ 384 #define FUNIT_CHANGED 0x100 /* diskette was changed after open */ 385 #define FUNIT_CHGDET 0x200 /* diskette removal was detected */ 386 #define FUNIT_3DMODE 0x4000 /* unit is in fast speed mode */ 387 #define FUNIT_BUSY 0x8000 /* unit is busy */ 388 389 #ifdef _VPIX 390 #define DRV_NONE 0x00 391 #define DRV_DBL 0x01 392 #define DRV_QUAD 0x02 393 #define DRV_720 0x04 /* LOW_35 gets changed to this for or'ing */ 394 #define DRV_144 0x08 /* HI35 gets changed to this for or'ing */ 395 396 /* ioctl numbers used by VPIX */ 397 #define FIOC ('F'<<8) 398 #define F_DTYP (FIOC|60) /* returns fd_drvtype */ 399 #define F_FCR (FIOC|61) /* output to Floppy Control Register */ 400 #define F_DOR (FIOC|62) /* output to Digital Output Register */ 401 #define F_RAW (FIOC|63) /* general raw controller interface */ 402 #endif 403 404 #ifdef __cplusplus 405 } 406 #endif 407 408 #endif /* !_SYS_FDC_H */ 409