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

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

?? ide-pmac.c

?? 講述linux的初始化過程
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* * linux/drivers/ide/ide-pmac.c		Version ?.??	Mar. 18, 2000 * * Support for IDE interfaces on PowerMacs. * These IDE interfaces are memory-mapped and have a DBDMA channel * for doing DMA. * *  Copyright (C) 1998 Paul Mackerras. * *  Bits from Benjamin Herrenschmidt * *  This program is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version *  2 of the License, or (at your option) any later version. * * Some code taken from drivers/ide/ide-dma.c: * *  Copyright (c) 1995-1998  Mark Lord * */#include <linux/config.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/ide.h>#include <asm/prom.h>#include <asm/io.h>#include <asm/dbdma.h>#include <asm/ide.h>#include <asm/mediabay.h>#include <asm/feature.h>#ifdef CONFIG_PMAC_PBOOK#include <linux/adb.h>#include <linux/pmu.h>#include <asm/irq.h>#endif#include "ide_modes.h"extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);#undef IDE_PMAC_DEBUG#define IDE_SYSCLK_NS		30#define IDE_SYSCLK_ULTRA_PS	0x1d4c /* (15 * 1000 / 2)*/struct pmac_ide_hwif {	ide_ioreg_t			regbase;	int				irq;	int				kind;	int				aapl_bus_id;	struct device_node*		node;	u32				timings[2];#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC	volatile struct dbdma_regs*	dma_regs;	struct dbdma_cmd*		dma_table;#endif	} pmac_ide[MAX_HWIFS];static int pmac_ide_count;enum {	controller_ohare,	/* OHare based */	controller_heathrow,	/* Heathrow/Paddington */	controller_kl_ata3,	/* KeyLargo ATA-3 */	controller_kl_ata4	/* KeyLargo ATA-4 */};#ifdef CONFIG_BLK_DEV_IDEDMA_PMACtypedef struct {	int	accessTime;	int	cycleTime;} pmac_ide_timing;/* Multiword DMA timings */static pmac_ide_timing mdma_timings[] ={    { 215,    480 },	/* Mode 0 */    {  80,    150 },	/*      1 */    {  70,    120 }	/*      2 */};/* Ultra DMA timings (for use when I know how to calculate them */static pmac_ide_timing udma_timings[] ={    {   0,    114 },	/* Mode 0 */    {   0,     75 },	/*      1 */    {   0,     55 },	/*      2 */    {   100,   45 },	/*      3 */    {   100,   25 }	/*      4 */};/* allow up to 256 DBDMA commands per xfer */#define MAX_DCMDS		256/* Wait 1.5s for disk to answer on IDE bus after * enable operation. * NOTE: There is at least one case I know of a disk that needs about 10sec *       before anwering on the bus. I beleive we could add a kernel command *       line arg to override this delay for such cases. */#define IDE_WAKEUP_DELAY_MS	1500static void pmac_ide_setup_dma(struct device_node *np, int ix);static int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);static int pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr);static int pmac_ide_tune_chipset(ide_drive_t *drive, byte speed);static void pmac_ide_tuneproc(ide_drive_t *drive, byte pio);static void pmac_ide_selectproc(ide_drive_t *drive);#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */#ifdef CONFIG_PMAC_PBOOKstatic int idepmac_notify_sleep(struct pmu_sleep_notifier *self, int when);struct pmu_sleep_notifier idepmac_sleep_notifier = {	idepmac_notify_sleep, SLEEP_LEVEL_BLOCK,};#endif /* CONFIG_PMAC_PBOOK */static intpmac_ide_find(ide_drive_t *drive){	ide_hwif_t *hwif = HWIF(drive);	ide_ioreg_t base;	int i;		for (i=0; i<pmac_ide_count; i++) {		base = pmac_ide[i].regbase;		if (base && base == hwif->io_ports[0])			return i;	}	return -1;}/* * N.B. this can't be an initfunc, because the media-bay task can * call ide_[un]register at any time. */void pmac_ide_init_hwif_ports(hw_regs_t *hw,			      ide_ioreg_t data_port, ide_ioreg_t ctrl_port,			      int *irq){	int i, ix;	if (data_port == 0)		return;	for (ix = 0; ix < MAX_HWIFS; ++ix)		if (data_port == pmac_ide[ix].regbase)			break;	if (ix >= MAX_HWIFS) {		/* Probably a PCI interface... */		for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i)			hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET;		/* XXX is this right? */		hw->io_ports[IDE_CONTROL_OFFSET] = 0;		if (irq != 0)			*irq = 0;		return;	}	for (i = 0; i < 8; ++i)		hw->io_ports[i] = data_port + i * 0x10;	hw->io_ports[8] = data_port + 0x160;	if (irq != NULL)		*irq = pmac_ide[ix].irq;	ide_hwifs[ix].tuneproc = pmac_ide_tuneproc;	ide_hwifs[ix].selectproc = pmac_ide_selectproc;	if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table) {		ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;#ifdef CONFIG_PMAC_IDEDMA_AUTO		ide_hwifs[ix].autodma = 1;#endif//		ide_hwifs[ix].speedproc = &pmac_ide_tune_chipset;	}}#if 0/* This one could be later extended to handle CMD IDE and be used by some kind * of /proc interface. I want to be able to get the devicetree path of a block * device for yaboot configuration */struct device_node*pmac_ide_get_devnode(ide_drive_t *drive){	int i = pmac_ide_find(drive);	if (i < 0)		return NULL;	return pmac_ide[i].node;}#endif/* Setup timings for the selected drive (master/slave). I still need to verify if this * is enough, I beleive selectproc will be called whenever an IDE command is started, * but... */static voidpmac_ide_selectproc(ide_drive_t *drive){	int i = pmac_ide_find(drive);	if (i < 0)		return;				if (drive->select.all & 0x10)		out_le32((unsigned *)(IDE_DATA_REG + 0x200 + _IO_BASE), pmac_ide[i].timings[1]);	else		out_le32((unsigned *)(IDE_DATA_REG + 0x200 + _IO_BASE), pmac_ide[i].timings[0]);}/* Number of IDE_SYSCLK_NS ticks, argument is in nanoseconds */#define SYSCLK_TICKS(t)		(((t) + IDE_SYSCLK_NS - 1) / IDE_SYSCLK_NS)#define SYSCLK_TICKS_UDMA(t)	(((t) + IDE_SYSCLK_ULTRA_PS - 1) / IDE_SYSCLK_ULTRA_PS)/* Calculate PIO timings */static voidpmac_ide_tuneproc(ide_drive_t *drive, byte pio){	ide_pio_data_t d;	int i;	u32 *timings;	int accessTicks, recTicks;		i = pmac_ide_find(drive);	if (i < 0)		return;			pio = ide_get_best_pio_mode(drive, pio, 4, &d);	accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);	if (drive->select.all & 0x10)		timings = &pmac_ide[i].timings[1];	else		timings = &pmac_ide[i].timings[0];		if (pmac_ide[i].kind == controller_kl_ata4) {		/* The "ata-4" IDE controller of Core99 machines */		accessTicks = SYSCLK_TICKS_UDMA(ide_pio_timings[pio].active_time * 1000);		recTicks = SYSCLK_TICKS_UDMA(d.cycle_time * 1000) - accessTicks;		*timings = ((*timings) & 0x1FFFFFC00) | accessTicks | (recTicks << 5);	} else {		/* The old "ata-3" IDE controller */		accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);		if (accessTicks < 4)			accessTicks = 4;		recTicks = SYSCLK_TICKS(d.cycle_time) - accessTicks - 4;		if (recTicks < 1)			recTicks = 1;			*timings = ((*timings) & 0xFFFFFF800) | accessTicks | (recTicks << 5);	}#ifdef IDE_PMAC_DEBUG	printk("ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n",		pio,  *timings);#endif				if (drive->select.all == IN_BYTE(IDE_SELECT_REG))		pmac_ide_selectproc(drive);}ide_ioreg_tpmac_ide_get_base(int index){	return pmac_ide[index].regbase;}static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };kdev_t __initpmac_find_ide_boot(char *bootdevice, int n){	int i;		/*	 * Look through the list of IDE interfaces for this one.	 */	for (i = 0; i < pmac_ide_count; ++i) {		char *name;		if (!pmac_ide[i].node || !pmac_ide[i].node->full_name)			continue;		name = pmac_ide[i].node->full_name;		if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {			/* XXX should cope with the 2nd drive as well... */			return MKDEV(ide_majors[i], 0);		}	}	return 0;}void __initpmac_ide_probe(void){	struct device_node *np;	int i;	struct device_node *atas;	struct device_node *p, **pp, *removables, **rp;	unsigned long base;	int irq, big_delay;	ide_hwif_t *hwif;	if (_machine != _MACH_Pmac)		return;	pp = &atas;	rp = &removables;	p = find_devices("ATA");	if (p == NULL)		p = find_devices("IDE");	if (p == NULL)		p = find_type_devices("ide");	if (p == NULL)		p = find_type_devices("ata");	/* Move removable devices such as the media-bay CDROM	   on the PB3400 to the end of the list. */	for (; p != NULL; p = p->next) {		if (p->parent && p->parent->type		    && strcasecmp(p->parent->type, "media-bay") == 0) {			*rp = p;			rp = &p->next;		} else {			*pp = p;			pp = &p->next;		}	}	*rp = NULL;	*pp = removables;	big_delay = 0;	for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {		struct device_node *tp;		int *bidp;		/*		 * If this node is not under a mac-io or dbdma node,		 * leave it to the generic PCI driver.		 */		for (tp = np->parent; tp != 0; tp = tp->parent)			if (tp->type && (strcmp(tp->type, "mac-io") == 0					 || strcmp(tp->type, "dbdma") == 0))				break;		if (tp == 0)			continue;		if (np->n_addrs == 0) {			printk(KERN_WARNING "ide: no address for device %s\n",			       np->full_name);			continue;		}		/*		 * If this slot is taken (e.g. by ide-pci.c) try the next one.		 */		while (i < MAX_HWIFS		       && ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0)			++i;		if (i >= MAX_HWIFS)			break;		base = (unsigned long) ioremap(np->addrs[0].address, 0x200) - _IO_BASE;		/* XXX This is bogus. Should be fixed in the registry by checking		   the kind of host interrupt controller, a bit like gatwick		   fixes in irq.c		 */		if (np->n_intrs == 0) {			printk("ide: no intrs for device %s, using 13\n",			       np->full_name);			irq = 13;		} else {			irq = np->intrs[0].line;		}		pmac_ide[i].regbase = base;		pmac_ide[i].irq = irq;		pmac_ide[i].node = np;		if (device_is_compatible(np, "keylargo-ata")) {			if (strcmp(np->name, "ata-4") == 0)				pmac_ide[i].kind = controller_kl_ata4;			else				pmac_ide[i].kind = controller_kl_ata3;		} else if (device_is_compatible(np, "heathrow-ata"))			pmac_ide[i].kind = controller_heathrow;		else			pmac_ide[i].kind = controller_ohare;		bidp = (int *)get_property(np, "AAPL,bus-id", NULL);		pmac_ide[i].aapl_bus_id =  bidp ? *bidp : 0;		if (np->parent && np->parent->name		    && strcasecmp(np->parent->name, "media-bay") == 0) {			media_bay_set_ide_infos(np->parent,base,irq,i);		} else if (pmac_ide[i].kind == controller_ohare) {			/* The code below is having trouble on some ohare machines			 * (timing related ?). Until I can put my hand on one of these			 * units, I keep the old way			 */			 feature_set(np, FEATURE_IDE0_enable);		} else { 			/* This is necessary to enable IDE when net-booting */			printk("pmac_ide: enabling IDE bus ID %d\n",				pmac_ide[i].aapl_bus_id);			switch(pmac_ide[i].aapl_bus_id) {			    case 0:				feature_set(np, FEATURE_IDE0_reset);				mdelay(10); 				feature_set(np, FEATURE_IDE0_enable);				mdelay(10);				feature_clear(np, FEATURE_IDE0_reset);				break;			    case 1:				feature_set(np, FEATURE_IDE1_reset);				mdelay(10); 				feature_set(np, FEATURE_IDE1_enable);				mdelay(10);				feature_clear(np, FEATURE_IDE1_reset);				break;			    case 2:			    	/* This one exists only for KL, I don't know				   about any enable bit */				feature_set(np, FEATURE_IDE2_reset);				mdelay(10);				feature_clear(np, FEATURE_IDE2_reset);				break;			}			big_delay = 1;		}		hwif = &ide_hwifs[i];		pmac_ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->irq);		memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));		hwif->chipset = ide_pmac;		hwif->noprobe = (!hwif->io_ports[IDE_DATA_OFFSET]) ||			(check_media_bay_by_base(base, MB_CD) == -EINVAL);#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC		if (np->n_addrs >= 2) {			/* has a DBDMA controller channel */			pmac_ide_setup_dma(np, i);		}#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */		++i;	}	pmac_ide_count = i;	if (big_delay)		mdelay(IDE_WAKEUP_DELAY_MS);#ifdef CONFIG_PMAC_PBOOK	pmu_register_sleep_notifier(&idepmac_sleep_notifier);#endif /* CONFIG_PMAC_PBOOK */}#ifdef CONFIG_BLK_DEV_IDEDMA_PMACstatic void __init pmac_ide_setup_dma(struct device_node *np, int ix){	pmac_ide[ix].dma_regs =		(volatile struct dbdma_regs*)ioremap(np->addrs[1].address, 0x200);	/*	 * Allocate space for the DBDMA commands.	 * The +2 is +1 for the stop command and +1 to allow for	 * aligning the start address to a multiple of 16 bytes.	 */	pmac_ide[ix].dma_table = (struct dbdma_cmd*)	       kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL);	if (pmac_ide[ix].dma_table == 0) {		printk(KERN_ERR "%s: unable to allocate DMA command list\n",		       ide_hwifs[ix].name);		return;	}	ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;#ifdef CONFIG_PMAC_IDEDMA_AUTO	ide_hwifs[ix].autodma = 1;#endif}/* * pmac_ide_build_dmatable builds the DBDMA command list * for a transfer and sets the DBDMA channel to point to it. */static intpmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr){	struct dbdma_cmd *table, *tstart;	int count = 0;	struct request *rq = HWGROUP(drive)->rq;	struct buffer_head *bh = rq->bh;	unsigned int size, addr;	volatile struct dbdma_regs *dma = pmac_ide[ix].dma_regs;	table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(pmac_ide[ix].dma_table);	out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);	while (in_le32(&dma->status) & RUN)		udelay(1);	do {		/*		 * Determine addr and size of next buffer area.  We assume that		 * individual virtual buffers are always composed linearly in		 * physical memory.  For example, we assume that any 8kB buffer		 * is always composed of two adjacent physical 4kB pages rather		 * than two possibly non-adjacent physical 4kB pages.		 */		if (bh == NULL) {  /* paging requests have (rq->bh == NULL) */			addr = virt_to_bus(rq->buffer);			size = rq->nr_sectors << 9;		} else {			/* group sequential buffers into one large buffer */			addr = virt_to_bus(bh->b_data);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
美女任你摸久久| 亚洲区小说区图片区qvod| 日韩综合小视频| 9191久久久久久久久久久| 午夜在线电影亚洲一区| 欧美一级欧美三级| 韩国v欧美v日本v亚洲v| 国产视频一区二区在线观看| 99re视频精品| 亚洲成av人片一区二区| 91精品国产综合久久精品图片 | 成人中文字幕在线| 国产精品毛片无遮挡高清| 91色九色蝌蚪| 午夜视频一区二区| 精品福利一区二区三区免费视频| 国产成人精品免费| 亚洲精品你懂的| 日韩一卡二卡三卡四卡| 欧美色图免费看| 免费成人你懂的| 欧美极品aⅴ影院| 欧美三级视频在线观看| 韩国精品一区二区| 亚洲精品国产精华液| 日韩美一区二区三区| 成人免费毛片嘿嘿连载视频| 午夜日韩在线观看| 中文无字幕一区二区三区| 欧美卡1卡2卡| 成人免费看的视频| 婷婷综合五月天| 国产精品久久久久三级| 欧美精品三级日韩久久| 成人性生交大片免费| 亚洲v日本v欧美v久久精品| 国产欧美精品国产国产专区| 欧美日韩国产综合视频在线观看| 国产精品91xxx| 人禽交欧美网站| 亚洲精品亚洲人成人网 | 韩国av一区二区三区在线观看| 国产精品久久久久久久久免费桃花 | 午夜久久久影院| 国产精品网站在线观看| 日韩欧美综合一区| 91黄色在线观看| 日韩欧美一级二级三级久久久| 国产成a人亚洲| 美女一区二区三区在线观看| 日本不卡一区二区| 中文字幕成人在线观看| 精品国产免费久久| 91麻豆精品91久久久久同性| 色国产综合视频| 成人亚洲一区二区一| 久国产精品韩国三级视频| 亚洲福利电影网| 亚洲激情第一区| 亚洲欧洲色图综合| 日本一区二区在线不卡| 精品国产伦一区二区三区观看方式 | 国产v日产∨综合v精品视频| 蜜桃久久精品一区二区| 日本亚洲三级在线| 天堂影院一区二区| 亚洲福利一区二区三区| 一二三区精品视频| 一区二区久久久久久| √…a在线天堂一区| 国产精品久久久久永久免费观看 | 一区二区三区**美女毛片| 国产精品久久久久久久蜜臀| 国产欧美日韩精品在线| 国产午夜精品在线观看| 日本一区二区综合亚洲| 欧美精彩视频一区二区三区| 亚洲国产精品99久久久久久久久| 国产亚洲人成网站| 国产目拍亚洲精品99久久精品| 日本欧美一区二区| 日本视频在线一区| 久久国产夜色精品鲁鲁99| 免费成人结看片| 国产一区二区三区四区五区美女 | 一区二区视频免费在线观看| 亚洲精品乱码久久久久久久久| 亚洲欧美成人一区二区三区| 亚洲欧美一区二区不卡| 亚洲自拍偷拍av| 日本不卡在线视频| 狠狠色综合日日| 粉嫩高潮美女一区二区三区| 99视频精品免费视频| 99久久久国产精品免费蜜臀| 日本久久电影网| 69成人精品免费视频| 欧美大片日本大片免费观看| 久久久久久久网| 综合久久综合久久| 五月天激情综合| 国产中文一区二区三区| 99综合影院在线| 欧美日本视频在线| 亚洲精品在线电影| 日韩一区在线看| 午夜视频一区二区三区| 国产精品羞羞答答xxdd| 99久久国产综合精品女不卡| 欧美色图在线观看| 日韩精品一区二区三区视频在线观看| 国产视频一区二区在线| 亚洲综合免费观看高清完整版在线 | 亚洲男人的天堂网| 免费不卡在线视频| 成人黄色国产精品网站大全在线免费观看| 色婷婷亚洲综合| 精品成人私密视频| 一区二区免费看| 国产电影一区二区三区| 欧美色图12p| 欧美国产日本视频| 日韩二区三区四区| av亚洲精华国产精华精| 日韩亚洲电影在线| 亚洲靠逼com| 国产一区二区剧情av在线| 欧美日韩免费观看一区三区| 国产欧美日韩亚州综合 | 色综合夜色一区| 精品日韩一区二区三区免费视频| 国产精品久久久久影视| 精品一区二区久久久| 欧美最猛性xxxxx直播| 久久精品亚洲乱码伦伦中文| 日韩电影在线免费观看| aaa亚洲精品一二三区| 久久亚洲一区二区三区明星换脸| 一区二区三区不卡在线观看 | 久久99精品国产91久久来源| 在线观看视频欧美| 国产精品嫩草久久久久| 国产在线观看一区二区 | 欧美成人福利视频| 午夜在线电影亚洲一区| 91在线观看成人| 欧美激情一区二区| 久久成人精品无人区| 欧美日韩国产经典色站一区二区三区| 国产精品久久久久久久久果冻传媒| 精品一区二区三区香蕉蜜桃| 欧美丰满高潮xxxx喷水动漫| 一区二区三区中文免费| 99久久精品久久久久久清纯| 国产人伦精品一区二区| 国产一区不卡在线| 欧美精品一区二区蜜臀亚洲| 麻豆91小视频| 日韩亚洲欧美在线观看| 美女国产一区二区三区| 欧美一级片在线看| 奇米四色…亚洲| 日韩欧美专区在线| 美女免费视频一区| 精品人伦一区二区色婷婷| 麻豆精品在线看| 精品乱码亚洲一区二区不卡| 秋霞午夜鲁丝一区二区老狼| 欧美一区二区三区色| 老鸭窝一区二区久久精品| 日韩视频在线你懂得| 欧美日韩国产首页| 亚洲 欧美综合在线网络| 欧美日韩国产不卡| 偷拍一区二区三区四区| 6080国产精品一区二区| 美女www一区二区| 久久网这里都是精品| 风流少妇一区二区| |精品福利一区二区三区| 91电影在线观看| 婷婷成人综合网| 日韩精品一区在线观看| 国产乱码精品一区二区三区av| 日本一区二区不卡视频| 94-欧美-setu| 亚洲成va人在线观看| 欧美一级理论片| 国产成人精品网址| 亚洲精品五月天| 欧美二区三区的天堂| 精品一区二区免费视频| 国产精品福利一区二区三区| 欧美私人免费视频| 精彩视频一区二区三区| 中文字幕制服丝袜成人av | 欧美一区二区三区在线观看| 国产一区中文字幕| 亚洲欧美一区二区三区极速播放| 7799精品视频|