diff options
author | Thomas Schwinge <tschwinge@gnu.org> | 2006-02-20 19:04:31 +0000 |
---|---|---|
committer | Thomas Schwinge <tschwinge@gnu.org> | 2009-06-18 00:26:32 +0200 |
commit | b40d1da0855a87519b5764415aec6519025a8338 (patch) | |
tree | e7f52b1b1b0b9892576f2e05c059a07757fd9728 /i386 | |
parent | 9335c8094c3797c93876b6a9f9a3d0e3842ad651 (diff) |
2006-02-20 Thomas Schwinge <tschwinge@gnu.org>
Remove unused and unsupported code. Consult the file
`DEVELOPMENT' for details. Partly based on suggestions by
Gianluca Guida <glguida@gmail.com>.
* i386/bogus/fd.h: Remove file.
* i386/i386at/fd.c: Likewise.
* i386/i386at/fdreg.h: Likewise.
* i386/i386at/nfd.c: Likewise.
* i386/i386at/nfdreg.h: Likewise.
* i386/Makefile.in (i386at-files): Remove `fd.c'.
* i386/i386at/autoconf.c: Don't include <fd.h> anymore and adopt all
users of NFD as if it were always defined to `0'.
* i386/i386at/conf.c: Likewise.
Diffstat (limited to 'i386')
-rw-r--r-- | i386/Makefile.in | 2 | ||||
-rw-r--r-- | i386/bogus/fd.h | 1 | ||||
-rw-r--r-- | i386/i386at/autoconf.c | 26 | ||||
-rw-r--r-- | i386/i386at/conf.c | 14 | ||||
-rw-r--r-- | i386/i386at/fd.c | 1701 | ||||
-rw-r--r-- | i386/i386at/fdreg.h | 368 | ||||
-rw-r--r-- | i386/i386at/nfd.c | 1484 | ||||
-rw-r--r-- | i386/i386at/nfdreg.h | 110 |
8 files changed, 1 insertions, 3705 deletions
diff --git a/i386/Makefile.in b/i386/Makefile.in index c6fe430..eaa03b7 100644 --- a/i386/Makefile.in +++ b/i386/Makefile.in @@ -70,7 +70,7 @@ endif # Source files for any i386 kernel -i386at-files = autoconf.c blit.c conf.c cons_conf.c fd.c rtc.c \ +i386at-files = autoconf.c blit.c conf.c cons_conf.c rtc.c \ i386at_ds_routines.c immc.c int_init.c iopl.c kd.c kd_event.c \ kd_mouse.c kd_queue.c model_dep.c phys_mem_grab_page.c pic_isa.c i386-files = ast_check.c db_disasm.c db_interface.c db_trace.c debug_i386.c \ diff --git a/i386/bogus/fd.h b/i386/bogus/fd.h deleted file mode 100644 index e2632b3..0000000 --- a/i386/bogus/fd.h +++ /dev/null @@ -1 +0,0 @@ -#define NFD 4/*2*/ diff --git a/i386/i386at/autoconf.c b/i386/i386at/autoconf.c index 77d825e..583cde8 100644 --- a/i386/i386at/autoconf.c +++ b/i386/i386at/autoconf.c @@ -47,12 +47,6 @@ #define SPL_TTY (vm_offset_t)SPLTTY -#include <fd.h> -#if NFD > 0 -extern struct bus_driver fddriver; -extern int fdintr(); -#endif /* NFD */ - #include <aha.h> #if NAHA > 0 extern struct bus_driver aha_driver; @@ -196,14 +190,6 @@ struct bus_ctlr bus_master_init[] = { {&eaha_driver, "eahac", 0, eaha_intr, 0xf000, 4, 0xf000, '?', 0, 0, SPL_FIVE, 12}, #endif /* NEAHA > 0 */ - -#if NFD > 0 - {&fddriver, "fdc", 0, fdintr, 0x3f2, 6, 0x3f2, - '?', 0, 0, SPL_FIVE, 6}, - - {&fddriver, "fdc", 1, fdintr, 0x372, 6, 0x372, - '?', 0, 0, SPL_FIVE, 10}, -#endif /* NFD > 0 */ #endif /* ! LINUX_DEV */ 0 @@ -277,18 +263,6 @@ struct bus_device bus_device_init[] = { { &eaha_driver, "tz", 7, 0, 0x0,0, 0, '?', 0, 0, 7, 0, }, #endif /* NEAHA > 0*/ -#if NFD > 0 - {&fddriver, "fd", 0, fdintr, 0x3f2, 6, 0x3f2, - '?', 0, 0, 0, 0, 0, 0, SPL_FIVE, 6}, - {&fddriver, "fd", 1, fdintr, 0x3f2, 6, 0x3f2, - '?', 0, 0, 1, 0, 0, 0, SPL_FIVE, 6}, - - {&fddriver, "fd", 2, fdintr, 0x372, 6, 0x372, - '?', 0, 1, 0, 0, 0, 0, SPL_FIVE, 10}, - {&fddriver, "fd", 3, fdintr, 0x372, 6, 0x372, - '?', 0, 1, 1, 0, 0, 0, SPL_FIVE, 10}, -#endif /* NFD > 0 */ - #if NPC586 > 0 /* For MACH Default */ {&pcdriver, "pc", 0, pc586intr, 0xd0000, 0, 0xd0000, diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c index 704d24f..9556c94 100644 --- a/i386/i386at/conf.c +++ b/i386/i386at/conf.c @@ -48,13 +48,6 @@ int cd_open(), cd_close(), cd_read(), cd_write(); #endif /*NAHA > 0*/ -#include <fd.h> -#if NFD > 0 -extern int fdopen(), fdclose(), fdread(), fdwrite(); -extern int fdgetstat(), fdsetstat(), fddevinfo(); -#define fdname "fd" -#endif /* NFD > 0 */ - #include <wt.h> #if NWT > 0 extern int wtopen(), wtread(), wtwrite(), wtclose(); @@ -224,13 +217,6 @@ struct dev_ops dev_name_list[] = #endif /*NAHA > 0*/ -#if NFD > 0 - { fdname, fdopen, fdclose, fdread, - fdwrite, fdgetstat, fdsetstat, nomap, - nodev, nulldev, nulldev, 64, - fddevinfo }, -#endif /* NFD > 0 */ - #if NWT > 0 { wtname, wtopen, wtclose, wtread, wtwrite, nulldev, nulldev, nomap, diff --git a/i386/i386at/fd.c b/i386/i386at/fd.c deleted file mode 100644 index 82c4077..0000000 --- a/i386/i386at/fd.c +++ /dev/null @@ -1,1701 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - Copyright 1988, 1989 by Intel Corporation, Santa Clara, California. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and -its documentation for any purpose and without fee is hereby -granted, provided that the above copyright notice appears in all -copies and that both the copyright notice and this permission notice -appear in supporting documentation, and that the name of Intel -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. - -INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, -IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, -NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION -WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -/* Copyright (c) 1987, 1988 TOSHIBA Corp. */ -/* All Rights Reserved */ - -#if 0 - -#include <fd.h> - -#ifdef MACH_KERNEL -#include <sys/types.h> -#include <sys/ioctl.h> -#include <device/buf.h> -#include <device/errno.h> -#else /* MACH_KERNEL */ -#include <sys/buf.h> -#include <sys/errno.h> -#include <sys/user.h> -#include <sys/ioctl.h> -#endif /* MACH_KERNEL */ -#include <i386/pio.h> -#include <i386/machspl.h> -#include <chips/busses.h> -#include <i386at/fdreg.h> -#include <i386at/disk.h> -#include <vm/vm_kern.h> - -#ifdef DEBUG -#define D(x) x -#define DD(x) x -#else /* DEBUG */ -#define D(x) -#define DD(x) -#endif /* DEBUG */ - -/* - * Floppy Device-Table Definitions (drtabs) - * - * Cyls,Sec,spc,part,Mtype,RWFpl,FGpl - */ -struct fddrtab m765f[] = { /* format table */ - 80, 18, 1440, 9, 0x88, 0x2a, 0x50, /* [0] 3.50" 720 Kb */ - 80, 36, 2880, 18, 0x08, 0x1b, 0x6c, /* [1] 3.50" 1.44 Meg */ - 40, 18, 720, 9, 0xa8, 0x2a, 0x50, /* [2] 5.25" 360 Kb */ - 80, 30, 2400, 15, 0x08, 0x1b, 0x54 /* [3] 5.25" 1.20 Meg */ -}; - -/* - * The following are static initialization variables - * which are based on the configuration. - */ -struct ctrl_info ctrl_info[MAXUNIT>>1] = { /* device data table */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } , - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -struct unit_info unit_info[MAXUNIT]; /* unit buffer headers */ - -char *fderr = "FD Error on unit"; -char *fdmsg[] = { - "?", - "Missing data address mark", - "Write protected", - "Sector not found", - "Data Overrun", /* Over run error */ - "Uncorrectable data read error", /* CRC Error */ - "FDC Error", - "Illegal format type", - "Drive not ready", - "diskette not present - please insert", - "Illegal interrupt type" -}; - -struct buf fdrbuf[MAXUNIT]; /* data transfer buffer structures */ - -int fdminphys(); -int fdintr(), fdprobe(), fdslave(); -void fdattach(); -int FdDmaEISA = 0; -int FdDmaThreshold = 16 * 1024 * 1024; -vm_offset_t FdDmaPage = (vm_offset_t) 0; -vm_offset_t fd_std[NFD] = { 0 }; -struct bus_device *fd_dinfo[NFD*2]; -struct bus_ctlr *fd_minfo[NFD]; -struct bus_driver fddriver = - {fdprobe, fdslave, fdattach, 0, fd_std, "fd", fd_dinfo, "fdc", fd_minfo, 0}; - -int m765verify[MAXUNIT] = {1,1,1,1}; /* write after read flag */ - /* 0 != verify mode */ - /* 0 == not verify mode */ -#ifdef MACH_KERNEL -extern struct buf *geteblk(); -#endif /* MACH_KERNEL */ - -#define trfrate(uip, type) outb(VFOREG(uip->addr),(((type)&RATEMASK)>>6)) -#define rbskrate(uip, type) trfrate(uip,(type)&RAPID?RPSEEK:NMSEEK) -#define getparm(type) ((type<0||type>3)?(struct fddrtab *)ERROR:&m765f[type]) -#define relative(s1,s2) ((s1)>(s2)?(s1)-(s2):(s2)-(s1)) - -fdprobe(port, ctlr) -struct bus_ctlr *ctlr; -{ - int spot = STSREG((int) ctlr->address); - struct ctrl_info *cip = &ctrl_info[ctlr->unit]; - int i, in; - - outb(spot, DATAOK); - for (i = 1000; i--;) { - in = inb(spot); - if ((in&DATAOK) == DATAOK && !(in&0x0f)) { - take_ctlr_irq(ctlr); - cip->b_cmd.c_rbmtr = 0; /* recalibrate/moter flag */ - cip->b_cmd.c_intr = CMDRST; /* interrupt flag */ - cip->b_unitf = 0; - cip->b_uip = 0; - cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0; - cip->usebuf = 0; - if (FdDmaPage) { - cip->b_pbuf = FdDmaPage + PAGE_SIZE * ctlr->unit; - if (kmem_alloc_pageable(kernel_map, - (vm_offset_t *)&cip->b_vbuf, - PAGE_SIZE) != KERN_SUCCESS) { - printf("%s%d: can not kmem_alloc_pageable.\n", - ctlr->name, ctlr->unit); - return 0; - } - (void)pmap_map(cip->b_vbuf, - (vm_offset_t)cip->b_pbuf, - (vm_offset_t)cip->b_pbuf+PAGE_SIZE, - VM_PROT_READ | VM_PROT_WRITE); - } - printf("%s%d: port = %x, spl = %d, pic = %d.\n", ctlr->name, - ctlr->unit, ctlr->address, ctlr->sysdep, ctlr->sysdep1); - return(1); - } - } - return(0); -} - -fdslave(dev, xxxx) -struct bus_device *dev; -{ - return(1); /* gross hack */ -} - -void fdattach(dev) -struct bus_device *dev; -{ - struct unit_info *uip = &unit_info[dev->unit]; - struct ctrl_info *cip = &ctrl_info[dev->ctlr]; - - uip->dev = dev; - dev->address = dev->mi->address; - uip->addr = dev->address; - uip->b_cmd = &cip->b_cmd; - uip->b_seekaddr = 0; - uip->av_forw = 0; - uip->wakeme = 0; - if (cip->b_unitf) { - uip->b_unitf=cip->b_unitf->b_unitf; - cip->b_unitf->b_unitf=uip; - } else { - uip->b_unitf=uip; - cip->b_unitf=uip; - } - uip->d_drtab.dr_type &= ~OKTYPE; - - printf(", port = %x, spl = %d, pic = %d.", - dev->address, dev->sysdep, dev->sysdep1); - - rstout(uip); - specify(uip); -} -/***************************************************************************** - * - * TITLE: fdopen - * - * ABSTRACT: Open a unit. - * - ****************************************************************************/ -fdopen(dev, flag, otyp) -dev_t dev; -int flag; /* not used */ -int otyp; /* not used */ -{ - struct fddrtab *driv; - struct buf *wbp; - spl_t x = SPL(); - int error = 0; - int unit = UNIT(dev); - struct unit_info *uip = &unit_info[unit]; - int slave = uip->dev->slave; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - if (unit < MAXUNIT){ - /* Since all functions that use this are called from open, we only - set this once, right here. */ - rstout(uip); - cip->b_wup = uip; - openchk(cmdp); - cmdp->c_devflag |= FDMCHK; - chkbusy(cmdp); - cmdp->c_stsflag |= MTRFLAG; - mtr_on(uip); - if(inb(VFOREG(uip->addr))&OPENBIT || - !(uip->d_drtab.dr_type&OKTYPE)){ - uip->d_drtab.dr_type &= ~OKTYPE; - if(!rbrate(RAPID, uip)) - fdseek(RAPID, uip, 2); - if(inb(VFOREG(uip->addr))&OPENBIT) - error = ENXIO; - } - cmdp->c_stsflag &= ~MTRFLAG; - mtr_on(uip); - openfre(cmdp); - if(!error && !(uip->d_drtab.dr_type & OKTYPE)) { - if (MEDIATYPE(dev)>3) - goto endopen; - driv = &m765f[MEDIATYPE(dev)]; - wbp = geteblk(BLKSIZE); - m765sweep(uip, driv); - cmdp->c_rbmtr &= ~(1<<(RBSHIFT+(slave))); - ++cip->b_rwerr; - wbp->b_dev = dev; wbp->b_error = 0; wbp->b_resid = 0; - wbp->b_flags = (B_READ|B_VERIFY); wbp->b_bcount = 512; - wbp->b_pfcent = 2*driv->dr_spc + driv->dr_nsec - 1; - setqueue(wbp, uip); - biowait(wbp); - brelse(wbp); - error = 0; - uip->d_drtab.dr_type |= OKTYPE; - } - } else - error = ENXIO; - endopen: - splx(x); - return(error); -} -/***************************************************************************** - * - * TITLE: fdclose - * - * ABSTRACT: Close a unit. - * - * Called on last close. mark the unit closed and not-ready. - * - * Unix doesn't actually "open" an inode for rootdev, swapdev or pipedev. - * If UNIT(swapdev) != UNIT(rootdev), then must add code in init() to - * "open" swapdev. These devices should never be closed. - * - *****************************************************************************/ -fdclose(dev, flag, otyp, offset) -dev_t dev; /* major, minor numbers */ -int flag; /* not used */ -int otyp; /* not used */ -off_t offset; /* not used */ -{ - extern dev_t rootdev, swapdev; - struct unit_info *uip = &unit_info[UNIT(dev)]; - spl_t s; - -#ifdef MACH_KERNEL -#else /* MACH_KERNEL */ - if ((dev == rootdev) || (dev == swapdev)) /* never close these */ - return(0); -#endif /* MACH_KERNEL */ - - /* Clear the bit. - * If last close of drive insure drtab queue is empty before returning. - */ - s = SPL(); - while(uip->av_forw != 0) { - uip->wakeme = 1; - sleep(uip, PRIBIO); - } - splx(s); -#ifdef MACH_KERNEL - return(0); -#else /* MACH_KERNEL */ - close(0); -#endif /* MACH_KERNEL */ -} -/***************************************************************************** - * - * TITLE: fdstrategy - * - * ABSTRACT: Queue an I/O Request, and start it if not busy already. - * - * Reject request if unit is not-ready. - * - * Note: check for not-ready done here ==> could get requests - * queued prior to unit going not-ready. - * not-ready status to those requests that are attempted - * before a new volume is inserted. Once a new volume is - * inserted, would get good I/O's to wrong volume. - * - * CALLS: iodone(),setqueue() - * - * CALLING ROUTINES: fdread (indirectly, thru physio) - * fdwrite (indirectly, thru physio) - * - ****************************************************************************/ -fdstrategy(bp) -struct buf *bp; /* buffer header */ -{ - unsigned bytes_left; - daddr_t secno; - struct unit_info *uip = &unit_info[UNIT(bp->b_dev)]; - struct fddrtab *dr = &uip->d_drtab; - struct fddrtab *sdr; - - bp->b_error = 0; - /* set b_resid to b_bcount because we haven't done anything yet */ - bp->b_resid = bp->b_bcount; - if (!(dr->dr_type & OKTYPE) || - ((sdr = getparm(MEDIATYPE(bp->b_dev)))==(struct fddrtab *)ERROR) || - /* wrong parameters */ - (sdr->dr_ncyl != dr->dr_ncyl) || (sdr->dr_nsec != dr->dr_nsec) || - ((sdr->dr_type|OKTYPE) != dr->dr_type) || - (sdr->dr_rwgpl != dr->dr_rwgpl) || - (sdr->dr_fgpl != dr->dr_fgpl)) { - bp->b_flags |= B_ERROR; - bp->b_error = EIO; - biodone(bp); - return(0); - } - /* - * Figure "secno" from b_blkno. Adjust sector # for partition. - * - * If reading just past the end of the device, it's - * End of File. If not reading, or if read starts further in - * than the first sector after the partition, it's an error. - * - * secno is logical blockno / # of logical blocks per sector */ - secno = (bp->b_blkno * NBPSCTR) >> 9; - if (secno >= dr->p_nsec) { - if (!((bp->b_flags & B_READ) && (secno == dr->p_nsec))){ - /* off the deep end */ - bp->b_flags |= B_ERROR; - bp->b_error = ENXIO; - } - biodone(bp); - return(0); - } -/* At this point, it is no longer possible to directly return from strategy. - We now set b_resid to the number of bytes we cannot transfer because - they lie beyond the end of the request's partition. This value is 0 - if the entire request is within the partition. */ - bytes_left = (dr->p_nsec - secno) << 9; - bp->b_resid = ((bp->b_bcount<=bytes_left)?0:(bp->b_bcount-bytes_left)); - bp->b_pfcent = secno; - setqueue(bp, uip); - return(0); -} - -/*************************************************************************** - * - * set queue to buffer - * - ***************************************************************************/ -setqueue(bp, uip) -struct buf *bp; -struct unit_info *uip; -{ - spl_t x = SPL(); - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - openchk(cmdp); /* openning check */ - cmdp->c_devflag |= STRCHK; - fd_disksort(uip, bp); /* queue the request */ - /* - * If no requests are in progress, start this one up. Else - * leave it on the queue, and fdintr will call m765io later. - */ - if(!cip->b_uip) - m765io(uip); - splx(x); -} -/*************************************************************************** - * - * check io_busy routine - * - ***************************************************************************/ -chkbusy(cmdp) -struct fdcmd *cmdp; -{ - while(cmdp->c_devflag & STRCHK){ - cmdp->c_devflag |= STRWAIT; - sleep(&cmdp->c_devflag,PZERO); - } -} -/*************************************************************************** - * - * check fdopen() routine - * - ***************************************************************************/ -openchk(cmdp) -struct fdcmd *cmdp; -{ - while(cmdp->c_devflag & FDMCHK ){ - cmdp->c_devflag |= FDWAIT; - sleep(&cmdp->c_devflag,PZERO); - } -} -/*************************************************************************** - * - * free fdopen() routine - * - ***************************************************************************/ -openfre(cmdp) -struct fdcmd *cmdp; -{ - cmdp->c_devflag &= ~FDMCHK; - if(cmdp->c_devflag & FDWAIT){ - cmdp->c_devflag &= ~FDWAIT; - wakeup(&cmdp->c_devflag); - } -} -/***************************************************************************** - * - * TITLE: m765io - * - * ABSTRACT: Start handling an I/O request. - * - ****************************************************************************/ -m765io(uip) -struct unit_info *uip; -{ - extern int(m765iosub)(); - register struct buf *bp; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - - bp = uip->av_forw; /*move bp to ctrl_info[ctrl].b_buf*/ - cip->b_buf = bp; - cip->b_uip = uip; - cip->b_xferaddr = bp->b_un.b_addr; - cip->b_xfercount = bp->b_bcount - bp->b_resid; - cip->b_sector = bp->b_pfcent; - uip->b_cmd->c_stsflag |= MTRFLAG; - if(!mtr_start(uip)) - timeout(m765iosub, uip, HZ); - else - m765iosub(uip); -} -/**************************************************************************** - * - * m765io subroutine - * - ****************************************************************************/ -m765iosub(uip) -struct unit_info *uip; -{ - struct fddrtab *dr = &uip->d_drtab; - int startsec; - int slave = uip->dev->slave; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - rwcmdset(uip); - if(cip->b_buf->b_flags&B_FORMAT) - goto skipchk; - startsec = (cmdp->c_rwdata[3] * dr->dr_nsec) + cmdp->c_rwdata[4]; - if(startsec+(cip->b_xfercount>>9)-1 > dr->dr_spc) - cip->b_xferdma = (dr->dr_spc-startsec+1) << 9; - else -skipchk: cip->b_xferdma = cip->b_xfercount; - if(!(cmdp->c_rbmtr & (1<<(RBSHIFT+slave)))) - cip->b_status = rbirate(uip); - else if(uip->b_seekaddr != cmdp->c_saddr) - cip->b_status = fdiseek(uip,cmdp->c_saddr); - else - cip->b_status = outicmd(uip); - if(cip->b_status) - intrerr0(uip); - return; -} -/*************************************************************************** - * - * read / write / format / verify command set to command table - * - ***************************************************************************/ -rwcmdset(uip) -struct unit_info *uip; -{ - short resid; - int slave = uip->dev->slave; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - switch(cip->b_buf->b_flags&(B_FORMAT|B_VERIFY|B_READ|B_WRITE)){ - case B_VERIFY|B_WRITE: /* VERIFY after WRITE */ - cmdp->c_rwdata[0] = RDMV; - break; - case B_FORMAT: - cmdp->c_dcount = FMTCNT; - cmdp->c_rwdata[0] = FMTM; - cmdp->c_saddr = cip->b_sector / uip->d_drtab.dr_spc; - resid = cip->b_sector % uip->d_drtab.dr_spc; - cmdp->c_rwdata[1] = slave|((resid/uip->d_drtab.dr_nsec)<<2); - cmdp->c_rwdata[2] = - ((struct fmttbl *)cip->b_buf->b_un.b_addr)->s_type; - cmdp->c_rwdata[3] = uip->d_drtab.dr_nsec; - cmdp->c_rwdata[4] = uip->d_drtab.dr_fgpl; - cmdp->c_rwdata[5] = FMTDATA; - break; - case B_WRITE: - case B_READ: - case B_READ|B_VERIFY: - cmdp->c_dcount = RWCNT; - if(cip->b_buf->b_flags&B_READ) - if(cip->b_buf->b_flags&B_VERIFY) - cmdp->c_rwdata[0] = RDMV; - else - cmdp->c_rwdata[0] = RDM; - else - cmdp->c_rwdata[0] = WTM; /* format or write */ - resid = cip->b_sector % uip->d_drtab.dr_spc; - cmdp->c_rwdata[3] = resid / uip->d_drtab.dr_nsec; - cmdp->c_rwdata[1] = slave|(cmdp->c_rwdata[3]<<2); - cmdp->c_rwdata[2] = cmdp->c_saddr = - cip->b_sector / uip->d_drtab.dr_spc; - cmdp->c_rwdata[4] = (resid % uip->d_drtab.dr_nsec) + 1; - cmdp->c_rwdata[5] = 2; - cmdp->c_rwdata[6] = uip->d_drtab.dr_nsec; - cmdp->c_rwdata[7] = uip->d_drtab.dr_rwgpl; - cmdp->c_rwdata[8] = DTL; - D(printf("SET %x %x C%x H%x S%x %x %x %x %x ", - cmdp->c_rwdata[0], cmdp->c_rwdata[1], - cmdp->c_rwdata[2], cmdp->c_rwdata[3], - cmdp->c_rwdata[4], cmdp->c_rwdata[5], - cmdp->c_rwdata[6], cmdp->c_rwdata[7], - cmdp->c_rwdata[8])); - break; - } -} -/***************************************************************************** - * - * TITLE: fdread - * - * ABSTRACT: "Raw" read. Use physio(). - * - * CALLS: m765breakup (indirectly, thru physio) - * - ****************************************************************************/ -fdread(dev, uio) -register dev_t dev; -struct uio *uio; -{ -#ifdef MACH_KERNEL - /* no need for page-size restriction */ - return (block_io(fdstrategy, minphys, uio)); -#else /* MACH_KERNEL */ - return(physio(fdstrategy,&fdrbuf[UNIT(dev)],dev,B_READ,fdminphys,uio)); -#endif /* MACH_KERNEL */ -} -/***************************************************************************** - * - * TITLE: fdwrite - * - * ABSTRACT: "Raw" write. Use physio(). - * - * CALLS: m765breakup (indirectly, thru physio) - * - ****************************************************************************/ -fdwrite(dev, uio) -register dev_t dev; -struct uio *uio; -{ -#ifdef MACH_KERNEL - /* no need for page-size restriction */ - return (block_io(fdstrategy, minphys, uio)); -#else /* MACH_KERNEL */ - return(physio(fdstrategy,&fdrbuf[UNIT(dev)],dev,B_WRITE,fdminphys,uio)); -#endif /* MACH_KERNEL */ -} -/***************************************************************************** - * - * TITLE: fdminphys - * - * ABSTRACT: Trim buffer length if buffer-size is bigger than page size - * - * CALLS: physio - * - ****************************************************************************/ -fdminphys(bp) -struct buf *bp; -{ - if (bp->b_bcount > PAGESIZ) - bp->b_bcount = PAGESIZ; -} -#ifdef MACH_KERNEL -/* IOC_OUT only and not IOC_INOUT */ -io_return_t fdgetstat(dev, flavor, data, count) - dev_t dev; - int flavor; - int * data; /* pointer to OUT array */ - unsigned int *count; /* OUT */ -{ - switch (flavor) { - - /* Mandatory flavors */ - - case DEV_GET_SIZE: { - int ret; - struct disk_parms p; - - ret = fd_getparms(dev, &p); - if (ret) return ret; - data[DEV_GET_SIZE_DEVICE_SIZE] = p.dp_pnumsec * NBPSCTR; - data[DEV_GET_SIZE_RECORD_SIZE] = NBPSCTR; - *count = DEV_GET_SIZE_COUNT; - break; - } - - /* Extra flavors */ - - case V_GETPARMS: - if (*count < sizeof (struct disk_parms)/sizeof (int)) - return (D_INVALID_OPERATION); - *count = sizeof (struct disk_parms)/sizeof(int); - return (fd_getparms(dev, data)); - default: - return (D_INVALID_OPERATION); - } -} -/* IOC_VOID or IOC_IN or IOC_INOUT */ -/*ARGSUSED*/ -io_return_t fdsetstat(dev, flavor, data, count) - dev_t dev; - int flavor; - int * data; - unsigned int count; -{ - int unit = UNIT(dev); - switch (flavor) { - case V_SETPARMS: /* Caller wants reset_parameters */ - return(fd_setparms(unit,*(int *)data)); - case V_FORMAT: - return(fd_format(dev,data)); - case V_VERIFY: /* cmdarg : 0 == no verify, 0 != verify */ - m765verify[unit] = *(int *)data; - return(D_SUCCESS); - default: - return(D_INVALID_OPERATION); - } -} - -/* - * Get block size - */ -int -fddevinfo(dev, flavor, info) -dev_t dev; -int flavor; -char *info; -{ - register struct fddrtab *dr; - register struct fdpart *p; - register int result = D_SUCCESS; - - switch (flavor) { - case D_INFO_BLOCK_SIZE: - dr = &unit_info[UNIT(dev)].d_drtab; - - if(dr->dr_type & OKTYPE) - *((int *) info) = 512; - else - result = D_INVALID_OPERATION; - - break; - default: - result = D_INVALID_OPERATION; - } - - return(result); -} -#else /* MACH_KERNEL */ -/***************************************************************************** - * - * TITLE: fdioctl - * - * ABSTRACT: m765 driver special functions. - * - * CALLING ROUTINES: kernel - * - ****************************************************************************/ -int -fdioctl(dev, cmd, cmdarg, flag) -dev_t dev; /* major, minor numbers */ -int cmd; /* command code */ -int *cmdarg; /* user structure with parameters */ -int flag; /* not used */ -{ - register unsigned unit = UNIT(dev); - switch (cmd) { - case V_SETPARMS: /* Caller wants reset_parameters */ - return(fd_setparms(unit,*cmdarg)); - case V_GETPARMS: /* Caller wants device parameters */ - return(fd_getparms(dev,cmdarg)); - case V_FORMAT: - return(fd_format(dev,cmdarg)); - case V_VERIFY: /* cmdarg : 0 == no verify, 0 != verify */ - m765verify[unit] = *cmdarg; - return(0); - } - return(EINVAL); -} -#endif /* MACH_KERNEL */ -/**************************************************************************** - * - * set fd parameters - * - ****************************************************************************/ -int -fd_setparms(unit, cmdarg) -register unsigned int unit; -long cmdarg; -{ - struct fddrtab *fdparm; - spl_t x; - struct unit_info *uip = &unit_info[unit]; - struct fdcmd *cmdp = uip->b_cmd; - - cmdp->c_rbmtr &= ~(1<<(RBSHIFT+uip->dev->slave)); - if ((fdparm = getparm(MEDIATYPE(cmdarg))) == (struct fddrtab *)ERROR) - return(EINVAL); - x = SPL(); - openchk(cmdp); - cmdp->c_devflag |= FDMCHK; - chkbusy(cmdp); - m765sweep(uip, fdparm); - uip->d_drtab.dr_type |= OKTYPE; - openfre(cmdp); - splx(x); - return(0); -} -/**************************************************************************** - * - * get fd parameters - * - ****************************************************************************/ -int -fd_getparms(dev,cmdarg) -dev_t dev; /* major, minor numbers */ -int *cmdarg; -{ - struct disk_parms *diskp = (struct disk_parms *)cmdarg; - register struct fddrtab *dr = &unit_info[UNIT(dev)].d_drtab; - - if(dr->dr_type & OKTYPE){ - diskp->dp_type = DPT_FLOPPY; - diskp->dp_heads = 2; - diskp->dp_sectors = dr->dr_nsec; - diskp->dp_pstartsec = 0; - diskp->dp_cyls = dr->dr_ncyl; - diskp->dp_pnumsec = dr->p_nsec; - return(0); - } - return(ENXIO); -} -/**************************************************************************** - * - * format command - * - ****************************************************************************/ -fd_format(dev,cmdarg) -dev_t dev; /* major, minor numbers */ -int *cmdarg; - -{ - register struct buf *bp; - register daddr_t track; - union io_arg *varg; - u_short num_trks; - register struct fddrtab *dr = &unit_info[UNIT(dev)].d_drtab; - - if(!(dr->dr_type & OKTYPE)) - return(EINVAL); - varg = (union io_arg *)cmdarg; - num_trks = varg->ia_fmt.num_trks; - track = (daddr_t)(varg->ia_fmt.start_trk*dr->dr_nsec); - if((track + (num_trks*dr->dr_nsec))>dr->p_nsec) - return(EINVAL); - bp = geteblk(BLKSIZE); /* get struct buf area */ - while (num_trks>0) { - bp->b_flags &= ~B_DONE; - bp->b_dev = dev; - bp->b_error = 0; bp->b_resid = 0; - bp->b_flags = B_FORMAT; - bp->b_bcount = dr->dr_nsec * FMTID; - bp->b_blkno = (daddr_t)((track << 9) / NBPSCTR); - if(makeidtbl(bp->b_un.b_addr,dr, - varg->ia_fmt.start_trk++,varg->ia_fmt.intlv)) - return(EINVAL); - fdstrategy(bp); - biowait(bp); - if(bp->b_error) - if((bp->b_error == (char)EBBHARD) || - (bp->b_error == (char)EBBSOFT)) - return(EIO); - else - return(bp->b_error); - num_trks--; - track += dr->dr_nsec; - } - brelse(bp); - return(0); -} -/**************************************************************************** - * - * make id table for format - * - ****************************************************************************/ -makeidtbl(tblpt,dr,track,intlv) -struct fmttbl *tblpt; -struct fddrtab *dr; -unsigned short track; -unsigned short intlv; -{ - register int i,j,secno; - - if(intlv >= dr->dr_nsec) - return(1); - for(i=0; i<dr->dr_nsec; i++) - tblpt[i].sector = 0; - for(i=0,j=0,secno=1; i<dr->dr_nsec; i++){ - tblpt[j].cyl = track >> 1; - tblpt[j].head = track & 1; - tblpt[j].sector = secno++; - tblpt[j].s_type = 2; - if((j+=intlv) < dr->dr_nsec) - continue; - for(j-=dr->dr_nsec; j < dr->dr_nsec ; j++) - if(!tblpt[j].sector) - break; - } - return(0); -} -/***************************************************************************** - * - * TITLE: fdintr - * - * ABSTRACT: Handle interrupt. - * - * Interrupt procedure for m765 driver. Gets status of last - * operation and performs service function according to the - * type of interrupt. If it was an operation complete interrupt, - * switches on the current driver state and either declares the - * operation done, or starts the next operation - * - ****************************************************************************/ -fdintr(ctrl) -int ctrl; -{ - extern int(m765intrsub)(); - struct unit_info *uip = ctrl_info[ctrl].b_uip; - struct unit_info *wup = ctrl_info[ctrl].b_wup; - struct fdcmd *cmdp = &ctrl_info[ctrl].b_cmd; - if(cmdp->c_stsflag & INTROUT) - untimeout(fdintr, ctrl); - cmdp->c_stsflag &= ~INTROUT; - switch(cmdp->c_intr){ - case RWFLAG: - rwintr(uip); - break; - case SKFLAG: - case SKEFLAG|SKFLAG: - case RBFLAG: - timeout(m765intrsub, uip, SEEKWAIT); - break; - case WUPFLAG: - cmdp->c_intr &= ~WUPFLAG; - wakeup(wup); - } - return(0); -} -/***************************************************************************** - * - * interrup subroutine (seek recalibrate) - * - *****************************************************************************/ -m765intrsub(uip) -struct unit_info *uip; -{ - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - - if((cip->b_status = sis(uip))!= ST0OK) - switch(uip->b_cmd->c_intr){ - case SKFLAG: - seekintr(uip); - break; - case SKEFLAG|SKFLAG: - seekintre(uip); - break; - case RBFLAG: - rbintr(uip); - } -} -/***************************************************************************** - * - * read / write / format / verify interrupt routine - * - *****************************************************************************/ -rwintr(uip) -struct unit_info *uip; -{ - int rsult[7]; - register int rtn, count; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - cmdp->c_intr &= ~RWFLAG; - if((cip->b_buf->b_flags&(B_READ|B_VERIFY))!=(B_READ|B_VERIFY)) - if(inb(VFOREG(uip->addr))&OPENBIT){ - if(cip->b_buf->b_flags&B_FORMAT){ - cip->b_status = TIMEOUT; - intrerr0(uip); - } else { - if((inb(STSREG(uip->addr))&ST0OK)!=ST0OK) - printf("%s %d : %s\n", - fderr, - uip-unit_info, - fdmsg[DOORERR]); - rstout(uip); - specify(uip); - cmdp->c_rbmtr &= RBRST; - cmdp->c_intr |= SKEFLAG; - if(cmdp->c_saddr > 2) - fdiseek(uip, cmdp->c_saddr-2); - else - fdiseek(uip, cmdp->c_saddr+2); - } - return; - } - for( count = 0 ; count < 7 ; count++ ){ - if(rtn = fdc_sts(FD_ISTS, uip)) /* status check */ - goto rwend; - rsult[count] = inb(DATAREG(uip->addr)); - } - rtn = 0; - if(rsult[0]&0xc0){ - rtn = cmdp->c_rwdata[0]<<8; - if(rsult[0]&0x80){ rtn |= FDCERR; goto rwend; } - if(rsult[1]&0x80){ rtn |= NOREC; goto rwend; } - if(rsult[1]&0x20){ rtn |= CRCERR; goto rwend; } - if(rsult[1]&0x10){ rtn |= OVERRUN; goto rwend; } - if(rsult[1]&0x04){ rtn |= NOREC; goto rwend; } - if(rsult[1]&0x02){ rtn |= WTPRT; goto rwend; } - if(rsult[1]&0x01){ rtn |= ADDRERR; goto rwend; } - rtn |= FDCERR; -rwend: outb(0x0a, 0x06); - } - if(cip->b_status = rtn) { - D(printf("\n->rwierr %x ", rtn)); - rwierr(uip); - } else { /* write command */ - if(((cip->b_buf->b_flags&(B_FORMAT|B_READ|B_WRITE))==B_WRITE) - && !(cip->b_buf->b_flags & B_VERIFY)) { - D(printf("->w/v ")); - cip->b_buf->b_flags |= B_VERIFY; - rwcmdset(uip); - if(cip->b_status = outicmd(uip)) - intrerr0(uip); - return; - } - /* clear retry count */ - if (cip->usebuf) { - bcopy(cip->b_vbuf, cip->b_xferaddr, cip->b_xferdma); - DD(printf("R(%x, %x, %x)\n", - cip->b_vbuf, cip->b_xferaddr, cip->b_xferdma)); - } - cip->b_buf->b_flags &= ~B_VERIFY; - cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0; - cip->b_xfercount -= cip->b_xferdma; - cip->b_xferaddr += cip->b_xferdma; - cip->b_sector = cip->b_sector+(cip->b_xferdma>>9); - D(printf("->done%s\n", cip->b_xfercount?"":"." )); - /* next address (cyl,head,sec) */ - if((int)cip->b_xfercount>0) - m765iosub(uip); - else - quechk(uip); - } -} -/***************************************************************************** - * - * read / write / format / verify error routine - * - *****************************************************************************/ -rwierr(uip) -struct unit_info *uip; -{ - short status; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - D(printf("%x-%x-%x ", cip->b_rwerr&SRMASK, cip->b_rwerr&MRMASK, cip->b_rwerr&LRMASK)); - if((cip->b_buf->b_flags&(B_READ|B_VERIFY))==(B_READ|B_VERIFY)){ - if((cip->b_rwerr&SRMASK)<MEDIARD) - goto rwrtry; - if((cip->b_rwerr&MRMASK)<MEDIASEEK) - goto rwseek; - goto rwexit; - } else - if(cip->b_buf->b_flags&B_VERIFY){ - cip->b_buf->b_flags &= ~B_VERIFY; - rwcmdset(uip); - } -rwrtry: status = cip->b_status; - if((++cip->b_rwerr&SRMASK)<SRETRY) - cip->b_status = outicmd(uip); - else { -rwseek: cip->b_rwerr = (cip->b_rwerr&RMRMASK)+MINC; - if((cip->b_rwerr&MRMASK)<MRETRY){ - cmdp->c_intr |= SKEFLAG; - if(cmdp->c_saddr > 2) - cip->b_status=fdiseek(uip,cmdp->c_saddr-2); - else - cip->b_status=fdiseek(uip,cmdp->c_saddr+2); - } else { - cip->b_rwerr = (cip->b_rwerr&LRMASK)+LINC; - if((cip->b_rwerr&LRMASK)<LRETRY) - cip->b_status=rbirate(uip); - } - } - if(cip->b_status){ - D(printf("ERR->intrerr0 ")); - cip->b_status = status; -rwexit: intrerr0(uip); - } -} -/***************************************************************************** - * - * recalibrate interrupt routine - * - *****************************************************************************/ -rbintr(uip) -struct unit_info *uip; -{ - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - cmdp->c_intr &= ~RBFLAG; - if(cip->b_status) { - if(++cip->b_rberr<SRETRY) - cip->b_status = rbirate(uip); - } else { - cmdp->c_rbmtr |= 1<<(RBSHIFT+uip->dev->slave); - uip->b_seekaddr = 0; - cip->b_rberr = 0; - cip->b_status=fdiseek(uip, cmdp->c_saddr); - } - if(cip->b_status) - intrerr0(uip); -} -/****************************************************************************** - * - * seek interrupt routine - * - *****************************************************************************/ -seekintr(uip) -struct unit_info *uip; -{ - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - cmdp->c_intr &= ~SKFLAG; - if(cip->b_status) - seekierr(uip, cmdp->c_saddr); - else { - uip->b_seekaddr = cmdp->c_saddr; - cip->b_status = outicmd(uip); - } - if(cip->b_status) - intrerr0(uip); - else - cip->b_seekerr = 0; -} -/***************************************************************************** - * - * seek error retry interrupt routine - * - *****************************************************************************/ -seekintre(uip) -struct unit_info *uip; -{ - register char seekpoint; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - - cmdp->c_intr &= ~(SKEFLAG|SKFLAG); - if(cmdp->c_saddr > 2) - seekpoint = cmdp->c_saddr-2; - else - seekpoint = cmdp->c_saddr+2; - if(cip->b_status) - seekierr(uip, seekpoint); - else { - uip->b_seekaddr = seekpoint; - cip->b_status = fdiseek(uip, cmdp->c_saddr); - } - if(cip->b_status) - intrerr0(uip); - else - cip->b_seekerr = 0; -} -/***************************************************************************** - * - * seek error routine - * - *****************************************************************************/ -seekierr(uip, seekpoint) -struct unit_info *uip; -register char seekpoint; -{ - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - - if((++cip->b_seekerr&SRMASK)<SRETRY) - cip->b_status=fdiseek(uip, seekpoint); - else { - cip->b_seekerr = (cip->b_seekerr&MRMASK) + MINC; - if((cip->b_seekerr&MRMASK)<MRETRY) - cip->b_status=rbirate(uip); - } - if(cip->b_status) - intrerr0(uip); -} -/***************************************************************************** - * - * TITLE: m765sweep - * - * ABSTRACT: Perform an initialization sweep. - * - **************************************************************************/ -m765sweep(uip, cdr) -struct unit_info *uip; -register struct fddrtab *cdr; /* device initialization data */ -{ - register struct fddrtab *dr = &uip->d_drtab; - - dr->dr_ncyl = cdr->dr_ncyl; - dr->dr_nsec = cdr->dr_nsec; - dr->dr_spc = cdr->dr_spc; - dr->p_nsec = cdr->p_nsec; - dr->dr_type = cdr->dr_type; - dr->dr_rwgpl= cdr->dr_rwgpl; - dr->dr_fgpl = cdr->dr_fgpl; -} -/***************************************************************************** - * - * TITLE: m765disksort - * - *****************************************************************************/ -fd_disksort(uip, bp) -struct unit_info *uip; /* Pointer to head of active queue */ -register struct buf *bp; /* Pointer to buffer to be inserted */ -{ - register struct buf *bp2; /* Pointer to next buffer in queue */ - register struct buf *bp1; /* Pointer where to insert buffer */ - - if (!(bp1 = uip->av_forw)) { - /* No other buffers to compare against */ - uip->av_forw = bp; - bp->av_forw = 0; - return; - } - bp2 = bp1->av_forw; - while(bp2 && (relative(bp1->b_pfcent,bp->b_pfcent) >= - relative(bp1->b_pfcent,bp2->b_pfcent))) { - bp1 = bp2; - bp2 = bp1->av_forw; - } - bp1->av_forw = bp; - bp->av_forw = bp2; -} -/***************************************************************************** - * - * Set Interrupt error and FDC reset - * - *****************************************************************************/ -intrerr0(uip) -struct unit_info *uip; -{ - struct buf *bp; /* Pointer to next buffer in queue */ - int resid; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - register struct fddrtab *dr = &uip->d_drtab; - - if((cip->b_buf->b_flags&(B_READ|B_VERIFY))!=(B_READ|B_VERIFY)){ - resid = cip->b_xfercount = cip->b_xferdma-1-inb(DMACNT)*0x101; - resid = (cip->b_sector + (resid>>9)) % dr->dr_spc; - printf("%s %d : %s\n", - fderr, - uip->dev->slave, - fdmsg[cip->b_status&BYTEMASK]); - printf("cylinder = %d ",cmdp->c_saddr); - printf("head = %d sector = %d byte/sec = %d\n", - resid / dr->dr_nsec , (resid % dr->dr_nsec)+1 , 512); - } - cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0; - cmdp->c_intr = CMDRST; - if(((cip->b_buf->b_flags&(B_READ|B_VERIFY))!=(B_READ|B_VERIFY)) && - uip->dev->slave) - dr->dr_type &= ~OKTYPE; - bp = cip->b_buf; - bp->b_flags |= B_ERROR; - switch(cip->b_status&BYTEMASK){ - case ADDRERR: - case OVERRUN: - case FDCERR: - case TIMEOUT: - bp->b_error = EIO; - break; - case WTPRT: -#ifdef MACH_KERNEL - bp->b_error = ENXIO; -#else - bp->b_error = ENODEV; -#endif - break; - case NOREC: - bp->b_error = EBBHARD; - break; - case CRCERR: - bp->b_error = EBBSOFT; - } - rstout(uip); - specify(uip); - cmdp->c_rbmtr &= RBRST; - quechk(uip); -} -/***************************************************************************** - * - * Next queue check routine - * - *****************************************************************************/ -quechk(uip) -struct unit_info *uip; -{ - register struct buf *bp = uip->av_forw; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct unit_info *loop; - struct fdcmd *cmdp = uip->b_cmd; - /* clear retry count */ - cip->b_rwerr = cip->b_seekerr = cip->b_rberr = 0; - bp->b_resid = bp->b_resid + cip->b_xfercount; - uip->av_forw=bp->av_forw; - if (!uip->av_forw && uip->wakeme) { - uip->wakeme = 0; - wakeup(uip); - } - biodone(bp); - loop = uip; - do { - loop=loop->b_unitf; - if (loop->av_forw) { - m765io(loop); - return; - } - } while (loop!=uip); - cip->b_uip = 0; - cmdp->c_stsflag &= ~MTRFLAG; - mtr_on(uip); - cmdp->c_devflag &= ~STRCHK; - if(cmdp->c_devflag & STRWAIT){ - cmdp->c_devflag &= ~STRWAIT; - wakeup(&cmdp->c_devflag); - } -} -fdprint(dev,str) -dev_t dev; -char *str; -{ - printf("floppy disk driver: %s on bad dev %d, partition %d\n", - str, UNIT(dev), 0); -} -fdsize() -{ - printf("fdsize() -- not implemented\n"); -} -fddump() -{ - printf("fddump() -- not implemented\n"); -} -/***************************************************************************** - * - * fdc reset routine - * - *****************************************************************************/ -rstout(uip) -struct unit_info *uip; -{ - register int outd; - - outd = ((uip->b_cmd->c_rbmtr&MTRMASK)<<MTR_ON)|uip->dev->slave; - outb(CTRLREG(uip->addr), outd); - outd |= FDC_RST; - outb(CTRLREG(uip->addr), outd); - outd |= DMAREQ; - outb(CTRLREG(uip->addr), outd); -} -/***************************************************************************** - * - * specify command routine - * - *****************************************************************************/ -specify(uip) -struct unit_info *uip; -{ - /* status check */ - if(fdc_sts(FD_OSTS, uip)) - return; - /* Specify command */ - outb(DATAREG(uip->addr), SPCCMD); - /* status check */ - if(fdc_sts(FD_OSTS, uip)) - return; - /* Step rate,Head unload time */ - outb(DATAREG(uip->addr), SRTHUT); - /* status check */ - if(fdc_sts(FD_OSTS, uip)) - return; - /* Head load time,Non DMA Mode*/ - outb(DATAREG(uip->addr), HLTND); - return; -} -/**************************************************************************** - * - * recalibrate command routine - * - ****************************************************************************/ -rbrate(mtype,uip) -char mtype; -struct unit_info *uip; -{ - register int rtn = 1, rty_flg=2; - spl_t x; - struct fdcmd *cmdp = uip->b_cmd; - - rbskrate(uip, mtype); /* set transfer rate */ - while((rty_flg--)&&rtn){ - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - break; - /*recalibrate command*/ - outb(DATAREG(uip->addr), RBCMD); - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - break; - /* Device to wake up specified in open */ - cmdp->c_intr |= WUPFLAG; - x = SPL(); - outb(DATAREG(uip->addr), uip->dev->slave); - rtn = ERROR; - while(rtn) { - uip->wakeme = 1; - sleep(uip, PZERO); - if((rtn = sis(uip)) == ST0OK) - /* Device to wake up specified in open */ - cmdp->c_intr |= WUPFLAG; - else - break; - } - splx(x); - } - return(rtn); -} -/***************************************************************************** - * - * seek command routine - * - ****************************************************************************/ -fdseek(mtype, uip, cylno) -register char mtype; -struct unit_info *uip; -register int cylno; -{ - spl_t x; - int rtn; - struct fdcmd *cmdp = uip->b_cmd; - - rbskrate(uip, mtype); - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - return(rtn); - outb(DATAREG(uip->addr), SEEKCMD); /* seek command */ - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - return(rtn); - outb(DATAREG(uip->addr), uip->dev->slave); /* drive number */ - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - return(rtn); - x = SPL(); - /* Device to wake up specified in open */ - cmdp->c_intr |= WUPFLAG; - outb(DATAREG(uip->addr), cylno); /* seek count */ - rtn = ERROR; - while(rtn){ - uip->wakeme = 1; - sleep(uip, PZERO); - if((rtn = sis(uip)) == ST0OK) - /* Device to wake up specified in open */ - cmdp->c_intr |= WUPFLAG; - else - break; - } - splx(x); - return(rtn); -} -/***************************************************************************** - * - * seek commnd routine(use interrupt) - * - *****************************************************************************/ -fdiseek(uip, cylno) -struct unit_info *uip; -int cylno; -{ - register int rtn; - - D(printf("SK %x ", cylno)); - rbskrate(uip, uip->d_drtab.dr_type);/* set transfer rate */ - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - goto fdiend; - outb(DATAREG(uip->addr), SEEKCMD); /* seek command */ - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - goto fdiend; - outb(DATAREG(uip->addr), uip->dev->slave); /* drive number */ - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - goto fdiend; - uip->b_seekaddr = cylno; - if(uip->d_drtab.dr_type&DOUBLE) - cylno = cylno * 2; - uip->b_cmd->c_intr |= SKFLAG; - outb(DATAREG(uip->addr), cylno); /* seek count */ -fdiend: - if(rtn) - rtn |= SEEKCMD<<8; - return(rtn); -} -/***************************************************************************** - * - * recalibrate command routine(use interrupt) - * - *****************************************************************************/ -rbirate(uip) -struct unit_info *uip; -{ - register int rtn; - - rbskrate(uip, uip->d_drtab.dr_type);/* set transfer rate */ - if(!(rtn = fdc_sts(FD_OSTS, uip))) { /* status check */ - /* recalibrate command */ - outb(DATAREG(uip->addr), RBCMD); - if(!(rtn = fdc_sts(FD_OSTS, uip))) { /* status check */ - uip->b_cmd->c_intr |= RBFLAG; - outb(DATAREG(uip->addr), uip->dev->slave); - } - } - return(rtn ? rtn|RBCMD<<8 : 0); -} -/***************************************************************************** - * - * read / write / format / verify command out routine(use interrupt) - * - *****************************************************************************/ -outicmd(uip) -struct unit_info *uip; -{ - int rtn; - register int *data,cnt0,dmalen; - register long address; - struct ctrl_info *cip = &ctrl_info[uip->dev->ctlr]; - struct fdcmd *cmdp = uip->b_cmd; - spl_t x = splhi(); - - outb(DMACMD1,DMADATA0); /* DMA #1 command register */ - outb(DMAMSK1,DMADATA1); /* DMA #1 all mask register */ - /* Perhaps outb(0x0a,0x02); might work better on line above? */ - switch(cmdp->c_rwdata[0]){ - case RDM: - D(printf("RDM")); - outb(DMABPFF,DMARD); - outb(DMAMODE,DMARD); - break; - case WTM: - case FMTM: - D(printf("W")); - outb(DMABPFF,DMAWT); - outb(DMAMODE,DMAWT); - break; - case RDMV: - D(printf("RDMV")); - outb(DMABPFF,DMAVRF); - outb(DMAMODE,DMAVRF); - } - /* get work buffer physical address */ - address = kvtophys(cip->b_xferaddr); - dmalen = i386_trunc_page(address) + I386_PGBYTES - address; - if ( (cip->b_rwerr&MRMASK) >= 0x10) - dmalen = 0x200; - if (dmalen<=cip->b_xferdma) - cip->b_xferdma = dmalen; - else - dmalen = cip->b_xferdma; - if (address >= FdDmaThreshold) { - DD(printf(">(%x[%x], %x[%x] L%x\n", - address, cip->b_pbuf, - cip->b_xferaddr, cip->b_vbuf, dmalen)); - if (!FdDmaEISA) { - cip->usebuf = 1; - address = (long)cip->b_pbuf; - if (cmdp->c_rwdata[0] == WTM || cmdp->c_rwdata[0] == FMTM) { - bcopy(cip->b_xferaddr, cip->b_vbuf, dmalen); - DD(printf("W(%x, %x, %x)\n", - cip->b_xferaddr, cip->b_vbuf, dmalen)); - } - } else - cip->usebuf = 0; - } else - cip->usebuf = 0; - D(printf(" %x L%x ", address, dmalen)); - /* set buffer address */ - outb(DMAADDR,(int)address&BYTEMASK); - outb(DMAADDR,(((int)address>>8)&BYTEMASK)); - outb(DMAPAGE,(((int)address>>16)&BYTEMASK)); - if (FdDmaEISA) - outb(FdDmaEISA+DMAPAGE-0x80,(((int)address>>24)&BYTEMASK)); - /* set transfer count */ - outb(DMACNT,(--dmalen)&BYTEMASK); - outb(DMACNT,((dmalen>>8)&BYTEMASK)); - outb(DMAMSK,CHANNEL2); - splx(x); - trfrate(uip, uip->d_drtab.dr_type); /* set transfer rate */ - data = &cmdp->c_rwdata[0]; - for(cnt0 = 0; cnt0<cmdp->c_dcount; cnt0++,data++){ - if(rtn = fdc_sts(FD_OSTS, uip)) /*status check*/ - break; - outb(DATAREG(uip->addr), *data); - } - if(!rtn){ - cmdp->c_intr |= RWFLAG; - cmdp->c_stsflag |= INTROUT; - cnt0 = ((cip->b_buf->b_flags&(B_READ|B_VERIFY)) == - (B_READ|B_VERIFY))?TOUT:ITOUT; -#ifdef MACH_KERNEL - timeout(fdintr,uip->dev->ctlr,cnt0); -#else /* MACH_KERNEL */ - cmdp->c_timeid = timeout(fdintr,uip->dev->ctlr,cnt0); -#endif /* MACH_KERNEL */ - } - return(rtn); -} -/***************************************************************************** - * - * sense interrupt status routine - * - *****************************************************************************/ -sis(uip) -struct unit_info *uip; -{ - register int rtn, st0; - - if(rtn = fdc_sts(FD_OSTS, uip)) /* status check */ - return(rtn); - outb(DATAREG(uip->addr), SISCMD); - if(rtn = fdc_sts(FD_ISTS, uip)) /* status check */ - return(rtn); - st0 = inb(DATAREG(uip->addr)) & ST0OK; /* get st0 */ - if(rtn = fdc_sts(FD_ISTS, uip)) /* status check */ - return(rtn); - inb(DATAREG(uip->addr)); /* get pcn */ - if (st0&(ST0AT|ST0IC)) - st0 = FDCERR; - return(st0); -} - -/***************************************************************************** - * - * fdc status get routine - * - *****************************************************************************/ -fdc_sts(mode, uip) -register int mode; -struct unit_info *uip; -{ - register int ind; - int cnt0 = STSCHKCNT; - - while(cnt0--) - if(((ind=inb(STSREG(uip->addr))) & DATAOK) && - ((ind & DTOCPU) == mode)) - return(0); - return(TIMEOUT); -} -/***************************************************************************** - * - * motor on routine - * - *****************************************************************************/ -mtr_on(uip) -struct unit_info *uip; -{ - extern int(mtr_off)(); - extern int(wakeup)(); - struct fdcmd *cmdp = uip->b_cmd; - - if(!(mtr_start(uip))){ - timeout(wakeup,&cmdp->c_stsflag,HZ); - sleep(&cmdp->c_stsflag,PZERO); - } - cmdp->c_stsflag |= MTROFF; -#ifdef MACH_KERNEL - timeout(mtr_off,uip,MTRSTOP); -#else /* MACH_KERNEL */ - cmdp->c_mtrid = timeout(mtr_off,uip,MTRSTOP); -#endif /* MACH_KERNEL */ -} -/***************************************************************************** - * - * motor start routine - * - *****************************************************************************/ -mtr_start(uip) -struct unit_info *uip; -{ - int status; - int (mtr_off)(); - struct fdcmd *cmdp = uip->b_cmd; - int slave = uip->dev->slave; - if(cmdp->c_stsflag & MTROFF){ - untimeout(mtr_off, uip); - cmdp->c_stsflag &= ~MTROFF; - } - status = cmdp->c_rbmtr&(1<<slave); - cmdp->c_rbmtr |= (1<<slave); - outb(CTRLREG(uip->addr), ((cmdp->c_rbmtr&MTRMASK)<<MTR_ON)| - FDC_RST|slave|DMAREQ); - return(status); -} -/***************************************************************************** - * - * motor off routine - * - *****************************************************************************/ -mtr_off(uip) -struct unit_info *uip; -{ - struct fdcmd *cmdp = uip->b_cmd; - - cmdp->c_stsflag &= ~MTROFF; - if(!(cmdp->c_stsflag&MTRFLAG)){ - cmdp->c_rbmtr &= MTRRST; - outb(CTRLREG(uip->addr), FDC_RST | DMAREQ); - } -} - -#endif diff --git a/i386/i386at/fdreg.h b/i386/i386at/fdreg.h deleted file mode 100644 index 98d8d00..0000000 --- a/i386/i386at/fdreg.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - Copyright 1988, 1989 by Intel Corporation, Santa Clara, California. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and -its documentation for any purpose and without fee is hereby -granted, provided that the above copyright notice appears in all -copies and that both the copyright notice and this permission notice -appear in supporting documentation, and that the name of Intel -not be used in advertising or publicity pertaining to distribution -of the software without specific, written prior permission. - -INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, -IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, -NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION -WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -/* Copyright (c) 1987, 1988 TOSHIBA Corp. */ -/* All Rights Reserved */ - -#ident "@(#)m765.h 1.13 - 88/02/17" - -/******************************************************************* - * - * Toshiba Floppy Driver for UNIX System V R3 - * - * June 21, 1988 - * - * Intended Drive Units: - * Worldwide - Model No. ND-356 3.5" unformatted 2MB/1MB - * UNIX Media Type Name: 2HD512/2DD512/2D512/1D512. - * - * In Japan Only - Model No. ND-355 3.5" unformatted 1.6MB/1MB - * UNIX Media Type Name: 2HC1024/2HC512/2HC256/2DD512/2D512/1D512. - * - * Worldwide - Model No. ND-04DT-A 5.25" unformatted 500 KB - * UNIX Media Type Name: 2D512/1D512. - * - * In Japan Only - Model No. ND-08DE 5.25" unformatted 1.6MB/1MB - * UNIX Media Type Name: 2HC1024/2HC512/2HC256/2DD512/2D512/1D512. - * - * Use with other devices may require modification. - * - * Notes: - * For further detail regarding drive units contact - * Toshiba America,Inc. Disk Products Division, - * Irvine, CA (714) 583-3000. - * - *******************************************************************/ - -/* - * fdcmd.c_rbmtr - * - * |--+--+--+--+--+--+--+--| - * | | | | | | | | | - * |--+--+--+--+--+--+--+--| - * ^ ^ ^ ^ - * | | | |--- unit0 motor on flag - * | | |------ unit1 motor on flag - * | |--------------- unit0 recalibrate flag - * |------------------ unit1 recalibrate flag - */ -#define MTRMASK 0x003 /* mask motor_flag for get status */ -#define MTRRST 0x0fc /* reset motor_flag data */ -#define RBSHIFT 0x004 /* shift count for recalibrate data */ -#define RBRST 0x0cf /* reset recalibrate data */ - -/* - * fdcmd.c_intr - * - * |--+--+--+--+--+--+--+--| - * | | | | | | | | | - * |--+--+--+--+--+--+--+--| - * ^ ^ ^ ^ ^ ^ ^ ^ - * reserved --+ | | | | | | +--- read/write flag - * reserved -----+ | | | | +------ seek flag - * reserved --------+ | | +------ seek flag for retry - * recalibrate/seek flag(for open) ----------+ +--------- recalibrate flag - */ -#define RWFLAG 0x001 -#define SKFLAG 0x002 -#define SKEFLAG 0x004 -#define RBFLAG 0x008 -#define WUPFLAG 0x010 -#define CMDRST 0x000 - -/* - * fddrtab.dr_type - * - * +---+---+---+---+---+---+---+---+ - * | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * ^ ^ ^ ^ ^ - * | | | | |----------- rapid seek flag - * |---| | | 0: normal seek - * | | | 1: rapid seek - * | | |--------------- detect format - * | | 0: no detect - * | | 1: format type OK - * | |------------------- 40 or 80 cylinder(for 2hc/2dd drive) - * | 0: 80 cylinder - * | 1: 40 cylinder - * |------------------------- transfer rate(for read/write/format) - * 00: 500kbps 10: 250kbps - * 01: 300kbps 11: reserved - */ -#define RPSEEK 0x00 /* rapid seek */ -#define RAPID 0x08 /* rapid seek flag */ -#define OKTYPE 0x10 /* media change flag */ -#define DOUBLE 0x20 /* double/single step change */ -#define NMSEEK 0x80 /* normal seek */ -#define RATEMASK 0xc0 /* transfer parameter mask data */ - -/* - * device number - * - * 15 10 9 8 7 0 - * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - * | 0 0 0 0 0 0 0 1| | 0| 0| 0| 0| | - * +-----------+-----+-----+--+--+--+--+-----------+ - * ^ ^ ^ ^ ^ ^ - * |____________________| |__| |__| - * | | | - * | | |- media type - * major number | 0: 3.50" 720 KB - * |- unit number 1: 3.50" 1.44 Meg - * 2: 5.25" 360 KB - * 3: 5.25" 1.20 Meg - */ -#define UNIT(dev) ((dev & 0xc0)>>6) /* get unit number */ -#define MEDIATYPE(dev) (dev & 0x03) /* get media type */ -/***************************************************************************** - - wait time / timeout count - - *****************************************************************************/ -#define STSCHKCNT 0x2800 /* For check status */ -#define ITOUT HZ*5 /* interrupt timeout count */ -#define TOUT HZ/4 /* media type check timeout count */ -#define MTRSTOP HZ*2 /* motor off time */ -#define SEEKWAIT HZ/100*3 /* head_lock time */ - -/****************************************************************************** - - define for FDC - - ******************************************************************************/ -/* FDC register */ -#define CTRLREG(ADDR) (ADDR) /* controle register */ -#define STSREG(ADDR) ((ADDR)+2) /* status register */ -#define DATAREG(ADDR) ((ADDR)+3) /* data register */ -#define VFOREG(ADDR) ((ADDR)+5) /* vfo register */ - -/* CTRLREG flags */ -#define FDC_RST 0x04 -#define MTR_ON 0x04 -#define DMAREQ 0x08 -#define RDY 0x40 -#define BSY 0x80 - -/* status for command_out */ -#define FD_OSTS 0x00 /* For output check */ -#define FD_ISTS 0x40 /* For input check */ -#define DTOCPU 0x40 -#define DATAOK 0x80 - -/* Command for FDC */ -#define SPCCMD 0x03 /* Specify command */ -#define RBCMD 0x07 /* Recalibrate command */ -#define SISCMD 0x08 /* Sense interrupt status command */ -#define SEEKCMD 0x0f /* seek command */ -#define RDM 0xe6 /* FDC READ command */ -#define RDMV 0x42e6 /* VERIFY READ command */ -#define WTM 0xc5 /* FDC WRITE command */ -#define FMTM 0x4d /* FDC FORMAT command */ -#define FMTDATA 0x5e /* format data */ - -/* check value */ -#define OPENBIT 0x80 /* VFO check define */ -#define BYTEMASK 0xff - -/* FDC error code define */ -#define ERROR 0xff -#define EBBHARD 128 -#define EBBSOFT 129 -#define ST0AT 0x40 -#define ST0IC 0x80 -#define ST0OK 0xc0 -#define ADDRERR 0x01 -#define WTPRT 0x02 -#define NOREC 0x03 -#define OVERRUN 0x04 -#define CRCERR 0x05 -#define FDCERR 0x06 -#define TIMEOUT 0x08 -#define DOORERR 0x09 - -/****************************************************************************** - - define for DMA - - *****************************************************************************/ -/* DMA register */ -#define DMACMD1 0x08 /* DMA #1 command register */ -#define DMAMSK1 0x0f /* DMA #1 all mask register */ -#define DMABPFF 0x0c -#define DMAMODE 0x0b -#define DMAADDR 0x04 -#define DMAPAGE 0x81 -#define DMACNT 0x05 -#define DMAMSK 0x0a - -/* dma set data */ -#define DMARD 0x46 /* DMA read mode */ -#define DMAWT 0x4a /* DMA write mode */ -#define DMAVRF 0x42 /* DMA verify mode */ - -#define DMADATA0 0x00 /* DMA #2 all mask data */ -#define DMADATA1 0x0b /* DMA #1 all mask data */ -#define CHANNEL2 0x02 - -#define SRTHUT 0xdf -#define HLTND 0x02 -#define DTL 0xff - -/****************************************************************************** - - etc. define - - *****************************************************************************/ -#define SPL spl5 /* Same as in i386at/autoconf.c */ -#define MAXUNIT 4 /* Max unit number */ -#define BLKSIZE 512 /* block size */ - -/* fdcmd.c_stsflag */ -#define MTRFLAG 0x01 -#define MTROFF 0x02 -#define INTROUT 0x04 - -/* fdcmd.c_devflag (media check flag . etc.) */ -#define FDMCHK 0x01 -#define FDWAIT 0x02 -#define STRCHK 0x04 -#define STRWAIT 0x08 - -/* fdcmd.c_dcount */ -#define FDCCNT 9 /* Command table for read/write/format (FDC) */ -#define RWCNT 9 /* Read/Write command count */ -#define FMTCNT 6 /* format command count */ - -struct fdcmd { - int c_rbmtr; /* moter & rcalibrate flag */ - int c_intr; /* intr flag */ - int c_stsflag; /* moter flag */ - int c_mtrid; /* motor off queue id */ - int c_timeid; /* interrupt timeout id */ - int c_devflag; /* device status */ - int c_dcount; /* Read/Write/Format data count */ - int c_rwdata[FDCCNT]; /* Read/Write/Format cmd (FDC) */ - int c_saddr; /* cmd seek address */ -}; - -/* fdmbuf.b_rberr/fdmbuf.b_seekerr/fdmbuf.b_rwerr */ -#define MEDIARD 0x01 -#define MEDIASEEK 0x01 -#define SRETRY 0x03 -#define MRETRY 0x30 -#define LRETRY 0x300 -#define SRMASK 0x0f -#define MRMASK 0xf0 -#define RMRMASK 0xff0 -#define LRMASK 0xf00 -#define MINC 0x10 -#define LINC 0x100 - -struct ctrl_info { - struct unit_info *b_unitf; /* first buffer for this dev */ - struct unit_info *b_uip; /* like b_unit */ - struct unit_info *b_wup; /* unit to wake up when WUPFLAG */ - short b_rberr; /* rb error count (for recovery) */ - short b_seekerr; /* seek error count (for recovery) */ - short b_rwerr; /* r/w error count (for recovery) */ - short b_status; /* error status */ - struct buf *b_buf; /* set bp address */ - caddr_t b_xferaddr; /* trasfer address */ - unsigned int b_xfercount; /* total transfer count */ - unsigned int b_xferdma; /* dma transfer count */ - int usebuf; /* use private dma page */ - caddr_t b_vbuf; /* virtual address for dma page */ - vm_offset_t b_pbuf; /* physical dma page (model_dep.c) */ - daddr_t b_sector; /* read/write sector */ - struct fdcmd b_cmd; /* set command table address */ -}; - -#define FMTID 4 -struct fmttbl { - unsigned char cyl; - unsigned char head; - unsigned char sector; - unsigned char s_type; -}; - -struct fddrtab { - u_short dr_ncyl; /* cylinder count */ - u_short dr_spc; /* actual sectors/cylinder */ - daddr_t p_nsec; /* disk length (sector count) */ - char dr_nsec; /* sector per track */ - char dr_type; /* media type */ - char dr_rwgpl; /* Read / Write Gap length */ - char dr_fgpl; /* Format Gap length */ -}; - -struct unit_info { - struct unit_info *b_unitf; /* next slave */ - struct buf *av_forw; /* head of I/O queue (b_forw) */ - int b_seekaddr; /* cylinder address */ - u_short addr; - struct fddrtab d_drtab; /* floppy disk parameter */ - struct bus_device *dev; - struct fdcmd *b_cmd; /* set command table address */ - char wakeme; /* set if someone wants to be woken */ -}; - -#define HZ 100 /* 100 ticks/second of the clock */ -#define NBPSCTR 512 /* Bytes per LOGICAL disk sector */ - /* These should be added to - "sys/param.h". */ -#define PAGESIZ 4096 -#ifdef MACH_KERNEL -#define PZERO 25 -#define PRIBIO 20 - -#define B_VERIFY IO_SPARE_START -#define B_FORMAT (IO_SPARE_START << 1) - -#define b_pfcent io_mode - -#endif MACH_KERNEL diff --git a/i386/i386at/nfd.c b/i386/i386at/nfd.c deleted file mode 100644 index 950f896..0000000 --- a/i386/i386at/nfd.c +++ /dev/null @@ -1,1484 +0,0 @@ -/* - * Copyright (c) 1994 Shantanu Goel - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - */ - -#include <fd.h> -#if NFD > 0 -/* - * Floppy disk driver. - * - * Supports: - * 1 controller and 2 drives. - * Media change and automatic media detection. - * Arbitrarily sized read/write requests. - * Misaligned requests - * DMA above 16 Meg - * - * TODO: - * 1) Real probe routines for controller and drives. - * 2) Support for multiple controllers. The driver does - * not assume a single controller since all functions - * take the controller and/or device structure as an - * argument, however the probe routines limit the - * number of controllers and drives to 1 and 2 respectively. - * 3) V_VERIFY ioctl. - * 4) User defined diskette parameters. - * 5) Detect Intel 82077 or compatible and use its FIFO mode. - * - * Shantanu Goel (goel@cs.columbia.edu) - */ -#include <sys/types.h> -#include <sys/ioctl.h> -#include "vm_param.h" -#include <kern/time_out.h> -#include <vm/pmap.h> -#include <device/param.h> -#include <device/buf.h> -#include <device/errno.h> -#include <chips/busses.h> -#include <i386/machspl.h> -#include <i386/pio.h> -#include <i386at/cram.h> -#include <i386at/disk.h> -#include <i386at/nfdreg.h> - -/* - * Number of drives supported by an FDC. - * The controller is actually capable of - * supporting 4 drives, however, most (all?) - * board implementations only support 2. - */ -#define NDRIVES_PER_FDC 2 -#define NFDC ((NFD + NDRIVES_PER_FDC - 1) / NDRIVES_PER_FDC) - -#define fdunit(dev) (((int)(dev) >> 6) & 3) -#define fdmedia(dev) ((int)(dev) & 3) - -#define b_cylin b_resid -#define B_FORMAT B_MD1 - -#define SECSIZE 512 - -#define DMABSIZE (18*1024) /* size of DMA bounce buffer */ - -#define OP_TIMEOUT 5 /* time to wait (secs) for an - operation before giving up */ -#define MOTOR_TIMEOUT 5 /* time to wait (secs) before turning - off an idle drive motor */ -#define MAX_RETRIES 48 /* number of times to try - an I/O operation */ - -#define SRTHUT 0xdf /* step rate/head unload time */ -#define HLTND 0x02 /* head load time/dma mode */ - -/* - * DMA controller. - * - * XXX: There should be a generic <i386/dma.h> file. - */ - -/* - * Ports - */ -#define DMA2_PAGE 0x81 /* channel 2, page register */ -#define DMA2_ADDR 0x04 /* channel 2, addr register */ -#define DMA2_COUNT 0x05 /* channel 2, count register */ -#define DMA_STATUS 0x08 /* status register */ -#define DMA_COMMAND 0x08 /* command register */ -#define DMA_WREQ 0x09 /* request register */ -#define DMA_SINGLEMSK 0x0a /* single mask register */ -#define DMA_MODE 0x0b /* mode register */ -#define DMA_FLIPFLOP 0x0c /* pointer flip/flop */ -#define DMA_TEMP 0x0d /* temporary register */ -#define DMA_MASTERCLR 0x0d /* master clear */ -#define DMA_CLRMASK 0x0e /* clear mask register */ -#define DMA_ALLMASK 0x0f /* all mask register */ - -/* - * Commands - */ -#define DMA_WRITE 0x46 /* write on channel 2 */ -#define DMA_READ 0x4a /* read on channel 2 */ - -/* - * Autoconfiguration stuff. - */ -struct bus_ctlr *fdminfo[NFDC]; -struct bus_device *fddinfo[NFD]; -int fdstd[] = { 0 }; -int fdprobe(), fdslave(), fdintr(); -void fdattach(); -struct bus_driver fddriver = { - fdprobe, fdslave, fdattach, 0, fdstd, "fd", fddinfo, "fdc", fdminfo -}; - -/* - * Per-controller state. - */ -struct fdcsoftc { - int sc_flags; -#define FDF_WANT 0x01 /* someone needs direct controller access */ -#define FDF_RESET 0x02 /* controller needs reset */ -#define FDF_LIMIT 0x04 /* limit transfer to a single sector */ -#define FDF_BOUNCE 0x08 /* using bounce buffer */ - int sc_state; /* transfer fsm */ - caddr_t sc_addr; /* buffer address */ - int sc_resid; /* amount left to transfer */ - int sc_amt; /* amount currently being transferred */ - int sc_op; /* operation being performed */ - int sc_mode; /* DMA mode */ - int sc_sn; /* sector number */ - int sc_tn; /* track number */ - int sc_cn; /* cylinder number */ - int sc_recalerr; /* # recalibration errors */ - int sc_seekerr; /* # seek errors */ - int sc_ioerr; /* # i/o errors */ - int sc_dor; /* copy of digital output register */ - int sc_rate; /* copy of transfer rate register */ - int sc_wticks; /* watchdog */ - u_int sc_buf; /* buffer for transfers > 16 Meg */ - u_char sc_cmd[9]; /* command buffer */ - u_char sc_results[7]; /* operation results */ -} fdcsoftc[NFDC]; - -#define sc_st0 sc_results[0] -#define sc_st3 sc_results[0] -#define sc_st1 sc_results[1] -#define sc_pcn sc_results[1] -#define sc_st2 sc_results[2] -#define sc_c sc_results[3] -#define sc_h sc_results[4] -#define sc_r sc_results[5] -#define sc_n sc_results[6] - -/* - * Transfer states. - */ -#define IDLE 0 /* controller is idle */ -#define RESET 1 /* reset controller */ -#define RESETDONE 2 /* reset completion interrupt */ -#define RECAL 3 /* recalibrate drive */ -#define RECALDONE 4 /* recalibration complete interrupt */ -#define SEEK 5 /* perform seek on drive */ -#define SEEKDONE 6 /* seek completion interrupt */ -#define TRANSFER 7 /* perform transfer on drive */ -#define TRANSFERDONE 8 /* transfer completion interrupt */ - -/* - * Per-drive state. - */ -struct fdsoftc { - int sc_flags; -#define FDF_RECAL 0x02 /* drive needs recalibration */ -#define FDF_SEEK 0x04 /* force seek during auto-detection */ -#define FDF_AUTO 0x08 /* performing auto-density */ -#define FDF_AUTOFORCE 0x10 /* force auto-density */ -#define FDF_INIT 0x20 /* drive is being initialized */ - int sc_type; /* drive type */ - struct fddk *sc_dk; /* diskette type */ - int sc_cyl; /* current head position */ - int sc_mticks; /* motor timeout */ -} fdsoftc[NFD]; - -struct buf fdtab[NFDC]; /* controller queues */ -struct buf fdutab[NFD]; /* drive queues */ - -/* - * Floppy drive type names. - */ -char *fdnames[] = { "360K", "1.2 Meg", "720K", "1.44 Meg" }; -#define NTYPES (sizeof(fdnames) / sizeof(fdnames[0])) - -/* - * Floppy diskette parameters. - */ -struct fddk { - int dk_nspu; /* sectors/unit */ - int dk_nspc; /* sectors/cylinder */ - int dk_ncyl; /* cylinders/unit */ - int dk_nspt; /* sectors/track */ - int dk_step; /* !=0 means double track steps */ - int dk_gap; /* read/write gap length */ - int dk_fgap; /* format gap length */ - int dk_rate; /* transfer rate */ - int dk_drives; /* bit mask of drives that accept diskette */ - char *dk_name; /* type name */ -} fddk[] = { - /* - * NOTE: largest density for each drive type must be first so - * fdauto() tries it before any lower ones. - */ - { 2880, 36, 80, 18, 0, 0x1b, 0x6c, 0x00, 0x08, "1.44 Meg" }, - { 2400, 30, 80, 15, 0, 0x1b, 0x54, 0x00, 0x02, "1.2 Meg" }, - { 1440, 18, 80, 9, 0, 0x2a, 0x50, 0x02, 0x0c, "720K" }, - { 720, 18, 40, 9, 1, 0x23, 0x50, 0x01, 0x02, "360K" }, - { 720, 18, 40, 9, 0, 0x2a, 0x50, 0x02, 0x01, "360K PC" } -}; -#define NDKTYPES (sizeof(fddk) / sizeof(fddk[0])) - -/* - * For compatibility with old driver. - * This array is indexed by the old floppy type codes - * and points to the corresponding entry for that - * type in fddk[] above. - */ -struct fddk *fdcompat[NDKTYPES]; - -int fdwstart = 0; -int fdstrategy(), fdformat(); -char *fderrmsg(); -void fdwatch(), fdminphys(), fdspinup(), wakeup(); - -#define FDDEBUG -#ifdef FDDEBUG -int fddebug = 0; -#define DEBUGF(n, stmt) { if (fddebug >= (n)) stmt; } -#else -#define DEBUGF(n, stmt) -#endif - -/* - * Probe for a controller. - */ -int -fdprobe(xxx, um) - int xxx; - struct bus_ctlr *um; -{ - struct fdcsoftc *fdc; - - if (um->unit >= NFDC) { - printf("fdc%d: not configured\n", um->unit); - return (0); - } - if (um->unit > 0) /* XXX: only 1 controller */ - return (0); - - /* - * XXX: need real probe - */ - take_ctlr_irq(um); - printf("%s%d: port 0x%x, spl %d, pic %d.\n", - um->name, um->unit, um->address, um->sysdep, um->sysdep1); - - /* - * Set up compatibility array. - */ - fdcompat[0] = &fddk[2]; - fdcompat[1] = &fddk[0]; - fdcompat[2] = &fddk[3]; - fdcompat[3] = &fddk[1]; - - fdc = &fdcsoftc[um->unit]; - fdc->sc_rate = -1; - if (!fdc->sc_buf) { - fdc->sc_buf = alloc_dma_mem(DMABSIZE, 64*1024); - if (fdc->sc_buf == 0) - panic("fd: alloc_dma_mem() failed"); - } - fdc->sc_dor = DOR_RSTCLR | DOR_IENABLE; - outb(FD_DOR(um->address), fdc->sc_dor); - return (1); -} - -/* - * Probe for a drive. - */ -int -fdslave(ui) - struct bus_device *ui; -{ - struct fdsoftc *sc; - - if (ui->unit >= NFD) { - printf("fd%d: not configured\n", ui->unit); - return (0); - } - if (ui->unit > 1) /* XXX: only 2 drives */ - return (0); - - /* - * Find out from CMOS if drive exists. - */ - sc = &fdsoftc[ui->unit]; - outb(CMOS_ADDR, 0x10); - sc->sc_type = inb(CMOS_DATA); - if (ui->unit == 0) - sc->sc_type >>= 4; - sc->sc_type &= 0x0f; - return (sc->sc_type); -} - -/* - * Attach a drive to the system. - */ -void -fdattach(ui) - struct bus_device *ui; -{ - struct fdsoftc *sc; - - sc = &fdsoftc[ui->unit]; - if (--sc->sc_type >= NTYPES) { - printf(": unknown drive type %d", sc->sc_type); - ui->alive = 0; - return; - } - printf(": %s", fdnames[sc->sc_type]); - sc->sc_flags = FDF_RECAL | FDF_SEEK | FDF_AUTOFORCE; -} - -int -fdopen(dev, mode) - dev_t dev; - int mode; -{ - int unit = fdunit(dev), error; - struct bus_device *ui; - struct fdsoftc *sc; - - if (unit >= NFD || (ui = fddinfo[unit]) == 0 || ui->alive == 0) - return (ENXIO); - - /* - * Start watchdog. - */ - if (!fdwstart) { - fdwstart++; - timeout(fdwatch, 0, hz); - } - /* - * Do media detection if drive is being opened for the - * first time or diskette has been changed since the last open. - */ - sc = &fdsoftc[unit]; - if ((sc->sc_flags & FDF_AUTOFORCE) || fddskchg(ui)) { - if (error = fdauto(dev)) - return (error); - sc->sc_flags &= ~FDF_AUTOFORCE; - } - return (0); -} - -int -fdclose(dev) - dev_t dev; -{ - int s, unit = fdunit(dev); - struct fdsoftc *sc = &fdsoftc[unit]; - - /* - * Wait for pending operations to complete. - */ - s = splbio(); - while (fdutab[unit].b_active) { - sc->sc_flags |= FDF_WANT; - assert_wait((event_t)sc, FALSE); - thread_block((void (*)())0); - } - splx(s); - return (0); -} - -int -fdread(dev, ior) - dev_t dev; - io_req_t ior; -{ - return (block_io(fdstrategy, fdminphys, ior)); -} - -int -fdwrite(dev, ior) - dev_t dev; - io_req_t ior; -{ - return (block_io(fdstrategy, fdminphys, ior)); -} - -int -fdgetstat(dev, flavor, status, status_count) - dev_t dev; - dev_flavor_t flavor; - dev_status_t status; - mach_msg_type_number_t *status_count; -{ - switch (flavor) { - - case DEV_GET_SIZE: - { - int *info; - io_return_t error; - struct disk_parms dp; - - if (error = fdgetparms(dev, &dp)) - return (error); - info = (int *)status; - info[DEV_GET_SIZE_DEVICE_SIZE] = dp.dp_pnumsec * SECSIZE; - info[DEV_GET_SIZE_RECORD_SIZE] = SECSIZE; - *status_count = DEV_GET_SIZE_COUNT; - return (D_SUCCESS); - } - case V_GETPARMS: - if (*status_count < (sizeof(struct disk_parms) / sizeof(int))) - return (D_INVALID_OPERATION); - *status_count = sizeof(struct disk_parms) / sizeof(int); - return (fdgetparms(dev, (struct disk_parms *)status)); - - default: - return (D_INVALID_OPERATION); - } -} - -int -fdsetstat(dev, flavor, status, status_count) - dev_t dev; - dev_flavor_t flavor; - dev_status_t status; - mach_msg_type_number_t status_count; -{ - switch (flavor) { - - case V_SETPARMS: - return (fdsetparms(dev, *(int *)status)); - - case V_FORMAT: - return (fdformat(dev, (union io_arg *)status)); - - case V_VERIFY: - /* - * XXX: needs to be implemented - */ - return (D_SUCCESS); - - default: - return (D_INVALID_OPERATION); - } -} - -int -fddevinfo(dev, flavor, info) - dev_t dev; - int flavor; - char *info; -{ - switch (flavor) { - - case D_INFO_BLOCK_SIZE: - *(int *)info = SECSIZE; - return (D_SUCCESS); - - default: - return (D_INVALID_OPERATION); - } -} - -/* - * Allow arbitrary transfers. Standard minphys restricts - * transfers to a maximum of 256K preventing us from reading - * an entire diskette in a single system call. - */ -void -fdminphys(ior) - io_req_t ior; -{ -} - -/* - * Return current media parameters. - */ -int -fdgetparms(dev, dp) - dev_t dev; - struct disk_parms *dp; -{ - struct fddk *dk = fdsoftc[fdunit(dev)].sc_dk; - - dp->dp_type = DPT_FLOPPY; - dp->dp_heads = 2; - dp->dp_sectors = dk->dk_nspt; - dp->dp_pstartsec = 0; - dp->dp_cyls = dk->dk_ncyl; - dp->dp_pnumsec = dk->dk_nspu; - return (0); -} - -/* - * Set media parameters. - */ -int -fdsetparms(dev, type) - dev_t dev; - int type; -{ - struct fdsoftc *sc; - struct fddk *dk; - - if (type < 0 || type >= NDKTYPES) - return (EINVAL); - dk = fdcompat[type]; - sc = &fdsoftc[fdunit(dev)]; - if ((dk->dk_drives & (1 << sc->sc_type)) == 0) - return (EINVAL); - sc->sc_dk = dk; - return (D_SUCCESS); -} - -/* - * Format a floppy. - */ -int -fdformat(dev, arg) - dev_t dev; - union io_arg *arg; -{ - int i, j, sect, error = 0; - unsigned track, num_trks; - struct buf *bp; - struct fddk *dk; - struct format_info *fmt; - - dk = fdsoftc[fdunit(dev)].sc_dk; - num_trks = arg->ia_fmt.num_trks; - track = arg->ia_fmt.start_trk; - if (num_trks == 0 || track + num_trks > (dk->dk_ncyl << 1) - || arg->ia_fmt.intlv >= dk->dk_nspt) - return (EINVAL); - - bp = (struct buf *)geteblk(SECSIZE); - bp->b_dev = dev; - bp->b_bcount = dk->dk_nspt * sizeof(struct format_info); - bp->b_blkno = track * dk->dk_nspt; - - while (num_trks-- > 0) { - /* - * Set up format information. - */ - fmt = (struct format_info *)bp->b_un.b_addr; - for (i = 0; i < dk->dk_nspt; i++) - fmt[i].sector = 0; - for (i = 0, j = 0, sect = 1; i < dk->dk_nspt; i++) { - fmt[j].cyl = track >> 1; - fmt[j].head = track & 1; - fmt[j].sector = sect++; - fmt[j].secsize = 2; - if ((j += arg->ia_fmt.intlv) < dk->dk_nspt) - continue; - for (j -= dk->dk_nspt; j < dk->dk_nspt; j++) - if (fmt[j].sector == 0) - break; - } - bp->b_flags = B_FORMAT; - fdstrategy(bp); - biowait(bp); - if (bp->b_flags & B_ERROR) { - error = bp->b_error; - break; - } - bp->b_blkno += dk->dk_nspt; - track++; - } - bp->b_flags &= ~B_FORMAT; - brelse(bp); - return (error); -} - -/* - * Strategy routine. - * Enqueue a request on drive queue. - */ -int -fdstrategy(bp) - struct buf *bp; -{ - int unit = fdunit(bp->b_dev), s; - int bn, sz, maxsz; - struct buf *dp; - struct bus_device *ui = fddinfo[unit]; - struct fddk *dk = fdsoftc[unit].sc_dk; - - bn = bp->b_blkno; - sz = (bp->b_bcount + SECSIZE - 1) / SECSIZE; - maxsz = dk->dk_nspu; - if (bn < 0 || bn + sz > maxsz) { - if (bn == maxsz) { - bp->b_resid = bp->b_bcount; - goto done; - } - sz = maxsz - bn; - if (sz <= 0) { - bp->b_error = EINVAL; - bp->b_flags |= B_ERROR; - goto done; - } - bp->b_bcount = sz * SECSIZE; - } - bp->b_cylin = bn / dk->dk_nspc; - dp = &fdutab[unit]; - s = splbio(); - disksort(dp, bp); - if (!dp->b_active) { - fdustart(ui); - if (!fdtab[ui->mi->unit].b_active) - fdstart(ui->mi); - } - splx(s); - return; - done: - biodone(bp); - return; -} - -/* - * Unit start routine. - * Move request from drive to controller queue. - */ -int -fdustart(ui) - struct bus_device *ui; -{ - struct buf *bp; - struct buf *dp; - - bp = &fdutab[ui->unit]; - if (bp->b_actf == 0) - return; - dp = &fdtab[ui->mi->unit]; - if (dp->b_actf == 0) - dp->b_actf = bp; - else - dp->b_actl->b_forw = bp; - bp->b_forw = 0; - dp->b_actl = bp; - bp->b_active++; -} - -/* - * Start output on controller. - */ -int -fdstart(um) - struct bus_ctlr *um; -{ - struct buf *bp; - struct buf *dp; - struct fdsoftc *sc; - struct fdcsoftc *fdc; - struct bus_device *ui; - struct fddk *dk; - - /* - * Pull a request from the controller queue. - */ - dp = &fdtab[um->unit]; - if ((bp = dp->b_actf) == 0) - return; - bp = bp->b_actf; - - fdc = &fdcsoftc[um->unit]; - ui = fddinfo[fdunit(bp->b_dev)]; - sc = &fdsoftc[ui->unit]; - dk = sc->sc_dk; - - /* - * Mark controller busy. - */ - dp->b_active++; - - /* - * Figure out where this request is going. - */ - fdc->sc_cn = bp->b_cylin; - fdc->sc_sn = bp->b_blkno % dk->dk_nspc; - fdc->sc_tn = fdc->sc_sn / dk->dk_nspt; - fdc->sc_sn %= dk->dk_nspt; - - /* - * Set up for multi-sector transfer. - */ - fdc->sc_op = ((bp->b_flags & B_FORMAT) ? CMD_FORMAT - : ((bp->b_flags & B_READ) ? CMD_READ : CMD_WRITE)); - fdc->sc_mode = (bp->b_flags & B_READ) ? DMA_WRITE : DMA_READ; - fdc->sc_addr = bp->b_un.b_addr; - fdc->sc_resid = bp->b_bcount; - fdc->sc_wticks = 0; - fdc->sc_recalerr = 0; - fdc->sc_seekerr = 0; - fdc->sc_ioerr = 0; - - /* - * Set initial transfer state. - */ - if (fdc->sc_flags & FDF_RESET) - fdc->sc_state = RESET; - else if (sc->sc_flags & FDF_RECAL) - fdc->sc_state = RECAL; - else if (sc->sc_cyl != fdc->sc_cn) - fdc->sc_state = SEEK; - else - fdc->sc_state = TRANSFER; - - /* - * Set transfer rate. - */ - if (fdc->sc_rate != dk->dk_rate) { - fdc->sc_rate = dk->dk_rate; - outb(FD_RATE(um->address), fdc->sc_rate); - } - /* - * Turn on drive motor. - * Don't start I/O if drive is spinning up. - */ - if (fdmotoron(ui)) { - timeout(fdspinup, (void *)um, hz / 2); - return; - } - /* - * Call transfer state routine to do the actual I/O. - */ - fdstate(um); -} - -/* - * Interrupt routine. - */ -int -fdintr(ctlr) - int ctlr; -{ - int timedout; - u_char results[7]; - struct buf *bp; - struct bus_device *ui; - struct fdsoftc *sc; - struct buf *dp = &fdtab[ctlr]; - struct fdcsoftc *fdc = &fdcsoftc[ctlr]; - struct bus_ctlr *um = fdminfo[ctlr]; - - if (!dp->b_active) { - printf("fdc%d: stray interrupt\n", ctlr); - return; - } - timedout = fdc->sc_wticks >= OP_TIMEOUT; - fdc->sc_wticks = 0; - bp = dp->b_actf->b_actf; - ui = fddinfo[fdunit(bp->b_dev)]; - sc = &fdsoftc[ui->unit]; - - /* - * Operation timed out, terminate request. - */ - if (timedout) { - fderror("timed out", ui); - fdmotoroff(ui); - sc->sc_flags |= FDF_RECAL; - bp->b_flags |= B_ERROR; - bp->b_error = ENXIO; - fddone(ui, bp); - return; - } - /* - * Read results from FDC. - * For transfer completion they can be read immediately. - * For anything else, we must issue a Sense Interrupt - * Status Command. We keep issuing this command till - * FDC returns invalid command status. The Controller Busy - * bit in the status register indicates completion of a - * read/write/format operation. - */ - if (inb(FD_STATUS(um->address)) & ST_CB) { - if (!fdresults(um, fdc->sc_results)) - return; - } else { - while (1) { - fdc->sc_cmd[0] = CMD_SENSEI; - if (!fdcmd(um, 1)) { - DEBUGF(2, printf(2, "fd%d: SENSEI failed\n")); - return; - } - if (!fdresults(um, results)) - return; - if ((results[0] & ST0_IC) == 0x80) - break; - if ((results[0] & ST0_US) == ui->slave) { - fdc->sc_results[0] = results[0]; - fdc->sc_results[1] = results[1]; - } - } - } - /* - * Let transfer state routine handle the rest. - */ - fdstate(um); -} - -/* - * Transfer finite state machine driver. - */ -int -fdstate(um) - struct bus_ctlr *um; -{ - int unit, max, pa, s; - struct buf *bp; - struct fdsoftc *sc; - struct bus_device *ui; - struct fddk *dk; - struct fdcsoftc *fdc = &fdcsoftc[um->unit]; - - bp = fdtab[um->unit].b_actf->b_actf; - ui = fddinfo[fdunit(bp->b_dev)]; - sc = &fdsoftc[ui->unit]; - dk = sc->sc_dk; - - while (1) switch (fdc->sc_state) { - - case RESET: - /* - * Reset the controller. - */ - fdreset(um); - return; - - case RESETDONE: - /* - * Reset complete. - * Mark all drives as needing recalibration - * and issue specify command. - */ - for (unit = 0; unit < NFD; unit++) - if (fddinfo[unit] && fddinfo[unit]->alive - && fddinfo[unit]->mi == um) - fdsoftc[unit].sc_flags |= FDF_RECAL; - fdc->sc_cmd[0] = CMD_SPECIFY; - fdc->sc_cmd[1] = SRTHUT; - fdc->sc_cmd[2] = HLTND; - if (!fdcmd(um, 3)) - return; - fdc->sc_flags &= ~FDF_RESET; - fdc->sc_state = RECAL; - break; - - case RECAL: - /* - * Recalibrate drive. - */ - fdc->sc_state = RECALDONE; - fdc->sc_cmd[0] = CMD_RECAL; - fdc->sc_cmd[1] = ui->slave; - fdcmd(um, 2); - return; - - case RECALDONE: - /* - * Recalibration complete. - */ - if ((fdc->sc_st0 & ST0_IC) || (fdc->sc_st0 & ST0_EC)) { - if (++fdc->sc_recalerr == 2) { - fderror("recalibrate failed", ui); - goto bad; - } - fdc->sc_state = RESET; - break; - } - sc->sc_flags &= ~FDF_RECAL; - fdc->sc_recalerr = 0; - sc->sc_cyl = -1; - fdc->sc_state = SEEK; - break; - - case SEEK: - /* - * Perform seek operation. - */ - fdc->sc_state = SEEKDONE; - fdc->sc_cmd[0] = CMD_SEEK; - fdc->sc_cmd[1] = (fdc->sc_tn << 2) | ui->slave; - fdc->sc_cmd[2] = fdc->sc_cn; - if (dk->dk_step) - fdc->sc_cmd[2] <<= 1; - fdcmd(um, 3); - return; - - case SEEKDONE: - /* - * Seek complete. - */ - if (dk->dk_step) - fdc->sc_pcn >>= 1; - if ((fdc->sc_st0 & ST0_IC) || (fdc->sc_st0 & ST0_SE) == 0 - || fdc->sc_pcn != fdc->sc_cn) { - if (++fdc->sc_seekerr == 2) { - fderror("seek failed", ui); - goto bad; - } - fdc->sc_state = RESET; - break; - } - fdc->sc_seekerr = 0; - sc->sc_cyl = fdc->sc_pcn; - fdc->sc_state = TRANSFER; - break; - - case TRANSFER: - /* - * Perform I/O transfer. - */ - fdc->sc_flags &= ~FDF_BOUNCE; - pa = pmap_extract(kernel_pmap, fdc->sc_addr); - if (fdc->sc_op == CMD_FORMAT) { - max = sizeof(struct format_info) * dk->dk_nspt; - } else if (fdc->sc_flags & FDF_LIMIT) { - fdc->sc_flags &= ~FDF_LIMIT; - max = SECSIZE; - } else { - max = (dk->dk_nspc - dk->dk_nspt * fdc->sc_tn - - fdc->sc_sn) * SECSIZE; - } - if (max > fdc->sc_resid) - max = fdc->sc_resid; - if (pa >= 16*1024*1024) { - fdc->sc_flags |= FDF_BOUNCE; - pa = fdc->sc_buf; - if (max < DMABSIZE) - fdc->sc_amt = max; - else - fdc->sc_amt = DMABSIZE; - } else { - int prevpa, curpa, omax; - vm_offset_t va; - - omax = max; - if (max > 65536 - (pa & 0xffff)) - max = 65536 - (pa & 0xffff); - fdc->sc_amt = I386_PGBYTES - (pa & (I386_PGBYTES - 1)); - va = (vm_offset_t)fdc->sc_addr + fdc->sc_amt; - prevpa = pa & ~(I386_PGBYTES - 1); - while (fdc->sc_amt < max) { - curpa = pmap_extract(kernel_pmap, va); - if (curpa >= 16*1024*1024 - || curpa != prevpa + I386_PGBYTES) - break; - fdc->sc_amt += I386_PGBYTES; - va += I386_PGBYTES; - prevpa = curpa; - } - if (fdc->sc_amt > max) - fdc->sc_amt = max; - if (fdc->sc_op == CMD_FORMAT) { - if (fdc->sc_amt != omax) { - fdc->sc_flags |= FDF_BOUNCE; - pa = fdc->sc_buf; - fdc->sc_amt = omax; - } - } else if (fdc->sc_amt != fdc->sc_resid) { - if (fdc->sc_amt < SECSIZE) { - fdc->sc_flags |= FDF_BOUNCE; - pa = fdc->sc_buf; - if (omax > DMABSIZE) - fdc->sc_amt = DMABSIZE; - else - fdc->sc_amt = omax; - } else - fdc->sc_amt &= ~(SECSIZE - 1); - } - } - - DEBUGF(2, printf("fd%d: TRANSFER: amt %d cn %d tn %d sn %d\n", - ui->unit, fdc->sc_amt, fdc->sc_cn, - fdc->sc_tn, fdc->sc_sn + 1)); - - if ((fdc->sc_flags & FDF_BOUNCE) && fdc->sc_op != CMD_READ) { - fdc->sc_flags &= ~FDF_BOUNCE; - bcopy(fdc->sc_addr, (caddr_t)phystokv(fdc->sc_buf), - fdc->sc_amt); - } - /* - * Set up DMA. - */ - s = sploff(); - outb(DMA_SINGLEMSK, 0x04 | 0x02); - outb(DMA_FLIPFLOP, 0); - outb(DMA_MODE, fdc->sc_mode); - outb(DMA2_ADDR, pa); - outb(DMA2_ADDR, pa >> 8); - outb(DMA2_PAGE, pa >> 16); - outb(DMA2_COUNT, fdc->sc_amt - 1); - outb(DMA2_COUNT, (fdc->sc_amt - 1) >> 8); - outb(DMA_SINGLEMSK, 0x02); - splon(s); - - /* - * Issue command to FDC. - */ - fdc->sc_state = TRANSFERDONE; - fdc->sc_cmd[0] = fdc->sc_op; - fdc->sc_cmd[1] = (fdc->sc_tn << 2) | ui->slave; - if (fdc->sc_op == CMD_FORMAT) { - fdc->sc_cmd[2] = 0x02; - fdc->sc_cmd[3] = dk->dk_nspt; - fdc->sc_cmd[4] = dk->dk_fgap; - fdc->sc_cmd[5] = 0xda; - fdcmd(um, 6); - } else { - fdc->sc_cmd[2] = fdc->sc_cn; - fdc->sc_cmd[3] = fdc->sc_tn; - fdc->sc_cmd[4] = fdc->sc_sn + 1; - fdc->sc_cmd[5] = 0x02; - fdc->sc_cmd[6] = dk->dk_nspt; - fdc->sc_cmd[7] = dk->dk_gap; - fdc->sc_cmd[8] = 0xff; - fdcmd(um, 9); - } - return; - - case TRANSFERDONE: - /* - * Transfer complete. - */ - if (fdc->sc_st0 & ST0_IC) { - fdc->sc_ioerr++; - if (sc->sc_flags & FDF_AUTO) { - /* - * Give up on second try if - * media detection is in progress. - */ - if (fdc->sc_ioerr == 2) - goto bad; - fdc->sc_state = RECAL; - break; - } - if (fdc->sc_ioerr == MAX_RETRIES) { - fderror(fderrmsg(ui), ui); - goto bad; - } - /* - * Give up immediately on write-protected diskettes. - */ - if (fdc->sc_st1 & ST1_NW) { - fderror("write-protected diskette", ui); - goto bad; - } - /* - * Limit transfer to a single sector. - */ - fdc->sc_flags |= FDF_LIMIT; - /* - * Every fourth attempt recalibrate the drive. - * Every eight attempt reset the controller. - * Also, every eighth attempt inform user - * about the error. - */ - if (fdc->sc_ioerr & 3) - fdc->sc_state = TRANSFER; - else if (fdc->sc_ioerr & 7) - fdc->sc_state = RECAL; - else { - fdc->sc_state = RESET; - fderror(fderrmsg(ui), ui); - } - break; - } - /* - * Transfer completed successfully. - * Advance counters/pointers, and if more - * is left, initiate I/O. - */ - if (fdc->sc_flags & FDF_BOUNCE) { - fdc->sc_flags &= ~FDF_BOUNCE; - bcopy((caddr_t)phystokv(fdc->sc_buf), fdc->sc_addr, - fdc->sc_amt); - } - if ((fdc->sc_resid -= fdc->sc_amt) == 0) { - bp->b_resid = 0; - fddone(ui, bp); - return; - } - fdc->sc_state = TRANSFER; - fdc->sc_ioerr = 0; - fdc->sc_addr += fdc->sc_amt; - if (fdc->sc_op == CMD_FORMAT) { - fdc->sc_sn = 0; - if (fdc->sc_tn == 1) { - fdc->sc_tn = 0; - fdc->sc_cn++; - fdc->sc_state = SEEK; - } else - fdc->sc_tn = 1; - } else { - fdc->sc_sn += fdc->sc_amt / SECSIZE; - while (fdc->sc_sn >= dk->dk_nspt) { - fdc->sc_sn -= dk->dk_nspt; - if (fdc->sc_tn == 1) { - fdc->sc_tn = 0; - fdc->sc_cn++; - fdc->sc_state = SEEK; - } else - fdc->sc_tn = 1; - } - } - break; - - default: - printf("fd%d: invalid state\n", ui->unit); - panic("fdstate"); - /*NOTREACHED*/ - } - bad: - bp->b_flags |= B_ERROR; - bp->b_error = EIO; - sc->sc_flags |= FDF_RECAL; - fddone(ui, bp); -} - -/* - * Terminate current request and start - * any others that are queued. - */ -int -fddone(ui, bp) - struct bus_device *ui; - struct buf *bp; -{ - struct bus_ctlr *um = ui->mi; - struct fdsoftc *sc = &fdsoftc[ui->unit]; - struct fdcsoftc *fdc = &fdcsoftc[um->unit]; - struct buf *dp = &fdtab[um->unit]; - - DEBUGF(1, printf("fd%d: fddone()\n", ui->unit)); - - /* - * Remove this request from queue. - */ - if (bp) { - fdutab[ui->unit].b_actf = bp->b_actf; - biodone(bp); - bp = &fdutab[ui->unit]; - dp->b_actf = bp->b_forw; - } else - bp = &fdutab[ui->unit]; - - /* - * Mark controller and drive idle. - */ - dp->b_active = 0; - bp->b_active = 0; - fdc->sc_state = IDLE; - sc->sc_mticks = 0; - fdc->sc_flags &= ~(FDF_LIMIT|FDF_BOUNCE); - - /* - * Start up other requests. - */ - fdustart(ui); - fdstart(um); - - /* - * Wakeup anyone waiting for drive or controller. - */ - if (sc->sc_flags & FDF_WANT) { - sc->sc_flags &= ~FDF_WANT; - wakeup((void *)sc); - } - if (fdc->sc_flags & FDF_WANT) { - fdc->sc_flags &= ~FDF_WANT; - wakeup((void *)fdc); - } -} - -/* - * Check if diskette change has occured since the last open. - */ -int -fddskchg(ui) - struct bus_device *ui; -{ - int s, dir; - struct fdsoftc *sc = &fdsoftc[ui->unit]; - struct bus_ctlr *um = ui->mi; - struct fdcsoftc *fdc = &fdcsoftc[um->unit]; - - /* - * Get access to controller. - */ - s = splbio(); - while (fdtab[um->unit].b_active) { - fdc->sc_flags |= FDF_WANT; - assert_wait((event_t)fdc, FALSE); - thread_block((void (*)())0); - } - fdtab[um->unit].b_active = 1; - fdutab[ui->unit].b_active = 1; - - /* - * Turn on drive motor and read digital input register. - */ - if (fdmotoron(ui)) { - timeout(wakeup, (void *)fdc, hz / 2); - assert_wait((event_t)fdc, FALSE); - thread_block((void (*)())0); - } - dir = inb(FD_DIR(um->address)); - fddone(ui, NULL); - splx(s); - - if (dir & DIR_DSKCHG) { - printf("fd%d: diskette change detected\n", ui->unit); - sc->sc_flags |= FDF_SEEK; - return (1); - } - return (0); -} - -/* - * Do media detection. - */ -int -fdauto(dev) - dev_t dev; -{ - int i, error = 0; - struct buf *bp; - struct bus_device *ui = fddinfo[fdunit(dev)]; - struct fdsoftc *sc = &fdsoftc[ui->unit]; - struct fddk *dk, *def = 0; - - sc->sc_flags |= FDF_AUTO; - bp = (struct buf *)geteblk(SECSIZE); - for (i = 0, dk = fddk; i < NDKTYPES; i++, dk++) { - if ((dk->dk_drives & (1 << sc->sc_type)) == 0) - continue; - if (def == 0) - def = dk; - sc->sc_dk = dk; - bp->b_flags = B_READ; - bp->b_dev = dev; - bp->b_bcount = SECSIZE; - if (sc->sc_flags & FDF_SEEK) { - sc->sc_flags &= ~FDF_SEEK; - bp->b_blkno = 100; - } else - bp->b_blkno = 0; - fdstrategy(bp); - biowait(bp); - if ((bp->b_flags & B_ERROR) == 0 || bp->b_error == ENXIO) - break; - } - if (i == NDKTYPES) { - printf("fd%d: couldn't detect type, using %s\n", - ui->unit, def->dk_name); - sc->sc_dk = def; - } else if ((bp->b_flags & B_ERROR) == 0) - printf("fd%d: detected %s\n", ui->unit, sc->sc_dk->dk_name); - else - error = ENXIO; - sc->sc_flags &= ~FDF_AUTO; - brelse(bp); - return (error); -} - -/* - * Turn on drive motor and select drive. - */ -int -fdmotoron(ui) - struct bus_device *ui; -{ - int bit; - struct bus_ctlr *um = ui->mi; - struct fdcsoftc *fdc = &fdcsoftc[um->unit]; - - bit = 1 << (ui->slave + 4); - if ((fdc->sc_dor & bit) == 0) { - fdc->sc_dor &= ~3; - fdc->sc_dor |= bit | ui->slave; - outb(FD_DOR(um->address), fdc->sc_dor); - return (1); - } - if ((fdc->sc_dor & 3) != ui->slave) { - fdc->sc_dor &= ~3; - fdc->sc_dor |= ui->slave; - outb(FD_DOR(um->address), fdc->sc_dor); - } - return (0); -} - -/* - * Turn off drive motor. - */ -int -fdmotoroff(ui) - struct bus_device *ui; -{ - struct bus_ctlr *um = ui->mi; - struct fdcsoftc *fdc = &fdcsoftc[um->unit]; - - fdc->sc_dor &= ~(1 << (ui->slave + 4)); - outb(FD_DOR(um->address), fdc->sc_dor); -} - -/* - * This routine is invoked via timeout() by fdstart() - * to call fdstate() at splbio. - */ -void -fdspinup(um) - struct bus_ctlr *um; -{ - int s; - - s = splbio(); - fdstate(um); - splx(s); -} - -/* - * Watchdog routine. - * Check for hung operations. - * Turn off motor of idle drives. - */ -void -fdwatch() -{ - int unit, s; - struct bus_device *ui; - - timeout(fdwatch, 0, hz); - s = splbio(); - for (unit = 0; unit < NFDC; unit++) - if (fdtab[unit].b_active - && ++fdcsoftc[unit].sc_wticks == OP_TIMEOUT) - fdintr(unit); - for (unit = 0; unit < NFD; unit++) { - if ((ui = fddinfo[unit]) == 0 || ui->alive == 0) - continue; - if (fdutab[unit].b_active == 0 - && (fdcsoftc[ui->mi->unit].sc_dor & (1 << (ui->slave + 4))) - && ++fdsoftc[unit].sc_mticks == MOTOR_TIMEOUT) - fdmotoroff(ui); - } - splx(s); -} - -/* - * Print an error message. - */ -int -fderror(msg, ui) - char *msg; - struct bus_device *ui; -{ - struct fdcsoftc *fdc = &fdcsoftc[ui->mi->unit]; - - printf("fd%d: %s, %sing cn %d tn %d sn %d\n", ui->unit, msg, - (fdc->sc_op == CMD_READ ? "read" - : (fdc->sc_op == CMD_WRITE ? "writ" : "formatt")), - fdc->sc_cn, fdc->sc_tn, fdc->sc_sn + 1); -} - -/* - * Return an error message for an I/O error. - */ -char * -fderrmsg(ui) - struct bus_device *ui; -{ - struct fdcsoftc *fdc = &fdcsoftc[ui->mi->unit]; - - if (fdc->sc_st1 & ST1_EC) - return ("invalid sector"); - if (fdc->sc_st1 & ST1_DE) - return ("CRC error"); - if (fdc->sc_st1 & ST1_OR) - return ("DMA overrun"); - if (fdc->sc_st1 & ST1_ND) - return ("sector not found"); - if (fdc->sc_st1 & ST1_NW) - return ("write-protected diskette"); - if (fdc->sc_st1 & ST1_MA) - return ("missing address mark"); - return ("hard error"); -} - -/* - * Output a command to FDC. - */ -int -fdcmd(um, n) - struct bus_ctlr *um; - int n; -{ - int i, j; - struct fdcsoftc *fdc = &fdcsoftc[um->unit]; - - for (i = j = 0; i < 200; i++) { - if ((inb(FD_STATUS(um->address)) & (ST_RQM|ST_DIO)) != ST_RQM) - continue; - outb(FD_DATA(um->address), fdc->sc_cmd[j++]); - if (--n == 0) - return (1); - } - /* - * Controller is not responding, reset it. - */ - DEBUGF(1, printf("fdc%d: fdcmd() failed\n", um->unit)); - fdreset(um); - return (0); -} - -/* - * Read results from FDC. - */ -int -fdresults(um, rp) - struct bus_ctlr *um; - u_char *rp; -{ - int i, j, status; - - for (i = j = 0; i < 200; i++) { - status = inb(FD_STATUS(um->address)); - if ((status & ST_RQM) == 0) - continue; - if ((status & ST_DIO) == 0) - return (j); - if (j == 7) - break; - *rp++ = inb(FD_DATA(um->address)); - j++; - } - /* - * Controller is not responding, reset it. - */ - DEBUGF(1, printf("fdc%d: fdresults() failed\n", um->unit)); - fdreset(um); - return (0); -} - -/* - * Reset controller. - */ -int -fdreset(um) - struct bus_ctlr *um; -{ - struct fdcsoftc *fdc = &fdcsoftc[um->unit]; - - outb(FD_DOR(um->address), fdc->sc_dor & ~(DOR_RSTCLR|DOR_IENABLE)); - fdc->sc_state = RESETDONE; - fdc->sc_flags |= FDF_RESET; - outb(FD_DOR(um->address), fdc->sc_dor); -} - -#endif /* NFD > 0 */ diff --git a/i386/i386at/nfdreg.h b/i386/i386at/nfdreg.h deleted file mode 100644 index 9bdf44d..0000000 --- a/i386/i386at/nfdreg.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 1994 Shantanu Goel - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - */ - -/* - * NEC 765/Intel 8272 floppy disk controller. - */ - -/* - * Ports - */ -#define FD_DOR(p) (p) /* digital output register */ -#define FD_STATUS(p) ((p) + 2) /* status register */ -#define FD_DATA(p) ((p) + 3) /* data register */ -#define FD_RATE(p) ((p) + 5) /* transfer rate register */ -#define FD_DIR(p) ((p) + 5) /* digital input register */ - -/* - * Digital output register. - */ -#define DOR_IENABLE 0x08 /* enable interrupts and DMA */ -#define DOR_RSTCLR 0x04 /* clear reset */ - -/* - * Status register. - */ -#define ST_RQM 0x80 /* request for master */ -#define ST_DIO 0x40 /* direction of data transfer - 1 = fdc to cpu, 0 = cpu to fdc */ -#define ST_NDM 0x20 /* non DMA mode */ -#define ST_CB 0x10 /* controller busy */ - -/* - * Digital input register. - */ -#define DIR_DSKCHG 0x80 /* diskette chnage has occured */ - -/* - * ST0 - */ -#define ST0_IC 0xc0 /* interrupt code */ -#define ST0_SE 0x20 /* seek end */ -#define ST0_EC 0x10 /* equipment check */ -#define ST0_NR 0x08 /* not ready */ -#define ST0_HD 0x04 /* head address */ -#define ST0_US 0x03 /* unit select */ - -/* - * ST1 - */ -#define ST1_EC 0x80 /* end of cylinder */ -#define ST1_DE 0x20 /* CRC data error */ -#define ST1_OR 0x10 /* DMA overrun */ -#define ST1_ND 0x04 /* sector not found */ -#define ST1_NW 0x02 /* write-protected diskette */ -#define ST1_MA 0x01 /* missing address mark */ - -/* - * ST2 - */ -#define ST2_CM 0x40 /* control mark */ -#define ST2_DD 0x20 /* data error */ -#define ST2_WC 0x10 /* wrong cylinder */ -#define ST2_SH 0x08 /* scan equal hit */ -#define ST2_SN 0x04 /* scan not satisfied */ -#define ST2_BC 0x02 /* bad cylinder */ -#define ST2_MD 0x01 /* missing address mark */ - -/* - * ST3 - */ -#define ST3_FT 0x80 /* fault */ -#define ST3_WP 0x40 /* write protect */ -#define ST3_RY 0x20 /* ready */ -#define ST3_T0 0x10 /* track 0 */ -#define ST3_TS 0x08 /* two side */ -#define ST3_HD 0x04 /* head address */ -#define ST3_US 0x03 /* unit select */ - -/* - * Commands. - */ -#define CMD_SPECIFY 0x03 -#define CMD_RECAL 0x07 -#define CMD_SENSEI 0x08 -#define CMD_SEEK 0x0f -#define CMD_FORMAT 0x4d -#define CMD_WRITE 0xc5 -#define CMD_READ 0xe6 - -/* - * Information required by FDC when formatting a diskette. - */ -struct format_info { - unsigned char cyl; - unsigned char head; - unsigned char sector; - unsigned char secsize; -}; |