diff options
Diffstat (limited to 'i386/i386at/fd.c')
-rw-r--r-- | i386/i386at/fd.c | 1701 |
1 files changed, 0 insertions, 1701 deletions
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 |