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

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

?? pdc4030.c

?? ep9315平臺下硬盤驅動的源碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
	if (!sectors_avail)		goto read_again;read_next:	rq = HWGROUP(drive)->rq;	nsect = rq->current_nr_sectors;	if (nsect > sectors_avail)		nsect = sectors_avail;	sectors_avail -= nsect;#ifdef CONFIG_IDE_TASKFILE_IO	to = ide_map_buffer(rq, &flags);	HWIF(drive)->ata_input_data(drive, to, nsect * SECTOR_WORDS);#else /* !CONFIG_IDE_TASKFILE_IO */	HWIF(drive)->ata_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);#endif /* CONFIG_IDE_TASKFILE_IO */#ifdef DEBUG_READ	printk(KERN_DEBUG "%s:  promise_read: sectors(%ld-%ld), "	       "buf=0x%08lx, rem=%ld\n", drive->name, rq->sector,	       rq->sector+nsect-1,#ifdef CONFIG_IDE_TASKFILE_IO		(unsigned long) to,#else /* !CONFIG_IDE_TASKFILE_IO */		(unsigned long) rq->buffer,#endif /* CONFIG_IDE_TASKFILE_IO */	       rq->nr_sectors-nsect);#endif /* DEBUG_READ */#ifdef CONFIG_IDE_TASKFILE_IO	ide_unmap_buffer(to, &flags);#else /* !CONFIG_IDE_TASKFILE_IO */	rq->buffer += nsect<<9;#endif /* CONFIG_IDE_TASKFILE_IO */	rq->sector += nsect;	rq->errors = 0;	rq->nr_sectors -= nsect;	total_remaining = rq->nr_sectors;	if ((rq->current_nr_sectors -= nsect) <= 0) {		DRIVER(drive)->end_request(drive, 1);	}/* * Now the data has been read in, do the following: *  * if there are still sectors left in the request,  *   if we know there are still sectors available from the interface, *     go back and read the next bit of the request. *   else if DRQ is asserted, there are more sectors available, so *     go back and find out how many, then read them in. *   else if BUSY is asserted, we are going to get an interrupt, so *     set the handler for the interrupt and just return */	if (total_remaining > 0) {		if (sectors_avail)			goto read_next;		status.all = HWIF(drive)->INB(IDE_STATUS_REG);		if (status.b.drq)			goto read_again;		if (status.b.bsy) {			if (HWGROUP(drive)->handler != NULL)				BUG();			ide_set_handler(drive,					&promise_read_intr,					WAIT_CMD,					NULL);#ifdef DEBUG_READ			printk(KERN_DEBUG "%s: promise_read: waiting for"			       "interrupt\n", drive->name);#endif /* DEBUG_READ */			return ide_started;		}		printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left "		       "!DRQ !BUSY\n", drive->name);		return DRIVER(drive)->error(drive,				"promise read intr", status.all);	}	return ide_stopped;}/* * promise_complete_pollfunc() * This is the polling function for waiting (nicely!) until drive stops * being busy. It is invoked at the end of a write, after the previous poll * has finished. * * Once not busy, the end request is called. */static ide_startstop_t promise_complete_pollfunc(ide_drive_t *drive){	ide_hwgroup_t *hwgroup = HWGROUP(drive);	struct request *rq = hwgroup->rq;	int i;	if ((HWIF(drive)->INB(IDE_STATUS_REG)) & BUSY_STAT) {		if (time_before(jiffies, hwgroup->poll_timeout)) {			if (hwgroup->handler != NULL)				BUG();			ide_set_handler(drive,					&promise_complete_pollfunc,					HZ/100,					NULL);			return ide_started; /* continue polling... */		}		hwgroup->poll_timeout = 0;		printk(KERN_ERR "%s: completion timeout - still busy!\n",		       drive->name);		return DRIVER(drive)->error(drive, "busy timeout",				HWIF(drive)->INB(IDE_STATUS_REG));	}	hwgroup->poll_timeout = 0;#ifdef DEBUG_WRITE	printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name);#endif /* DEBUG_WRITE */	for (i = rq->nr_sectors; i > 0; ) {		i -= rq->current_nr_sectors;		DRIVER(drive)->end_request(drive, 1);	}	return ide_stopped;}/* * promise_multwrite() transfers a block of up to mcount sectors of data * to a drive as part of a disk multiple-sector write operation. * * Returns 0 on success. * * Note that we may be called from two contexts - the do_rw_disk context * and IRQ context. The IRQ can happen any time after we've output the * full "mcount" number of sectors, so we must make sure we update the * state _before_ we output the final part of the data! */int promise_multwrite (ide_drive_t *drive, unsigned int mcount){	ide_hwgroup_t *hwgroup	= HWGROUP(drive);	struct request *rq	= &hwgroup->wrq;	do {		char *buffer;		int nsect = rq->current_nr_sectors;#ifdef CONFIG_IDE_TASKFILE_IO		unsigned long flags;#endif /* CONFIG_IDE_TASKFILE_IO */		if (nsect > mcount)			nsect = mcount;		mcount -= nsect;#ifdef CONFIG_IDE_TASKFILE_IO		buffer = ide_map_buffer(rq, &flags);		rq->sector += nsect;#else /* !CONFIG_IDE_TASKFILE_IO */		buffer = rq->buffer;		rq->sector += nsect;		rq->buffer += nsect << 9;#endif /* CONFIG_IDE_TASKFILE_IO */		rq->nr_sectors -= nsect;		rq->current_nr_sectors -= nsect;		/* Do we move to the next bh after this? */		if (!rq->current_nr_sectors) {			struct buffer_head *bh = rq->bh->b_reqnext;			/* end early early we ran out of requests */			if (!bh) {				mcount = 0;			} else {				rq->bh			= bh;				rq->current_nr_sectors	= bh->b_size >> 9;				rq->hard_cur_sectors = rq->current_nr_sectors;				rq->buffer		= bh->b_data;			}		}		/*		 * Ok, we're all setup for the interrupt		 * re-entering us on the last transfer.		 */		taskfile_output_data(drive, buffer, nsect<<7);#ifdef CONFIG_IDE_TASKFILE_IO		ide_unmap_buffer(buffer, &flags);#endif /* CONFIG_IDE_TASKFILE_IO */	} while (mcount);	return 0;}/* * promise_write_pollfunc() is the handler for disk write completion polling. */static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive){	ide_hwgroup_t *hwgroup = HWGROUP(drive);	if (HWIF(drive)->INB(IDE_NSECTOR_REG) != 0) {		if (time_before(jiffies, hwgroup->poll_timeout)) {			if (hwgroup->handler != NULL)				BUG();			ide_set_handler(drive,					&promise_write_pollfunc,					HZ/100,					NULL);			return ide_started; /* continue polling... */		}		hwgroup->poll_timeout = 0;		printk(KERN_ERR "%s: write timed-out!\n",drive->name);		return DRIVER(drive)->error(drive, "write timeout",				HWIF(drive)->INB(IDE_STATUS_REG));	}	/*	 * Now write out last 4 sectors and poll for not BUSY	 */	promise_multwrite(drive, 4);	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;	if (hwgroup->handler != NULL)		BUG();	ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);#ifdef DEBUG_WRITE	printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",		drive->name, HWIF(drive)->INB(IDE_STATUS_REG));#endif /* DEBUG_WRITE */	return ide_started;}/* * promise_write() transfers a block of one or more sectors of data to a * drive as part of a disk write operation. All but 4 sectors are transferred * in the first attempt, then the interface is polled (nicely!) for completion * before the final 4 sectors are transferred. There is no interrupt generated * on writes (at least on the DC4030VL-2), we just have to poll for NOT BUSY. */static ide_startstop_t promise_write (ide_drive_t *drive){	ide_hwgroup_t *hwgroup = HWGROUP(drive);	struct request *rq = &hwgroup->wrq;#ifdef DEBUG_WRITE	printk(KERN_DEBUG "%s: promise_write: sectors(%ld-%ld), "	       "buffer=%p\n", drive->name, rq->sector,	       rq->sector + rq->nr_sectors - 1, rq->buffer);#endif /* DEBUG_WRITE */	/*	 * If there are more than 4 sectors to transfer, do n-4 then go into	 * the polling strategy as defined above.	 */	if (rq->nr_sectors > 4) {		if (promise_multwrite(drive, rq->nr_sectors - 4))			return ide_stopped;		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;		if (hwgroup->handler != NULL)	/* paranoia check */			BUG();		ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);		return ide_started;	} else {	/*	 * There are 4 or fewer sectors to transfer, do them all in one go	 * and wait for NOT BUSY.	 */		if (promise_multwrite(drive, rq->nr_sectors))			return ide_stopped;		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;		if (hwgroup->handler != NULL)			BUG();		ide_set_handler(drive,				&promise_complete_pollfunc,				HZ/100,				NULL);#ifdef DEBUG_WRITE		printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "			"status = %02x\n", drive->name,			HWIF(drive)->INB(IDE_STATUS_REG));#endif /* DEBUG_WRITE */		return ide_started;	}}/* * do_pdc4030_io() is called from promise_rw_disk, having had the block number * already set up. It issues a READ or WRITE command to the Promise * controller, assuming LBA has been used to set up the block number. */#ifndef CONFIG_IDE_TASKFILE_IOide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq){#else /* CONFIG_IDE_TASKFILE_IO */ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task){	struct request *rq	= HWGROUP(drive)->rq;	task_struct_t *taskfile = (task_struct_t *) task->tfRegister;#endif /* CONFIG_IDE_TASKFILE_IO */	ide_startstop_t startstop;	unsigned long timeout;	u8 stat = 0;#ifdef CONFIG_IDE_TASKFILE_IO	if (IDE_CONTROL_REG)		HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */	SELECT_MASK(drive, 0);	HWIF(drive)->OUTB(taskfile->feature, IDE_FEATURE_REG);	HWIF(drive)->OUTB(taskfile->sector_count, IDE_NSECTOR_REG);	/* refers to number of sectors to transfer */	HWIF(drive)->OUTB(taskfile->sector_number, IDE_SECTOR_REG);	/* refers to sector offset or start sector */	HWIF(drive)->OUTB(taskfile->low_cylinder, IDE_LCYL_REG);	HWIF(drive)->OUTB(taskfile->high_cylinder, IDE_HCYL_REG);	HWIF(drive)->OUTB(taskfile->device_head, IDE_SELECT_REG);	HWIF(drive)->OUTB(taskfile->command, IDE_COMMAND_REG);#endif /* CONFIG_IDE_TASKFILE_IO */	switch(rq->cmd) {	case READ:#ifndef CONFIG_IDE_TASKFILE_IO		HWIF(drive)->OUTB(PROMISE_READ, IDE_COMMAND_REG);#endif /* CONFIG_IDE_TASKFILE_IO *//* * The card's behaviour is odd at this point. If the data is * available, DRQ will be true, and no interrupt will be * generated by the card. If this is the case, we need to call the  * "interrupt" handler (promise_read_intr) directly. Otherwise, if * an interrupt is going to occur, bit0 of the SELECT register will * be high, so we can set the handler the just return and be interrupted. * If neither of these is the case, we wait for up to 50ms (badly I'm * afraid!) until one of them is. */		timeout = jiffies + HZ/20; /* 50ms wait */		do {			stat = HWIF(drive)->INB(IDE_STATUS_REG);			if (stat & DRQ_STAT) {				udelay(1);				return promise_read_intr(drive);			}			if (HWIF(drive)->INB(IDE_SELECT_REG) & 0x01) {#ifdef DEBUG_READ				printk(KERN_DEBUG "%s: read: waiting for "						"interrupt\n", drive->name);#endif /* DEBUG_READ */				ide_set_handler(drive,						&promise_read_intr,						WAIT_CMD,						NULL);				return ide_started;			}			udelay(1);		} while (time_before(jiffies, timeout));		printk(KERN_ERR "%s: reading: No DRQ and not "				"waiting - Odd!\n", drive->name);		return ide_stopped;	case WRITE:#ifndef CONFIG_IDE_TASKFILE_IO		HWIF(drive)->OUTB(PROMISE_WRITE, IDE_COMMAND_REG);#endif /* CONFIG_IDE_TASKFILE_IO */		if (ide_wait_stat(&startstop, drive, DATA_READY,				drive->bad_wstat, WAIT_DRQ)) {			printk(KERN_ERR "%s: no DRQ after issuing "				"PROMISE_WRITE\n", drive->name);			return startstop;	    	}		if (!drive->unmask)			local_irq_disable();		HWGROUP(drive)->wrq = *rq; /* scratchpad */		return promise_write(drive);	default:		printk("KERN_WARNING %s: bad command: %d\n",			drive->name, rq->cmd);		DRIVER(drive)->end_request(drive, 0);		return ide_stopped;	}}static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block){	/* The four drives on the two logical (one physical) interfaces	   are distinguished by writing the drive number (0-3) to the	   Feature register.	   FIXME: Is promise_selectproc now redundant??	*/	int drive_number = (HWIF(drive)->channel << 1) + drive->select.b.unit;#ifndef CONFIG_IDE_TASKFILE_IO	ide_hwif_t *hwif = HWIF(drive);	BUG_ON(rq->nr_sectors > 127);	if (IDE_CONTROL_REG)		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);#ifdef DEBUG	printk("%s: %sing: LBAsect=%ld, sectors=%ld, "		"buffer=0x%08lx\n", drive->name,		(rq->cmd==READ)?"read":"writ", block,		rq->nr_sectors, (unsigned long) rq->buffer);#endif	hwif->OUTB(drive_number, IDE_FEATURE_REG);	hwif->OUTB(rq->nr_sectors, IDE_NSECTOR_REG);	hwif->OUTB(block,IDE_SECTOR_REG);	hwif->OUTB(block>>=8,IDE_LCYL_REG);	hwif->OUTB(block>>=8,IDE_HCYL_REG);	hwif->OUTB(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);	return do_pdc4030_io(drive, rq);#else /* CONFIG_IDE_TASKFILE_IO */	struct hd_drive_task_hdr	taskfile;	ide_task_t			args;	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));	taskfile.feature	= drive_number;	taskfile.sector_count	= rq->nr_sectors;	taskfile.sector_number	= block;	taskfile.low_cylinder	= (block>>=8);	taskfile.high_cylinder	= (block>>=8);	taskfile.device_head	= ((block>>8)&0x0f)|drive->select.all;	taskfile.command	= (rq->cmd==READ)?PROMISE_READ:PROMISE_WRITE;	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));	memset(args.hobRegister, 0, sizeof(struct hd_drive_hob_hdr));	/* We can't call ide_cmd_type_parser here, since it won't understand	   our command, but that doesn't matter, since we don't use the	   generic interrupt handlers either. Setup the bits of args that we	   do need.	*/	args.handler		= NULL;	args.rq			= (struct request *) rq;	rq->special		= (ide_task_t *)&args;	return do_pdc4030_io(drive, &args);#endif /* CONFIG_IDE_TASKFILE_IO */}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
粉嫩一区二区三区在线看| 亚洲综合一区二区精品导航| 91麻豆精品国产91久久久| 欧美性xxxxxxxx| 在线观看亚洲一区| 欧美做爰猛烈大尺度电影无法无天| 成人99免费视频| 色婷婷av一区二区三区软件| 色激情天天射综合网| 欧美无砖专区一中文字| 欧美精品一二三| 欧美mv和日韩mv国产网站| 亚洲精品在线观看网站| 中文字幕 久热精品 视频在线| 国产精品免费看片| 亚洲欧美电影一区二区| 午夜精品一区二区三区电影天堂| 日本欧美一区二区三区| 久久97超碰国产精品超碰| 国产.精品.日韩.另类.中文.在线.播放| 国产福利91精品一区二区三区| 成人国产在线观看| 欧美日本在线一区| 久久欧美一区二区| 一区二区三区 在线观看视频| 亚洲国产一区二区在线播放| 久久99精品久久只有精品| 粉嫩蜜臀av国产精品网站| 91福利视频久久久久| 91精品国产综合久久福利软件| 久久久高清一区二区三区| 国产精品大尺度| 日本亚洲一区二区| 成人美女视频在线观看18| 在线视频一区二区免费| 久久影院午夜论| 亚洲黄色在线视频| 国产尤物一区二区| 欧美日韩中文国产| 欧美国产日韩亚洲一区| 奇米影视一区二区三区小说| 国内精品视频一区二区三区八戒| av激情成人网| 精品国产乱码久久久久久牛牛| 国产精品福利一区| 国内精品免费**视频| 在线观看www91| 国产精品久久夜| 美国一区二区三区在线播放| 色综合久久综合网欧美综合网| 精品美女一区二区| 亚洲成a人片综合在线| 成人97人人超碰人人99| 精品欧美一区二区久久| 亚洲图片欧美视频| 91日韩在线专区| 久久久.com| 久久精品国产精品亚洲精品| 欧美亚男人的天堂| 国产精品国产三级国产aⅴ原创| 亚洲.国产.中文慕字在线| av一区二区三区| 中文乱码免费一区二区| 国产一区在线观看视频| 日韩区在线观看| 午夜精品久久久久久久久久| 91国偷自产一区二区开放时间 | 国产一区日韩二区欧美三区| 欧美日韩1区2区| 亚洲国产精品精华液网站| 99精品久久久久久| 欧美国产精品一区| 国产69精品久久777的优势| 久久久久久久网| 国产伦精品一区二区三区视频青涩| 欧美一区二区在线视频| 男男视频亚洲欧美| 精品欧美久久久| 国模套图日韩精品一区二区| 久久久亚洲精华液精华液精华液| 久久国产精品99久久久久久老狼 | 亚洲小少妇裸体bbw| 色综合久久久久综合体| 一区二区三区在线视频免费| 色婷婷av一区二区三区软件| 亚洲午夜一区二区| 制服丝袜亚洲色图| 激情成人午夜视频| 国产欧美日韩麻豆91| 91玉足脚交白嫩脚丫在线播放| 亚洲日本丝袜连裤袜办公室| 色婷婷久久久久swag精品| 偷拍与自拍一区| 精品国产成人系列| 99热在这里有精品免费| 亚洲午夜羞羞片| 精品日韩欧美一区二区| 成人丝袜高跟foot| 一区二区三区中文字幕电影| 欧美夫妻性生活| 国产精品1区2区3区| 亚洲免费在线视频一区 二区| 欧美日韩免费观看一区三区| 九九精品一区二区| 国产精品视频观看| 欧美三级中文字幕| 国产综合一区二区| 一区二区三区四区精品在线视频| 欧美亚洲高清一区| 国产专区欧美精品| 亚洲精品视频在线| 久久色视频免费观看| 色激情天天射综合网| 久久成人av少妇免费| 亚洲精品中文字幕在线观看| 日韩欧美aaaaaa| 91视频免费看| 国产一区二区视频在线| 亚洲一区二区在线免费看| 26uuu色噜噜精品一区| 欧洲生活片亚洲生活在线观看| 韩国理伦片一区二区三区在线播放| 最新欧美精品一区二区三区| 日韩欧美国产精品| 色菇凉天天综合网| 国产成人久久精品77777最新版本 国产成人鲁色资源国产91色综 | 盗摄精品av一区二区三区| 亚洲一区视频在线| 自拍av一区二区三区| 精品区一区二区| 欧美视频在线不卡| 99精品久久免费看蜜臀剧情介绍 | 久久综合九色综合欧美98| 精品视频全国免费看| av高清不卡在线| 国产精品一区二区久激情瑜伽| 日韩黄色免费网站| 亚洲影视在线播放| 日韩一区在线看| 中文字幕在线一区免费| 久久久久久久久99精品| 欧美成人一级视频| 91精品国产91久久综合桃花| 欧美系列亚洲系列| 欧美色图在线观看| 在线亚洲欧美专区二区| 91视频在线观看| 色88888久久久久久影院野外| 国产成人亚洲综合a∨婷婷| 国产一区欧美二区| 国产一区二区不卡| 国产成人啪午夜精品网站男同| 国模少妇一区二区三区| 国产精品自在在线| 国产伦精品一区二区三区在线观看| 久久国产精品99久久久久久老狼| 青青草成人在线观看| 久久爱www久久做| 国产一区二区伦理| 国产精品一区二区在线观看网站| 国产综合成人久久大片91| 狠狠色丁香婷综合久久| 国产成人一级电影| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 91麻豆.com| 欧美视频中文一区二区三区在线观看| 欧美日韩综合在线免费观看| 欧美日韩国产免费一区二区| 欧美二区在线观看| 久久久电影一区二区三区| 国产精品丝袜久久久久久app| 亚洲欧美一区二区三区孕妇| 依依成人精品视频| 日本v片在线高清不卡在线观看| 精品亚洲成av人在线观看| 国产成人亚洲综合a∨婷婷| 色菇凉天天综合网| 日韩欧美亚洲国产另类| 亚洲国产精品99久久久久久久久| 亚洲私人黄色宅男| 日韩avvvv在线播放| 丰满少妇在线播放bd日韩电影| 本田岬高潮一区二区三区| 欧美性生活影院| 国产亚洲综合性久久久影院| 亚洲三级在线免费| 美国精品在线观看| 91免费版在线| 精品少妇一区二区| 亚洲蜜臀av乱码久久精品| 美女mm1313爽爽久久久蜜臀| 97久久超碰国产精品| 欧美一区二区三区在线观看视频| 欧美国产精品劲爆| 天天亚洲美女在线视频| 成人av在线播放网址| 日韩一二三区视频| 一区二区三区丝袜| 成人久久视频在线观看| 欧美一区二区三区电影|