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

📄 acpiphp_res.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ACPI PCI HotPlug Utility functions * * Copyright (C) 1995,2001 Compaq Computer Corporation * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2001 IBM Corp. * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (C) 2002 NEC Corporation * * All rights reserved. * * 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. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or * NON INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com> * */#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/proc_fs.h>#include <linux/sysctl.h>#include <linux/pci.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/timer.h>#include <linux/ioctl.h>#include <linux/fcntl.h>#include <linux/list.h>#include "pci_hotplug.h"#include "acpiphp.h"#define MY_NAME "acpiphp_res"/* * sort_by_size - sort nodes by their length, smallest first */static int sort_by_size(struct pci_resource **head){	struct pci_resource *current_res;	struct pci_resource *next_res;	int out_of_order = 1;	if (!(*head))		return 1;	if (!((*head)->next))		return 0;	while (out_of_order) {		out_of_order = 0;		/* Special case for swapping list head */		if (((*head)->next) &&		    ((*head)->length > (*head)->next->length)) {			out_of_order++;			current_res = *head;			*head = (*head)->next;			current_res->next = (*head)->next;			(*head)->next = current_res;		}		current_res = *head;		while (current_res->next && current_res->next->next) {			if (current_res->next->length > current_res->next->next->length) {				out_of_order++;				next_res = current_res->next;				current_res->next = current_res->next->next;				current_res = current_res->next;				next_res->next = current_res->next;				current_res->next = next_res;			} else				current_res = current_res->next;		}	}  /* End of out_of_order loop */	return 0;}#if 0/* * sort_by_max_size - sort nodes by their length, largest first */static int sort_by_max_size(struct pci_resource **head){	struct pci_resource *current_res;	struct pci_resource *next_res;	int out_of_order = 1;	if (!(*head))		return 1;	if (!((*head)->next))		return 0;	while (out_of_order) {		out_of_order = 0;		/* Special case for swapping list head */		if (((*head)->next) &&		    ((*head)->length < (*head)->next->length)) {			out_of_order++;			current_res = *head;			*head = (*head)->next;			current_res->next = (*head)->next;			(*head)->next = current_res;		}		current_res = *head;		while (current_res->next && current_res->next->next) {			if (current_res->next->length < current_res->next->next->length) {				out_of_order++;				next_res = current_res->next;				current_res->next = current_res->next->next;				current_res = current_res->next;				next_res->next = current_res->next;				current_res->next = next_res;			} else				current_res = current_res->next;		}	}  /* End of out_of_order loop */	return 0;}#endif/** * get_io_resource - get resource for I/O ports * * this function sorts the resource list by size and then * returns the first node of "size" length that is not in the * ISA aliasing window.  If it finds a node larger than "size" * it will split it up. * * size must be a power of two. * * difference from get_resource is handling of ISA aliasing space. * */struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size){	struct pci_resource *prevnode;	struct pci_resource *node;	struct pci_resource *split_node;	u64 temp_qword;	if (!(*head))		return NULL;	if (acpiphp_resource_sort_and_combine(head))		return NULL;	if (sort_by_size(head))		return NULL;	for (node = *head; node; node = node->next) {		if (node->length < size)			continue;		if (node->base & (size - 1)) {			/* this one isn't base aligned properly			   so we'll make a new entry and split it up */			temp_qword = (node->base | (size-1)) + 1;			/* Short circuit if adjusted size is too small */			if ((node->length - (temp_qword - node->base)) < size)				continue;			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);			if (!split_node)				return NULL;			node->base = temp_qword;			node->length -= split_node->length;			/* Put it in the list */			split_node->next = node->next;			node->next = split_node;		} /* End of non-aligned base */		/* Don't need to check if too small since we already did */		if (node->length > size) {			/* this one is longer than we need			   so we'll make a new entry and split it up */			split_node = acpiphp_make_resource(node->base + size, node->length - size);			if (!split_node)				return NULL;			node->length = size;			/* Put it in the list */			split_node->next = node->next;			node->next = split_node;		}  /* End of too big on top end */		/* For IO make sure it's not in the ISA aliasing space */		if ((node->base & 0x300L) && !(node->base & 0xfffff000))			continue;		/* If we got here, then it is the right size		   Now take it out of the list */		if (*head == node) {			*head = node->next;		} else {			prevnode = *head;			while (prevnode->next != node)				prevnode = prevnode->next;			prevnode->next = node->next;		}		node->next = NULL;		/* Stop looping */		break;	}	return node;}#if 0/** * get_max_resource - get the largest resource * * Gets the largest node that is at least "size" big from the * list pointed to by head.  It aligns the node on top and bottom * to "size" alignment before returning it. */static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size){	struct pci_resource *max;	struct pci_resource *temp;	struct pci_resource *split_node;	u64 temp_qword;	if (!(*head))		return NULL;	if (acpiphp_resource_sort_and_combine(head))		return NULL;	if (sort_by_max_size(head))		return NULL;	for (max = *head;max; max = max->next) {		/* If not big enough we could probably just bail,		   instead we'll continue to the next. */		if (max->length < size)			continue;		if (max->base & (size - 1)) {			/* this one isn't base aligned properly			   so we'll make a new entry and split it up */			temp_qword = (max->base | (size-1)) + 1;			/* Short circuit if adjusted size is too small */			if ((max->length - (temp_qword - max->base)) < size)				continue;			split_node = acpiphp_make_resource(max->base, temp_qword - max->base);			if (!split_node)				return NULL;			max->base = temp_qword;			max->length -= split_node->length;			/* Put it next in the list */			split_node->next = max->next;			max->next = split_node;		}		if ((max->base + max->length) & (size - 1)) {			/* this one isn't end aligned properly at the top			   so we'll make a new entry and split it up */			temp_qword = ((max->base + max->length) & ~(size - 1));			split_node = acpiphp_make_resource(temp_qword,							   max->length + max->base - temp_qword);			if (!split_node)				return NULL;			max->length -= split_node->length;			/* Put it in the list */			split_node->next = max->next;			max->next = split_node;		}		/* Make sure it didn't shrink too much when we aligned it */		if (max->length < size)			continue;		/* Now take it out of the list */		temp = (struct pci_resource*) *head;		if (temp == max) {			*head = max->next;		} else {			while (temp && temp->next != max) {				temp = temp->next;			}			temp->next = max->next;		}		max->next = NULL;		return max;	}	/* If we get here, we couldn't find one */	return NULL;}#endif/** * get_resource - get resource (mem, pfmem) * * this function sorts the resource list by size and then * returns the first node of "size" length.  If it finds a node

⌨️ 快捷键说明

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