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

📄 mcdx.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
			toc->cdth_trk0 = stuffp->di.n_first;			toc->cdth_trk1 = stuffp->di.n_last;			xtrace(TOCHDR,			       "ioctl() track0 = %d, track1 = %d\n",			       stuffp->di.n_first, stuffp->di.n_last);			return 0;		}	case CDROMPAUSE:{			xtrace(IOCTL, "ioctl() PAUSE\n");			if (stuffp->audiostatus != CDROM_AUDIO_PLAY)				return -EINVAL;			if (-1 == mcdx_stop(stuffp, 1))				return -EIO;			stuffp->audiostatus = CDROM_AUDIO_PAUSED;			if (-1 ==			    mcdx_requestsubqcode(stuffp, &stuffp->start,						 1))				return -EIO;			return 0;		}	case CDROMMULTISESSION:{			struct cdrom_multisession *ms =			    (struct cdrom_multisession *) arg;			xtrace(IOCTL, "ioctl() MULTISESSION\n");			/* Always return stuff in LBA, and let the Uniform cdrom driver			   worry about what the user actually wants */			ms->addr.lba = msf2log(&stuffp->multi.msf_last);			ms->xa_flag = !!stuffp->multi.multi;			xtrace(MS,			       "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",			       ms->xa_flag, ms->addr.lba,			       stuffp->multi.msf_last.minute,			       stuffp->multi.msf_last.second,			       stuffp->multi.msf_last.frame);			return 0;		}	case CDROMEJECT:{			xtrace(IOCTL, "ioctl() EJECT\n");			if (stuffp->users > 1)				return -EBUSY;			return (mcdx_tray_move(cdi, 1));		}	case CDROMCLOSETRAY:{			xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");			return (mcdx_tray_move(cdi, 0));		}	case CDROMVOLCTRL:{			struct cdrom_volctrl *volctrl =			    (struct cdrom_volctrl *) arg;			xtrace(IOCTL, "ioctl() VOLCTRL\n");#if 0				/* not tested! */			/* adjust for the weirdness of workman (md) */			/* can't test it (hs) */			volctrl.channel2 = volctrl.channel1;			volctrl.channel1 = volctrl.channel3 = 0x00;#endif			return mcdx_setattentuator(stuffp, volctrl, 2);		}	default:		return -EINVAL;	}}void do_mcdx_request(request_queue_t * q){	int dev;	struct s_drive_stuff *stuffp;      again:	if (QUEUE_EMPTY) {		xtrace(REQUEST, "end_request(0): CURRENT == NULL\n");		return;	}	if (CURRENT->rq_status == RQ_INACTIVE) {		xtrace(REQUEST,		       "end_request(0): rq_status == RQ_INACTIVE\n");		return;	}	INIT_REQUEST;	dev = MINOR(CURRENT->rq_dev);	stuffp = mcdx_stuffp[dev];	if ((dev < 0)	    || (dev >= MCDX_NDRIVES)	    || !stuffp || (!stuffp->present)) {		xwarn("do_request(): bad device: %s\n",		      kdevname(CURRENT->rq_dev));		xtrace(REQUEST, "end_request(0): bad device\n");		end_request(0);		return;	}	if (stuffp->audio) {		xwarn("do_request() attempt to read from audio cd\n");		xtrace(REQUEST, "end_request(0): read from audio\n");		end_request(0);		return;	}	xtrace(REQUEST, "do_request() (%lu + %lu)\n",	       CURRENT->sector, CURRENT->nr_sectors);	switch (CURRENT->cmd) {	case WRITE:		xwarn("do_request(): attempt to write to cd!!\n");		xtrace(REQUEST, "end_request(0): write\n");		end_request(0);		return;	case READ:		stuffp->status = 0;		while (CURRENT->nr_sectors) {			int i;			i = mcdx_transfer(stuffp,					  CURRENT->buffer,					  CURRENT->sector,					  CURRENT->nr_sectors);			if (i == -1) {				end_request(0);				goto again;			}			CURRENT->sector += i;			CURRENT->nr_sectors -= i;			CURRENT->buffer += (i * 512);		}		end_request(1);		goto again;		xtrace(REQUEST, "end_request(1)\n");		end_request(1);		break;	default:		panic(MCDX "do_request: unknown command.\n");		break;	}	goto again;}static int mcdx_open(struct cdrom_device_info *cdi, int purpose){	struct s_drive_stuff *stuffp;	xtrace(OPENCLOSE, "open()\n");	stuffp = mcdx_stuffp[MINOR(cdi->dev)];	if (!stuffp->present)		return -ENXIO;	/* Make the modules looking used ... (thanx bjorn).	 * But we shouldn't forget to decrement the module counter	 * on error return */	/* this is only done to test if the drive talks with us */	if (-1 == mcdx_getstatus(stuffp, 1))		return -EIO;	if (stuffp->xxx) {		xtrace(OPENCLOSE, "open() media changed\n");		stuffp->audiostatus = CDROM_AUDIO_INVALID;		stuffp->readcmd = 0;		xtrace(OPENCLOSE, "open() Request multisession info\n");		if (-1 ==		    mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))			xinfo("No multidiskinfo\n");	} else {		/* multisession ? */		if (!stuffp->multi.multi)			stuffp->multi.msf_last.second = 2;		xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",		       stuffp->multi.multi,		       stuffp->multi.msf_last.minute,		       stuffp->multi.msf_last.second,		       stuffp->multi.msf_last.frame);		{;		}		/* got multisession information */		/* request the disks table of contents (aka diskinfo) */		if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {			stuffp->lastsector = -1;		} else {			stuffp->lastsector = (CD_FRAMESIZE / 512)			    * msf2log(&stuffp->di.msf_leadout) - 1;			xtrace(OPENCLOSE,			       "open() start %d (%02x:%02x.%02x) %d\n",			       stuffp->di.n_first,			       stuffp->di.msf_first.minute,			       stuffp->di.msf_first.second,			       stuffp->di.msf_first.frame,			       msf2log(&stuffp->di.msf_first));			xtrace(OPENCLOSE,			       "open() last %d (%02x:%02x.%02x) %d\n",			       stuffp->di.n_last,			       stuffp->di.msf_leadout.minute,			       stuffp->di.msf_leadout.second,			       stuffp->di.msf_leadout.frame,			       msf2log(&stuffp->di.msf_leadout));		}		if (stuffp->toc) {			xtrace(MALLOC, "open() free old toc @ %p\n",			       stuffp->toc);			kfree(stuffp->toc);			stuffp->toc = NULL;		}		xtrace(OPENCLOSE, "open() init irq generation\n");		if (-1 == mcdx_config(stuffp, 1))			return -EIO;#if FALLBACK		/* Set the read speed */		xwarn("AAA %x AAA\n", stuffp->readcmd);		if (stuffp->readerrs)			stuffp->readcmd = READ1X;		else			stuffp->readcmd =			    stuffp->present | SINGLE ? READ1X : READ2X;		xwarn("XXX %x XXX\n", stuffp->readcmd);#else		stuffp->readcmd =		    stuffp->present | SINGLE ? READ1X : READ2X;#endif		/* try to get the first sector, iff any ... */		if (stuffp->lastsector >= 0) {			char buf[512];			int ans;			int tries;			stuffp->xa = 0;			stuffp->audio = 0;			for (tries = 6; tries; tries--) {				stuffp->introk = 1;				xtrace(OPENCLOSE, "open() try as %s\n",				       stuffp->xa ? "XA" : "normal");				/* set data mode */				if (-1 == (ans = mcdx_setdatamode(stuffp,								  stuffp->								  xa ?								  MODE2 :								  MODE1,								  1))) {					/* return -EIO; */					stuffp->xa = 0;					break;				}				if ((stuffp->audio = e_audio(ans)))					break;				while (0 ==				       (ans =					mcdx_transfer(stuffp, buf, 0, 1)));				if (ans == 1)					break;				stuffp->xa = !stuffp->xa;			}		}		/* xa disks will be read in raw mode, others not */		if (-1 == mcdx_setdrivemode(stuffp,					    stuffp->xa ? RAW : COOKED,					    1))			return -EIO;		if (stuffp->audio) {			xinfo("open() audio disk found\n");		} else if (stuffp->lastsector >= 0) {			xinfo("open() %s%s disk found\n",			      stuffp->xa ? "XA / " : "",			      stuffp->multi.			      multi ? "Multi Session" : "Single Session");		}	}	stuffp->xxx = 0;	stuffp->users++;	return 0;}static void mcdx_close(struct cdrom_device_info *cdi){	struct s_drive_stuff *stuffp;	xtrace(OPENCLOSE, "close()\n");	stuffp = mcdx_stuffp[MINOR(cdi->dev)];	--stuffp->users;}static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)/*	Return: 1 if media changed since last call to this function			0 otherwise */{	struct s_drive_stuff *stuffp;	xinfo("mcdx_media_changed called for device %s\n",	      kdevname(cdi->dev));	stuffp = mcdx_stuffp[MINOR(cdi->dev)];	mcdx_getstatus(stuffp, 1);	if (stuffp->yyy == 0)		return 0;	stuffp->yyy = 0;	return 1;}#ifndef MODULEstatic int __init mcdx_setup(char *str){	int pi[4];	(void) get_options(str, ARRAY_SIZE(pi), pi);	if (pi[0] > 0)		mcdx_drive_map[0][0] = pi[1];	if (pi[0] > 1)		mcdx_drive_map[0][1] = pi[2];	return 1;}__setup("mcdx=", mcdx_setup);#endif/* DIRTY PART ******************************************************/static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)/* This routine is used for sleeping. * A jifs value <0 means NO sleeping, *              =0 means minimal sleeping (let the kernel *                 run for other processes) *              >0 means at least sleep for that amount. *	May be we could use a simple count loop w/ jumps to itself, but *	I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */{	if (jifs < 0)		return;	xtrace(SLEEP, "*** delay: sleepq\n");	interruptible_sleep_on_timeout(&stuff->sleepq, jifs);	xtrace(SLEEP, "delay awoken\n");	if (signal_pending(current)) {		xtrace(SLEEP, "got signal\n");	}}static void mcdx_intr(int irq, void *dev_id, struct pt_regs *regs){	struct s_drive_stuff *stuffp;	unsigned char b;	stuffp = mcdx_irq_map[irq];	if (stuffp == NULL) {		xwarn("mcdx: no device for intr %d\n", irq);		return;	}#ifdef AK2	if (!stuffp->busy && stuffp->pending)		stuffp->int_err = 1;#endif				/* AK2 */	/* get the interrupt status */	b = inb((unsigned int) stuffp->rreg_status);	stuffp->introk = ~b & MCDX_RBIT_DTEN;	/* NOTE: We only should get interrupts if the data we	 * requested are ready to transfer.	 * But the drive seems to generate ``asynchronous'' interrupts	 * on several error conditions too.  (Despite the err int enable	 * setting during initialisation) */	/* if not ok, read the next byte as the drives status */	if (!stuffp->introk) {		xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);		if (~b & MCDX_RBIT_STEN) {			xinfo("intr() irq %d    status 0x%02x\n",			      irq, inb((unsigned int) stuffp->rreg_data));		} else {			xinfo("intr() irq %d ambiguous hw status\n", irq);		}	} else {		xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);	}	stuffp->busy = 0;	wake_up_interruptible(&stuffp->busyq);}static int mcdx_talk(struct s_drive_stuff *stuffp,	  const unsigned char *cmd, size_t cmdlen,	  void *buffer, size_t size, unsigned int timeout, int tries)/* Send a command to the drive, wait for the result. * returns -1 on timeout, drive status otherwise * If buffer is not zero, the result (length size) is stored there. * If buffer is zero the size should be the number of bytes to read * from the drive.  These bytes are discarded. */{	int st;	char c;	int discard;	/* Somebody wants the data read? */	if ((discard = (buffer == NULL)))		buffer = &c;	while (stuffp->lock) {		xtrace(SLEEP, "*** talk: lockq\n");		interruptible_sleep_on(&stuffp->lockq);		xtrace(SLEEP, "talk: awoken\n");	}	stuffp->lock = 1;	/* An operation other then reading data destroys the	   * data already requested and remembered in stuffp->request, ... */	stuffp->valid = 0;#if MCDX_DEBUG & TALK	{		unsigned char i;		xtrace(TALK,		       "talk() %d / %d tries, res.size %d, command 0x%02x",		       tries, timeout, size, (unsigned char) cmd[0]);		for (i = 1; i < cmdlen; i++)			xtrace(TALK, " 0x%02x", cmd[i]);		xtrace(TALK, "\n");	}#endif	/*  give up if all tries are done (bad) or if the status	 *  st != -1 (good) */	for (st = -1; st == -1 && tries; tries--) {		char *bp = (char *) buffer;		size_t sz = size;		outsb((unsigned int) stuffp->wreg_data, cmd, cmdlen);		xtrace(TALK, "talk() command sent\n");		/* get the status byte */		if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {			xinfo("talk() %02x timed out (status), %d tr%s left\n",			     cmd[0], tries - 1, tries == 2 ? "y" : "ies");			continue;		}		st = *bp;		sz--;		if (!discard)			bp++;		xtrace(TALK, "talk() got status 0x%02x\n", st);		/* command error? */		if (e_cmderr(st)) {			xwarn("command error cmd = %02x %s \n",			      cmd[0], cmdlen > 1 ? "..." : "");			st = -1;			continue;		}

⌨️ 快捷键说明

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