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

📄 st.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
stclose(sip)	register struct saioreq *sip;{	register struct stparam *stp;	EPRINTF("stclose:\n");	stp = (struct stparam *) sip->si_devdata;	if (stp->st_lastcmd == SC_WRITE)		(void) stcmd(SC_WRITE_FILE_MARK, sip, 0);	sc_reset = 0;	return (0);}/* * Perform a read or write of the SCSI tape. */ststrategy(sip, rw)	register struct saioreq *sip;	int rw;{	register struct stparam *stp;	DPRINTF("ststrategy:\n");	sc_reset = 1;	stp = (struct stparam *) sip->si_devdata;	if (stp->st_eof) {		stp->st_eof = 0;		return (0);	}	DPRINTF2("ststrategy:  addr= 0x%x  size= 0x%x\n",		 (int)(sip->si_ma), sip->si_cc);	rw = stcmd((rw == WRITE ? SC_WRITE : SC_READ), sip, 1);	return (rw);}/* * Execute a scsi tape command */static intstcmd(cmd, sip, errprint)	short cmd;	register struct saioreq *sip;	int errprint;{	register struct stparam *stp;	register struct host_saioreq *h_sip;	/* Sip for host adapter */	register struct st_ms_mspl *mode;	register struct st_sense *ems;	register struct sysgen_sense *scs;	struct scsi_cdb6 cdb, scdb;	struct scsi_scb scb, sscb;	char *buf;	int density;	int r, cc;	DPRINTF("stcmd:\n");AGAIN:	stp = (struct stparam *)sip->si_devdata;	h_sip = &stp->h_sip;		/* host adapter */	h_sip->unit = stp->st_target;	buf =  sip->si_ma;	/* Set up cdb */	bzero((char *) &scb, sizeof scb);	bzero((char *) &cdb, CDB_GROUP0);	stp->st_lastcmd = cmd;	cdb.cmd = cmd;	cdb.lun = stp->st_unit;	h_sip->cc = 0; 	h_sip->ma = 0;	DPRINTF2("stcmd: cmd= 0x%x  lun= 0x%x\n", cdb.cmd, cdb.lun);	/* Some fields in the cdb are command specific */	switch (cmd) {	case SC_READ:		h_sip->dma_dir = SC_RECV_DATA;		if (stp->st_dev_bsize == 0) {			DPRINTF1("stcmd: variable read (0x%x)\n", sip->si_cc);			cc = h_sip->cc = sip->si_cc;		} else {			DPRINTF1("stcmd: read (0x%x)\n", sip->si_cc);			cc = h_sip->cc = ROUNDUP(sip->si_cc);			cc = cc / stp->st_dev_bsize;			cdb.t_code = 1;		}STCMD_RD:		cdb.mid_count = (cc >> 8) & 0xFF;		cdb.low_count = cc & 0xFF;		if (buf >= DVMA_BASE) {			h_sip->ma = buf;			DPRINTF1("stcmd: DVMA addr= 0x%x\n", h_sip->ma);		} else {			h_sip->ma = BUF;			DPRINTF("stcmd: BUF addr\n");		}		if (cc == 0)			h_sip->dma_dir = SC_NO_DATA;		break;	case SC_WRITE:		h_sip->dma_dir = SC_SEND_DATA;		if (buf < DVMA_BASE) {			DPRINTF("stcmd: write bcopy\n");			bcopy(buf, BUF, sip->si_cc);		}		if (stp->st_dev_bsize == 0) {			DPRINTF1("stcmd: variable write (0x%x)\n", sip->si_cc);			cc = h_sip->cc = sip->si_cc;		} else {			DPRINTF1("stcmd: write (0x%x)\n", sip->si_cc);			cc = h_sip->cc = ROUNDUP(sip->si_cc);			cc = cc / stp->st_dev_bsize;			cdb.t_code = 1;		}		goto STCMD_RD;		/* break; */	case SC_MODE_SENSE:		DPRINTF("stcmd:  mode sense\n");		h_sip->dma_dir = SC_RECV_DATA;		h_sip->cc = sip->si_cc = sizeof (struct st_ms_mspl);		cdb.low_count = h_sip->cc & 0xFF;		h_sip->ma = BUF;		bzero((char *)h_sip->ma, sizeof (struct st_ms_mspl));		break;	case SC_QIC11:		EPRINTF("stcmd: low density (qic-11)\n");		sip->si_cc = 0;		h_sip->dma_dir = SC_NO_DATA;		if (ISASYSGEN(stp)) {			cdb.cmd = SC_QIC02;			cdb.high_count = ST_SYSGEN_QIC11;		} else {			density = ST_EMULEX_QIC11;			goto MODE;		}		break;	case SC_QIC24:		EPRINTF("stcmd: high density (qic-24)\n");		sip->si_cc = 0;		h_sip->dma_dir = SC_NO_DATA;		if (ISASYSGEN(stp)) {			cdb.cmd = SC_QIC02;			cdb.high_count = ST_SYSGEN_QIC24;		} else {			density = ST_EMULEX_QIC24;			goto MODE;		}		break;	case SC_MODE_SELECT:MODE:		cdb.cmd = SC_MODE_SELECT; 		mode = (struct st_ms_mspl *)STSBUF;		bzero((char *)mode, sizeof(*mode));		mode->bufm = 1;		mode->bd_len = MS_BD_LEN;		mode->density = density;		mode->mid_bl =  (stp->st_dev_bsize >> 8) & 0xff;		mode->low_bl =  stp->st_dev_bsize & 0xff;		h_sip->ma = (char *)mode;		h_sip->dma_dir = SC_SEND_DATA;		sip->si_cc = h_sip->cc = cdb.low_count =			sizeof (struct st_ms_mspl);		break;	case SC_SPACE_FILE:		EPRINTF("stcmd: space file\n");		cdb.cmd = SC_SPACE_REC;	/* Real SCSI cmd */		cdb.t_code = 1;		/* Space file, not rec */		cdb.low_count = 1;	/* Space 1 file */		sip->si_cc = 0;		h_sip->dma_dir = SC_NO_DATA;		break;	case SC_WRITE_FILE_MARK:		DPRINTF("stcmd: write file mark\n");		cdb.low_count = 1;			sip->si_cc = 0;		h_sip->dma_dir = SC_NO_DATA;		break;	case SC_REQUEST_SENSE:		DPRINTF("stcmd: request sense\n");		cdb.low_count = h_sip->cc = sip->si_cc;		h_sip->ma = buf;		h_sip->dma_dir = SC_RECV_DATA;		/* bzero((char *)buf, sizeof (struct st_ms_mspl)); */		break;	case SC_INQUIRY:		EPRINTF("stcmd: inquiry\n");		h_sip->cc = sip->si_cc = sizeof (struct scsi_inquiry_data);		cdb.low_count = h_sip->cc;		h_sip->dma_dir = SC_RECV_DATA;		h_sip->ma = buf;		bzero((char *)buf, h_sip->cc);		break;	case SC_TEST_UNIT_READY:#ifdef		STDEBUG		DPRINTF("stcmd: test unit\n");		sip->si_cc = 0;		h_sip->dma_dir = SC_NO_DATA;		break;#endif		STDEBUG	case SC_REWIND:		DPRINTF("stcmd: rewind\n");		sip->si_cc = 0;		h_sip->dma_dir = SC_NO_DATA;		break;	default:		SC_ERROR1("st: unknown command (0x%x)\n", cdb.cmd);		return (0);	}	/* Execute the command */	r = (*h_sip->doit)(&cdb, &scb, h_sip);	DPRINTF2("stcmd: r = 0x%x (0x%x)\n", r, sip->si_cc);	/* Host adapter error */	if (r < 0) {		EPRINTF("stcmd: SCSI bus error\n");		return (r);	}	/* Allow for tape blocking */	if (r > sip->si_cc) {		EPRINTF1("stcmd: round to 0x%x\n", sip->si_cc);		r = sip->si_cc;	}	/* Device busy error */	if(scb.busy) {		EPRINTF("stcmd: busy\n");		DELAY(2000000);		goto AGAIN;		}	if (cmd == SC_READ  &&  buf < DVMA_BASE) {		DPRINTF("stcmd: read bcopy\n");		if (min(sip->si_cc, r))			bcopy(BUF, buf, (min(sip->si_cc, r)));	}	/* We may need to get sense data */	if (scb.chk) {		EPRINTF("stcmd: check condition\n");		bzero((char *) &sscb, sizeof(sscb));		bzero((char *) &scdb, CDB_GROUP0);		scdb.cmd = SC_REQUEST_SENSE;		scdb.lun = stp->st_unit;		if (ISASYSGEN(stp)) {			h_sip->cc = scdb.low_count = ST_SYSGEN_SENSE_LEN;		} else {			h_sip->cc = scdb.low_count = ST_EMULEX_SENSE_LEN;		}		h_sip->ma = STSBUF;		h_sip->dma_dir = SC_RECV_DATA;		(void) (*h_sip->doit)(&scdb, &sscb, h_sip);		/* Process Sysgen tape drive errors */		if (ISASYSGEN(stp)) {			scs = (struct sysgen_sense *)STSBUF;			stp->st_eof = 1;			/* No tape */			if (scs->no_cart) {				EPRINTF("stcmd: not ready\n");				return (-2);			}			/* QIC-24 */			if (scs->no_data != 0) {				EPRINTF("stcmd: blank check\n");				return (-2);			}			/* EOF */#ifdef			STDEBUG			if (scs->file_mark)				EPRINTF("stcmd: eof\n");#endif			STDEBUG			/* Other errors */			if ((scs->file_mark == 0)  &&  errprint) {				SC_ERROR1("st: error %x\n", 					*(u_short *)&STSBUF[SENSELOC]);			}			return (r);		/* Process MT-02 and CCS tape drive errors */		} else  {			ems = (struct st_sense *)STSBUF;			/* Blank Check error */			if (ems->key == SC_BLANK_CHECK) {				EPRINTF("stcmd: blank check\n");				stp->st_eof = 1;				return (-2);			/* Soft error */			} else if (ems->key == SC_RECOVERABLE_ERROR) {				EPRINTF("stcmd: soft error\n");				return (r ? r : 1);			/* EOF error */			}else if (ems->fil_mk) {				EPRINTF("stcmd: eof\n");				stp->st_eof = 1;				return (r);			/* Illegal length error */			} else if (ems->ili) {				EPRINTF("stcmd: illegal length\n");				return (r ? r : 1);			/* Other errors */			} else if(errprint) {				SC_ERROR1("st: sense key = %x", ems->key);#ifdef	 			STDEBUG				SC_ERROR1(" (%s)", st_key_error_str[ems->key]);#endif	 			STDEBUG				SC_ERROR1("  error = %x\n", ems->error);				stp->st_eof = 1;				return (-1);			}		}	}	if (r >= sip->si_cc) {		/* Normal completion exit */		return (sip->si_cc ? sip->si_cc : 1);	} else {		/* Error exit */		if (errprint) {			EPRINTF1("stcmd: short transfer (0x%x)\n", r);		}		return (r);	}}

⌨️ 快捷键说明

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