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

📄 sd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. * * 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. * * from: $Hdr: sd.c,v 4.300 91/06/27 20:42:56 root Rel41 $ SONY * *	@(#)sd.c	8.2 (Berkeley) 9/23/93 */#define	dkblock(bp)	bp->b_blkno/* * Copyright (c) 1987-1991 by SONY Corporation. */#include "sd.h"#if NSD > 0#include <sys/param.h>#include <sys/buf.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/dkstat.h>#include <sys/uio.h>#include <sys/kernel.h>#include <sys/reboot.h>#include <sys/ioctl.h>#include <sys/systm.h>#include <sys/mtio.h>#include <sys/stat.h>#include <sys/disklabel.h>#include <vm/vm.h>#include <sys/syslog.h>#include <ufs/ffs/fs.h># include <machine/cpu.h>#ifdef IPC_MRX# include "../iop/iopvar.h"# include "../ipc/newsipc.h"#endif#ifdef CPU_SINGLE# include <news3400/hbdev/hbvar.h># include <news3400/iodev/ioptohb.h>#endif#include <news3400/iodev/scsireg.h>#include <news3400/iodev/scu.h>#include <news3400/iodev/dkio.h>#include <news3400/iodev/sdreg.h>#define	sce_sdecode	sce_hdecode#define	dev2unit(x)	((minor(x) & ~0x80) >> 3)#define	dev2part(x)	(minor(x) & 0x7)/* /sys/sys/file.h */#define	FREAD		00001		/* descriptor read/receive'able */#define	FWRITE		00002		/* descriptor write/send'able */#define	PART_A		0#define	PART_B		1#define	PART_C		2#define	PART_D		3#define	PART_E		4#define	PART_F		5#define	PART_G		6#define	PART_H		7#define	MAXPROBERETRY	100#define	NRETRY		10#define	MAXHRDERR	100#define	MAXRETRYCNT	16#define	SDBSIZE1K	(DEV_BSIZE * 2)#define	MAXSDPHYS	((NSCMAP - 1) * NBPG)#define	D100MSEC	100000#if OD_STOPTIME < 1# define	OD_STOPTIME	5#endif /* OD_STOPTIME < 1 */#define FORMAT_MODE_CORRUPTED	0x31#define	ONLY_ONE	1/************** PARTITIONS *************************************/#define	PART_UNUSED	(0)#define	PART_SPEC	(-1)#define	PART_CALCF	(-2)#define	PART_CALCG	(-3)struct defpart {	int range_min;	int range_max;	int partsize[PNUM];};struct defpart defpart_std[] = {	{		0,		/* range_min */		20,		/* range_max */		  PART_SPEC,		/* A: */		PART_UNUSED,		/* B: */		  PART_SPEC,		/* C: */		PART_UNUSED,		/* D: */		PART_UNUSED,		/* E: */		PART_UNUSED,		/* F: */		PART_UNUSED,		/* G: */		PART_UNUSED,		/* H: */	},	{		20,		/* range_min */		61,		/* range_max */		      15884,		/* A: */		      10032,		/* B: */		  PART_SPEC,		/* C: */		      15884,		/* D: */		PART_UNUSED,		/* E: */		 PART_CALCF,		/* F: */		 PART_CALCG,		/* G: */		PART_UNUSED,		/* H: */	},	{		61,		/* range_min */		206,		/* range_max */		      15884,		/* A: */		      33440,		/* B: */		  PART_SPEC,		/* C: */		      15884,		/* D: */		      55936,		/* E: */		 PART_CALCF,		/* F: */		 PART_CALCG,		/* G: */		PART_UNUSED,		/* H: */	},	{		206,		/* range_min */		356,		/* range_max */		      15884,		/* A: */		      33440,		/* B: */		  PART_SPEC,		/* C: */		      15884,		/* D: */		      55936,		/* E: */		 PART_CALCF,		/* F: */		 PART_CALCG,		/* G: */		     291346,		/* H: */	},	{		356,		/* range_min */		99999999,	/* range_max */		      15884,		/* A: */		      66880,		/* B: */		  PART_SPEC,		/* C: */		      15884,		/* D: */		     307200,		/* E: */		 PART_CALCF,		/* F: */		 PART_CALCG,		/* G: */		     291346,		/* H: */	},	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }};/************* ADDITIONAL SENSE ERROR CODES *************************/struct msg_list {	int	ml_code;		/* message code */	int	ml_msglvl;		/* message level */	char	*ml_msgstr;		/* message string */};#define	sdskeylist	skeyliststruct msg_list ecodelist_mo[] = {	{ 0x80, 0, NULL },	{ 0x81, 0, NULL },	{ 0x82, 0, NULL },	{ 0x83, 0, NULL },	{ -1,   0, NULL }};/************** Ref. sd_var.c ********************************/extern struct iop/**/_ctlr *sdminfo[];extern struct iop/**/_device *sddinfo[];extern struct iop/**/_device *sdip[][MAXSLAVE];extern struct buf rsdbuf[];		/* buffer for raw I/O */extern struct buf csdbuf[];		/* buffer for controll */extern struct buf sdutab[];		/* per drive buffers */extern struct sdc_softc sdc_softc[];extern struct sdd_softc sdd_softc[];extern u_char sd_b_openf[][PNUM];extern u_char sd_c_openf[][PNUM];extern struct scsi kernscsi[];extern struct sdst sdstdrv[];extern struct disklabel sdlabel[];extern struct size sdsizedrv[][PNUM];extern u_char sdc_rsense[][RSEN_CNT];extern struct sync_param sd_sync_param[];extern int nsd;extern int nsdc;/************** Ref. sddefs.c *********************************/extern struct sddevinfo sddevinfo[];/**************************************************************/extern struct msg_list skeylist[];extern struct msg_list ecodelist[];extern int	boothowto;extern int	rsense_msg_disp;	/* RSENSE-message display flag */extern int	mo_disp_format;		/* MO format mode display flag */int sd_ignore_error;static int re_init_done;static u_char sdwork[2340];		/* buffer for error recovery */static u_char sdtmp[DEV_BSIZE];		/* buffer for temporary */#ifdef mipsvolatile static int sdtmp_stat = 0;	/* status of sdtmp */#elsestatic int sdtmp_stat = 0;		/* status of sdtmp */#endifchar	pname[] = "abcdefgh";struct scsi *get_scsi();struct sc_map *get_sc_map();struct sc_inq *get_sc_inq();int	sdprobe(), sdslave(), sdattach(), sddgo(), sdintr();int	sdwstart, sdwatch(), sdstop();	/* Have started guardian */void	sdexec();static sd_check(), sd_tstdrv(), sd_other_pages(), sd_err_rcv(), sd_synctr_on();static disklabel2sdst(), sdst2disklabel(), sd_scu_exec();#ifdef CPU_SINGLEstruct hb_driver sdcdriver =    {sdprobe, sdslave, sdattach, sddgo, sdintr, "sd", sddinfo, "sdc", sdminfo};#elsestruct iop_driver sdcdriver =    {sdprobe, sdslave, sdattach, sddgo, "sd", sddinfo, "sdc", sdminfo};#endif/*ARGSUSED*/sdprobe(im)	struct iop/**/_ctlr *im;{	static int sdd_init = 0;	register struct sc_inq *sci;	register int ctlr;	register int fw;	int i;	if (sdd_init == 0) {		sdd_init++;		for (i = 0; i < nsd; i++)			sdd_softc[i].sdd_start = -2;	}	sci = get_sc_inq(im->im_intr);	ctlr = im->im_ctlr;	/*	 * Check device type	 *	0x00: Direct access device.	 *	0x01: Sequential access device.	 *	0x04: Write-once read-multiple device.	 *	0x05: Read-only Direct-access device.	 *	0x7f: Specified device is nonexistent.	 */	fw = sdc_softc[ctlr].sdc_firmware & ~SDCFW_DEVMASK;	switch (sci->sci_devtype) {	case 0x00:		/*		 * Assumed that the device is HD.		 *	Later, distinguish MO from HD.		 */		sdc_softc[ctlr].sdc_firmware = fw | SDCFW_HD;		break;	default:		/*		 * device type mis-match		 */		return (0);	}	/*	 * Set interrupt handler routine	 */	if (set_inthandler(im, sdintr) == 0)		return (0);	return (1);}/*ARGSUSED*/sdslave(ii, reg, intr)	register struct iop/**/_device *ii;	caddr_t reg;	int intr;{	register struct scsi *sc;	sc = get_scsi(intr);	sdip[ii->ii_ctlr][ii->ii_slave] = ii;	ii->ii_intr = intr;	/*	 * check what the device is.	 */	if ((ii->ii_type = sd_check(ii, sc)) < 0)		goto bad_slave;	/*	 * set up ERROR RECOVERY PARAMETERS	 */	if (sd_err_rcv(ii, sc) < 0)		goto bad_slave;	/*	 * set up OTHER PARAMETERS	 */	if (sd_other_pages(ii, sc) < 0)		goto bad_slave;	/*	 * set up Synchronous Transfer	 */	sd_synctr_on(ii, sc);	return (1);bad_slave:	/*	 * no such slave	 */	ii->ii_intr = -1;	return (0);}identity_check(sci, capacity, unit)	register struct sc_inq *sci;	int capacity;	int unit;{	register struct sddevinfo *sdi;	register u_char *id_name;	register int index;	register int i;	int id_pass;	id_name = sci->sci_vendid;	while (*id_name == ' ')		id_name++;	index = UNKNOWN_DISK;	id_pass = 0;	for (sdi = sddevinfo; sdi->id_len >= 0; sdi++) {		/*		 * check vendor & product ID		 */		if (strncmp(id_name, sdi->id_name, sdi->id_len) != 0)			continue;		id_pass = sdi - sddevinfo;		/*		 * check revision		 */		if (strncmp(sdi->revs, sci->sci_revision, 4) == 0)			index = id_pass;		else {			for (i = 0; i < 4; i++) {				if (*(sdi->revs + i) == '?')					continue;				if (*(sdi->revs + i) != sci->sci_revision[i])					break;			}			if (i < 4)				continue;		}		/*		 * check capacity		 */		if (capacity == -1)			break;		if (sdi->capacity == -1) {			printf("sd%d: capacity=0x%x(%d)\n",				unit, capacity, capacity);			break;		}		if (capacity == sdi->capacity)			break;	}	if (index == 0)		index = id_pass;	return (index);}search_index(type)	register int type;{	register struct sddevinfo *sdi;	register int i;	int index;	index = UNKNOWN_DISK;	i = 0;	for (sdi = sddevinfo; sdi->id_len > 0; sdi++) {		if (sdi->type == type) {			index = i;			break;		}		i++;	}	return (index);}staticsd_check(ii, sc)	register struct iop/**/_device *ii;	register struct scsi *sc;{	register struct sc_inq *sci;	register struct sc_rcap *scr;	register int intr;	register int slave;	register int unit;	struct sdc_softc *sdc;	struct sdd_softc *sdd;	struct sc_extnd *sce;	int retrycnt;	int index;	int media_in;	intr = ii->ii_intr;	slave = ii->ii_slave;	unit = ii->ii_unit;	sdc = &sdc_softc[ii->ii_ctlr];	sdd = &sdd_softc[unit];	scr = (struct sc_rcap *)sc->sc_param;	sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0];	/*	 * check if the logical unit is ready.	 *	(by TEST UNIT READY command)	 */	media_in = sd_tstdrv(ii, sc);	if (media_in < 0)		return (-3);	/*	 * Get controller and drive information.	 *	(by INQUIRY command)	 */	retrycnt = 0;	sci = get_sc_inq(intr);loop_inq:	if (retrycnt++ > MAXPROBERETRY)		return (-1);	scop_inquiry(intr, sc, slave, SCSI_INTDIS, sizeof(struct sc_inq), sci);	sc->sc_tstatus &= TGSTMASK;	if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) {		bzero((caddr_t)sce, RSEN_CNT);		scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT,				(caddr_t)sce);		sc->sc_tstatus &= TGSTMASK;		if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD)			return (-1);		if (sce->sce_extend != 0x70)			goto loop_inq;		switch (sce->sce_sdecode) {		case 0x04:	/* Drive Not Ready */		case 0x28:	/* Medium Changed */		case 0x29:	/* Power On or Reset or Bus Device Reset */		case 0x2a:	/* Mode Select Parameter Changed */			break;		default:			return (-1);		}		DELAY(D100MSEC);		/* wait 100 ms. */		goto loop_inq;	}	index = identity_check(sci, -1, unit);	switch (sddevinfo[index].type) {	case SMO_S501:	case SMO_S501_ISO:	case SMO_S501_ISO2:		sdc->sdc_firmware =			SDCFW_MO | (sdc->sdc_firmware & ~SDCFW_DEVMASK);		break;	defaults:		break;	}	if (sci->sci_qual & 0x80) {		/*		 * removable medium device		 */		sdc->sdc_firmware |= SDCFW_RMB;

⌨️ 快捷键说明

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