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

📄 matcd.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	Creative adapter boards:		#1330A	Sound Blaster PRO		#1730	Sound Blaster 16		#1740	Sound Blaster 16 (cost reduced)		#2230	Sound Blaster 16 (cost reduced)		#2770	Sound Blaster 16 Value (cost reduced)		#1810	omniCD upgrade kit adapter card (stand-alone CD)		#3100	PhoneBlaster SB16 + Sierra 14.4K modem combo	Creative releases a newer and cheaper-to-make Sound Blaster	board every few months, so by the original release date of this	software, there are probably 8 different board models called	Sound Blaster 16.  These include "Vibra", "Value", etc.	Please report additional part numbers and board descriptions	and new port numbers that work to the author.---------------------------------------------------------------------------*/static intmatcd_probe(struct isa_device *dev){	int	i,cdrive;	unsigned char	y;	int port = dev->id_iobase;	/*Take port hint from config file*/	cdrive=nextcontroller;		/*Controller defined by pass for now*/	if (nextcontroller==NUMCTRLRS) {		printf("matcdc%d: - Too many interfaces specified in config\n",		       nextcontroller);		return(0);	}	if (nextcontroller==0) {	/*Very first time to be called*/		for (i=0; i<TOTALDRIVES; i++) {			matcd_data[i].drivemode=MODE_UNKNOWN;			matcd_data[i].flags=0;		}	}	i=nextcontroller*DRIVESPERC;	/*Precompute controller offset*/	for (y=0; y<DRIVESPERC; y++) {		matcd_data[i+y].flags=0;	}#ifdef DEBUGPROBE	printf("matcdc%d: In probe i %d y %d port %x\n",	       nextcontroller,i,y,port);#endif /*DEBUGPROBE*/#ifdef AUTOHUNT#ifdef DEBUGPROBE	printf("matcd%d: size of port_hints %d\n",	       nextcontroller,sizeof(port_hints));#endif /*DEBUGPROBE*/	if (port==-1) {		for(i=0;i<(sizeof(port_hints)/sizeof(short));i++) {			port=port_hints[i];#ifdef DEBUGPROBE	printf("matcdc%d: Port hint %x\n",nextcontroller,port);#endif /*DEBUGPROBE*/			if (port==-1) {				dev->id_iobase=-1;	/*Put port ? back*/				return(0);/*Nothing left to try*/			}			if (port!=0) {	/*Untested port found*/				dev->id_iobase=port;				port_hints[i]=0;/*Don't use that port again*/				if (doprobe(port,cdrive)==0) return(NUMPORTS);			}		}		dev->id_iobase=-1;	/*Put port ? back as it was*/		return(0);		/*Interface not found*/	} else {			/*Config specified a port*/		i=0;			/*so eliminate it from the hint list*/		for(i=0;;i++) {		/*or we might try to assign it again*/			if (port_hints[i]== -1) break;	/*End of list*/			if (port_hints[i]==port) {				port_hints[i]=0;	/*Clear duplicate*/				break;			}		}		if (doprobe(port,cdrive)==0) return(NUMPORTS);		else return(0);	}#else /*AUTOHUNT*/	if (port==-1) {		printf("matcdc%d: AUTOHUNT disabled but port? specified in config\n",		       nextcontroller);		return(0);	}	if (doprobe(port,cdrive)==0) return(NUMPORTS);	else return(0);#endif /*AUTOHUNT*/}/*---------------------------------------------------------------------------	doprobe - Common probe code that actually checks the ports we		have decided to test.<20>	Edit 20 changes adds code to determine if the host interface	is one that behaves like the Creative SoundBlaster cards,	or whether the host interface like those used by some boards	made by Media Vision and a version known as Lasermate.---------------------------------------------------------------------------*/int doprobe(int port,int cdrive){	unsigned char cmd[MAXCMDSIZ];	int i;#ifdef RESETONBOOT	doreset(port,cdrive);		/*Reset what might be our device*/#endif /*RESETONBOOT*/	outb(port+PHASE,0);		/*<16>Guarantee status phase*/	zero_cmd(cmd);	cmd[0]=NOP;			/*A reasonably harmless command.				  	  This command will fail after				  	  power-up or after reset. That's OK*/#ifdef RESETONBOOT	if (((inb(port+STATUS) & (DTEN|STEN)) != (DTEN|STEN)) ||	    (inb(port+DATA) != 0xff))		return(-1);		/*<20>Something detected but it isn't					      the device we wanted*/#endif /*RESETONBOOT*/	if (matcd_fastcmd(port,0,0,cmd)==0) {/*Issue command*/		outb(port+PHASE,1);	/*<20>Switch to Creative Data phase*/		i=inb(port+CMD);	/*<20>Read a byte in data phase*/		outb(port+PHASE,0);	/*<20>Switch to Creative Status phase*/		if ((inb(port+STATUS) & (DTEN|STEN))		    == (DTEN|STEN)) {	/*<20>Drive went idle*/			iftype=1;	/*<20>It is not a Creative interface.*/		} else {		/*<20>Status byte still available*/			iftype=0;			inb(port+CMD);	/*<20>Read status byte*/		}#ifdef DEBUGPROBE		printf("matcdc%d: Probe found something\n",nextcontroller);#endif /*DEBUGPROBE*//*------Don't change anything below this line - see license -----------------*/		if (drivepresent==0) {	/*Don't change*/			printf("matcd - Matsushita (Panasonic) CD-ROM Driver by FDIV, %s\n",					/*Don't change*/		               MATCDVERSION); /*Don't change*/			drivepresent++;	/*Don't change*/			if (drivepresent==0) /*Don't change - make LINT happy*/				printf("%s\n",MATCDCOPYRIGHT); /*Don't change*/		}			/*Don't change*//*------Don't change anything above this line - see license -----------------*/		return(0);		/*Drive 0 detected*/	}#ifdef DEBUGPROBE	printf("matcdc%d: Probe DID NOT find something\n",nextcontroller);#endif /*DEBUGPROBE*/	return(1);}/*---------------------------------------------------------------------------	matcd_attach - Locates drives on the adapters that were located.		If we got here, we located an interface and at least one		drive.  Now we figure out how many drives are under that		interface.  The Panasonic interface is too simple to call		it a controller, but in the existing PDP model, that is		what it would be.---------------------------------------------------------------------------*/static intmatcd_attach(struct isa_device *dev){	int	i;	unsigned int	z,cdrive;	unsigned char cmd[MAXCMDSIZ];	unsigned char data[12];	struct matcd_data *cd;	int port = dev->id_iobase;	/*Take port ID selected in probe()*/#ifdef DEBUGPROBE	printf("matcdc: Attach dev %x id_unit %d\n",	       (unsigned int)dev,dev->id_unit);#endif /*DEBUGPROBE*/	printf("matcdc%d Host interface type %d\n",		nextcontroller,iftype);	bufq_init(&request_head[nextcontroller]);	for (cdrive=0; cdrive<4; cdrive++) {	/*We're hunting drives...*/		zero_cmd(cmd);		cmd[0]=NOP;		/*A reasonably harmless command.					  This command will fail after					  power-up or after reset. It's OK*/		i=cdrive+(DRIVESPERC*nextcontroller);		if (matcd_fastcmd(port,i,cdrive,cmd)==0) {	/*Issue cmd*/			z=get_stat(port,cdrive);/*Read status byte*/			if ((z & MATCD_ST_ERROR)) {	/*If there was an error,						  we must ask for error info						  or subsequent cmds fail*/				zero_cmd(cmd);				cmd[0]=READERROR;	/*Inquire*/				matcd_fastcmd(port,i,cdrive,cmd);				matcd_pread(port,8,data);/*Read data returned*/				z=get_stat(port,i);/*Read status byte*/#ifdef DEBUGPROBE				printf("matcd%d: Status byte %x ",i,z);#endif /*DEBUGPROBE*/			}			zero_cmd(cmd);			cmd[0]=READID;	/*Get drive ID*/			matcd_fastcmd(port,i,cdrive,cmd);			matcd_pread(port,10,data);/*Read Drive Parm*/			get_stat(port,i);	/*Read and toss status byte*/			data[10]=0;	/*Build ASCIZ string*/			printf("matcd%d: [%s]  ",i,data);			cd=&matcd_data[i];			cd->flags |= MATCDINIT;			cd->iobase=dev->id_iobase;			cd->iftype=iftype;			cd->openflags=0;			cd->volume[0]=cd->volume[1]=DEFVOL;					/*<12>Match volume drive resets to*/			cd->patch[0]=0x01;	/*<12>Channel 0 to Left*/			cd->patch[1]=0x02;	/*<12>Channel 1 to Right*/			cd->status=CD_AS_NO_STATUS;			for (i=0; i<MAXPARTITIONS; i++) {				cd->partflags[i]=0;			}#ifdef DEVFS			cd->ra_devfs_token = devfs_add_devswf(&matcd_cdevsw,				dkmakeminor(i, 0, 0), DV_CHR,				UID_ROOT, GID_OPERATOR, 0640, "rmatcd%da", i);			cd->rc_devfs_token = devfs_add_devswf(&matcd_cdevsw,				dkmakeminor(i, 0, RAW_PART), DV_CHR,				UID_ROOT, GID_OPERATOR, 0640, "rmatcd%dc", i);			cd->a_devfs_token = devfs_add_devswf(&matcd_bdevsw,				dkmakeminor(i, 0, 0), DV_BLK,				UID_ROOT, GID_OPERATOR, 0640, "matcd%da", i);			cd->c_devfs_token = devfs_add_devswf(&matcd_bdevsw,				dkmakeminor(i, 0, RAW_PART), DV_BLK,				UID_ROOT, GID_OPERATOR, 0640, "matcd%dc", i);			cd->rla_devfs_token = devfs_add_devswf(&matcd_cdevsw,				0x80 | dkmakeminor(i, 0, 0), DV_CHR,				UID_ROOT, GID_OPERATOR, 0640, "rmatcd%dla", i);			cd->rlc_devfs_token = devfs_add_devswf(&matcd_cdevsw,				0x80 | dkmakeminor(i, 0, RAW_PART), DV_CHR,				UID_ROOT, GID_OPERATOR, 0640, "rmatcd%dc", i);			cd->la_devfs_token = devfs_add_devswf(&matcd_bdevsw,				0x80 | dkmakeminor(i, 0, 0), DV_BLK,				UID_ROOT, GID_OPERATOR, 0640, "matcd%dla", i);			cd->lc_devfs_token = devfs_add_devswf(&matcd_bdevsw,				0x80 | dkmakeminor(i, 0, RAW_PART), DV_BLK,				UID_ROOT, GID_OPERATOR, 0640, "matcd%dlc", i);#endif		}	}	nextcontroller++;		/*Bump ctlr assign to next number*/	printf("\n");			/*End line of drive reports*/	return(1);}/*---------------------------------------------------------------------------	zero_cmd - Initialize command buffer---------------------------------------------------------------------------*/void zero_cmd(char * lcmd){	int	i;	for (i=0; i<MAXCMDSIZ; lcmd[i++]=0);	return;}/*---------------------------------------------------------------------------	doreset - Resets all the drives connected to a interface---------------------------------------------------------------------------*/void doreset(int port,int cdrive){	register int	i,z;	outb(port+RESET,0);		/*Reset what might be our device*/					/*Although this ensures a known					  state, it does close the drive					  door (if open) and aborts any					  audio playback in progress. */	for (i=0;i<(125*ISABUSKHZ);i++){/*DELAY 500msec minimum. Worst					  case is door open and none or					  unreadable media */		z=inb(port+CMD);	/*This makes the loop run at a					  known speed.  This value is ok					  for 8.33MHz bus*/	}	for (i=0;i<4;i++) {		matcd_data[(cdrive*4)+i].drivemode=MODE_UNKNOWN;	}	return;}/*---------------------------------------------------------------------------	matcd_fastcmd - Send a command to a drive	This routine executed commands that return instantly (or reasonably	quick), such as RESET, NOP, READ ERROR, etc.  The only difference	between it and handling for slower commands, is the slower commands	will invoke a timeout/sleep if they don't get an instant response.	Fastcmd is mainly used in probe(), attach() and error related	functions.  Every attempt should be made to NOT use this	function for any command that might be executed when the system	is up.---------------------------------------------------------------------------*/int matcd_fastcmd(int port,int ldrive,int cdrive,unsigned char * cp){	unsigned int	i;	unsigned char	z;	int	level;#ifdef DEBUGCMD	unsigned char *cx;#endif /*DEBUGCMD*/	draincmd(port,cdrive,ldrive);	/*Make sure bus is really idle*/#ifdef DEBUGCMD	cx=cp;	printf("matcd%d: Fast Send port %x sel %d command %x %x %x %x %x %x %x\n",	       ldrive,port,cdrive,cx[0],cx[1],cx[2],cx[3],cx[4],cx[5],cx[6]);#endif	/*DEBUGCMD*/	selectdrive(port,cdrive);	/*Enable the desired target drive*/	level=splhigh();	/*----------------------------------------*/	for (i=0; i<7; i++) {		/*The seven bytes of the command*/		outb(port+CMD,*cp++);	/*must be sent within 10msec or*/	}				/*the drive will ignore the cmd*/	splx(level);	/*------------------------------------------------*//*	Now we wait a maximum of 240msec for a response.	Only in a few rare cases does it take this long.	If it is longer, the command should probably be slept on	rather than increasing the timing value*/	for (i=0; i<(60*ISABUSKHZ); i++) {		z = (inb(port+STATUS)) & (DTEN|STEN);		if (z != (DTEN|STEN)) break;	}/*	We are now either in a data or status phase, OR we timed-out.*/	if (z == (DTEN|STEN)) {#ifdef DEBUGCMD		printf("matcd%d: Command time-out\n",ldrive);#endif /*DEBUGCMD*/		return(-1);	}	if (z != DTEN) {		return(1);	}	return(0);}/*---------------------------------------------------------------------------	matcd_slowcmd - Issue a command to the drive	This routine is for commands that might take a long time, such	as a read or seek.  The caller must determine if the command	completes instantly or schedule a poll later on.---------------------------------------------------------------------------*/void matcd_slowcmd(int port,int ldrive,int cdrive,unsigned char * cp){	unsigned int	i;	int	level,size;#ifdef DEBUGCMD	unsigned char *cx;#endif /*DEBUGCMD*/	draincmd(port,cdrive,ldrive);	/*Make sure bus is really idle*/#ifdef DEBUGCMD	cx=cp;	printf("matcd%d: Slow Send port %x sel %d command %x %x %x %x %x %x %x\n",	       ldrive,port,cdrive,cx[0],cx[1],cx[2],cx[3],cx[4],cx[5],cx[6]);#endif	/*DEBUGCMD*/	selectdrive(port,cdrive);	/*Enable the desired target drive*/	if (*cp==ABORT) size=1;	else size=7;	level=splhigh();	/*----------------------------------------*/	for (i=0; i<size; i++) {	/*The seven bytes of the command*/

⌨️ 快捷键说明

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