⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flp.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic	char	*sccsid = "@(#)flp.c	4.1	(ULTRIX)	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1989 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any	other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived	from  software	received  from	the	* *   University    of	California,   Berkeley,   and	from   Bell	* *   Laboratories.  Use, duplication, or disclosure is	subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or	reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ * Modification history: /sys/vax/flp.c * * 30-May-89	darrell *	Added include of ../../machine/common/cpuconf.h -- cpu types *	were moved there. * ***********************************************************************/#if VAX780#include "../h/param.h"#include "../h/systm.h"#include "../h/conf.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/buf.h"#include "../h/uio.h"#include "../vax/cons.h"#include "../vax/cpu.h"#include "../../machine/common/cpuconf.h"#include "../vax/flp.h"#include "../vax/mtpr.h"struct {	short	fl_state;		/* open and busy flags */	short	fl_active;		/* driver state flag */	struct	buf *fl_buf;		/* buffer we're using */	unsigned char *fl_xaddr;	/* transfer address */	short	fl_errcnt;} fltab;/*ARGSUSED*/flopen(dev, flag)	dev_t dev;	int flag;{	struct buf *geteblk();#if VAX750	if (cpu != VAX_780)		return (ENXIO);#endif	if (fltab.fl_state != 0)		return (ENXIO);	fltab.fl_state = FL_OPEN;	fltab.fl_buf = geteblk(512);	fltab.fl_active = FL_IDLE;	return (0);}/*ARGSUSED*/flclose(dev, flag)	dev_t dev;	int flag;{	brelse(fltab.fl_buf);	fltab.fl_state = 0;}floperation(rw, uio)	enum uio_rw rw;	struct uio *uio;{	register struct buf *bp;	register int i;	int error;	/*	 * Assume one block read/written for each call - 	 * and enforce this by checking for block size of 128.	 * Use the b_blkno field to address	 * physical, 128-byte blocks (u.u_offset/128).	 * This is checked for validity, and is further interpreted as:	 *	 *	track# * (sectors/track) + sector #	 */	if (uio->uio_resid == 0) 		return (0);	(void) spl4();	while (fltab.fl_state & FL_BUSY)		sleep((caddr_t)&fltab, PRIBIO);	fltab.fl_state |= FL_BUSY;	(void) spl0();	bp = fltab.fl_buf;	error = 0;	while ((i = imin(RXBYSEC, uio->uio_resid)) > 0) {		bp->b_blkno = uio->uio_offset>>7;		if (bp->b_blkno >= MAXSEC || (uio->uio_offset & 0177) != 0)			return (ENXIO);		if (rw == UIO_WRITE) {			error = uiomove(bp->b_un.b_addr, i, UIO_WRITE, uio);			if (error)				break;		}		bp->b_flags = rw == UIO_WRITE ? B_WRITE : B_READ;		(void) spl4(); 		flstart();		while ((bp->b_flags & B_DONE) == 0)			sleep((caddr_t)bp, PRIBIO);			(void) spl0();		if (bp->b_flags & B_ERROR) {			error = EIO;			break;		}		if (rw == UIO_READ) {			error = uiomove(bp->b_un.b_addr, i, UIO_READ, uio);			if (error)				break;		}	}	fltab.fl_state &= ~FL_BUSY;	wakeup((caddr_t)&fltab);	return (error);}/*ARGSUSED*/flread(dev, uio)	dev_t dev;	struct uio *uio;{	return (floperation(UIO_READ, uio));}/*ARGSUSED*/flwrite(dev, uio)	dev_t dev;	struct uio *uio;{	return (floperation(UIO_WRITE, uio));}flstart(){	register struct buf *bp;	bp = fltab.fl_buf;	fltab.fl_active = FL_MAND;	fltab.fl_errcnt = 0;	fltab.fl_xaddr = (unsigned char *) bp->b_un.b_addr;	bp->b_resid = 0;	bp->b_bcount = RXBYSEC; /* always transfer a full sector */	if ((mfpr(TXCS) & TXCS_RDY) == 0)		/* not ready to receive order */		return;	/*	 * Wake up floppy LSI software with command	 */	fltab.fl_active = FL_SEC;	if ((bp->b_flags&B_READ) == B_READ)		mtpr(TXDB, FL_RS);	else		mtpr(TXDB, FL_WS);}/* * See if we want to transmit something * to the floppy - and do it */conxfl(){	register int databyte;	register struct buf *bp;	bp = fltab.fl_buf;	switch (fltab.fl_active) {	case FL_MAND:		/* send command */		if ((bp->b_flags&B_READ) == B_READ)			mtpr(TXDB,FL_RS);		else			mtpr(TXDB,  FL_WS);		fltab.fl_active = FL_SEC;		break;	case FL_SEC:		/* send sector address */		databyte = (int)bp->b_blkno % RXSTRK + 1;		mtpr(TXDB, FL_DATA | databyte);		fltab.fl_active = FL_TRACK;		break;	case FL_TRACK:		/* send track address */		databyte = (int)bp->b_blkno / RXSTRK;		mtpr(TXDB , FL_DATA | databyte);		if ((bp->b_flags&B_READ) == B_READ)			/* prepare to receive complete */			fltab.fl_active = FL_COM;		else			/* prepare to send data */			fltab.fl_active = FL_DAX;		break;	case FL_DAX:		databyte = *(fltab.fl_xaddr++);		mtpr(TXDB, FL_DATA | databyte);		if (--bp->b_bcount == 0)			fltab.fl_active = FL_COM;		break;	case FL_CAN:		/* give cancel order */		mtpr(TXDB, FL_CANCEL);		if (++fltab.fl_errcnt <= FLERRS) {			/* If error count permits, retry order */			fltab.fl_active = FL_MAND;			bp->b_bcount = RXBYSEC;			fltab.fl_xaddr = (unsigned char *) bp->b_un.b_addr;		} else {			/*			 * We're really stupid today - call it an			 * error and give up			 */			bp->b_flags |= B_ERROR | B_DONE;			bp->b_resid = -RXBYSEC;			fltab.fl_active = FL_IDLE;			wakeup((caddr_t)bp);		}	}}cnrfl(c)	int c;{	register int datum;	register struct buf *bp;	datum = c;	bp = fltab.fl_buf;	if (datum == FL_PERR) {		/*		 * Got a protocol error - cancel the		 * current function and try again if error count isn't		 * too great.  First, though, make sure that an actual		 * transaction is in progress (so a spurious error from		 * the LSI won't screw us up too much!		 */		if (fltab.fl_active != FL_IDLE)			fltab.fl_active = FL_CAN;	} else switch(fltab.fl_active ) {	case FL_DAR:		/* expecting a datum */		if ((c&RXDB_ID) != FL_DATA)			goto error;		*(fltab.fl_xaddr++) = (c & RXDB_DATA);		if (--bp->b_bcount==0) {			fltab.fl_active = FL_IDLE;			bp->b_flags |= B_DONE;			wakeup((caddr_t)bp);		}		break;	case FL_COM:		/* expecting a "function complete" */		if ((c&RXDB_ID)!= FL_FFC || (c&FL_ERR) == FL_ERR){error:			bp->b_flags |= B_ERROR | B_DONE;			bp->b_resid = -bp->b_bcount;			fltab.fl_active = FL_IDLE;			wakeup((caddr_t)bp);		} else if ((bp->b_flags&B_READ) == B_READ)			/* got function complete, now get data */			fltab.fl_active = FL_DAR;		else {			/* got function complete on write - finish up */			fltab.fl_active = FL_IDLE;			bp->b_flags |= B_DONE;				wakeup((caddr_t)bp);		}		break;	}}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -