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

📄 prom.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		ADDBASE(np->properties);		ADDBASE(np->parent);		ADDBASE(np->child);		ADDBASE(np->sibling);		ADDBASE(np->allnext);		for (pp = np->properties; pp != 0; pp = pp->next) {			ADDBASE(pp->name);			ADDBASE(pp->value);			ADDBASE(pp->next);		}	}}intprom_n_addr_cells(struct device_node* np){	int* ip;	do {		if (np->parent)			np = np->parent;		ip = (int *) get_property(np, "#address-cells", NULL);		if (ip != NULL)			return *ip;	} while (np->parent);	/* No #address-cells property for the root node, default to 1 */	return 1;}intprom_n_size_cells(struct device_node* np){	int* ip;	do {		if (np->parent)			np = np->parent;		ip = (int *) get_property(np, "#size-cells", NULL);		if (ip != NULL)			return *ip;	} while (np->parent);	/* No #size-cells property for the root node, default to 1 */	return 1;}static unsigned long __initmap_addr(struct device_node *np, unsigned long space, unsigned long addr){	int na;	unsigned int *ranges;	int rlen = 0;	unsigned int type;	type = (space >> 24) & 3;	if (type == 0)		return addr;	while ((np = np->parent) != NULL) {		if (strcmp(np->type, "pci") != 0)			continue;		/* PCI bridge: map the address through the ranges property */		na = prom_n_addr_cells(np);		ranges = (unsigned int *) get_property(np, "ranges", &rlen);		while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) {			if (((ranges[0] >> 24) & 3) == type			    && ranges[2] <= addr			    && addr - ranges[2] < ranges[na+4]) {				/* ok, this matches, translate it */				addr += ranges[na+2] - ranges[2];				break;			}			ranges += na + 5;		}	}	return addr;}static unsigned long __initinterpret_pci_props(struct device_node *np, unsigned long mem_start,		    int naddrc, int nsizec){	struct address_range *adr;	struct pci_reg_property *pci_addrs;	int i, l, *ip;	pci_addrs = (struct pci_reg_property *)		get_property(np, "assigned-addresses", &l);	if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct pci_reg_property)) >= 0) {			adr[i].space = pci_addrs[i].addr.a_hi;			adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi,						  pci_addrs[i].addr.a_lo);			adr[i].size = pci_addrs[i].size_lo;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip == 0 && np->parent)		ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}	}	return mem_start;}static unsigned long __initinterpret_dbdma_props(struct device_node *np, unsigned long mem_start,		      int naddrc, int nsizec){	struct reg_property *rp;	struct address_range *adr;	unsigned long base_address;	int i, l, *ip;	struct device_node *db;	base_address = 0;	for (db = np->parent; db != NULL; db = db->parent) {		if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {			base_address = db->addrs[0].address;			break;		}	}	rp = (struct reg_property *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property)) >= 0) {			adr[i].space = 2;			adr[i].address = rp[i].address + base_address;			adr[i].size = rp[i].size;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}	}	return mem_start;}static unsigned long __initinterpret_macio_props(struct device_node *np, unsigned long mem_start,		      int naddrc, int nsizec){	struct reg_property *rp;	struct address_range *adr;	unsigned long base_address;	int i, l, *ip;	struct device_node *db;	base_address = 0;	for (db = np->parent; db != NULL; db = db->parent) {		if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {			base_address = db->addrs[0].address;			break;		}	}	rp = (struct reg_property *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property)) >= 0) {			adr[i].space = 2;			adr[i].address = rp[i].address + base_address;			adr[i].size = rp[i].size;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}		mem_start += np->n_intrs * sizeof(struct interrupt_info);	}	return mem_start;}static unsigned long __initinterpret_isa_props(struct device_node *np, unsigned long mem_start,		    int naddrc, int nsizec){	struct isa_reg_property *rp;	struct address_range *adr;	int i, l, *ip;	rp = (struct isa_reg_property *) get_property(np, "reg", &l);	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= sizeof(struct reg_property)) >= 0) {			adr[i].space = rp[i].space;			adr[i].address = rp[i].address				+ (adr[i].space? 0: _ISA_MEM_BASE);			adr[i].size = rp[i].size;			++i;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / (2 * sizeof(int));		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = *ip++;		}	}	return mem_start;}static unsigned long __initinterpret_root_props(struct device_node *np, unsigned long mem_start,		     int naddrc, int nsizec){	struct address_range *adr;	int i, l, *ip;	unsigned int *rp;	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);	rp = (unsigned int *) get_property(np, "reg", &l);	if (rp != 0 && l >= rpsize) {		i = 0;		adr = (struct address_range *) mem_start;		while ((l -= rpsize) >= 0) {			adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2);			adr[i].address = rp[naddrc - 1];			adr[i].size = rp[naddrc + nsizec - 1];			++i;			rp += naddrc + nsizec;		}		np->addrs = adr;		np->n_addrs = i;		mem_start += i * sizeof(struct address_range);	}	if (use_of_interrupt_tree)		return mem_start;	ip = (int *) get_property(np, "AAPL,interrupts", &l);	if (ip == 0)		ip = (int *) get_property(np, "interrupts", &l);	if (ip != 0) {		np->intrs = (struct interrupt_info *) mem_start;		np->n_intrs = l / sizeof(int);		mem_start += np->n_intrs * sizeof(struct interrupt_info);		for (i = 0; i < np->n_intrs; ++i) {			np->intrs[i].line = *ip++;			np->intrs[i].sense = 1;		}	}	return mem_start;}/* * Work out the sense (active-low level / active-high edge) * of each interrupt from the device tree. */void __initprom_get_irq_senses(unsigned char *senses, int off, int max){	struct device_node *np;	int i, j;	/* default to level-triggered */	memset(senses, 1, max - off);	if (!use_of_interrupt_tree)		return;	for (np = allnodes; np != 0; np = np->allnext) {		for (j = 0; j < np->n_intrs; j++) {			i = np->intrs[j].line;			if (i >= off && i < max) {				if (np->intrs[j].sense == 1)					senses[i-off] = (IRQ_SENSE_LEVEL						| IRQ_POLARITY_NEGATIVE);				else					senses[i-off] = (IRQ_SENSE_EDGE						| IRQ_POLARITY_POSITIVE);			}		}	}}/* * Construct and return a list of the device_nodes with a given name. */struct device_node *find_devices(const char *name){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (np->name != 0 && strcasecmp(np->name, name) == 0) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = NULL;	return head;}/* * Construct and return a list of the device_nodes with a given type. */struct device_node *find_type_devices(const char *type){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (np->type != 0 && strcasecmp(np->type, type) == 0) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = NULL;	return head;}/* * Returns all nodes linked together */struct device_node * __openfirmwarefind_all_nodes(void){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		*prevp = np;		prevp = &np->next;	}	*prevp = NULL;	return head;}/* Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */intdevice_is_compatible(struct device_node *device, const char *compat){	const char* cp;	int cplen, l;	cp = (char *) get_property(device, "compatible", &cplen);	if (cp == NULL)		return 0;	while (cplen > 0) {		if (strncasecmp(cp, compat, strlen(compat)) == 0)			return 1;		l = strlen(cp) + 1;		cp += l;		cplen -= l;	}	return 0;}/* * Indicates whether the root node has a given value in its * compatible property. */intmachine_is_compatible(const char *compat){	struct device_node *root;	root = find_path_device("/");	if (root == 0)		return 0;	return device_is_compatible(root, compat);}/* * Construct and return a list of the device_nodes with a given type * and compatible property. */struct device_node *find_compatible_devices(const char *type, const char *compat){	struct device_node *head, **prevp, *np;	prevp = &head;	for (np = allnodes; np != 0; np = np->allnext) {		if (type != NULL		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))			continue;		if (device_is_compatible(np, compat)) {			*prevp = np;			prevp = &np->next;		}	}	*prevp = NULL;	return head;}/* * Find the device_node with a given full_name. */struct device_node *find_path_device(const char *path){	struct device_node *np;	for (np = allnodes; np != 0; np = np->allnext)		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)			return np;	return NULL;}/******* * * New implementation of the OF "find" APIs, return a refcounted * object, call of_node_put() when done. Currently, still lacks * locking as old implementation, this is beeing done for ppc64. * * Note that property management will need some locking as well, * this isn't dealt with yet * *******//**

⌨️ 快捷键说明

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