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

📄 sdc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef lintstatic char *sccsid = "@(#)sdc.c	4.1	ULTRIX	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986,87,88 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//*********************************************************************** * * Modification History: *   Apr-1-91	Matthew Sacks *	Changed rx23_type() so that it does a ready check and drive *	restore before doing the I/O operation which distinguishes high *	density (2880) from double density (1440) floppy disks. *	Otherwise, this density test causes Sync errors when *	floppy cartridges are interchanged. * *   30-Dec-88	Fred Canter *	Added sdreset() to reset ST506 controllers before calling the *	VMB boot drive to write out a crash dump. * *   28-Sep-88 Fred Canter *	Clean up comments. Use CFGTST regiser bit to determine floopy *	drive type, i.e., RX33 or RX23. * *   08-Aug-88 Fred Canter *	Make probe fail if not drives present (PVAX only). *	The installation will generate a bad config file if the *	sdc controller is present with no drives (undefined sdintr). * *   14-Jul-88 George Mathew *	Added support for RX23 floppy drive * *   19-May-88 Fred Canter *	Changes for operating in either compatibility or *	extended I/O mode on CVAXstar/PVAX. * *   15-Feb-88 Fred Canter *	Changes for VAX420 (CVAXstar/PVAX) support. *	Added RD33 support. *	Changed sd_delay from one instruction to a macro. * *   01-Jun-87 George Mathew *	Fix the problem with spurious deleted data mark. Check for Write Fault *	before Deleted Data Mark! * *   28-Apr-87 George Mathew *	DEVIOCGET ioctl reports correctly if the diskette is write preotected * *   23-Apr-97 darrell *	Changed the calls to vs_bufctl to pass a pointer to a structure *	that contains a pointer to the routine that vs_bufctl is to  *	call in this driver. * *   12-Mar-87 George Mathew *	Fix for the protection fault: if going through bbr code (using  *	rdwr_poll for read/write) and the no. of bytes to be transferred *	from the last sector in the track containing the bad sector is not *	512, transfer the correct no. of bytes. * *   11-Feb-87 gmm (George Mathew) *	Removed all the debug stuff related to deleted data mark (undid  *	most of 01/15/87 work). Included a couple of more delays hoping to *	get rid of the spurious deleted data marks. * *   28-Jan-87 gmm (George Mathew) *	Restore to track 0 whenever starting on a new diskette (Causes *	sync error otherwise). Put the last drive serviced at the end of the *	queue for the next round. Made some changes to take care of lint *	warning messages * *   15-Jan-87 gmm (George Mathew) *	Does not report I/O error if deleted data mark not written by the *	driver (through BBR) is reported by the controller. But error *	messages are printed. (To be removed before SDC) * *   06-Jan-87 gmm (George Mathew) *	Updated BBR code to the latest algorithm (ECO #20). BBR messages *	made the same as of uda. Added ioctl support for radisk. Removed *	sdreset(). Changes to diskette drive. * *   3-Dec-86  gmm (George Mathew) *	Performance enhancements. Changed the way deleted data mark is *	reported. First version after field test. * *   8-Oct-86  gmm (George Mathew) *	Fix a bug in bbr: if the sector is not bad, but the data *	is invalid (Forced error bit set) the block no. is correctly  *      calculated in sd_rpl() . * *   6-Oct-86  gmm (George Mathew) *	Check validity of unit number before status field updated in the *	open routine (sdopen()). * *   20-Sep-86 gmm (George Mathew) *	BBR bug fix: RCT gets updated correctly even if not the first one. *	Some changes for RX50 read/write to be more robust. *	DEVIOCGET ioctl updates stat field correctly. * *   9-Sep-86  gmm (George Mathew) *      Changed the way presence of RX33 drive is detected in sdslave. *	Improved some of the error messages * *   4-Sep-86  gmm (George Mathew) *	Improvements, bug fixes, and cleanup. * *  27-Aug-86  gmm (George Mathew) *	Many changes: RX50 improved performance, BBR improvements, and *	general cleanup. * *  26-Aug-86 -- rsp (Ricky Palmer) *	Cleaned up devioctl code to (1) zero out devget structure *	upon entry and (2) use strlen instead of fixed storage *	for bcopy's. * *  14-Aug-86  gmm (George Mathew) *	Several driver improvements and clean out debug messages. *	Change slave names from sd to rd/rx. * *   5-Aug-86  gmm (George Mathew) *	Extensive rewrite for real VAXstar disk driver. * *   2-Jul-86  gmm (George Mathew) *	Added partial devioctl support and many improvements to driver. * *  18-Jun-86  gmm (Geroge Mathew) *      Created this VAXstar RD/RX disk driver file. * **********************************************************************/#include "rd.h"#include "rx.h"#if NRX > 0#define	NSX	1#else#define	NSX	0#endif#define		NSD	NRD+NSX#if defined(BINARY) || NSD > 0int	sdpip;		/* DEBUG */int	sdnosval;	/* DEBUG */extern int cvs_exmode_on;#include "../data/sdc_data.c"int	sdprobe(), sdslave(), sdattach(), sdintr(), sdustart();u_short	sdstd[] = { 0 };struct	uba_driver sdcdriver = { sdprobe, sdslave, sdattach, 0, sdstd, "rd", sddinfo, "sdc", sdminfo, 0 };struct	sdspace	SD_bufmap[];struct	vsdev vsdiskdev = { VS_SDC, 0, sdustart };/* !!! IMPORTANT !!!*//* If any new disk type added to this structure (sdst), make sure the type  * number defined in sdcreg.h and the position of the new disk in this  * sturcture MATCH. */struct	sdst {	short	nsect;  /* no. of sectors(blocks) per track */	short	ncyl;   /* no. of cylinders */	short	nheads; /* no. of heads or tracks per cylinder */	short	nspc;	/* no. of sectors(blocks) per cylinder */	struct	size *sizes;} sdst[] = {	NRX50SECT,NRXCYL,NRX50HDS,NRX50SECT*NRX50HDS,sd_rx50_sizes,	NRX33SECT,NRXCYL,NRX33HDS,NRX33SECT*NRX33HDS,sd_rx33_sizes,	NRX23SECTH,NRXCYL,NRX23HDS,NRX23SECTH*NRX23HDS,sd_rx23h_sizes,	NRX23SECTD,NRXCYL,NRX23HDS,NRX23SECTD*NRX23HDS,sd_rx23d_sizes,	NRDSECT,NRD31CYL,NRD31HDS,NRDSECT*NRD31HDS,sd_rd31_sizes,	NRDSECT,NRD32CYL,NRD32HDS,NRDSECT*NRD32HDS,sd_rd32_sizes,	NRDSECT,NRD33CYL,NRD33HDS,NRDSECT*NRD33HDS,sd_rd33_sizes,	NRDSECT,NRD53CYL,NRD53HDS,NRDSECT*NRD53HDS,sd_rd53_sizes,	NRDSECT,NRD54CYL,NRD54HDS,NRDSECT*NRD54HDS,sd_rd54_sizes,};short	rx_table[50] =		{ 1, 3, 5, 7, 9, 2, 4, 6, 8, 10,		3, 5, 7, 9, 1, 4, 6, 8, 10, 2,		5, 7, 9, 1, 3, 6, 8, 10, 2, 4,		7, 9, 1, 3, 5, 8, 10, 2, 4, 6,		9, 1, 3, 5, 7, 10, 2, 4, 6, 8 };struct buf sdcbuf;	/* Pointer to controller queue */char xbnbuf[SD_SIZE],tmpbuf[SD_SIZE],rct0[SD_SIZE],rct1[SD_SIZE],rct2[SD_SIZE],rct3[SD_SIZE];short xbnflag = 0;short rtr_cnt = 0;   /* no. of times read/write retried */short dsket_type = -1; /* type of diskette */int ddm_err = 0;  /* Deleted Data Mark error */int rx50blk, rx50nsect;  /* starting block no. and no. of sectors for each 			 * transfer for RX50 *//* * HDC 9224 chip register access delay macro. * Must insure a minimum of 700 ns between disk * controller register accesses. * CVAXstar vs VAXstar CPU speed complicates this issue. * Best we can to is make sure delay long enough for faster CPU. */int	sd_delay = 0;#define	sdc_delay()	sd_delay = 1; sd_delay = 1; sd_delay = 1;char *HARD_ERR = "HARD ERROR";char *SOFT_ERR = "SOFT ERROR";char *DEV_ID = "sd";int     sd_rx23wakeup();int sd_bbrcount = RTRY_CNT;   /* change this to adjust the retry count in 		* sd_retry() while doing read/write for bbr. sd_bbrcount 		* should be >= 1 !! */int sddebug = 0;int sdbbrdbug = 0;int rx_reselect = 0;int xbn_sum = 0;int xbn_check = 0;int start_sn ;	   /* physical starting sector no. in the track on which I/O *		    * is being done */int sd_poll = 0;   /* controller in poll mode */int sd_nodelay = 0;  /* NODELAY flag for open */int sd_openerr = 0;  /* Error in opening the device */int sd_rxcyl = 0;  /* the last cylinder no. for Rx drive, used by STEP */u_char rbn_addr1,rbn_addr2;	 /***********************	 * !!! DO NOT use BBR_TST option unless you are absolutely sure of 	 * what you are doing. It should be used only for debugging bad block	 * replacement code. !!! 	 ************************/#ifdef BBR_TST	int bbr_sleep;	int bbr_force;  /* setting this to non zero forces bbr on the block 			 * even if found good in STEP 7 of put_rbn() */#endif BBR_TSTextern struct nexus nexus[];#define DELAYTEN	1000#define LOOP_DELAY	1000000	/* for the following macros: i=unit, j=partition */#define BAD_LBN(i)	sd_st.sd_blkno-sd_st.ucb[i].lbnbase-sd_st.sd_nsect+sd_st.ucb[i].badsect#define BAD_SECT(i,j)	sd_st.sd_blkno-sd_st.ucb[i].lbnbase-sd_st.sd_nsect-sd_part[i].pt_part[j].pi_blkoff+sd_st.ucb[i].badsectextern	int	cpu;extern	int	cpu_subtype;sdprobe(reg, cntlr)	caddr_t reg;	int cntlr;{	register struct nb1_regs *sdaddr = (struct nb1_regs *)qmem;	register struct nb_regs *sdiaddr = (struct nb_regs *)nexus;	int count = 0;#ifdef lint		sdintr(0);	reg = reg;#endif	/*	 * ONLY on a VAXstar/TEAMmate	 * Also CVAXstar/PVAX	 */	if ((cpu != VAXSTAR) && (cpu != C_VAXSTAR))		return(0);	/*	 * Only if ST506 disk controller configured.	 * PVAX server uses 2nd SCSI in place of ST506 controller.	 */	if ((vs_cfgtst & VS_SC_TYPE) != VS_ST506_SCSI)		return(0);	/*	 * Don't allow controller to configure if no drives present	 * (PVAX only). The installation will build a config file	 * with the sdc0 controller, but no slaves on a PVAX with	 * the ST506/SCSI controller if no ST506 drives are found.	 * The causes the kernel build fail (undefined sdintr).	 */	if ((vs_cfgtst & (VS_DRV0PR | VS_DRV1PR | VS_DRV2PR)) == 0x0700)		return(0);	sdiaddr->nb_int_msk |= SINT_DC;	sdaddr->dkc_cmd = SD_RESET;	while(count < DELAYTEN) {		if(sdaddr->dkc_stat & DKC_DONE )			break;		DELAY(10);		count++;	}	if (count == DELAYTEN){		printf("%s%c:%s: SD_RESET failed in sdprobe\n",DEV_ID,'c',HARD_ERR);		return(0);	}	sdaddr->dkc_cmd = (SD_SETREG | UDC_TERM);	sdc_delay();	if((sdaddr->dkc_stat & DKC_DONE) == 0) {		printf("%s%c:%s: Set Register Pointer command failed in sdprobe\n",DEV_ID,'c',HARD_ERR);		return(0);	}	sdaddr->dkc_reg = (TERM_CRC | TERM_INT | TERM_DEL | TERM_WRPR |  TERM_WRFL);	sdc_delay();	sdaddr->dkc_cmd = SD_DESEL;   /* just to generate an interrupt */	return(8);}sdslave(ui)	struct uba_device *ui;{	register struct nb1_regs *sdaddr = (struct nb1_regs *)qmem;	u_char cmd;	sdaddr->dkc_cmd = (SD_SETREG | UDC_DHEAD);	sdc_delay();	sdaddr->dkc_reg = 0;  /* Play safe by using head 0 here */	/* RESET TERM_CODES AGAIN?? */	sdc_delay();	sdaddr->dkc_cmd = (SD_SETREG | UDC_TERM);	sdc_delay();	sdaddr->dkc_reg = (TERM_CRC | TERM_INT | TERM_DEL | TERM_WRPR |  TERM_WRFL);	sdc_delay();	sdaddr->dkc_cmd = (SD_SETREG | UDC_RTCNT);	switch(ui->ui_slave) {		case 0:		case 1:		    sdaddr->dkc_reg = RT_CNT;  /* UDC_RTCNT */		    sdc_delay();		    sdaddr->dkc_reg = (MOD_HD | MOD_CHKECC | MOD_SRTRDN);  /* UDC_MODE */		    sd_st.sd_drno = ui->ui_slave;		    sd_st.sd_type[ui->ui_slave] = -1;		    cmd = (SD_SELECT | DTRT_HDSK | ui->ui_slave);		    if(sd_select(cmd,0)) {			if(sddebug >=2) cprintf("%s%d:%s: Not selected\n",DEV_ID,ui->ui_slave,HARD_ERR);			sd_st.sd_type[ui->ui_slave] = -1;			    return(0);  		    }		    if(sd_rdfmt(ui->ui_slave)){			printf("%s%d:%s:cannot read XBN\n",DEV_ID,ui->ui_slave,HARD_ERR);			sd_st.sd_type[ui->ui_slave] = -1;			return(0);		    }		    /* media type (sd_st.sd_type[]) updated in sd_rdfmt() */		    /* Sanity check on RCT to see if bbr was stopped in the middle */		    if(put_rbn(-1)) { /* Sanity check on RCT to see if bbr was stopped in the middel */			printf("%s%d:%s: CANNOT RECOVER FROM PREVIOUS BBR\n",DEV_ID,ui->ui_slave,HARD_ERR);		    }		    sd_st.sd_cyl.sd_word = -1;		    sd_st.sd_drno = -1;		    ui->ui_type = sd_st.sd_type[ui->ui_slave];		    return(1);		    /* break; */		case 2:		    sd_st.sd_drno = ui->ui_slave;		    sdaddr->dkc_reg = (RT_CNT | RT_INVRDY |RT_MOTOR);  /* UDC_RTCNT */		    sdc_delay();		    sdaddr->dkc_reg = (MOD_HD | MOD_CHKCRC | MOD_SRTRXH);   /* UDC_MODE */		    rx_reselect = 1;		    cmd = (SD_SELECT | DTRT_RX50 | DRV_NUM2);		    if(sd_select(cmd,1)) {			/* Select again to set READY in UDC_DSTAT */			sdaddr->dkc_cmd = (SD_SETREG | UDC_RTCNT);			sdc_delay();			sdaddr->dkc_reg = (RT_CNT | RT_MOTOR);			rx_reselect = 1;			if(sd_select(cmd,1)) {			    if(sddebug >=2) cprintf("%s%d:%s: Not selected \n",DEV_ID,ui->ui_slave,HARD_ERR);			    return(0);   			}			/* if a diskette drive is present, TRK0 should be 			 * set when RESTORE issued */			if( sd_restore(1)) {			    if(sddebug >=2) cprintf("%s%d:%s: Not selected\n",DEV_ID,ui->ui_slave,HARD_ERR);				return(0);			}		    }		    /* Even if there is no diskette drive, READY bit in		     * UDC_DSTAT is 1 !!. So restore to see if drive		     * really present */		    else {			if(sd_restore(1)) {			    if(sddebug >=2) cprintf("%s%d:%s: Not selected\n",DEV_ID,ui->ui_slave,HARD_ERR);			    return(0);			}		    }		    sd_st.sd_cyl.sd_word = -1;		    sd_st.sd_drno = -1;		    sd_rxtype(ui->ui_slave);		    /* On PVAX, CFGTST reg bit for floppy type (RX23 or RX33) */		    if ((cpu == C_VAXSTAR) && ((vs_cfgtst&VS_DRV2RX33) == 0)) {			    sd_rx23htype(ui->ui_slave);   			    ui->ui_type = DT_RX23H; 			    sd_st.sd_type[ui->ui_slave] = DT_RX23H;		    }		    else {			    sd_rx33type(ui->ui_slave);   			    ui->ui_type = DT_RX33; 			    sd_st.sd_type[ui->ui_slave] = DT_RX33;		    }		    return(1);		    /* break; */		default:			mprintf("%s%d:%s: wrong unit number for sdslave\n",DEV_ID,ui->ui_slave,SOFT_ERR);			return(0);	}}sdattach(ui)	register struct uba_device *ui;{	/* Initialize iostat values */	if(ui->ui_dk >= 0) {		dk_mspw[ui->ui_dk] = .0000032;  /* 16bit transfer time */	}	sd_st.sd_softcnt[ui->ui_slave] = 0;  /* initialize soft error count */	sd_st.sd_hardcnt[ui->ui_slave] = 0;  /* initialize hard error count */	ui->ui_flags = 0;} 

⌨️ 快捷键说明

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