亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? mcd.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 2 頁
字號:
		SET_TIMER(mcd_status, 1);
		return;
	}

	if (st & MST_DSK_CHG)
	{
		mcdDiskChanged = 1;
	}
	
	if ((st & MST_READY) == 0)
	{
		printk("mcd: disk removed\n");
		mcdDiskChanged = 1;		
		end_request(0);
		do_mcd_request();
		return;
	}

	outb(0x50, MCDPORT(0));	/* set mode */
	outb(0x01, MCDPORT(0));	/* mode = cooked data */
	McdTimeout = 100;
	SET_TIMER(mcd_read_cmd, 1);
}


/*
 * Check the result of the set-mode command.  On success, send the
 * read-data command.
 */

static void
mcd_read_cmd()
{
	int st;
	long block;
	struct mcd_Play_msf mcdcmd;

	McdTimeout--;
	st = mcdStatus();

	if (st & MST_DSK_CHG)
	{
		mcdDiskChanged = 1;
	}
	
	if (st == -1)
	{
		if (McdTimeout == 0)
		{
			printk("mcd: set mode timed out\n");
			SET_TIMER(mcd_start, 1);	/* wait a bit, try again */
			return;
		}

		SET_TIMER(mcd_read_cmd, 1);
		return;
	}

	mcd_bn = -1;			/* purge our buffer */
	block = CURRENT -> sector / 4;
	hsg2msf(block, &mcdcmd.start);	/* cvt to msf format */

	mcdcmd.end.min = 0;
	mcdcmd.end.sec = 0;
	mcdcmd.end.frame = 1;

	sendMcdCmd(MCMD_PLAY_READ, &mcdcmd);	/* read command */
	McdTimeout = 200;
	SET_TIMER(mcd_data, 1);
}


/*
 * Check the completion of the read-data command.  On success, read
 * the 2048 bytes of data from the disk into our buffer.
 */

static void
mcd_data()
{
	int i;

	McdTimeout--;
	cli();
	i =inb(MCDPORT(1)) & (MFL_STATUS | MFL_DATA);
	if (i == MFL_DATA)
	{
		printk("mcd: read failed\n");
#ifdef MCD_DEBUG
		printk("got 0xB %02X\n", inb(MCDPORT(0)) & 0xFF);
#endif
		SET_TIMER(mcd_start, 1);
		sti();
		return;
	}
	
	if (i == (MFL_STATUS | MFL_DATA))
	{
		if (McdTimeout == 0)
		{
			printk("mcd: data timeout, retrying\n");
			SET_TIMER(mcd_start, 1);
		}
		
		else
			SET_TIMER(mcd_data, 1);
		
		sti();
		return;
	}

	CLEAR_TIMER;
	READ_DATA(MCDPORT(0), &mcd_buf[0], 2048);
	sti();

	mcd_bn = CURRENT -> sector / 4;
	mcd_transfer();
	end_request(1);
	SET_TIMER(do_mcd_request, 1);
}


/*
 * Open the device special file.  Check that a disk is in.
 */

int
mcd_open(struct inode *ip, struct file *fp)
{
	int st;

	if (mcdPresent == 0)
		return -ENXIO;			/* no hardware */

	st = statusCmd();			/* check drive status */
	if (st == -1)
		return -EIO;			/* drive doesn't respond */

	if ((st & MST_READY) == 0)		/* no disk in drive */
	{
		printk("mcd: no disk in drive\n");
		return -EIO;
	}

	if (updateToc() < 0)
		return -EIO;

	return 0;
}


/*
 * On close, we flush all mcd blocks from the buffer cache.
 */

static void
mcd_release(struct inode * inode, struct file * file)
{
	mcd_bn = -1;
	sync_dev(inode->i_rdev);
	invalidate_buffers(inode -> i_rdev);
}


static struct file_operations mcd_fops = {
	NULL,			/* lseek - default */
	block_read,		/* read - general block-dev read */
	block_write,		/* write - general block-dev write */
	NULL,			/* readdir - bad */
	NULL,			/* select */
	mcd_ioctl,		/* ioctl */
	NULL,			/* mmap */
	mcd_open,		/* open */
	mcd_release		/* release */
};


/*
 * MCD interrupt descriptor
 */

static struct sigaction mcd_sigaction = {
	mcd_interrupt,
	0,
	SA_INTERRUPT,
	NULL
};


/*
 * Test for presence of drive and initialize it.  Called at boot time.
 */

unsigned long
mcd_init(unsigned long mem_start, unsigned long mem_end)
{
	int count;
	unsigned char result[3];

	if (register_blkdev(MAJOR_NR, "mcd", &mcd_fops) != 0)
	{
		printk("mcd: Unable to get major %d for Mitsumi CD-ROM\n",
		       MAJOR_NR);
		return mem_start;
	}

        if (check_region(mcd_port, 4)) {
	  printk("mcd: Init failed, I/O port (%X) already in use\n",
		 mcd_port);
	  return mem_start;
	}
	  
	blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
	read_ahead[MAJOR_NR] = 4;

	/* check for card */

	outb(0, MCDPORT(1));			/* send reset */
	for (count = 0; count < 1000000; count++)
		(void) inb(MCDPORT(1));		/* delay a bit */

	outb(0x40, MCDPORT(0));			/* send get-stat cmd */
	for (count = 0; count < 1000000; count++)
		if (!(inb(MCDPORT(1)) & MFL_STATUS))
			break;

	if (count >= 1000000) {
		printk("mcd: Init failed. No mcd device at 0x%x irq %d\n",
		     mcd_port, mcd_irq);
		return mem_start;
	}
	count = inb(MCDPORT(0));		/* pick up the status */
	
	outb(MCMD_GET_VERSION,MCDPORT(0));
	for(count=0;count<3;count++)
		if(getValue(result+count)) {
			printk("mcd: mitsumi get version failed at 0x%d\n",
			       mcd_port);
			return mem_start;
		}	

	if (result[0] == result[1] && result[1] == result[2])
		return mem_start;

	printk("mcd: Mitsumi version : %02X %c %x\n",
	       result[0],result[1],result[2]);


	mcdVersion=result[2];

	if (mcdVersion >=4)
		outb(4,MCDPORT(2)); 	/* magic happens */

	/* don't get the IRQ until we know for sure the drive is there */

	if (irqaction(MCD_INTR_NR,  &mcd_sigaction))
	{
		printk("mcd: Unable to get IRQ%d for Mitsumi CD-ROM\n", MCD_INTR_NR);
		return mem_start;
	}
	snarf_region(mcd_port, 4);
	mcdPresent = 1;
	printk("mcd: Mitsumi CD-ROM Drive present at addr %x, irq %d\n",
	       mcd_port, mcd_irq);
	return mem_start;
}


static void
hsg2msf(long hsg, struct msf *msf)
{
	hsg += 150;
	msf -> min = hsg / 4500;
	hsg %= 4500;
	msf -> sec = hsg / 75;
	msf -> frame = hsg % 75;

	bin2bcd(&msf -> min);		/* convert to BCD */
	bin2bcd(&msf -> sec);
	bin2bcd(&msf -> frame);
}


static void
bin2bcd(unsigned char *p)
{
	int u, t;

	u = *p % 10;
	t = *p / 10;
	*p = u | (t << 4);
}

static int
bcd2bin(unsigned char bcd)
{
	return (bcd >> 4) * 10 + (bcd & 0xF);
}


/*
 * See if a status is ready from the drive and return it
 * if it is ready.
 */

static int
mcdStatus(void)
{
	int i;
	int st;

	st = inb(MCDPORT(1)) & MFL_STATUS;
	if (!st)
	{
		i = inb(MCDPORT(0)) & 0xFF;
		return i;
	}
	else
		return -1;
}


/*
 * Send a play or read command to the drive
 */

static void
sendMcdCmd(int cmd, struct mcd_Play_msf *params)
{
	outb(cmd, MCDPORT(0));
	outb(params -> start.min, MCDPORT(0));
	outb(params -> start.sec, MCDPORT(0));
	outb(params -> start.frame, MCDPORT(0));
	outb(params -> end.min, MCDPORT(0));
	outb(params -> end.sec, MCDPORT(0));
	outb(params -> end.frame, MCDPORT(0));
}


/*
 * Timer interrupt routine to test for status ready from the drive.
 * (see the next routine)
 */

static void
mcdStatTimer(void)
{
	if (!(inb(MCDPORT(1)) & MFL_STATUS))
	{
		wake_up(&mcd_waitq);
		return;
	}

	McdTimeout--;
	if (McdTimeout <= 0)
	{
		wake_up(&mcd_waitq);
		return;
	}

	SET_TIMER(mcdStatTimer, 1);
}


/*
 * Wait for a status to be returned from the drive.  The actual test
 * (see routine above) is done by the timer interrupt to avoid
 * excessive rescheduling.
 */

static int
getMcdStatus(int timeout)
{
	int st;

	McdTimeout = timeout;
	SET_TIMER(mcdStatTimer, 1);
	sleep_on(&mcd_waitq);
	if (McdTimeout <= 0)
		return -1;

	st = inb(MCDPORT(0)) & 0xFF;
	if (st == 0xFF)
		return -1;

	if ((st & MST_BUSY) == 0 && audioStatus == CDROM_AUDIO_PLAY)
		/* XXX might be an error? look at q-channel? */
		audioStatus = CDROM_AUDIO_COMPLETED;

	if (st & MST_DSK_CHG)
	{
		mcdDiskChanged = 1;
		tocUpToDate = 0;
		audioStatus = CDROM_AUDIO_NO_STATUS;
	}

	return st;
}


/*
 * Read a value from the drive.  Should return quickly, so a busy wait
 * is used to avoid excessive rescheduling.
 */

static int
getValue(unsigned char *result)
{
	int count;
	int s;

	for (count = 0; count < 2000; count++)
		if (!(inb(MCDPORT(1)) & MFL_STATUS))
			break;

	if (count >= 2000)
	{
		printk("mcd: getValue timeout\n");
		return -1;
	}

	s = inb(MCDPORT(0)) & 0xFF;
	*result = (unsigned char) s;
	return 0;
}


/*
 * Read the current Q-channel info.  Also used for reading the
 * table of contents.
 */

int
GetQChannelInfo(struct mcd_Toc *qp)
{
	unsigned char notUsed;
	int retry;

	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
	{
		outb(MCMD_GET_Q_CHANNEL, MCDPORT(0));
		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
			break;
	}

	if (retry >= MCD_RETRY_ATTEMPTS)
		return -1;

	if (getValue(&qp -> ctrl_addr) < 0) return -1;
	if (getValue(&qp -> track) < 0) return -1;
	if (getValue(&qp -> pointIndex) < 0) return -1;
	if (getValue(&qp -> trackTime.min) < 0) return -1;
	if (getValue(&qp -> trackTime.sec) < 0) return -1;
	if (getValue(&qp -> trackTime.frame) < 0) return -1;
	if (getValue(&notUsed) < 0) return -1;
	if (getValue(&qp -> diskTime.min) < 0) return -1;
	if (getValue(&qp -> diskTime.sec) < 0) return -1;
	if (getValue(&qp -> diskTime.frame) < 0) return -1;

	return 0;
}


/*
 * Read the table of contents (TOC) and TOC header if neccessary
 */

static int
updateToc()
{
	if (tocUpToDate)
		return 0;

	if (GetDiskInfo() < 0)
		return -EIO;

	if (GetToc() < 0)
		return -EIO;

	tocUpToDate = 1;
	return 0;
}


/*
 * Read the table of contents header
 */

static int
GetDiskInfo()
{
	int retry;

	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
	{
		outb(MCMD_GET_DISK_INFO, MCDPORT(0));
		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
			break;
	}

	if (retry >= MCD_RETRY_ATTEMPTS)
		return -1;

	if (getValue(&DiskInfo.first) < 0) return -1;
	if (getValue(&DiskInfo.last) < 0) return -1;

	DiskInfo.first = bcd2bin(DiskInfo.first);
	DiskInfo.last = bcd2bin(DiskInfo.last);

	if (getValue(&DiskInfo.diskLength.min) < 0) return -1;
	if (getValue(&DiskInfo.diskLength.sec) < 0) return -1;
	if (getValue(&DiskInfo.diskLength.frame) < 0) return -1;
	if (getValue(&DiskInfo.firstTrack.min) < 0) return -1;
	if (getValue(&DiskInfo.firstTrack.sec) < 0) return -1;
	if (getValue(&DiskInfo.firstTrack.frame) < 0) return -1;

#ifdef MCD_DEBUG
printk("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
	DiskInfo.first,
	DiskInfo.last,
	DiskInfo.diskLength.min,
	DiskInfo.diskLength.sec,
	DiskInfo.diskLength.frame,
	DiskInfo.firstTrack.min,
	DiskInfo.firstTrack.sec,
	DiskInfo.firstTrack.frame);
#endif

	return 0;
}


/*
 * Read the table of contents (TOC)
 */

static int
GetToc()
{
	int i, px;
	int limit;
	int retry;
	struct mcd_Toc qInfo;

	for (i = 0; i < MAX_TRACKS; i++)
		Toc[i].pointIndex = 0;

	i = DiskInfo.last + 3;

	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
	{
		outb(MCMD_STOP, MCDPORT(0));
		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
			break;
	}

	if (retry >= MCD_RETRY_ATTEMPTS)
		return -1;

	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
	{
		outb(MCMD_SET_MODE, MCDPORT(0));
		outb(0x05, MCDPORT(0));			/* mode: toc */
		if (getMcdStatus(MCD_STATUS_DELAY) != -1)
			break;
	}

	if (retry >= MCD_RETRY_ATTEMPTS)
		return -1;

	for (limit = 300; limit > 0; limit--)
	{
		if (GetQChannelInfo(&qInfo) < 0)
			break;

		px = bcd2bin(qInfo.pointIndex);
		if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
			if (Toc[px].pointIndex == 0)
			{
				Toc[px] = qInfo;
				i--;
			}

		if (i <= 0)
			break;
	}

	Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;

	for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
	{
                outb(MCMD_SET_MODE, MCDPORT(0));
                outb(0x01, MCDPORT(0));
                if (getMcdStatus(MCD_STATUS_DELAY) != -1)
                        break;
	}

#ifdef MCD_DEBUG
for (i = 1; i <= DiskInfo.last; i++)
printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
for (i = 100; i < 103; i++)
printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
#endif

	return limit > 0 ? 0 : -1;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲欧美日韩国产综合在线| 天堂久久一区二区三区| 欧美一级高清大全免费观看| 91黄色激情网站| 精品视频123区在线观看| 日韩一级大片在线| 中文字幕欧美日本乱码一线二线 | 国产精品久久久久久久久免费丝袜| 国产欧美日韩三区| 亚洲精品成人a在线观看| 美国三级日本三级久久99| 狠狠色丁香婷婷综合| 成人精品视频.| 成人av手机在线观看| 91福利视频网站| 精品乱人伦一区二区三区| 中文字幕一区日韩精品欧美| 蜜臀av一区二区| 成人福利视频网站| 精品欧美一区二区久久| 亚洲精品国产a| 韩国一区二区三区| 欧美视频一区在线观看| 日本一区二区久久| 日本欧美肥老太交大片| 色先锋久久av资源部| 久久久久国产精品人| 亚洲成av人片www| 99久久精品免费看国产免费软件| 日韩欧美国产一区二区三区| 有坂深雪av一区二区精品| 国产高清不卡二三区| 欧美一区二区高清| 亚洲欧美另类小说视频| 成人深夜在线观看| 91精品国产综合久久久久久久| 国产精品乱码一区二区三区软件| 亚洲自拍另类综合| 91在线观看地址| 国产欧美一区二区三区网站| 久久国产剧场电影| 欧美日韩一区二区在线观看 | 毛片不卡一区二区| 欧美在线观看一二区| 亚洲欧洲日产国码二区| 成人黄色大片在线观看| 久久午夜国产精品| 极品美女销魂一区二区三区| 337p亚洲精品色噜噜噜| 五月天激情小说综合| 欧美午夜影院一区| 一区二区三区在线免费观看| 99精品国产热久久91蜜凸| 国产欧美日韩亚州综合| 免费成人在线播放| 日韩一区二区影院| 美国三级日本三级久久99| 日韩美女视频在线| 久久成人免费电影| 精品1区2区在线观看| 国产精品一区一区三区| 久久久一区二区三区捆绑**| 国产传媒日韩欧美成人| 国产欧美一区二区精品久导航 | 伊人婷婷欧美激情| 91福利国产精品| 亚洲视频一区二区在线| 欧美性色黄大片手机版| 日日夜夜免费精品视频| 91精品久久久久久久91蜜桃| 精品中文字幕一区二区小辣椒| 欧美一区二区三区视频在线观看| 免费成人av在线| 久久久亚洲欧洲日产国码αv| 国产成人亚洲精品狼色在线 | 欧美性猛交一区二区三区精品 | 石原莉奈在线亚洲三区| 日韩一区二区三区在线视频| 国产真实乱对白精彩久久| 国产欧美日韩三级| 在线观看国产一区二区| 捆绑调教美女网站视频一区| 精品福利视频一区二区三区| www.亚洲在线| 五月天亚洲精品| 国产日韩精品一区| 欧美日韩一区二区欧美激情| 亚洲国产成人va在线观看天堂| 欧美一区二区三区白人| 成人精品小蝌蚪| 亚洲成人午夜电影| 久久久亚洲精品石原莉奈| 色综合久久久久| 精品一二三四在线| 一区二区三区欧美日| 欧美v国产在线一区二区三区| 成人综合日日夜夜| 天堂一区二区在线免费观看| 欧美国产乱子伦| 欧美剧情片在线观看| 成人国产视频在线观看| 日韩av中文字幕一区二区三区| 欧美激情综合在线| 白白色 亚洲乱淫| 日本美女一区二区三区| 中文字幕欧美日本乱码一线二线| 欧美丝袜自拍制服另类| 国产aⅴ精品一区二区三区色成熟| 亚洲一级二级三级在线免费观看| 日本一区二区三区高清不卡| 9191久久久久久久久久久| 成人av在线资源网站| 精品一区二区三区影院在线午夜 | 国产电影精品久久禁18| 午夜欧美在线一二页| 一色屋精品亚洲香蕉网站| 精品国产伦理网| 欧美最新大片在线看| 丰满亚洲少妇av| 精品一区二区综合| 丝袜亚洲另类欧美综合| 一区二区三区蜜桃| 久久综合色之久久综合| 欧美午夜在线观看| 成人短视频下载| 国产福利一区二区三区视频在线 | 午夜视频在线观看一区二区 | 国产欧美日韩视频在线观看| 日韩三级电影网址| 欧美视频一区二区三区在线观看 | 亚洲男人天堂av网| 国产精品短视频| 国产精品色哟哟| 国产精品久久久一本精品 | 日韩成人精品在线| 亚洲国产综合人成综合网站| 伊人一区二区三区| 一区二区三区小说| 国产欧美视频一区二区三区| 日韩三级免费观看| 欧美日韩亚洲综合在线 欧美亚洲特黄一级| 成人性色生活片免费看爆迷你毛片| 国产黑丝在线一区二区三区| 国产成人av电影在线观看| 国产一区二区视频在线| 国产精品一区二区免费不卡| 国产乱人伦偷精品视频不卡| 国产69精品久久99不卡| 国产黑丝在线一区二区三区| 激情偷乱视频一区二区三区| 亚洲电影第三页| 亚洲福利视频三区| 七七婷婷婷婷精品国产| 韩国av一区二区三区四区| 国产精品一区三区| 91视频www| 精品视频1区2区| 日韩欧美国产不卡| 久久久噜噜噜久噜久久综合| 亚洲国产高清不卡| 一区二区成人在线视频| 亚欧色一区w666天堂| 久88久久88久久久| 久久精品国产澳门| 国产精品系列在线观看| 成人h动漫精品一区二区| 在线影院国内精品| 欧美成人三级电影在线| 综合电影一区二区三区 | 91影院在线免费观看| 欧美一级日韩免费不卡| 亚洲男同性恋视频| 福利一区二区在线观看| 日韩久久久久久| 亚洲国产成人va在线观看天堂| 成人精品鲁一区一区二区| 日韩一级二级三级| 亚洲国产综合91精品麻豆| 97精品视频在线观看自产线路二| 精品奇米国产一区二区三区| 亚洲成av人片www| 99vv1com这只有精品| 久久久青草青青国产亚洲免观| 日韩国产精品大片| 欧美性大战久久久| 亚洲精品欧美激情| 99久久99久久精品国产片果冻 | 3751色影院一区二区三区| 亚洲永久免费av| 99天天综合性| 国产精品理论片在线观看| 国产aⅴ综合色| 久久精品一区二区三区不卡牛牛| 久久精工是国产品牌吗| 日韩一区二区在线观看| 丝袜美腿亚洲一区二区图片| 欧洲精品一区二区| 亚洲自拍偷拍麻豆| 欧美日精品一区视频| 亚洲成人精品一区|