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

📄 sf.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "sf.h"#if	NSF > 0/************************************************************************ ************************************************************************ *									* *									* *		SCSI floppy disk driver					* *									* *									* ************************************************************************ ************************************************************************//* * Copyright (C) 1989 Sun Microsystems, Inc. */#ident	"@(#)sf.c 1.1 92/07/30 SMI"/************************************************************************ ************************************************************************ *									* *									* *		Includes, Declarations and Local Data			* *									* *									* ************************************************************************ ************************************************************************/#include <scsi/scsi.h>#include <scsi/targets/sfdef.h>#include <sun/vddrv.h>#include <vm/hat.h>#include <vm/seg.h>#include <vm/as.h>/************************************************************************ *									* * Local definitions, for clarity of code				* *									* ************************************************************************/#ifdef	OPENPROMS#define	DNAME		devp->sd_dev->devi_name#define	DUNIT		devp->sd_dev->devi_unit#define	CNAME		devp->sd_dev->devi_parent->devi_name#define	CUNIT		devp->sd_dev->devi_parent->devi_unit#else	OPENPROMS#define	DNAME		devp->sd_dev->md_driver->mdr_dname#define	DUNIT		devp->sd_dev->md_unit#define	CNAME		devp->sd_dev->md_driver->mdr_cname#define	CUNIT		devp->sd_dev->md_ctlr->mc_ctlr#endif	OPENPROMS#define	UPTR		((struct scsi_floppy *)(devp)->sd_private)#define	SCBP(pkt)	((struct scsi_status *)(pkt)->pkt_scbp)#define	SCBP_C(pkt)	((*(pkt)->pkt_scbp) & STATUS_MASK)#define	CDBP(pkt)	((union scsi_cdb *)(pkt)->pkt_cdbp)#define	ROUTE		(&devp->sd_address)#define	BP_PKT(bp)	((struct scsi_pkt *)bp->av_back)#define	Tgt(devp)	(devp->sd_address.a_target)#define	Lun(devp)	(devp->sd_address.a_lun)#define	SFUNIT(dev)	(minor((dev))>>3)#define	SFPART(dev)	(minor((dev))&0x7)/* * Parameters */	/*	 * 120 seconds is a *very* reasonable amount of time for most floppy	 * operations.	 */#define	DEFAULT_SF_TIMEOUT	120	/*	 * 5 seconds is what we'll wait if we get a Busy Status back	 */#define	SFTIMEOUT		5*hz	/* 2 seconds Busy Waiting */	/*	 * Number of times we'll retry a normal operation.	 *	 * XXX This includes retries due to transport failure	 * XXX Need to distinguish between Target and Transport	 * XXX failure.	 */#define	SF_RETRY_COUNT		30	/*	 * maximum number of supported units	 */#define	SF_MAXUNIT		2/* * Debugging macros */#define	DEBUGGING	((scsi_options & SCSI_DEBUG_TGT) || sfdebug > 1)#define	DEBUGGING_ALL	((scsi_options & SCSI_DEBUG_TGT) || sfdebug)#define	DPRINTF		if(DEBUGGING) printf#define	DPRINTF_ALL	if (DEBUGGING || sfdebug > 0) printf#define	DPRINTF_IOCTL	DPRINTF_ALL/************************************************************************ *									* * Gloabal Data Definitions						* *									* ************************************************************************/struct scsi_device *sfunits[SF_MAXUNIT];extern int nsf = SF_MAXUNIT;/************************************************************************ *									* * Local Static Data							* *									* ************************************************************************/static int sfpri = 0;static int sfdebug = 0;static int sf_error_reporting = SDERR_RETRYABLE;static struct sf_drivetype sf_drivetypes[] = {/* Emulex MD21 */{	"SMS",		0,		CTYPE_SMS,	3,	"SMS" },/* Connor */{	"NCR",		0,		CTYPE_NCR,	3,	"NCR" },};#define	MAX_SFTYPES (sizeof sf_drivetypes/ (sizeof sf_drivetypes[0]))static u_char media_types[] = {	/*	 * first one must be ff (replaced with whatever the drive starts with)	 */	0xff, 0x1e, };/* * Configuration Data */#ifdef	OPENPROMS/* * Device driver ops vector */int sfslave(), sfopen(), sfclose(), sfread(), sfwrite();int sfstrategy(), sfioctl(), sfsize();extern int nulldev(), nodev();struct dev_ops sf_ops = {	1,	sfslave,	nulldev,	sfopen,	sfclose,	sfread,	sfwrite,	sfstrategy,	nodev,	sfsize,	sfioctl};	#else	OPENPROMSXXX * BARF * XXX#endif/************************************************************************ *									* * Local Function Declarations						* *									* ************************************************************************/static void sfintr(), sferrmsg(), sfdone(), make_sf_cmd(), sfstart(), sfdone();static int sfrunout(), sf_findslave(), sf_unit_ready();/**/#if	defined(VDDRV) && defined(LOADABLE)/*********************************************************************** ************************************************************************ *									* *									* *		Loadable Module support					* *									* *									* ************************************************************************ ************************************************************************/#ifndef	OPENPROMSXXXXXXXXXXXXXXXXXXXXXXXXXX BLETCH XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#endif/* * Loadable module support: *	for a loadable driver *	modload modstat & modunload */int nsf = NSF;struct scsi_device *sfunits[NSF];/* * awk. */static int targetid = 6;static int sf_can_load(), sf_can_unload();extern int seltrue();static struct bdevsw sf_bdevsw = {	sfopen, sfclose, sfstrategy, nodev, sfsize, 0};static struct cdevsw sf_cdevsw = {	sfopen, sfclose, sfread, sfwrite, sfioctl, nulldev, seltrue, 0, 0};static struct vdldrv sfdrv = {	VDMAGIC_DRV,	"SCSI Floppy Driver",	&sf_ops,	&sf_bdevsw,	&sf_cdevsw,	9,	33};sfinit(fcn, vdp, vdi, vds)int			fcn;register struct vddrv	*vdp;caddr_t			vdi;struct vdstat		*vds;{	extern struct scsi_device *sd_root;	struct scsi_device *devp;	int status = 0;	switch (fcn) {	case VDLOAD:		status = sf_can_load();		if (status == 0) {			vdp->vdd_vdtab = (struct vdlinkage *)&sfdrv;		}		break;	case VDUNLOAD:		status = sf_can_unload();		break;	case VDSTAT:		break; 	default:		printf("sfinit: unknown function 0x%x\n", fcn);		status = EINVAL;	} 	return status;}static intsf_can_load(){	register scsi_device *devp, *newdevp;	register i, s;	if (sfpri == 0)		sfpri = pritospl(SPLMB);	s = splr(sfpri);	for  (i = 0; i < nsf; i++) {		if (sfunits[i]) {			(void) splx(s);			return (EBUSY);		}	}	if (devp = sd_root) {		for (;;) {			if (devp->sd_address.a_target == targetid) {				(void) splx(s);				return (EBUSY);			}			if (devp->sd_next) {				devp = devp->sd_next;			} else				break;		}	}	(void) splx(s);	newdevp =		(struct scsi_device *) kmem_zalloc((unsigned) sizeof (*devp));	if (!newdevp)		return (ENOMEM);	newdevp->sd_address = devp->sd_address;	newdevp->sd_address.a_target = targetid;	newdevp->sd_address.a_lun = 0;	devp->sd_next = newdevp;}#endif	defined(VDDRV) && defined(LOADABLE)/************************************************************************ ************************************************************************ *									* *									* *		Autoconfiguration Routines				* *									* *									* ************************************************************************ ************************************************************************/intsfslave(devp)struct scsi_device *devp;{	/*	 * fill in our local array	 */	if (DUNIT >= nsf)		return (0);	sfunits[DUNIT] = devp;#ifdef	OPENPROMS	sfpri = MAX(sfpri,ipltospl(devp->sd_dev->devi_intr->int_pri));#else	XXX BARF XXX sfpri = MAX(sfpri,pritospl(devp->sd_dev->md_inr));#endif	/*	 * Turn around and call real slave routine..	 */	return (sf_findslave(devp,0));}static intsf_findslave(devp,canwait)register struct scsi_device *devp;int canwait;{	static char *badtyp1 =		"%s%d:\tdevice is a '%s' device\n\texpected a '%s' device\n";	static char *badtyp2 = "\tat target %d lun %d on %s%d\n";	static char *nonccs ="%s%d: non-CCS device found at target %d lun %d on %s%d- not supported\n";	struct scsi_pkt *pkt, *rqpkt;	struct scsi_floppy *un;	struct scsi_capacity *cap;	struct sf_drivetype *dp;	long capacity, lbasize;	auto int (*f)() = (canwait == 0)? NULL_FUNC: SLEEP_FUNC;	/*	 * Call the routine scsi_slave to do some of the dirty work.	 * All scsi_slave does is do a TEST UNIT READY (and possibly	 * a non-extended REQUEST SENSE or two), and an INQUIRY command.	 * If the INQUIRY command succeeds, the field sd_inq in the	 * device structure will be filled in.	 *	 * XXX NEED TO CHANGE scsi_slave TO JUST DO REQUEST_SENSE	 * XXX AND INQUIRY- THAT WAY WE CAN DO THE TEST_UNIT_READY	 * XXX HERE AND POSSIBLY SEND A START UNIT COMMAND IF IT	 * XXX ISN'T READY..	 */	switch (scsi_slave(devp,canwait)) {	default:	case SCSIPROBE_NOMEM:	case SCSIPROBE_FAILURE:	case SCSIPROBE_NORESP:		return (0);	case SCSIPROBE_NONCCS:		printf(nonccs,DNAME,DUNIT,Tgt(devp),Lun(devp),CNAME,CUNIT);		return (0);	case SCSIPROBE_EXISTS:		if(devp->sd_inq->inq_dtype != DTYPE_DIRECT) {			printf(badtyp1,DNAME,DUNIT,				scsi_dname((int)devp->sd_inq->inq_dtype),				scsi_dname(DTYPE_DIRECT));			printf(badtyp2,Tgt(devp),Lun(devp),CNAME,CUNIT);			return (0);		}		break;	}	/*	 * Sigh. Look through our list of supported drives to dredge	 * up information that we haven't figured out a clever way	 * to get inference yet.	 */	/*	 * The actual unit is present.	 * Now is the time to fill in the rest of our info..	 */	un = UPTR = (struct scsi_floppy *)		kmem_zalloc(sizeof(struct scsi_floppy));	if (!un) {		printf("%s%d: no memory for disk structure\n",DNAME,DUNIT);		return (0);	}	for (dp = &sf_drivetypes[0]; dp < &sf_drivetypes[MAX_SFTYPES]; dp++) {		if (bcmp(devp->sd_inq->inq_vid,dp->vid,dp->vidlen) == 0) {			un->un_dp = dp;			break;		}	}	if (dp == &sf_drivetypes[MAX_SFTYPES]) {		printf("%s%d: unknown drive not supported\n",DNAME,DUNIT);		(void) kmem_free((caddr_t) un,			(unsigned) sizeof (struct scsi_floppy));		return 0;	}	/*	 * now allocate a request sense packet	 */	rqpkt = scsi_pktiopb(ROUTE,(caddr_t *)&devp->sd_sense,CDB_GROUP0,		1,SENSE_LENGTH,B_READ,f);	if (!rqpkt) {		(void) kmem_free((caddr_t) un,			(unsigned) sizeof (struct scsi_floppy));		return (0);	}	makecom_g0(rqpkt,devp,0,SCMD_REQUEST_SENSE,0,SENSE_LENGTH);	rqpkt->pkt_pmon = -1;	un->un_mode = (caddr_t) rmalloc(iopbmap, (long) MSIZE);	un->un_rbufp = (struct buf *) kmem_zalloc(sizeof (struct buf));	un->un_sbufp = (struct buf *) kmem_zalloc(sizeof (struct buf));	if (!un->un_rbufp || !un->un_sbufp || !un->un_mode) {		printf("sfslave: no memory for data structures\n");		if (un->un_sbufp)			(void) kmem_free((caddr_t)un->un_rbufp,sizeof (struct buf));		if (un->un_rbufp)			(void) kmem_free((caddr_t)un->un_rbufp,sizeof (struct buf));		if (un->un_mode)			(void) rmfree(iopbmap,				(long) MSIZE, (u_long) un->un_mode);		(void) kmem_free((caddr_t) un,sizeof (struct scsi_floppy));		(void) rmfree(iopbmap,			(long) SENSE_LENGTH, (u_long) devp->sd_sense);		scsi_resfree(rqpkt);		return 0;	}	devp->sd_present = 1;	un->un_capacity = -1;		/* XXX */	un->un_lbasize = SECSIZE;	/* XXX */	rqpkt->pkt_comp = sfintr;	rqpkt->pkt_time = DEFAULT_SF_TIMEOUT;	un->un_rqs = rqpkt;	un->un_sd = devp;	un->un_dev = DUNIT<<3;#ifdef	OPENPROMS	devp->sd_dev->devi_driver = &sf_ops;#endif	un->un_g.dkg_ncyl = 78;	un->un_g.dkg_acyl = 0;	un->un_g.dkg_pcyl = 80;	un->un_g.dkg_nhead = 2;	un->un_g.dkg_nsect = 9;	return (1);}/**//************************************************************************ ************************************************************************ *									* *									* *			Unix Entry Points				* *									* *									* ************************************************************************ ************************************************************************/intsfopen(dev, flag)dev_t dev;int flag;{	register struct scsi_device *devp;	register struct scsi_floppy *un;	register int unit, s;	if((unit = SFUNIT(dev)) >= nsf) {		return ENXIO;	} else if (!(devp = sfunits[unit])) {		return ENXIO;	} else if (!devp->sd_present) {		s = splr(sfpri);		if (sf_findslave(devp,1)) {			printf("%s%d at %s%d target %d lun %d\n",DNAME,DUNIT,				CNAME,CUNIT,Tgt(devp),Lun(devp));		} else {			(void) splx(s);			return ENXIO;		}		(void) splx(s);	}	un = UPTR;	if (un->un_state >= SF_STATE_OPEN)		return (0);	un->un_last_state = un->un_state;	un->un_state = SF_STATE_OPENING;	/*	 * sf_unit_ready just determines whether a diskette is inserted	 *	 */	if (sf_unit_ready(dev) == 0) {		un->un_state = un->un_last_state;		un->un_last_state = SF_STATE_OPENING;		return (ENXIO);	}	/*	 * sf_get_density will run through all known density modes	 * to try and read the device. If that fails, it must be	 * either an unformatted disk, or must be a density we cannot	 * hack. In either case, we will allow only a format command	 * of this device at this point to open the device.	 */	if (sf_get_density(dev) == 0) {		/*		 * Are we opening this for format(8) or fdformat?		 */		if ((flag & (FNDELAY|FNBIO)) == 0 ||				cdevsw[major(dev)].d_open != sfopen) {			un->un_last_state = un->un_state;			un->un_state = SF_STATE_CLOSED;			return ENXIO;		}		/*		 * XXX:	put in a block here- opening for formatting is		 * XXX:	exclusive use.		 */		if (sf_set_density(dev) == 0) {			un->un_last_state = un->un_state;			un->un_state = SF_STATE_CLOSED;			return EIO;		}	}	un->un_last_state = un->un_state;	un->un_state = SF_STATE_OPEN;	un->un_open |= (1<<SFPART(dev));	return (0);}intsfclose(dev)dev_t dev;{	register struct scsi_device *devp;	register struct scsi_floppy *un;	int unit;#ifdef	NOT

⌨️ 快捷键说明

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