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

📄 tmscp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
				 * serious exception on the next command.				 */				tms->tms_serex = 2;			}		/*		 * The tmscp spec states that controllers do not have to		 * report the number of records or files skipped.  So on		 * reposition commands we go strictly by cmd status.		 */		if (mp->mscp_opcode != (M_OP_REPOS|M_OP_END))			bp->b_resid = bp->b_bcount - mp->mscp_bytecnt;		else			bp->b_resid = 0;		tms->tms_resid = bp->b_resid;		iodone(bp);		break;	case M_OP_GTUNT|M_OP_END:#		ifdef DEBUG		printd("tmscprsp: GTUNT end packet status = 0%o\n",st);		printd("tmscprsp: unit %d mediaid %x %c%c %c%c%c%d %x %x t=%d\n"		    ,mp->mscp_unit, mp->mscp_mediaid		    ,F_to_C(mp,4),F_to_C(mp,3),F_to_C(mp,2)		    ,F_to_C(mp,1),F_to_C(mp,0)		    ,mp->mscp_mediaid & 0x7f		    ,mp->mscp_unitid.val[0]		    ,mp->mscp_unitid.val[1]		    ,mp->mscp_format);#		endif				tms->tms_type = mp->mscp_mediaid;		tms->tms_fmtmenu = mp->mscp_fmtmenu;		tms->tms_unitflgs = mp->mscp_unitflgs;		break;	default:		printf("tmscp unknown packet\n");		tmserror(um, (struct mslg *)mp);	}	/* end switch mp->mscp_opcode */}/*  * Give a meaningful error when the mscp_status field returns an error code. */errinfo(st)	int st;			/* the status code */{	switch(st) {	case M_ST_ICMD:		printf("invalid command\n");		break;	case M_ST_ABRTD:		printf("command aborted\n");		break;	case M_ST_OFFLN:		printf("unit offline\n");		break;	case M_ST_WRTPR:		printf("unit write protected\n");		break;	case M_ST_COMP:		printf("compare error\n");		break;	case M_ST_DATA:		printf("data error\n");		break;	case M_ST_HSTBF:		printf("host buffer access error\n");		break;	case M_ST_CNTLR:		printf("controller error\n");		break;	case M_ST_DRIVE:		printf("drive error\n");		break;	case M_ST_FMTER:		printf("formatter error\n");		break;	case M_ST_BOT:		printf("BOT encountered\n");		break;	case M_ST_TAPEM:		printf("tape mark encountered\n");		break;	case M_ST_RDTRN:		printf("record data truncated\n");		break;	case M_ST_PLOST:		printf("position lost\n");		break;	case M_ST_SEX:		printf("serious exception\n");		break;	case M_ST_LED:		printf("LEOT detected\n");		break;	}}/* * Manage buffers and perform block mode read and write operations. */tmscpstrategy (bp)	register struct buf *bp;{	register struct uba_device *ui;	register struct uba_ctlr *um;	register struct buf *dp;	register int unit = TMSUNIT(bp->b_dev);	int s;	if (unit >= NTMS)		{#		ifdef DEBUG		printd ("tmscpstrategy: bad unit # %d\n",unit);#		endif		bp->b_flags |= B_ERROR;		iodone(bp);		return;		}	ui = tmsdinfo[unit];	um = ui->ui_mi;	if (ui == 0 || ui->ui_alive == 0)		{		bp->b_flags |= B_ERROR;		iodone(bp);		return;		}	s = spl5();	/*	 * Link the buffer onto the drive queue	 */	dp = &tmsutab[ui->ui_unit];	if (dp->b_actf == 0)		dp->b_actf = bp;	else		dp->b_actl->av_forw = bp;	dp->b_actl = bp;	bp->av_forw = 0;	/*	 * Link the drive onto the controller queue	 */	if (dp->b_active == 0)		{		dp->b_forw = NULL;		if (um->um_tab.b_actf == NULL)			um->um_tab.b_actf = dp;		else			um->um_tab.b_actl->b_forw = dp;		um->um_tab.b_actl = dp;		dp->b_active = 1;		}	/*	 * If the controller is not active, start it.	 */	if (um->um_tab.b_active == 0)		{#		if defined(VAX750)		if (cpu == VAX_750				 && tmscpwtab[um->um_ctlr].av_forw == &tmscpwtab[um->um_ctlr])			{			if (um->um_ubinfo != 0)				log(TMS_PRI, "tmscpstrategy: ubinfo 0x%x\n",				    um->um_ubinfo);			else				um->um_ubinfo = uballoc(um->um_ubanum, (caddr_t)0, 0, UBA_NEEDBDP);			}#		endif#		ifdef DEBUG		printd10("tmscpstrategy: Controller not active, starting it\n");#		endif		(void) tmscpstart(um);		}	splx(s);	return;}#define DBSIZE 32#define ca_Rspdsc       ca_rspdsc[0]#define ca_Cmddsc       ca_rspdsc[1]#define tmscp_Rsp       tmscp_rsp[0]#define tmscp_Cmd       tmscp_cmd[0]struct  tmscp     tmscpd[NTMSCP];tmscpdump(dev)	dev_t dev;{	struct tmscpdevice *tmscpaddr;	struct tmscp *tmscp_ubaddr;	char *start;	int num, blk, unit;	register struct uba_regs *uba;	register struct uba_device *ui;	register struct tmscp *tmscpp;	register struct pte *io;	register int i;	unit = minor(dev) & 03;	if (unit >= NTMS)		return (ENXIO);#	define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))	ui = phys(struct uba_device *, tmsdinfo[unit]);	if (ui->ui_alive == 0)		return (ENXIO);	uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;	ubainit(uba);	tmscpaddr = (struct tmscpdevice *)ui->ui_physaddr;	DELAY(2000000);	tmscpp = phys(struct tmscp *, &tmscpd[ui->ui_ctlr]);	num = btoc(sizeof(struct tmscp)) + 1;	io = &uba->uba_map[NUBMREG-num];	for(i = 0; i<num; i++)		*(int *)io++ = UBAMR_MRV|(btop(tmscpp)+i);	tmscp_ubaddr = (struct tmscp *)(((int)tmscpp & PGOFSET)|((NUBMREG-num)<<9));	tmscpaddr->tmscpip = 0;	while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)		if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);	tmscpaddr->tmscpsa = TMSCP_ERR;	while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0)		if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);	tmscpaddr->tmscpsa = (short)&tmscp_ubaddr->tmscp_ca.ca_ringbase;	while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)		if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);	tmscpaddr->tmscpsa = (short)(((int)&tmscp_ubaddr->tmscp_ca.ca_ringbase) >> 16);	while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)		if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);	tmscpaddr->tmscpsa = TMSCP_GO;	tmscpp->tmscp_ca.ca_Rspdsc = (long)&tmscp_ubaddr->tmscp_Rsp.mscp_cmdref;	tmscpp->tmscp_ca.ca_Cmddsc = (long)&tmscp_ubaddr->tmscp_Cmd.mscp_cmdref;	tmscpp->tmscp_Cmd.mscp_header.tmscp_vcid = 1;	/* for tape */	tmscpp->tmscp_Cmd.mscp_cntflgs = 0;	tmscpp->tmscp_Cmd.mscp_version = 0;	if (tmscpcmd(M_OP_STCON, tmscpp, tmscpaddr) == 0) {		return(EFAULT);	}	tmscpp->tmscp_Cmd.mscp_unit = ui->ui_slave;	if (tmscpcmd(M_OP_ONLIN, tmscpp, tmscpaddr) == 0) {		return(EFAULT);	}	num = maxfree;	start = 0;	while (num > 0)		{		blk = num > DBSIZE ? DBSIZE : num;		io = uba->uba_map;		for (i = 0; i < blk; i++)			*(int *)io++ = (btop(start)+i) | UBAMR_MRV;		*(int *)io = 0;		tmscpp->tmscp_Cmd.mscp_lbn = btop(start);		tmscpp->tmscp_Cmd.mscp_unit = ui->ui_slave;		tmscpp->tmscp_Cmd.mscp_bytecnt = blk*NBPG;#		ifdef	MVAX		if( cpu == MVAX_I )			tmscpp->tmscp_Cmd.mscp_buffer = (long) start;		else#		endif 	MVAX			tmscpp->tmscp_Cmd.mscp_buffer = 0;		if (tmscpcmd(M_OP_WRITE, tmscpp, tmscpaddr) == 0)			return(EIO);		start += blk*NBPG;		num -= blk;		}	return (0);}/* * Perform a standalone tmscp command.  This routine is only used by tmscpdump. */tmscpcmd(op, tmscpp, tmscpaddr)	int op;	register struct tmscp *tmscpp;	struct tmscpdevice *tmscpaddr;{	int i;	tmscpp->tmscp_Cmd.mscp_opcode = op;	tmscpp->tmscp_Rsp.mscp_header.tmscp_msglen = mscp_msglen;	tmscpp->tmscp_Cmd.mscp_header.tmscp_msglen = mscp_msglen;	tmscpp->tmscp_ca.ca_Rspdsc |= TMSCP_OWN|TMSCP_INT;	tmscpp->tmscp_ca.ca_Cmddsc |= TMSCP_OWN|TMSCP_INT;	if (tmscpaddr->tmscpsa&TMSCP_ERR)		printf("tmscp fatal error (0%o)\n", tmscpaddr->tmscpsa&0xffff);	i = tmscpaddr->tmscpip;#ifdef lint	i = i;#endif	for (;;)		{		if (tmscpp->tmscp_ca.ca_cmdint)			tmscpp->tmscp_ca.ca_cmdint = 0;		if (tmscpp->tmscp_ca.ca_rspint)			break;		}	tmscpp->tmscp_ca.ca_rspint = 0;	if (tmscpp->tmscp_Rsp.mscp_opcode != (op|M_OP_END) ||	    (tmscpp->tmscp_Rsp.mscp_status&M_ST_MASK) != M_ST_SUCC)		{		printf("error: com %d opc 0x%x stat 0x%x\ndump ", op,			tmscpp->tmscp_Rsp.mscp_opcode, tmscpp->tmscp_Rsp.mscp_status);		return(0);		}	return(1);}/* * Catch ioctl commands, and call the "command" routine to do them. *//* ARGSUSED */tmscpioctl(dev, cmd, data, flag)	dev_t dev;	int cmd;	caddr_t data;	int flag;{	register struct buf *bp = &ctmscpbuf[TMSCPCTLR(dev)];	register callcount;	/* number of times to call cmd routine */	register struct uba_device *ui;	register struct tms_info *tms;	int fcount;		/* number of files (or records) to space */	int error = 0;	register struct mtop *mtop;	/* mag tape cmd op to perform */	register struct mtget *mtget;	/* mag tape struct to get info in */	/* we depend of the values and order of the TMS ioctl codes here */	static tmsops[] =	 {TMS_WRITM,TMS_FSF,TMS_BSF,TMS_FSR,TMS_BSR,TMS_REW,TMS_OFFL,TMS_SENSE,	  TMS_CACHE,TMS_NOCACHE};	switch (cmd) {	case MTIOCTOP:	/* tape operation */		mtop = (struct mtop *)data;		switch (mtop->mt_op) {		case MTWEOF:			callcount = mtop->mt_count;			fcount = 1;			break;		case MTFSF: case MTBSF:		case MTFSR: case MTBSR:			callcount = 1;			fcount = mtop->mt_count;			break;		case MTREW: case MTOFFL: case MTNOP:		case MTCACHE: case MTNOCACHE:			callcount = 1;			fcount = 1;		/* wait for this rewind */			break;		default:			return (ENXIO);		}	/* end switch mtop->mt_op */		if (callcount <= 0 || fcount <= 0)			return (EINVAL);		while (--callcount >= 0)			{			tmscpcommand(dev, tmsops[mtop->mt_op], fcount);			if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) &&			    bp->b_resid)				return (EIO);			if (bp->b_flags & B_ERROR)	/* like hitting BOT */				break;			}		if (bp->b_flags&B_ERROR)			if ((error = bp->b_error)==0)				return (EIO);		return (error);	case MTIOCGET:		/*		 * Return status info associated with the particular UNIT.		 */		ui = tmsdinfo[TMSUNIT(dev)];		tms = &tms_info[ui->ui_unit];		mtget = (struct mtget *)data;		mtget->mt_type = MT_ISTMSCP;		mtget->mt_dsreg = tms->tms_flags << 8;		mtget->mt_dsreg |= tms->tms_endcode;		mtget->mt_erreg = tms->tms_status;		mtget->mt_resid = tms->tms_resid;		break;	default:		return (ENXIO);	}	return (0);}/* * Reset (for raw mode use only). */tmscpreset (uban)	int uban;{	register struct uba_ctlr *um;	register struct uba_device *ui;	register struct buf *bp, *dp;	register int unit;	struct buf *nbp;	int d;	for (d = 0; d < NTMSCP; d++)		{		if ((um = tmscpminfo[d]) == 0 || um->um_ubanum != uban ||		    um->um_alive == 0)			continue;		printf(" tmscp%d", d);		um->um_tab.b_active = 0;		um->um_tab.b_actf = um->um_tab.b_actl = 0;		tmscp_softc[d].sc_state = S_IDLE;		tmscp_softc[d].sc_mapped = 0;		for (unit = 0; unit < NTMS; unit++)			{			if ((ui = tmsdinfo[unit]) == 0)				continue;			if (ui->ui_alive == 0 || ui->ui_mi != um)				continue;			tmsutab[unit].b_active = 0;			tmsutab[unit].b_qsize = 0;			}		for (bp = tmscpwtab[d].av_forw; bp != &tmscpwtab[d]; bp = nbp)			{			nbp = bp->av_forw;			bp->b_ubinfo = 0;			/*			 * Link the buffer onto the drive queue			 */			dp = &tmsutab[TMSUNIT(bp->b_dev)];			if (dp->b_actf == 0)				dp->b_actf = bp;			else				dp->b_actl->av_forw = bp;			dp->b_actl = bp;			bp->av_forw = 0;			/*			 * Link the drive onto the controller queue			 */			if (dp->b_active == 0)				{				dp->b_forw = NULL;				if (um->um_tab.b_actf == NULL)					um->um_tab.b_actf = dp;				else					um->um_tab.b_actl->b_forw = dp;				um->um_tab.b_actl = dp;				dp->b_active = 1;				}			}		(void)tmscpinit(d);		}}/* * Process an error log message * * Only minimal decoding is done, only "useful" * information is printed.  Eventually should * send message to an error logger. */tmserror(um, mp)	register struct uba_ctlr *um;	register struct mslg *mp;{	register i;#	ifdef DEBUG	printd("tmserror:\n");#	endif	if(!(mp->mslg_flags & (M_LF_SUCC | M_LF_CONT)))		log(TMS_PRI, "tmscp%d: %s error, ", um->um_ctlr,		mp->mslg_flags & ( M_LF_SUCC | M_LF_CONT ) ? "soft" : "hard");	switch (mp->mslg_format) {	case M_FM_CNTERR:		log(TMS_PRI, "controller error, event 0%o\n", mp->mslg_event);		break;	case M_FM_BUSADDR:		log(TMS_PRI, "host memory access error, event 0%o, addr 0%o\n",			mp->mslg_event, mp->mslg_busaddr);		break;	case M_FM_TAPETRN:		log(TMS_PRI, "tape transfer error, unit %d, grp 0x%x, event 0%o\n",			mp->mslg_unit, mp->mslg_group, mp->mslg_event);		break;	case M_FM_STIERR:		log(TMS_PRI, "STI error, unit %d, event 0%o\n",			mp->mslg_unit, mp->mslg_event);#ifdef notdef		/* too painful to do with log() */		for(i = 0; i < 62;i++)			mprintf("\t0x%x",mp->mslg_stiunsucc[i] & 0xff);		mprintf("\n");#endif		break;	case M_FM_STIDEL:		log(TMS_PRI, "STI Drive Error Log, unit %d, event 0%o\n",			mp->mslg_unit, mp->mslg_event);		break;	case M_FM_STIFEL:		log(TMS_PRI, "STI Formatter Error Log, unit %d, event 0%o\n",			mp->mslg_unit, mp->mslg_event);		break;	default:		log(TMS_PRI, "unknown error, unit %d, format 0%o, event 0%o\n",			mp->mslg_unit, mp->mslg_format, mp->mslg_event);	}	if (tmscperror)		{		register long *p = (long *)mp;		for (i = 0; i < mp->mslg_header.tmscp_msglen; i += sizeof(*p))			printf("%x ", *p++);		printf("\n");		}}#endif

⌨️ 快捷键说明

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