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

📄 st.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1992 OMRON Corporation. * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * OMRON Corporation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)st.c	8.1 (Berkeley) 6/10/93 *//* * st.c -- SCSI Disk Device Driver for LUNA-68K * remaked by A.Fujita, MAR-22-1992 *//* * SCSI CCS (Command Command Set) disk driver. */#define NST	1#include <sys/param.h>#include <sys/mtio.h>#include <luna68k/dev/scsireg.h>#include <luna68k/stand/device.h>extern int scsi_test_unit_rdy();extern int scsi_request_sense();extern int scsi_immed_command();extern int scgo();extern void scfree();int	stinit(), ststrategy(), ststart(), stintr();struct	driver stdriver = {	stinit, "st", ststart, (int (*)()) 0, stintr, (int (*)()) 0};struct	st_softc {	struct	hp_device *sc_hd;	struct	devqueue sc_dq;	int	sc_flags;	short	sc_type;	/* drive type */	short	sc_punit;	/* physical unit (scsi lun) */} st_softc[NST];/* softc flags */#define STF_ALIVE	0x0001#define STF_OPEN	0x0002#define STF_WMODE	0x0004#define STF_WRTTN	0x0008#define STF_CMD		0x0010#define STF_LEOT	0x0020#define STF_MOVED	0x0040struct	scsi_fmt_sense stsense[NST];#define	stunit(x)	(minor(x) & 3)#define	stpunit(x)	((x) & 7)#define STDEV_NOREWIND	0x04#define STDEV_HIDENSITY	0x08#define STDEV_EXSFMK	0x10#define STDEV_FIXEDBLK	0x20#define	b_lba		b_resid#define	STRETRY		2	/* IO retry count *//* * Initialize */intstinit(hd)	register struct hp_device *hd;{	register struct st_softc *sc = &st_softc[hd->hp_unit];	sc->sc_hd = hd;	sc->sc_punit = stpunit(hd->hp_flags);	sc->sc_type = stident(sc, hd);	if (sc->sc_type < 0)		return(0);	sc->sc_dq.dq_ctlr = hd->hp_ctlr;	sc->sc_dq.dq_unit = hd->hp_unit;	sc->sc_dq.dq_slave = hd->hp_slave;	sc->sc_dq.dq_driver = &stdriver;	sc->sc_flags = STF_ALIVE;	return(1);}static struct scsi_inquiry inqbuf;static struct scsi_fmt_cdb inq = {	6,	CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0};intstident(sc, hd)	struct st_softc *sc;	struct hp_device *hd;{	char idstr[32];	int unit;	register int ctlr, slave;	register int i, stat;	register int tries = 10;	ctlr = hd->hp_ctlr;	slave = hd->hp_slave;	unit = sc->sc_punit;	/*	 * See if unit exists and is a disk then read block size & nblocks.	 */	while ((stat = scsi_immed_command(ctlr, slave, unit,				  &inq, (u_char *)&inqbuf, sizeof(inqbuf))) != 0) {		if (stat < 0 || --tries < 0)			return (-1);		DELAY(1000);	}	if (stat)		return (-1);	switch (inqbuf.type) {	case 1:		/* tape */		break;	default:	/* not a disk */		return (-1);	}	bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28);	for (i = 27; i > 23; --i)		if (idstr[i] != ' ')			break;	idstr[i+1] = 0;	for (i = 23; i > 7; --i)		if (idstr[i] != ' ')			break;	idstr[i+1] = 0;	for (i = 7; i >= 0; --i)		if (idstr[i] != ' ')			break;	idstr[i+1] = 0;	printf("st%d: %s %s rev %s\n", hd->hp_unit, idstr, &idstr[8],	       &idstr[24]);	return(inqbuf.type);}/* * Open */intstopen(dev)	dev_t dev;{	register int unit = stunit(dev);	register struct st_softc *sc = &st_softc[unit];	if (unit >= NST || (sc->sc_flags & STF_ALIVE) == 0)		return(-1);	if (sc->sc_flags & STF_OPEN)		return(-1);	sc->sc_flags |= STF_OPEN;	sc->sc_flags |= STF_WMODE;	sc->sc_flags &= ~STF_MOVED;	return(0);}/*ARGSUSED*/stclose(dev)	dev_t dev;{	register int unit = stunit(dev);	register struct st_softc *sc = &st_softc[unit];	printf("st: sc->sc_flags = 0x%s\n", hexstr(sc->sc_flags, 8));	if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) {		st_write_EOF(dev);	}	if ((minor(dev) & STDEV_NOREWIND) == 0) {		st_rewind(dev);	}	sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN);	return(0);}/* * Strategy */intststrategy(){}intststart(unit)	register int unit;{}/* * Interrupt *//* * Return: *	0	if not really an error *	<0	if we should do a retry *	>0	if a fatal error */static intsterror(unit, sc, hp, stat)	int unit, stat;	register struct st_softc *sc;	register struct hp_device *hp;{	int cond = 1;	stsense[unit].status = stat;	if (stat & STS_CHECKCOND) {		struct scsi_xsense *sp;		scsi_request_sense(hp->hp_ctlr, hp->hp_slave,				   sc->sc_punit, stsense[unit].sense,				   sizeof(stsense[unit].sense));		sp = (struct scsi_xsense *)stsense[unit].sense;		printf("st%d: scsi sense class %d, code %d", unit,			sp->class, sp->code);		if (sp->class == 7) {			printf(", key %d", sp->key);			if (sp->valid)				printf(", blk %d", *(int *)&sp->info1);			switch (sp->key) {			/* no sense, try again */			case 0:				cond = -1;				break;			/* recovered error, not a problem */			case 1:				cond = 0;				break;			}		}		printf("\n");	}	return(cond);}intstintr(unit, stat)	register int unit;	int stat;{}/* * RAW Device Routines */char *sense_key(key)	int key;{	if (key == 0)		return("No Sense");	else if (key == 2)		return("Not Ready");	else if (key == 3)		return("Medium Error");	else if (key == 4)		return("Hardware Error");	else if (key == 5)		return("Illegal Request");	else if (key == 6)		return("Unit Attention");	else if (key == 7)		return("Data Protect");	else if (key == 8)		return("No Data");	else if (key == 11)		return("Aborted Command");	else if (key == 13)		return("Volume Overflow");	else		return("Unknown Error");}static struct scsi_fmt_cdb st_cmd  = { 6, 0, 0, 0, 0, 0, 0 };u_char sensebuf[8];intstread(dev, buf, size)	dev_t dev;	char *buf;	int   size;{	register int unit = stunit(dev);	register struct st_softc *sc = &st_softc[unit];	register struct scsi_fmt_cdb *cdb = &st_cmd;	register int nblk = size >> DEV_BSHIFT;	struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;	int ctlr, slave, stat;	ctlr  = sc->sc_hd->hp_ctlr;	slave = sc->sc_hd->hp_slave;		cdb->cdb[0] = CMD_READ;	cdb->cdb[1] = 1;		/* unknown setup */	cdb->cdb[2] = (nblk & 0xff0000) >> 16;	cdb->cdb[3] = (nblk & 0x00ff00) >>  8;	cdb->cdb[4] = (nblk & 0x0000ff);	cdb->cdb[5] = 0;		/* unknown setup */	stat = scsi_immed_command(ctlr, slave, 0, cdb, buf, size);	if (stat == 0)		return(size);	else {		scsi_request_sense(ctlr, slave, 0, sp, 8);		if (stat == STS_CHECKCOND) {			printf("stread: Sense Key = [%s]", sense_key(sp->key));			if (sp->filemark)				printf(" [EOF]");			if (sp->eom)				printf(" [EOM]");			printf("\n");		}		return(-1);	}}intstwrite(dev, buf, size)	dev_t dev;	char *buf;	int   size;{	register int unit = stunit(dev);	register struct st_softc *sc = &st_softc[unit];	register struct scsi_fmt_cdb *cdb = &st_cmd;	struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;	register int nblk;	int ctlr, slave, stat;	nblk = size >> DEV_BSHIFT;	if (size % DEV_BSIZE)		nblk++;	size = nblk << DEV_BSHIFT;	ctlr  = sc->sc_hd->hp_ctlr;	slave = sc->sc_hd->hp_slave;	sc->sc_flags |= STF_WRTTN;		cdb->cdb[0] = CMD_WRITE;	cdb->cdb[1] = 1;		/* unknown setup */	cdb->cdb[2] = (nblk & 0xff0000) >> 16;	cdb->cdb[3] = (nblk & 0x00ff00) >>  8;	cdb->cdb[4] = (nblk & 0x0000ff);	cdb->cdb[5] = 0;		/* unknown setup */	stat = scsi_immed_command(ctlr, slave, 0, cdb, buf, size);	if (stat == 0)		return(size);	else {		scsi_request_sense(ctlr, slave, 0, sp, 8);		if (stat == STS_CHECKCOND) {			printf("stwrite: Sense Key = [%s]", sense_key(sp->key));			if (sp->eom)				printf(" [EOM]");			printf("\n");		}		return(-1);	}}intstioctl(dev, cmd, data, flag, p)	dev_t dev;	int cmd;	caddr_t data;	int flag;	struct proc *p;{}st_rewind(dev)	dev_t dev;{	register int unit = stunit(dev);	register struct st_softc *sc = &st_softc[unit];	register struct scsi_fmt_cdb *cdb = &st_cmd;	struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;	int ctlr, slave, stat;	int retry = 5;	ctlr  = sc->sc_hd->hp_ctlr;	slave = sc->sc_hd->hp_slave;	cdb->cdb[0] = CMD_REWIND;	cdb->cdb[1] = 1;	/* command finished soon */	cdb->cdb[2] = 0;	cdb->cdb[3] = 0;	cdb->cdb[4] = 0;	cdb->cdb[5] = 0;		/* unknown setup */ rewind:	stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0);	if (stat == 0) {		return(1);	} else {		scsi_request_sense(ctlr, slave, 0, sp, 8);		if (stat == STS_CHECKCOND) {			printf("st_rewind: Sense Key = [%s]", sense_key(sp->key));			printf("\n");		}		if (retry > 0) {			DELAY(1000000);			retry--;			goto rewind;		}		return(0);	}}st_write_EOF(dev)	dev_t dev;{	register int unit = stunit(dev);	register struct st_softc *sc = &st_softc[unit];	register struct scsi_fmt_cdb *cdb = &st_cmd;	int ctlr, slave, stat;	int marks = 1;	ctlr  = sc->sc_hd->hp_ctlr;	slave = sc->sc_hd->hp_slave;		cdb->cdb[0] = CMD_WRITE_FILEMARK;	cdb->cdb[1] = 1;	/* command finished soon */	cdb->cdb[2] = (marks & 0xff0000) >> 16;	cdb->cdb[3] = (marks & 0x00ff00) >>  8;	cdb->cdb[4] = (marks & 0x0000ff);	cdb->cdb[5] = 0;		/* unknown setup */	stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0);	if (stat == 0)		return(1);	printf("st: write EOF error\n");	return(0);}intst_skip(dev)	dev_t dev;{	register int unit = stunit(dev);	register struct st_softc *sc = &st_softc[unit];	register struct scsi_fmt_cdb *cdb = &st_cmd;	register int nfmk = 1;	struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;	int ctlr, slave, stat;	ctlr  = sc->sc_hd->hp_ctlr;	slave = sc->sc_hd->hp_slave;		cdb->cdb[0] = CMD_SPACE;	cdb->cdb[1] = 1;		/* it mean skip until EOF */	cdb->cdb[2] = (nfmk & 0xff0000) >> 16;	cdb->cdb[3] = (nfmk & 0x00ff00) >>  8;	cdb->cdb[4] = (nfmk & 0x0000ff);	cdb->cdb[5] = 0;		/* unknown setup */	stat = scsi_immed_command(ctlr, slave, 0, cdb, 0, 0);	if (stat == 0)		return(0);	else {		scsi_request_sense(ctlr, slave, 0, sp, 8);		if (stat == STS_CHECKCOND) {			printf("st_skip: Sense Key = [%s]", sense_key(sp->key));			if (sp->filemark)				printf(" [EOF]");			if (sp->eom)				printf(" [EOM]");			printf("\n");		}		return(-1);	}}/* * Dump */intstdump(dev)	dev_t dev;{}

⌨️ 快捷键说明

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