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

📄 scsi_disk.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * we will think the partition table is good, but	 * it will be the default pt not the one read from the disk.	 */	if ((sz_part[unit].pt_valid == 0) || (sz_unit_online[unit] == 0)) {		stp = sc->sc_dstp[targid];		for( i = 0; i < 8; i++ ) {			sz_part[unit].pt_part[i].pi_nblocks = stp[i].nblocks;			sz_part[unit].pt_part[i].pi_blkoff = stp[i].blkoffs;		}		sz_part[unit].pt_valid = PT_VALID;		/*	 *	Default partition are now set. Call rsblk to set	 *	the driver's partition tables, if any exists, from	 *	the "a" partition superblock	 */		/*		 * TODO: this is a temporary fix!		 *	 If rsblk returns an error, revert		 *	 back to the default partition table.		 *		 * NOTE: the read by rsblk wipes out the current pt.		 * ABOVE comment wrong.		 *		 *	 Must get pt every time media changed!		 *	 RZ are fixed media disks, but.....		 */		i = rsblk(rzstrategy, dev, &sz_part[unit]);	}	/* So open nodelay doesn't falsely set on-line! */	if (dev_ready)	    sz_unit_online[unit] = 1;	return (0);}/* TODO: need funct header */rzsize(dev){	register struct sz_softc *sc;	register struct uba_device *ui;	int unit = minor(dev) >> 3;	int targid;	int part;	daddr_t psize;	/* TODO: check meaning of ui_flags == 0 in udsize???? */	if (unit >= nNSZ || (ui = szdinfo[unit]) == 0 || ui->ui_alive == 0)		return(-1);	sc = &sz_softc[ ui->ui_ctlr ];	targid = ui->ui_slave;	/*	 *	Sanity check			 */	if ( sz_part[unit].pt_valid != PT_VALID )	    panic("rzsize: invalid partition table ");	part = minor(dev) & 7;	if (sz_part[unit].pt_part[part].pi_nblocks != -1) 	    psize = sz_part[unit].pt_part[part].pi_nblocks; 	else	    psize = sc->sc_disksize[targid] - sz_part[unit].pt_part[part].pi_blkoff;	return(psize);}/* * rzcommand() - Execute a SCSI Command. * * Inputs:	dev = The device major/minor number. *		com = The SCSI command code. *		count = The command count. *		retry = The retry count. * * Return Value: *		Returns 0 for SUCCESS, or error code. */intrzcommand (dev, com, count, retry)register dev_t dev;register int com;register int count;register int retry;{	int unit = minor(dev) >> 3;	register struct buf *bp = &cszbuf[unit];	register struct sz_softc *sc;	register struct uba_device *ui;	register int s;	int cntlr, targid, error;	ui = szdinfo[unit];	cntlr = ui->ui_ctlr;	targid = ui->ui_slave;	sc = &sz_softc[cntlr];	if (error = rziowait (bp, sc->sc_rzspecial[targid])) {		return (error);	}	/*	 * Load the buffer.  The bp field usage is (see scsireg.h):	 *	 *	b_bcount  = The command count.	 *	b_gid     = The command mnemonic.	 *	b_bufsize = The retry count.	 *	 * These two fields are "known" to be "save" to use for this purpose.	 * (Most other drivers also use these fields in this way.)	 */	bp->b_flags = B_BUSY|B_READ;	bp->b_dev = dev;	bp->b_comand = com;	bp->b_bcount = count;	bp->b_blkno = 0;	bp->b_retry = retry;	bp->b_error = 0;	bp->b_proc = u.u_procp;	rzstrategy(bp);	iowait(bp);	s = splbio();	if (bp->b_flags & B_WANTED) {		wakeup ((caddr_t)bp);	}	splx(s);	bp->b_flags &= ~(B_BUSY | B_WANTED);	return (geterror (bp));}/* * rziowait() - Wait For Prior I/O To Complete (if busy). * * Inputs:	bp = The buffer to check. *		special = Special I/O active flag. * * Return Value: *		Return 0 for SUCCESS, or EINTR if sleep interrupted. */static intrziowait (bp, special)register struct buf *bp;register int special;{	register int error = 0;	register int s;	s = splbio();	while (bp->b_flags & B_BUSY) {	    bp->b_flags |= B_WANTED;	    if (special) {		if (sleep ((caddr_t)bp, (PCATCH | PZERO + 1))) {		    error = EINTR;		}	    } else {		(void) sleep ((caddr_t)bp, PRIBIO + 1);	    }	}	splx (s);	return (error);}rzstrategy(bp)	register struct buf *bp;{	register struct sz_softc *sc;	struct uba_device *ui;	register struct buf *dp;	register int s;	int unit = minor(bp->b_dev) >> 3;	int targid;	int cntlr;	int bad, err;	daddr_t sz, maxsz;	int part;	struct pt *pt;	ui = szdinfo[unit];	targid = ui->ui_slave;	cntlr = ui->ui_ctlr;	sc = &sz_softc[cntlr];	/* TODO1: note - no queue sorting! */	/*	 * Validate things like block number,	 * unit number, on-line, etc.	 */	bad = 0;	while(1) {	    if (unit >= nNSZ) {		bad = 1;		err = ENXIO;		break;	    }	    /*	     * CDROM is read only!	     */	    if ((sc->sc_devtyp[targid] & SZ_CDROM) &&		((bp->b_flags & B_READ) == 0)) {		bad = 1;		err = EROFS;		break;	    }	    /*	     * RSP says we must have this check.	     * It prevents open no delay burning us if the	     * disk's partition table is not valid.	     * We only do this check for data transfer commands.	     * House keeping commands (TUR, RDCAP, MODSEL, etc.)	     * also call rzstrategy.	     */	    if (bp != &cszbuf[unit]) {		if (sz_part[unit].pt_valid != PT_VALID) {		    if (sc->sc_szflags[targid] & SZ_NODEVICE) {			bad = 1;			err = ENXIO;			break;		    }		    else {			panic("rzstrategy: invalid partition table ");		    }		}	    }	    /* TODO: check ui == 0 || ui->ui_alive == 0 here - someday */	    /* TODO: EOM maybe, CSE - don't think so */	    /* TODO: don't think this can happen for disks */	    if ((sc->sc_flags[targid]&DEV_EOM) && !((sc->sc_flags[targid]&DEV_CSE) ||		(dis_eot_sz[unit] & DISEOT))) {		    bad = 1;		    err = ENOSPC;		    break;	    }	    /* 	     * If SZ_NODEVICE is set, the device was opened	     * with FNDELAY, but the device didn't respond.	     * We'll try again to see if the device is here,	     * if it is not, return an error.	     */	    if (sc->sc_szflags[targid] & SZ_NODEVICE) {		DEV_UGH(sc->sc_device[targid], unit, "offline");		bad = 1;	        err = ENXIO;		break;	    }	    /*	     * Check transfer size,	     * to be sure it does not overflow the	     * bounds of the partition.	     * Only check data transfer commands.	     */	    if (bp == &cszbuf[unit])		break;	    part = minor(bp->b_dev) & 7;	    sz = (bp->b_bcount + 511) >> 9;	    pt = &sz_part[unit];	    if (pt->pt_part[part].pi_nblocks == -1)		maxsz = sc->sc_disksize[targid] - pt->pt_part[part].pi_blkoff;	    else		maxsz = pt->pt_part[part].pi_nblocks;	    if ((bp->b_blkno < 0) || (bp->b_blkno+sz > maxsz) ||		(pt->pt_part[part].pi_blkoff >= sc->sc_disksize[targid])) {		    bad = 1;			err = ENOSPC;		    break;	    }	    break;	}	if (bad) {	    bp->b_flags |= B_ERROR;	    bp->b_resid = bp->b_bcount;	    bp->b_error = err;	    biodone(bp);	    return;	}	/* TODO: DISKLOG stuff in uda.c?????? */#ifdef vax	s = spl5();#endif vax#ifdef mips	s = splbio();#endif mips	dp = &szutab[unit];	if (dp->b_actf == NULL)		dp->b_actf = bp;	else		dp->b_actl->av_forw = bp;	dp->b_actl = bp;	bp->av_forw = NULL;	if ((dp->b_active == 0) && (sc->sc_active == 0)) {		sc->sc_xstate[targid] = SZ_NEXT;		sc->sc_xevent[targid] = SZ_BEGIN;		sz_start(sc, targid);	}	splx(s);}rzread(dev, uio)	register dev_t dev;	register struct uio *uio;{	int unit = minor(dev) >> 3;	return (physio(rzstrategy, &rszbuf[unit], dev, B_READ, minphys, uio));}rzwrite(dev, uio)	register dev_t dev;	register struct uio *uio;{	register struct sz_softc *sc;	struct uba_device *ui;	int unit = minor(dev) >> 3;		int targid;	ui = szdinfo[unit];	targid = ui->ui_slave;	sc = &sz_softc[ui->ui_ctlr];	/*	 * CDROM is read only!	 */	if (sc->sc_devtyp[targid] & SZ_CDROM)	    return(EROFS);	return (physio(rzstrategy, &rszbuf[unit], dev, B_WRITE, minphys, uio));}rzioctl(dev, cmd, data, flag)	dev_t dev;	register int cmd;	caddr_t data;	int flag;{	register struct sz_softc *sc;	register struct uba_device *ui;	register struct uba_ctlr *um;	int unit = minor(dev) >> 3;	int cntlr;	int targid;	register struct buf *bp = &cszbuf[unit];	struct devget *devget;	int i;	struct size *stp;	struct pt *pt = (struct pt *)data;	int error;	struct scsi_devtab *sdp;	struct sz_rdcap_dt *rdp;	struct sz_rzmodsns_dt *msdp;	struct page_code_3 *p3;	struct page_code_4 *p4;	struct page_code_5 *p5;	DEVGEOMST *devgeom;	ui = szdinfo[unit];	cntlr = ui->ui_ctlr;        um = szminfo[cntlr];	targid = ui->ui_slave;	sc = &sz_softc[cntlr];	sdp = (struct scsi_devtab *)sc->sc_devtab[targid];	switch (cmd) {	case DIOCGETPT:		/* Return disk partition table to user */	case DIOCDGTPT:		/* Return default disk partition table */		if (cmd == DIOCGETPT) {		    /*		     * Copy pt structure into user's data area.		     */		    *pt = sz_part[unit];		}		else {		    /*		     * Copy the default partition table to user's data area.		     */		    stp = sc->sc_dstp[targid];		    for (i=0; i<8; i++) {			pt->pt_part[i].pi_nblocks = stp[i].nblocks;			pt->pt_part[i].pi_blkoff = stp[i].blkoffs;		    }		}		/*		 * Change all -1 nblocks to disk unit size.		 */		for (i=0; i<8; i++) {		   if (pt->pt_part[i].pi_nblocks == -1)			pt->pt_part[i].pi_nblocks =			    sc->sc_disksize[targid] - pt->pt_part[i].pi_blkoff;		}		pt->pt_magic = PT_MAGIC;		break;	/* TODO1: what if user does this with open no delay? */	case DIOCSETPT: /* set the driver partition tables */		/*		 * Only super users can set the pack's partition table.		 */		if (!suser())		    return(EACCES);		/*		 * CDROM is read only, don't allow set partition table.		 */		if (sc->sc_devtyp[targid] & SZ_CDROM)		    return(EROFS);				/*		 * Before we set the new partition tables make sure		 * that it will no corrupt any of the kernel data		 * structures.		 */		if ((error = ptcmp(dev, &sz_part[unit], pt)) != 0)		    return(error);		/*		 *	Using the user's data to set the partition table		 *	for the pack		 */		sz_part[unit] = *pt;		/*		 * See if we need to update the superblock of the		 * "a" partition of this disk.		 */		ssblk(dev, pt);		/*		 * Just make sure that we set the valid bit.		 */		sz_part[unit].pt_valid = PT_VALID;		break;	case DEVIOCGET: 			/* device status */		devget = (struct devget *)data;		bzero(devget,sizeof(struct devget));		devget->category = DEV_DISK;#ifdef vax		devget->bus = DEV_NB;		bcopy(DEV_VS_SCSI, devget->interface, strlen(DEV_VS_SCSI));#endif vax#ifdef mips		devget->bus = DEV_SCSI;		bcopy(DEV_SCSI_GEN, devget->interface, strlen(DEV_SCSI_GEN));#endif mips		bcopy(sc->sc_device[targid], devget->device, DEV_SIZE);		devget->adpt_num = um->um_adpt;		devget->nexus_num = 0;		devget->bus_num = 0;		devget->ctlr_num = cntlr;		devget->rctlr_num = 0;		devget->slave_num = targid;		bcopy("rz", devget->dev_name, 3);		devget->unit_num = unit;		devget->soft_count = sc->sc_softcnt[targid];		devget->hard_count = sc->sc_hardcnt[targid];		devget->stat = sc->sc_flags[targid];		if (sc->sc_devtyp[targid] & SZ_CDROM) {		    /* To make sure we don't break the installation! */		    devget->stat |= DEV_WRTLCK;		}		else {

⌨️ 快捷键说明

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