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

📄 matcd.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	unsigned char	type;		/*00 CD-DA or CD-ROM					  10 CD-I					  20 XA */	unsigned char	trk_low;	/*Normally 1*/	unsigned char	trk_high;	/*Highest track number*/	unsigned char	vol_msf[3];	/*Size of disc in min/sec/frame*/};struct	matcd_mbx {	short	controller;	short	ldrive;	short	partition;	short	port;	short	iftype;			/*<20>Host interface type*/	short	retry;	short	nblk;	int	sz;	u_long	skip;	struct	buf	*bp;	int	p_offset;	short	count;};static	struct matcd_data {	short	drivemode;		/*Last state drive was set to*/	short	flags;	short	status;			/*Last audio-related function*/	int	blksize;	u_long	disksize;	short	iobase;	short	iftype;			/*<20>Host interface type*/	struct	disklabel dlabel;	unsigned int	partflags[MAXPARTITIONS];	unsigned int	openflags;	struct	matcd_volinfo volinfo;	struct	matcd_mbx mbx;	u_char	patch[2];		/*<12>Last known audio routing*/	u_char	volume[2];		/*<12>Last known volume setting*/#ifdef DEVFS	void	*ra_devfs_token;	/* handle for devfs entry */	void	*rc_devfs_token;	void	*a_devfs_token;	void	*c_devfs_token;	void	*rla_devfs_token;	void	*rlc_devfs_token;	void	*la_devfs_token;	void	*lc_devfs_token;#endif DEVFS} matcd_data[TOTALDRIVES];/*	Bit equates for matcd_data.flags*/#define	MATCDINIT	0x0001		/*Probe ran on host adapter*/#define	MATCDLABEL	0x0004		/*Valid TOC exists*/#define	MATCDLOCK	0x0008		/*<15>Drive door is locked*/#define	MATCDWARN	0x0020		/*Have reported an open disc change*//*	Bit equates for matcd_data.partflags*/#define	MATCDOPEN	0x0001#define	MATCDREADRAW	0x0002/*	Error classes returned by chk_error()*/#define ERR_RETRY	1		/*A retry might recover this*/#define ERR_INIT	2		/*A retry certainly will get this*/#define ERR_FATAL	3		/*This cannot be recovered from*/static	struct	buf_queue_head request_head[NUMCTRLRS];	/*<18>A queue for each host interface*/static	int	nextcontroller=0;	/*<18>Number of interface units found*/static	int	drivepresent=0; 	/*<18>Don't change this - see license*/static	int	iftype;			/*<20>Probe/Attach i.f. type relay*/static	unsigned char	if_state[4]={0,0,0,0};	/*<18>State of the host I/F and bus*//*	Flags in the if_state array*/#define	BUSBUSY	0x01			/*<18>Bus is already busy*/struct matcd_read2 {	unsigned char	start_msf[3];	unsigned char	end_msf[3];};/*	This mystery structure is supposed to make dynamic driver	loading possible.*//*---------------------------------------------------------------------------	These macros take apart the minor number and yield the	partition, drive on controller, and controller.	This must match the settings in /dev/MAKEDEV.---------------------------------------------------------------------------*/#define		matcd_partition(dev)	((minor(dev)) & 0x07)#define		matcd_ldrive(dev)	(((minor(dev)) & 0x78) >> 3)#define		matcd_cdrive(dev)	(((minor(dev)) & 0x18) >> 3)#define		matcd_controller(dev)	(((minor(dev)) & 0x60) >> 5)#ifdef LOCKDRIVE#define		matcd_lockable(dev)	(((minor(dev)) & 0x80) >> 5)#endif /*LOCKDRIVE*//*---------------------------------------------------------------------------	Entry points and other connections to/from kernel - see also conf.h           --- not any more :)---------------------------------------------------------------------------*/static	int	matcd_probe(struct isa_device *dev);static	int	matcd_attach(struct isa_device *dev);struct	isa_driver	matcddriver={matcd_probe, matcd_attach,				     "matcdc"};static d_open_t		matcdopen;static d_close_t	matcdclose;static d_ioctl_t	matcdioctl;static d_psize_t	matcdsize;static d_strategy_t	matcdstrategy;#define CDEV_MAJOR 46#define BDEV_MAJOR 17static struct cdevsw matcd_cdevsw;static struct bdevsw matcd_bdevsw = 	{ matcdopen,	matcdclose,	matcdstrategy,	matcdioctl,	/*17*/	  nodump,	matcdsize,	0,		"matcd",	  &matcd_cdevsw,	-1 };/*---------------------------------------------------------------------------	Internal function declarations---------------------------------------------------------------------------*/static	void	matcd_drvinit(void *unused);static	void	matcd_start(int controller);static	void	zero_cmd(char *);static	void	matcd_pread(int port, int count, unsigned char * data);static	int	matcd_fastcmd(int port,int ldrive,int cdrive,			      unsigned char * cp);static	void	matcd_slowcmd(int port,int ldrive,int cdrive,			      unsigned char * cp);static	void	matcd_blockread(int state);static	void	selectdrive(int port,int drive);static	void	doreset(int port,int cdrive);static	int	doprobe(int port,int cdrive);static	void	lockbus(int controller, int ldrive);static	void	unlockbus(int controller, int ldrive);static	int	matcd_volinfo(int ldrive);static	void	draincmd(int port,int cdrive,int ldrive);static	int 	get_error(int port, int ldrive, int cdrive);static	int	chk_error(int errnum);static	int	msf_to_blk(unsigned char * cd);#ifdef	FULLDRIVERstatic	int	matcd_playtracks(int ldrive, int cdrive, int controller,				 struct ioc_play_track *pt);static	int	matcd_playmsf(int ldrive, int cdrive, int controller,				 struct ioc_play_msf *pt);static	int	matcd_pause(int ldrive, int cdrive, int controller,			    int action);static	int	matcd_stop(int ldrive, int cdrive, int controller);static	int	matcd_level(int ldrive, int cdrive, int controller,		            struct ioc_vol * volume, int action);static	int	matcd_patch(int ldrive, int cdrive, int controller,		            struct ioc_patch * routing);static	int	matcd_route(int ldrive, int cdrive, int controller,		            int command);static	int	matcd_pitch(int ldrive, int cdrive, int controller,		            struct ioc_pitch * speed);#endif /*FULLDRIVER*/static	int	matcd_toc_header(int ldrive, int cdrive, int controller,		                 struct ioc_toc_header * toc);static	int	matcd_toc_entries(int ldrive, int cdrive,				  int controller,				  struct ioc_read_toc_entry *ioc_entry);static	int	matcd_read_subq(int ldrive, int cdrive, int controller,			        struct ioc_read_subchannel * sqp);static	int	matcd_igot(struct ioc_capability * sqp);static	int	waitforit(int timelimit, int state, int port,			   char * where);static	int	get_stat(int port, int ldrive);static	int	media_chk(struct matcd_data *cd,int errnum,			  int ldrive,int test);static	int	matcd_eject(int ldrive, int cdrive, int controller);static	int	matcd_doorclose(int ldrive, int cdrive, int controller);static	int	matcd_dlock(int ldrive, int cdrive,			    int controller, int action);static	int	docmd(char * cmd, int ldrive, int cdrive,		      int controller, int port);/*---------------------------------------------------------------------------	matcdopen - Open the device	This routine actually gets called every time anybody opens	any partition on a drive.  But the first call is the one that	does all the work.<15>	If LOCKDRIVE is enabled, additional minor number devices allow<15>	the drive to be locked while being accessed.---------------------------------------------------------------------------*/int	matcdopen(dev_t dev, int flags, int fmt,		  struct proc *p){	int cdrive,ldrive,partition,controller,lock;	struct matcd_data *cd;	int	i,z,port;	unsigned char	cmd[MAXCMDSIZ];	ldrive=matcd_ldrive(dev);	cdrive=matcd_cdrive(dev);	partition=matcd_partition(dev);	controller=matcd_controller(dev);	lock=matcd_lockable(dev);	cd= &matcd_data[ldrive];	port=cd->iobase;	/*and port#*/	if (ldrive >= TOTALDRIVES) return(ENXIO);#ifdef DEBUGOPEN	printf("matcd%d: Open: dev %x partition %x controller %x flags %x cdrive %x\n",	       ldrive,(int)dev,partition,controller,cd->flags,	       matcd_cdrive(dev));#endif /*DEBUGOPEN*/	if (!(cd->flags & MATCDINIT)) {	/*Did probe find this drive*/		return(ENXIO);	}	if (!(cd->flags & MATCDLABEL) &&	    cd->openflags) {		/*Has drive completely closed?*/		return(ENXIO);		/*No, all partitions must close*/	}/*	Now, test to see if the media is ready*/	lockbus(controller,ldrive);	zero_cmd(cmd);	cmd[0]=NOP;			/*Test drive*/	matcd_slowcmd(port,ldrive,cdrive,cmd);	i=waitforit(10*TICKRES,DTEN,port,"matopen");	z=get_stat(port,ldrive);	/*Read status byte*/#ifdef DEBUGOPEN	printf("matcd%d Result of NOP is %x %x\n",ldrive,i,z);#endif /*DEBUGOPEN*/	if ((z & MATCD_ST_DSKIN)==0) {	/*Is there a disc in the drive?*/#ifdef DEBUGOPEN		printf("matcd%d: No Disc in open\n",ldrive);#endif /*DEBUGOPEN*/		unlockbus(controller, ldrive);	/*Release bus lock*/		cd->flags &= ~MATCDLABEL;	/*<16>Mark label as invalid*/		if (major(dev)==RAW_DEVICE) {	/*<16>Is the char device?*/			return(0);		/*<16>Allow Semi open*/		}		else {			return(ENXIO);		/*<16>Normally blow off*/		}	}	if (z & MATCD_ST_ERROR) {		/*Was there an error*/		i=get_error(port,ldrive,cdrive);/*Find out what it was*/#ifdef DEBUGOPEN		printf("matcd%d NOP Error was %x\n",ldrive,i);#endif /*DEBUGOPEN*/		if (cd->openflags) {		/*Any parts open?*/			if (media_chk(cd,i,ldrive,0)) {	/*<14>Was it a disc chg?*/#ifdef DEBUGOPEN				printf("matcd%d: Disc change detected i %x z %x\n",				       ldrive,i,z);#endif /*DEBUGOPEN*/				unlockbus(controller, ldrive);	/*Release bus lock*/				return(ENOTTY);			}		} else {			media_chk(cd,i,ldrive,1);/*<14>Was it a disc chg?*/						 /*<14>Clear volume info*/		}	}	unlockbus(controller, ldrive);	/*Release bus lock*//*	Here we fill in the disklabel structure although most is	hardcoded.*/	if ((cd->flags & MATCDLABEL)==0) {		bzero(&cd->dlabel,sizeof(struct disklabel));/*	Now we query the drive for the actual size of the media.	This is where we find out of there is any media or if the	media isn't a Mode 1 or Mode 2/XA disc.	See version information about Mode 2/XA support.*/		lockbus(controller,ldrive);		i=matcdsize(dev);		unlockbus(controller, ldrive);	/*Release bus lock*/#ifdef DEBUGOPEN		printf("matcd%d: Bus unlocked in open\n",ldrive);#endif /*DEBUGOPEN*/		if (i < 0) {			printf("matcd%d: Could not read the disc size\n",ldrive);			return(ENXIO);		}			/*matcdsize filled in rest of dlabel*//*	Based on the results, fill in the variable entries in the disklabel*/		cd->dlabel.d_secsize=cd->blksize;		cd->dlabel.d_ncylinders=(cd->disksize/100)+1;		cd->dlabel.d_secperunit=cd->disksize;		cd->dlabel.d_partitions[0].p_size=cd->disksize;		cd->dlabel.d_checksum=dkcksum(&cd->dlabel);/*	Now fill in the hardcoded section*/					     /*123456789012345678*/		strncpy(cd->dlabel.d_typename,"Matsushita CDR ",16);		strncpy(cd->dlabel.d_packname,"(c) 1994, fdiv ",16);		cd->dlabel.d_magic=DISKMAGIC;		cd->dlabel.d_magic2=DISKMAGIC;		cd->dlabel.d_nsectors=100;		cd->dlabel.d_secpercyl=100;		cd->dlabel.d_ntracks=1;		cd->dlabel.d_interleave=1;		cd->dlabel.d_rpm=300;		cd->dlabel.d_npartitions=1;	/*See note below*/		cd->dlabel.d_partitions[0].p_offset=0;		cd->dlabel.d_partitions[0].p_fstype=9;		cd->dlabel.d_flags=D_REMOVABLE;/*	I originally considered allowing the partition match tracks or	sessions on the media, but since you are allowed up to 99	tracks in the RedBook world, this would not fit in with the	BSD fixed partition count scheme.  So ioctls will be used to shift	the track to be accessed into partition 1.*/		cd->flags |= MATCDLABEL;	/*Mark drive as having TOC*/	}#ifdef DEBUGOPEN	printf("matcd%d open2: partition=%d disksize=%d blksize=%x flags=%x\n",	       ldrive,partition,(int)cd->disksize,cd->blksize,cd->flags);#endif /*DEBUGOPEN*/#ifdef LOCKDRIVE	if (cd->openflags==0 && lock) {		zero_cmd(cmd);		cmd[0]=LOCK;		/*Lock drive*/		cmd[1]=1;		docmd(cmd,ldrive,cdrive,controller,port);/*<15>Issue cmd*/		cd->flags |= MATCDLOCK;	/*<15>Drive is now locked*/	}#endif /*LOCKDRIVE*/	cd->openflags |= (1<<(partition+lock));/*<24>Mark partition open*/	if (partition==RAW_PART ||	    (partition < cd->dlabel.d_npartitions &&	     cd->dlabel.d_partitions[partition].p_fstype != FS_UNUSED)) {		cd->partflags[partition] |= MATCDOPEN;		if (partition == RAW_PART) {			cd->partflags[partition] |= MATCDREADRAW;		}#ifdef DEBUGOPEN		printf("matcd%d: Open is complete - openflags %x\n",		       ldrive,cd->openflags);#endif /*DEBUGOPEN*/		return(0);	}#ifdef DEBUGOPEN	printf("matcd%d: Open FAILED\n",ldrive);#endif /*DEBUGOPEN*/	return(ENXIO);}

⌨️ 快捷键说明

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