Пример #1
0
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
						unsigned int option_flags,
						struct acpi_resource *r)
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
	unsigned char flags = 0;

	status = acpi_resource_to_address64(r, p);
	if (ACPI_FAILURE(status)) {
		dev_warn(&dev->dev, "can't convert resource type %d\n",
			 r->type);
		return;
	}

	if (p->resource_type == ACPI_MEMORY_RANGE) {
		if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
			flags = IORESOURCE_MEM_WRITEABLE;
		pnp_register_mem_resource(dev, option_flags, p->minimum,
					  p->minimum, 0, p->address_length,
					  flags);
	} else if (p->resource_type == ACPI_IO_RANGE)
		pnp_register_port_resource(dev, option_flags, p->minimum,
					   p->minimum, 0, p->address_length,
					   IORESOURCE_IO_FIXED);
}
Пример #2
0
static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
						  struct acpi_resource *res)
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;

	status = acpi_resource_to_address64(res, p);
	if (!ACPI_SUCCESS(status)) {
		dev_warn(&dev->dev, "failed to convert resource type %d\n",
			 res->type);
		return;
	}

	if (p->producer_consumer == ACPI_PRODUCER)
		return;

	if (p->resource_type == ACPI_MEMORY_RANGE)
		pnpacpi_parse_allocated_memresource(dev,
			p->minimum, p->address_length,
			p->info.mem.write_protect);
	else if (p->resource_type == ACPI_IO_RANGE)
		pnpacpi_parse_allocated_ioresource(dev,
			p->minimum, p->address_length,
			p->granularity == 0xfff ? ACPI_DECODE_10 :
				ACPI_DECODE_16);
}
Пример #3
0
static int
acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
{
	acpi_status status;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_resource *resource = NULL;
	struct acpi_resource_address64 address64;

	ACPI_FUNCTION_TRACE("acpi_memory_get_device_resources");

	/* Get the range from the _CRS */
	status = acpi_get_current_resources(mem_device->handle, &buffer);
	if (ACPI_FAILURE(status))
		return_VALUE(-EINVAL);

	resource = (struct acpi_resource *)buffer.pointer;
	status = acpi_resource_to_address64(resource, &address64);
	if (ACPI_SUCCESS(status)) {
		if (address64.resource_type == ACPI_MEMORY_RANGE) {
			/* Populate the structure */
			mem_device->cache_attribute =
			    address64.attribute.memory.cache_attribute;
			mem_device->read_write_attribute =
			    address64.attribute.memory.read_write_attribute;
			mem_device->start_addr = address64.min_address_range;
			mem_device->end_addr = address64.max_address_range;
		}
	}

	acpi_os_free(buffer.pointer);
	return_VALUE(0);
}
static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
						  struct acpi_resource *res)
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
	int window;
	u64 len;

	status = acpi_resource_to_address64(res, p);
	if (!ACPI_SUCCESS(status)) {
		dev_warn(&dev->dev, "failed to convert resource type %d\n",
			 res->type);
		return;
	}

	/* Windows apparently computes length rather than using _LEN */
	len = p->maximum - p->minimum + 1;
	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;

	if (p->resource_type == ACPI_MEMORY_RANGE)
		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
			p->info.mem.write_protect, window);
	else if (p->resource_type == ACPI_IO_RANGE)
		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
			p->granularity == 0xfff ? ACPI_DECODE_10 :
				ACPI_DECODE_16, window);
	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
}
Пример #5
0
/**
 * acpi_dev_resource_address_space - Extract ACPI address space information.
 * @ares: Input ACPI resource object.
 * @win: Output generic resource object.
 *
 * Check if the given ACPI resource object represents an address space resource
 * and if that's the case, use the information in it to populate the generic
 * resource object pointed to by @win.
 *
 * Return:
 * 1) false with win->res.flags setting to zero: not the expected resource type
 * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
 *    resource
 * 3) true: valid assigned resource
 */
bool acpi_dev_resource_address_space(struct acpi_resource *ares,
				     struct resource_win *win)
{
	struct acpi_resource_address64 addr;

	win->res.flags = 0;
	if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr)))
		return false;

	return acpi_decode_space(win, (struct acpi_resource_address *)&addr,
				 &addr.address);
}
Пример #6
0
static acpi_status
count_window (struct acpi_resource *resource, void *data)
{
	unsigned int *windows = (unsigned int *) data;
	struct acpi_resource_address64 addr;
	acpi_status status;

	status = acpi_resource_to_address64(resource, &addr);
	if (ACPI_SUCCESS(status))
		if (addr.resource_type == ACPI_MEMORY_RANGE ||
		    addr.resource_type == ACPI_IO_RANGE)
			(*windows)++;

	return AE_OK;
}
Пример #7
0
static acpi_status
resource_to_addr(struct acpi_resource *resource,
			struct acpi_resource_address64 *addr)
{
	acpi_status status;
	struct acpi_resource_memory24 *memory24;
	struct acpi_resource_memory32 *memory32;
	struct acpi_resource_fixed_memory32 *fixed_memory32;

	memset(addr, 0, sizeof(*addr));
	switch (resource->type) {
	case ACPI_RESOURCE_TYPE_MEMORY24:
		memory24 = &resource->data.memory24;
		addr->resource_type = ACPI_MEMORY_RANGE;
		addr->minimum = memory24->minimum;
		addr->address_length = memory24->address_length;
		addr->maximum = addr->minimum + addr->address_length - 1;
		return AE_OK;
	case ACPI_RESOURCE_TYPE_MEMORY32:
		memory32 = &resource->data.memory32;
		addr->resource_type = ACPI_MEMORY_RANGE;
		addr->minimum = memory32->minimum;
		addr->address_length = memory32->address_length;
		addr->maximum = addr->minimum + addr->address_length - 1;
		return AE_OK;
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
		fixed_memory32 = &resource->data.fixed_memory32;
		addr->resource_type = ACPI_MEMORY_RANGE;
		addr->minimum = fixed_memory32->address;
		addr->address_length = fixed_memory32->address_length;
		addr->maximum = addr->minimum + addr->address_length - 1;
		return AE_OK;
	case ACPI_RESOURCE_TYPE_ADDRESS16:
	case ACPI_RESOURCE_TYPE_ADDRESS32:
	case ACPI_RESOURCE_TYPE_ADDRESS64:
		status = acpi_resource_to_address64(resource, addr);
		if (ACPI_SUCCESS(status) &&
		    (addr->resource_type == ACPI_MEMORY_RANGE ||
		    addr->resource_type == ACPI_IO_RANGE) &&
		    addr->address_length > 0) {
			return AE_OK;
		}
		break;
	}
	return AE_ERROR;
}
Пример #8
0
static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data)
{
	struct serial_struct *serial_req = (struct serial_struct *) data;
	struct acpi_resource_address64 addr;
	acpi_status status;

	status = acpi_resource_to_address64(res, &addr);
	if (ACPI_SUCCESS(status))
		return acpi_serial_mmio(serial_req, &addr);
	else if (res->id == ACPI_RSTYPE_IO)
		return acpi_serial_port(serial_req, &res->data.io);
	else if (res->id == ACPI_RSTYPE_EXT_IRQ)
		return acpi_serial_ext_irq(serial_req, &res->data.extended_irq);
	else if (res->id == ACPI_RSTYPE_IRQ)
		return acpi_serial_irq(serial_req, &res->data.irq);
	return AE_OK;
}
Пример #9
0
static acpi_status find_csr_space(struct acpi_resource *resource, void *data)
{
	struct csr_space *space = data;
	struct acpi_resource_address64 addr;
	acpi_status status;

	status = acpi_resource_to_address64(resource, &addr);
	if (ACPI_SUCCESS(status) &&
	    addr.resource_type == ACPI_MEMORY_RANGE &&
	    addr.address_length &&
	    addr.producer_consumer == ACPI_CONSUMER) {
		space->base = addr.minimum;
		space->length = addr.address_length;
		return AE_CTRL_TERMINATE;
	}
	return AE_OK;		/*              */
}
Пример #10
0
static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
{
	struct pci_root_info *info = data;
	struct pci_window *window;
	struct acpi_resource_address64 addr;
	acpi_status status;
	unsigned long flags, offset = 0;
	struct resource *root;

	status = acpi_resource_to_address64(res, &addr);
	if (!ACPI_SUCCESS(status))
		return AE_OK;

	if (!addr.address_length)
		return AE_OK;

	if (addr.resource_type == ACPI_MEMORY_RANGE) {
		flags = IORESOURCE_MEM;
		root = &iomem_resource;
		offset = addr.address_translation_offset;
	} else if (addr.resource_type == ACPI_IO_RANGE) {
		flags = IORESOURCE_IO;
		root = &ioport_resource;
		offset = add_io_space(&addr);
		if (offset == ~0)
			return AE_OK;
	} else
		return AE_OK;

	window = &info->controller->window[info->controller->windows++];
	window->resource.name = info->name;
	window->resource.flags = flags;
	window->resource.start = addr.min_address_range + offset;
	window->resource.end = addr.max_address_range + offset;
	window->resource.child = NULL;
	window->offset = offset;

	if (insert_resource(root, &window->resource)) {
		printk(KERN_ERR "alloc 0x%lx-0x%lx from %s for %s failed\n",
			window->resource.start, window->resource.end,
			root->name, info->name);
	}

	return AE_OK;
}
Пример #11
0
static acpi_status
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{
	struct resource *res = data;
	struct acpi_resource_address64 address;
	acpi_status status;

	status = acpi_resource_to_address64(resource, &address);
	if (ACPI_FAILURE(status))
		return AE_OK;

	if ((address.address_length > 0) &&
	    (address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
		res->start = address.minimum;
		res->end = address.minimum + address.address_length - 1;
	}

	return AE_OK;
}
Пример #12
0
static acpi_status
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{
	struct resource *res = data;
	struct acpi_resource_address64 address;

	if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
		return AE_OK;

	acpi_resource_to_address64(resource, &address);
	if ((address.address_length > 0) &&
	    (address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
		res->start = address.minimum;
		res->end = address.minimum + address.address_length - 1;
	}

	return AE_OK;
}
Пример #13
0
static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
	struct acpi_resource_address64 *addr)
{
	acpi_status status;

	/*
	 * We're only interested in _CRS descriptors that are
	 *	- address space descriptors for memory or I/O space
	 *	- non-zero size
	 *	- producers, i.e., the address space is routed downstream,
	 *	  not consumed by the bridge itself
	 */
	status = acpi_resource_to_address64(resource, addr);
	if (ACPI_SUCCESS(status) &&
	    (addr->resource_type == ACPI_MEMORY_RANGE ||
	     addr->resource_type == ACPI_IO_RANGE) &&
	    addr->address_length &&
	    addr->producer_consumer == ACPI_PRODUCER)
		return AE_OK;

	return AE_ERROR;
}
Пример #14
0
static void
pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r)
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;
	struct pnp_mem *mem;
	struct pnp_port *port;

	status = acpi_resource_to_address64(r, p);
	if (!ACPI_SUCCESS(status)) {
		pnp_warn("PnPACPI: failed to convert resource type %d", r->type);
		return;
	}

	if (p->address_length == 0)
		return;

	if (p->resource_type == ACPI_MEMORY_RANGE) {
		mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
		if (!mem)
			return;
		mem->min = mem->max = p->minimum;
		mem->size = p->address_length;
		mem->align = 0;
		mem->flags = (p->info.mem.write_protect ==
		    ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0;
		pnp_register_mem_resource(option, mem);
	} else if (p->resource_type == ACPI_IO_RANGE) {
		port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
		if (!port)
			return;
		port->min = port->max = p->minimum;
		port->size = p->address_length;
		port->align = 0;
		port->flags = PNP_PORT_FLAG_FIXED;
		pnp_register_port_resource(option, port);
	}
}
Пример #15
0
static void
pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
	struct acpi_resource *res)
{
	struct acpi_resource_address64 addr, *p = &addr;
	acpi_status status;

	status = acpi_resource_to_address64(res, p);
	if (!ACPI_SUCCESS(status)) {
		pnp_warn("PnPACPI: failed to convert resource type %d",
			res->type);
		return;
	}

	if (p->producer_consumer == ACPI_PRODUCER)
		return;

	if (p->resource_type == ACPI_MEMORY_RANGE)
		pnpacpi_parse_allocated_memresource(res_table,
				p->minimum, p->address_length);
	else if (p->resource_type == ACPI_IO_RANGE)
		pnpacpi_parse_allocated_ioresource(res_table,
				p->minimum, p->address_length);
}