📄 fd.c
字号:
/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Don Ahn. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)fd.c 8.1 (Berkeley) 6/11/93 */#include "fd.h"#if NFD > 0/* * This driver assumed that NFD == 2. Now it works for NFD == 1 or NFD == 2 * It will probably not work for NFD > 2. */#include <sys/param.h>#include <sys/dkbad.h>#include <sys/systm.h>#include <sys/conf.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/buf.h>#include <sys/uio.h>#include <i386/isa/isa_device.h>#include <i386/isa/fdreg.h>#include <i386/isa/icu.h>#define FDUNIT(s) ((s)&1)#define FDTYPE(s) (((s)>>1)&7)#define FDMOTOR(u) (fd_unit[(u)].motor ? (1 << (4 + (u))) : 0)#define b_cylin b_resid#define b_step b_resid#define FDBLK 512#define NUMTYPES 4struct fd_type { int sectrac; /* sectors per track */ int secsize; /* size code for sectors */ int datalen; /* data len when secsize = 0 */ int gap; /* gap len between sectors */ int tracks; /* total num of tracks */ int size; /* size of disk in sectors */ int steptrac; /* steps per cylinder */ int trans; /* transfer speed code */};struct fd_type fd_types[NUMTYPES] = { { 18,2,0xFF,0x1B,80,2880,1,0 }, /* 1.44 meg HD 3.5in floppy */ { 15,2,0xFF,0x1B,80,2400,1,0 }, /* 1.2 meg HD floppy */ { 9,2,0xFF,0x23,40,720,2,1 }, /* 360k floppy in 1.2meg drive */ { 9,2,0xFF,0x2A,40,720,1,1 }, /* 360k floppy in DD drive */};struct fd_u { int type; /* Drive type (HD, DD */ int active; /* Drive activity boolean */ int motor; /* Motor on flag */ struct buf head; /* Head of buf chain */ struct buf rhead; /* Raw head of buf chain */ int reset;} fd_unit[NFD];extern int hz;/* state needed for current transfer */static fdc; /* floppy disk controller io base register */int fd_dmachan = 2;static int fd_skip;static int fd_state;static int fd_retry;static int fd_drive;static int fd_track = -1;static int fd_status[7];/* make sure bounce buffer for DMA is aligned since the DMA chip doesn't roll over properly over a 64k boundary*/extern struct buf *dma_bounce[];/****************************************************************************//* autoconfiguration stuff *//****************************************************************************/int fdprobe(), fdattach(), fd_turnoff();struct isa_driver fddriver = { fdprobe, fdattach, "fd",};fdprobe(dev)struct isa_device *dev;{ return 1;}fdattach(dev)struct isa_device *dev;{ int s; fdc = dev->id_iobase; /* Set transfer to 500kbps */ outb(fdc+fdctl,0); fd_turnoff(0);}intFdsize(dev)dev_t dev;{ return(2400);}/****************************************************************************//* fdstrategy *//****************************************************************************/Fdstrategy(bp) register struct buf *bp; /* IO operation to perform */{ register struct buf *dp; long nblocks,blknum; int unit, type, s; unit = FDUNIT(minor(bp->b_dev)); type = FDTYPE(minor(bp->b_dev));#ifdef FDTESTprintf("fdstrat%d, blk = %d, bcount = %d, addr = %x|", unit, bp->b_blkno, bp->b_bcount,bp->b_un.b_addr);#endif if ((unit >= NFD) || (bp->b_blkno < 0)) { printf("fdstrat: unit = %d, blkno = %d, bcount = %d\n", unit, bp->b_blkno, bp->b_bcount); pg("fd:error in fdstrategy"); bp->b_error = EINVAL; bp->b_flags |= B_ERROR; goto bad; } /* * Set up block calculations. */ blknum = (unsigned long) bp->b_blkno * DEV_BSIZE/FDBLK; nblocks = fd_types[type].size; if (blknum + (bp->b_bcount / FDBLK) > nblocks) { if (blknum == nblocks) { bp->b_resid = bp->b_bcount; } else { bp->b_error = ENOSPC; bp->b_flags |= B_ERROR; }#ifdef FDTESTprintf("fdstrat%d, too big\n");#endif goto bad; } bp->b_cylin = blknum / (fd_types[type].sectrac * 2); dp = &fd_unit[unit].head; dp->b_step = (fd_types[fd_unit[unit].type].steptrac); s = splbio(); disksort(dp, bp); if ((fd_unit[0].head.b_active == 0)#if NFD > 1 && (fd_unit[1].head.b_active == 0)#endif ) {#ifdef FDDEBUGprintf("T|");#endif dp->b_active = 1; fd_drive = unit; fd_track = -1; /* force seek on first xfer */ untimeout(fd_turnoff,unit); fdstart(unit); /* start drive if idle */ } splx(s); return;bad: biodone(bp);}/****************************************************************************//* motor control stuff *//****************************************************************************/set_motor(unit,reset)int unit,reset;{ outb(fdc+fdout,unit | (reset ? 0 : 0xC) | FDMOTOR(0) #if NFD > 1 | FDMOTOR(1)#endif );}fd_turnoff(unit)int unit;{ fd_unit[unit].motor = 0; if (unit) set_motor(0,0); else set_motor(1,0);}fd_turnon(unit)int unit;{ fd_unit[unit].motor = 1; set_motor(unit,0);}/****************************************************************************//* fdc in/out *//****************************************************************************/intin_fdc(){ int i; while ((i = inb(fdc+fdsts) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM)) if (i == NE7_RQM) return -1; return inb(fdc+fddata);}dump_stat(){ int i; for(i=0;i<7;i++) { fd_status[i] = in_fdc(); if (fd_status[i] < 0) break; }printf("FD bad status :%lx %lx %lx %lx %lx %lx %lx\n", fd_status[0], fd_status[1], fd_status[2], fd_status[3], fd_status[4], fd_status[5], fd_status[6] );}out_fdc(x)int x;{ int r,errcnt; static int maxcnt = 0; errcnt = 0; do { r = (inb(fdc+fdsts) & (NE7_DIO|NE7_RQM)); if (r== NE7_RQM) break; if (r==(NE7_DIO|NE7_RQM)) { dump_stat(); /* error: direction. eat up output */#ifdef FDOTHERprintf("%lx\n",x);#endif } /* printf("Error r = %d:",r); */ errcnt++; } while (1); if (errcnt > maxcnt) { maxcnt = errcnt;#ifdef FDOTHERprintf("New MAX = %d\n",maxcnt);#endif } outb(fdc+fddata,x);}/* see if fdc responding */intcheck_fdc(){ int i; for(i=0;i<100;i++) { if (inb(fdc+fdsts)& NE7_RQM) return 0; } return 1;}/****************************************************************************//* fdopen/fdclose *//****************************************************************************/Fdopen(dev, flags) dev_t dev; int flags;{ int unit = FDUNIT(minor(dev)); int type = FDTYPE(minor(dev)); int s; printf("fdopen %x %d %d\n", minor(dev), unit, type); /* check bounds */ if (unit >= NFD) return(ENXIO); if (type >= NUMTYPES) return(ENXIO);/* if (check_fdc()) return(EBUSY);*/ /* Set proper disk type, only allow one type */ return 0;}Fdclose(dev, flags) dev_t dev;{ return (0);}/****************************************************************************//* fdread/fdwrite *//****************************************************************************//* * Routines to do raw IO for a unit.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -