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

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

?? floppy.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 3 頁
字號:
	clear_dma_ff(FLOPPY_DMA);
	set_dma_mode(FLOPPY_DMA, (command == FD_READ)? DMA_MODE_READ : DMA_MODE_WRITE);
	set_dma_addr(FLOPPY_DMA, addr);
	set_dma_count(FLOPPY_DMA, count);
	enable_dma(FLOPPY_DMA);
	sti();
}

static void output_byte(char byte)
{
	int counter;
	unsigned char status;

	if (reset)
		return;
	for(counter = 0 ; counter < 10000 ; counter++) {
		status = inb_p(FD_STATUS) & (STATUS_READY | STATUS_DIR);
		if (status == STATUS_READY) {
			outb(byte,FD_DATA);
			return;
		}
	}
	current_track = NO_TRACK;
	reset = 1;
	printk("Unable to send byte to FDC\n");
}

static int result(void)
{
	int i = 0, counter, status;

	if (reset)
		return -1;
	for (counter = 0 ; counter < 10000 ; counter++) {
		status = inb_p(FD_STATUS)&(STATUS_DIR|STATUS_READY|STATUS_BUSY);
		if (status == STATUS_READY) {
			return i;
		}
		if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
			if (i >= MAX_REPLIES) {
				printk("floppy_stat reply overrun\n");
				break;
			}
			reply_buffer[i++] = inb_p(FD_DATA);
		}
	}
	reset = 1;
	current_track = NO_TRACK;
	printk("Getstatus times out\n");
	return -1;
}

static void bad_flp_intr(void)
{
	int errors;

	current_track = NO_TRACK;
	if (format_status == FORMAT_BUSY)
		errors = ++format_errors;
	else if (!CURRENT) {
		printk(DEVICE_NAME ": no current request\n");
		reset = recalibrate = 1;
		return;
	} else
		errors = ++CURRENT->errors;
	if (errors > MAX_ERRORS) {
		request_done(0);
	}
	if (errors > MAX_ERRORS/2)
		reset = 1;
	else
		recalibrate = 1;
}	


/* Set perpendicular mode as required, based on data rate, if supported.
 * 82077 Untested! 1Mbps data rate only possible with 82077-1.
 * TODO: increase MAX_BUFFER_SECTORS, add floppy_type entries.
 */
static inline void perpendicular_mode(unsigned char rate)
{
	if (fdc_version == FDC_TYPE_82077) {
		output_byte(FD_PERPENDICULAR);
		if (rate & 0x40) {
			unsigned char r = rate & 0x03;
			if (r == 0)
				output_byte(2);	/* perpendicular, 500 kbps */
			else if (r == 3)
				output_byte(3);	/* perpendicular, 1Mbps */
			else {
				printk(DEVICE_NAME ": Invalid data rate for perpendicular mode!\n");
				reset = 1;
			}
		} else
			output_byte(0);		/* conventional mode */
	} else {
		if (rate & 0x40) {
			printk(DEVICE_NAME ": perpendicular mode not supported by this FDC.\n");
			reset = 1;
		}
	}
} /* perpendicular_mode */


/*
 * This has only been tested for the case fdc_version == FDC_TYPE_STD.
 * In case you have a 82077 and want to test it, you'll have to compile
 * with `FDC_FIFO_UNTESTED' defined. You may also want to add support for
 * recognizing drives with vertical recording support.
 */
static void configure_fdc_mode(void)
{
	if (need_configure && (fdc_version == FDC_TYPE_82077)) {
		/* Enhanced version with FIFO & vertical recording. */
		output_byte(FD_CONFIGURE);
		output_byte(0);
		output_byte(0x1A);	/* FIFO on, polling off, 10 byte threshold */
		output_byte(0);		/* precompensation from track 0 upwards */
		need_configure = 0;
		printk(DEVICE_NAME ": FIFO enabled\n");
	}
	if (cur_spec1 != floppy->spec1) {
		cur_spec1 = floppy->spec1;
		output_byte(FD_SPECIFY);
		output_byte(cur_spec1);		/* hut etc */
		output_byte(6);			/* Head load time =6ms, DMA */
	}
	if (cur_rate != floppy->rate) {
		/* use bit 6 of floppy->rate to indicate perpendicular mode */
		perpendicular_mode(floppy->rate);
		outb_p((cur_rate = (floppy->rate)) & ~0x40, FD_DCR);
	}
} /* configure_fdc_mode */


static void tell_sector(int nr)
{
	if (nr!=7) {
		printk(" -- FDC reply errror");
		reset = 1;
	} else
		printk(": track %d, head %d, sector %d", reply_buffer[3],
			reply_buffer[4], reply_buffer[5]);
} /* tell_sector */


/*
 * Ok, this interrupt is called after a DMA read/write has succeeded
 * or failed, so we check the results, and copy any buffers.
 * hhb: Added better error reporting.
 */
static void rw_interrupt(void)
{
	char * buffer_area;
	int nr;
	char bad;

	nr = result();
	/* check IC to find cause of interrupt */
	switch ((ST0 & ST0_INTR)>>6) {
		case 1:	/* error occured during command execution */
			bad = 1;
			if (ST1 & ST1_WP) {
				printk(DEVICE_NAME ": Drive %d is write protected\n", current_drive);
				request_done(0);
				bad = 0;
			} else if (ST1 & ST1_OR) {
				if (ftd_msg[ST0 & ST0_DS])
					printk(DEVICE_NAME ": Over/Underrun - retrying\n");
				/* could continue from where we stopped, but ... */
				bad = 0;
			} else if (CURRENT_ERRORS > min_report_error_cnt[ST0 & ST0_DS]) {
				printk(DEVICE_NAME " %d: ", ST0 & ST0_DS);
				if (ST0 & ST0_ECE) {
					printk("Recalibrate failed!");
				} else if (ST2 & ST2_CRC) {
					printk("data CRC error");
					tell_sector(nr);
				} else if (ST1 & ST1_CRC) {
					printk("CRC error");
					tell_sector(nr);
				} else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
					if (!probing) {
						printk("sector not found");
						tell_sector(nr);
					} else
						printk("probe failed...");
				} else if (ST2 & ST2_WC) {	/* seek error */
					printk("wrong cylinder");
				} else if (ST2 & ST2_BC) {	/* cylinder marked as bad */
					printk("bad cylinder");
				} else {
					printk("unknown error. ST[0..3] are: 0x%x 0x%x 0x%x 0x%x\n", ST0, ST1, ST2, ST3);
				}
				printk("\n");

			}
			if (bad)
				bad_flp_intr();
			redo_fd_request();
			return;
		case 2: /* invalid command given */
			printk(DEVICE_NAME ": Invalid FDC command given!\n");
			request_done(0);
			return;
		case 3:
			printk(DEVICE_NAME ": Abnormal termination caused by polling\n");
			bad_flp_intr();
			redo_fd_request();
			return;
		default: /* (0) Normal command termination */
			break;
	}

	if (probing) {
		int drive = MINOR(CURRENT->dev);

		if (ftd_msg[drive])
			printk("Auto-detected floppy type %s in fd%d\n",
			    floppy->name,drive);
		current_type[drive] = floppy;
		floppy_sizes[drive] = floppy->size >> 1;
		probing = 0;
	}
	if (read_track) {
		buffer_track = seek_track;
		buffer_drive = current_drive;
		buffer_area = floppy_track_buffer +
			((sector-1 + head*floppy->sect)<<9);
		copy_buffer(buffer_area,CURRENT->buffer);
	} else if (command == FD_READ &&
		(unsigned long)(CURRENT->buffer) >= LAST_DMA_ADDR)
		copy_buffer(tmp_floppy_area,CURRENT->buffer);
	request_done(1);
	redo_fd_request();
}

/*
 * We try to read tracks, but if we get too many errors, we
 * go back to reading just one sector at a time.
 *
 * This means we should be able to read a sector even if there
 * are other bad sectors on this track.
 */
inline void setup_rw_floppy(void)
{
	setup_DMA();
	do_floppy = rw_interrupt;
	output_byte(command);
	if (command != FD_FORMAT) {
		if (read_track) {
			output_byte(current_drive);
			output_byte(track);
			output_byte(0);
			output_byte(1);
		} else {
			output_byte(head<<2 | current_drive);
			output_byte(track);
			output_byte(head);
			output_byte(sector);
		}
		output_byte(2);		/* sector size = 512 */
		output_byte(floppy->sect);
		output_byte(floppy->gap);
		output_byte(0xFF);	/* sector size (0xff when n!=0 ?) */
	} else {
		output_byte(head<<2 | current_drive);
		output_byte(2);
		output_byte(floppy->sect);
		output_byte(floppy->fmt_gap);
		output_byte(FD_FILL_BYTE);
	}
	if (reset)
		redo_fd_request();
}

/*
 * This is the routine called after every seek (or recalibrate) interrupt
 * from the floppy controller. Note that the "unexpected interrupt" routine
 * also does a recalibrate, but doesn't come here.
 */
static void seek_interrupt(void)
{
/* sense drive status */
	output_byte(FD_SENSEI);
	if (result() != 2 || (ST0 & 0xF8) != 0x20 || ST1 != seek_track) {
		printk(DEVICE_NAME ": seek failed\n");
		recalibrate = 1;
		bad_flp_intr();
		redo_fd_request();
		return;
	}
	current_track = ST1;
	setup_rw_floppy();
}


/*
 * This routine is called when everything should be correctly set up
 * for the transfer (ie floppy motor is on and the correct floppy is
 * selected).
 */
static void transfer(void)
{
	read_track = (command == FD_READ) && (CURRENT_ERRORS < 4) &&
	    (floppy->sect <= MAX_BUFFER_SECTORS);

	configure_fdc_mode();

	if (reset) {
		redo_fd_request();
		return;
	}
	if (!seek) {
		setup_rw_floppy();
		return;
	}

	do_floppy = seek_interrupt;
	output_byte(FD_SEEK);
	if (read_track)
		output_byte(current_drive);
	else
		output_byte((head<<2) | current_drive);
	output_byte(seek_track);
	if (reset)
		redo_fd_request();
}

/*
 * Special case - used after a unexpected interrupt (or reset)
 */

static void recalibrate_floppy(void);

static void recal_interrupt(void)
{
	output_byte(FD_SENSEI);
	current_track = NO_TRACK;
	if (result()!=2 || (ST0 & 0xE0) == 0x60)
		reset = 1;
/* Recalibrate until track 0 is reached. Might help on some errors. */
	if ((ST0 & 0x10) == 0x10)
		recalibrate_floppy();	/* FIXME: should limit nr of recalibrates */
	else
		redo_fd_request();
}

static void unexpected_floppy_interrupt(void)
{
	current_track = NO_TRACK;
	output_byte(FD_SENSEI);
	printk(DEVICE_NAME ": unexpected interrupt\n");
	if (result()!=2 || (ST0 & 0xE0) == 0x60)
		reset = 1;
	else
		recalibrate = 1;
}

static void recalibrate_floppy(void)
{
	recalibrate = 0;
	current_track = 0;
	do_floppy = recal_interrupt;
	output_byte(FD_RECALIBRATE);
	output_byte(head<<2 | current_drive);
	if (reset)
		redo_fd_request();
}

/*
 * Must do 4 FD_SENSEIs after reset because of ``drive polling''.
 */
static void reset_interrupt(void)
{
	short i;

	for (i=0; i<4; i++) {
		output_byte(FD_SENSEI);
		(void) result();
	}
	output_byte(FD_SPECIFY);
	output_byte(cur_spec1);		/* hut etc */
	output_byte(6);			/* Head load time =6ms, DMA */
	configure_fdc_mode();		/* reprogram fdc */
	if (initial_reset_flag) {
		initial_reset_flag = 0;
		recalibrate = 1;
		reset = 0;
		return;
	}
	if (!recover)
		redo_fd_request();
	else {
		recalibrate_floppy();
		recover = 0;
	}
}

/*
 * reset is done by pulling bit 2 of DOR low for a while.
 */
static void reset_floppy(void)
{
	int i;

	do_floppy = reset_interrupt;
	reset = 0;
	current_track = NO_TRACK;
	cur_spec1 = -1;
	cur_rate = -1;
	recalibrate = 1;
	need_configure = 1;
	if (!initial_reset_flag)
		printk("Reset-floppy called\n");
	cli();
	outb_p(current_DOR & ~0x04, FD_DOR);
	for (i=0 ; i<1000 ; i++)
		__asm__("nop");
	outb(current_DOR, FD_DOR);
	sti();
}

static void floppy_shutdown(void)
{
	cli();
	do_floppy = NULL;
	request_done(0);
	recover = 1;
	reset_floppy();
	sti();
	redo_fd_request();
}

static void shake_done(void)
{
	current_track = NO_TRACK;
	if (inb(FD_DIR) & 0x80)
		request_done(0);
	redo_fd_request();
}

static int retry_recal(void (*proc)(void))
{
	output_byte(FD_SENSEI);
	if (result() == 2 && (ST0 & 0x10) != 0x10) return 0;
	do_floppy = proc;
	output_byte(FD_RECALIBRATE);
	output_byte(head<<2 | current_drive);
	return 1;
}

static void shake_zero(void)
{
	if (!retry_recal(shake_zero)) shake_done();
}

static void shake_one(void)
{
	if (retry_recal(shake_one)) return;
	do_floppy = shake_done;
	output_byte(FD_SEEK);
	output_byte(head << 2 | current_drive);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
午夜成人免费电影| 激情综合网激情| 久久久亚洲午夜电影| 在线观看日韩国产| 国产自产2019最新不卡| 午夜电影一区二区三区| 一区二区中文视频| 国产亚洲欧美日韩日本| 91精品国产欧美日韩| 91丨九色丨黑人外教| 国产精品一级在线| 午夜精品久久久久久久 | 色综合激情久久| 国产精品一级二级三级| 蜜臀久久99精品久久久久宅男| 亚洲免费资源在线播放| 国产精品久久久久影视| 久久久久9999亚洲精品| 精品国产乱码久久久久久图片| 国产三级精品三级在线专区| 欧美精品久久一区| 欧美性一级生活| 91麻豆视频网站| 91丨porny丨国产入口| 国产一区二区三区四区五区入口| 日本一区中文字幕| 亚洲高清在线视频| 午夜视频一区二区| 亚洲在线视频一区| 亚洲一区二区四区蜜桃| 亚洲男帅同性gay1069| 最新国产精品久久精品| 中文字幕欧美激情| 国产精品美女久久久久久久| 国产视频911| 国产日韩欧美综合一区| 国产欧美一区二区三区在线看蜜臀| 欧美成人精品1314www| 精品国产青草久久久久福利| 精品国产免费人成在线观看| 日韩精品一区二区在线| 精品久久久久久久久久久久久久久久久 | 中文字幕在线观看不卡视频| 国产亚洲va综合人人澡精品| 国产网站一区二区| 中文字幕免费一区| 亚洲丝袜自拍清纯另类| 亚洲欧美综合网| 亚洲你懂的在线视频| 亚洲一区二区精品视频| 五月天婷婷综合| 蜜臀久久99精品久久久久久9| 蜜臀a∨国产成人精品| 国内偷窥港台综合视频在线播放| 国产一区二区三区免费播放| 国产精品66部| 成人精品一区二区三区中文字幕| 成人三级伦理片| 日本高清不卡aⅴ免费网站| 欧美日韩一区高清| 日韩午夜精品电影| 国产欧美日韩另类一区| 一区在线播放视频| 偷偷要91色婷婷| 国产麻豆精品视频| 日本丶国产丶欧美色综合| 欧美高清dvd| 国产校园另类小说区| 亚洲男同性视频| 美女视频黄免费的久久 | 免费成人在线影院| 福利视频网站一区二区三区| 色婷婷激情综合| 日韩精品一区二区三区四区视频| 国产精品国产三级国产| 午夜伦欧美伦电影理论片| 国产乱人伦偷精品视频不卡| 一本久久综合亚洲鲁鲁五月天| 在线不卡中文字幕| 中文字幕在线不卡一区| 免费欧美在线视频| 不卡视频一二三| 日韩一级高清毛片| 亚洲欧洲99久久| 久国产精品韩国三级视频| 99久久99久久综合| 日韩欧美国产一区在线观看| 国产精品欧美综合在线| 日韩精品久久理论片| 成人高清视频在线| 日韩欧美www| 一区二区久久久| 国产成人自拍网| 91麻豆精品91久久久久久清纯| 国产精品欧美极品| 麻豆国产精品官网| 欧美视频一区二| 中文字幕不卡的av| 九九在线精品视频| 欧美日韩国产免费一区二区| 国产精品网站在线播放| 青青草精品视频| 在线日韩国产精品| 国产欧美精品一区二区色综合| 免费人成在线不卡| 欧美日本不卡视频| 一区二区三区在线视频观看58| 国产剧情av麻豆香蕉精品| 欧美精品黑人性xxxx| 亚洲免费观看高清| 99久久精品国产网站| 久久久综合九色合综国产精品| 爽爽淫人综合网网站| 91久久人澡人人添人人爽欧美| 国产精品久久久久天堂| 国内精品国产成人| 日韩欧美一二区| 日韩极品在线观看| 精品视频一区三区九区| 亚洲最大的成人av| 99久久久久免费精品国产| 欧美激情一区二区三区全黄| 久久精品99久久久| 欧美一级二级三级乱码| 亚洲电影在线播放| 欧美日韩精品一二三区| 亚洲一区在线观看免费观看电影高清 | 在线一区二区视频| 亚洲免费av高清| 色综合久久天天| 自拍偷拍欧美精品| 99免费精品视频| 中文字幕亚洲在| 91一区二区在线观看| 国产精品成人一区二区艾草| 成人av电影在线| 国产精品久久久久久户外露出 | 精品一区二区三区免费毛片爱 | 制服丝袜在线91| 日韩精品一卡二卡三卡四卡无卡| 欧美精品在线观看播放| 丝袜亚洲另类欧美| 日韩一区二区精品| 韩国欧美国产一区| 欧美激情一区二区三区不卡| 国产999精品久久久久久绿帽| 国产欧美日韩精品在线| 成人一道本在线| 亚洲欧美在线观看| 欧美影视一区在线| 日韩电影在线观看网站| 久久新电视剧免费观看| 成人午夜av电影| 亚洲一区二区美女| 日韩欧美一卡二卡| 高清不卡一二三区| 夜夜精品视频一区二区| 91麻豆精品久久久久蜜臀| 久久99国产乱子伦精品免费| 久久久久亚洲综合| 色哟哟一区二区| 美女一区二区三区| 国产午夜亚洲精品羞羞网站| 91在线观看成人| 青椒成人免费视频| 久久精品亚洲国产奇米99| 91玉足脚交白嫩脚丫在线播放| 午夜精品久久久久久久99水蜜桃| 日韩精品中文字幕在线不卡尤物| 国产91对白在线观看九色| 一区二区三区成人在线视频| 日韩免费一区二区| 成人av在线资源网站| 五月天中文字幕一区二区| 精品国产制服丝袜高跟| 97精品视频在线观看自产线路二| 天天色天天爱天天射综合| 久久久综合视频| 欧美色偷偷大香| 国产一区二区在线观看视频| 一区二区视频在线| 日韩免费福利电影在线观看| 99精品1区2区| 狠狠色丁香久久婷婷综合丁香| 国产精品第五页| 欧美成人高清电影在线| 色婷婷综合五月| 国产精品一区二区黑丝| 丝袜诱惑亚洲看片| 国产精品国模大尺度视频| 日韩欧美成人午夜| 在线免费一区三区| 韩国理伦片一区二区三区在线播放| 一区二区在线观看视频| 国产丝袜在线精品| 日韩限制级电影在线观看| 91国在线观看| 菠萝蜜视频在线观看一区| 捆绑调教一区二区三区| 一区二区理论电影在线观看|