/*
 * support.c - standard functions for the use of pnp protocol drivers
 *
 * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
 *	Bjorn Helgaas <bjorn.helgaas@hp.com>
 */

#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/pnp.h>
#include "base.h"

/**
 * pnp_is_active - Determines if a device is active based on its current
 *	resources
 * @dev: pointer to the desired PnP device
 */
int pnp_is_active(struct pnp_dev *dev)
{
	/*
	 * I don't think this is very reliable because pnp_disable_dev()
	 * only clears out auto-assigned resources.
	 */
	if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 &&
	    !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 &&
	    pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1)
		return 0;
	else
		return 1;
}

EXPORT_SYMBOL(pnp_is_active);

/*
 * Functionally similar to acpi_ex_eisa_id_to_string(), but that's
 * buried in the ACPI CA, and we can't depend on it being present.
 */
void pnp_eisa_id_to_string(u32 id, char *str)
{
	id = be32_to_cpu(id);

	/*
	 * According to the specs, the first three characters are five-bit
	 * compressed ASCII, and the left-over high order bit should be zero.
	 * However, the Linux ISAPNP code historically used six bits for the
	 * first character, and there seem to be IDs that depend on that,
	 * e.g., "nEC8241" in the Linux 8250_pnp serial driver and the
	 * FreeBSD sys/pc98/cbus/sio_cbus.c driver.
	 */
	str[0] = 'A' + ((id >> 26) & 0x3f) - 1;
	str[1] = 'A' + ((id >> 21) & 0x1f) - 1;
	str[2] = 'A' + ((id >> 16) & 0x1f) - 1;
	str[3] = hex_asc_hi(id >> 8);
	str[4] = hex_asc_lo(id >> 8);
	str[5] = hex_asc_hi(id);
	str[6] = hex_asc_lo(id);
	str[7] = '\0';
}

char *pnp_resource_type_name(struct resource *res)
{
	switch (pnp_resource_type(res)) {
	case IORESOURCE_IO:
		return "io";
	case IORESOURCE_MEM:
		return "mem";
	case IORESOURCE_IRQ:
		return "irq";
	case IORESOURCE_DMA:
		return "dma";
	}
	return NULL;
}

void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
{
#ifdef DEBUG
	char buf[128];
	int len = 0;
	struct pnp_resource *pnp_res;
	struct resource *res;

	if (list_empty(&dev->resources)) {
		dev_dbg(&dev->dev, "%s: no current resources\n", desc);
		return;
	}

	dev_dbg(&dev->dev, "%s: current resources:\n", desc);
	list_for_each_entry(pnp_res, &dev->resources, list) {
		res = &pnp_res->res;

		len += snprintf(buf + len, sizeof(buf) - len, "  %-3s ",
				pnp_resource_type_name(res));

		if (res->flags & IORESOURCE_DISABLED) {
			dev_dbg(&dev->dev, "%sdisabled\n", buf);
			continue;
		}

		switch (pnp_resource_type(res)) {
		case IORESOURCE_IO:
		case IORESOURCE_MEM:
			len += snprintf(buf + len, sizeof(buf) - len,
					"%#llx-%#llx flags %#lx",
					(unsigned long long) res->start,
					(unsigned long long) res->end,
					res->flags);
			break;
		case IORESOURCE_IRQ:
		case IORESOURCE_DMA:
			len += snprintf(buf + len, sizeof(buf) - len,
					"%lld flags %#lx",
					(unsigned long long) res->start,
					res->flags);
			break;
		}
		dev_dbg(&dev->dev, "%s\n", buf);
	}
#endif
}

char *pnp_option_priority_name(struct pnp_option *option)
{
	switch (pnp_option_priority(option)) {
	case PNP_RES_PRIORITY_PREFERRED:
		return "preferred";
	case PNP_RES_PRIORITY_ACCEPTABLE:
		return "acceptable";
	case PNP_RES_PRIORITY_FUNCTIONAL:
		return "functional";
	}
	return "invalid";
}

void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
{
#ifdef DEBUG
	char buf[128];
	int len = 0, i;
	struct pnp_port *port;
	struct pnp_mem *mem;
	struct pnp_irq *irq;
	struct pnp_dma *dma;

	if (pnp_option_is_dependent(option))
		len += snprintf(buf + len, sizeof(buf) - len,
				"  dependent set %d (%s) ",
				pnp_option_set(option),
				pnp_option_priority_name(option));
	else
		len += snprintf(buf + len, sizeof(buf) - len, "  independent ");

	switch (option->type) {
	case IORESOURCE_IO:
		port = &option->u.port;
		len += snprintf(buf + len, sizeof(buf) - len, "io  min %#llx "
				"max %#llx align %lld size %lld flags %#x",
				(unsigned long long) port->min,
				(unsigned long long) port->max,
				(unsigned long long) port->align,
				(unsigned long long) port->size, port->flags);
		break;
	case IORESOURCE_MEM:
		mem = &option->u.mem;
		len += snprintf(buf + len, sizeof(buf) - len, "mem min %#llx "
				"max %#llx align %lld size %lld flags %#x",
				(unsigned long long) mem->min,
				(unsigned long long) mem->max,
				(unsigned long long) mem->align,
				(unsigned long long) mem->size, mem->flags);
		break;
	case IORESOURCE_IRQ:
		irq = &option->u.irq;
		len += snprintf(buf + len, sizeof(buf) - len, "irq");
		if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
			len += snprintf(buf + len, sizeof(buf) - len,
					" <none>");
		else {
			for (i = 0; i < PNP_IRQ_NR; i++)
				if (test_bit(i, irq->map.bits))
					len += snprintf(buf + len,
							sizeof(buf) - len,
							" %d", i);
		}
		len += snprintf(buf + len, sizeof(buf) - len, " flags %#x",
				irq->flags);
		if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
			len += snprintf(buf + len, sizeof(buf) - len,
					" (optional)");
		break;
	case IORESOURCE_DMA:
		dma = &option->u.dma;
		len += snprintf(buf + len, sizeof(buf) - len, "dma");
		if (!dma->map)
			len += snprintf(buf + len, sizeof(buf) - len,
					" <none>");
		else {
			for (i = 0; i < 8; i++)
				if (dma->map & (1 << i))
					len += snprintf(buf + len,
							sizeof(buf) - len,
							" %d", i);
		}
		len += snprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) "
				"flags %#x", dma->map, dma->flags);
		break;
	}
	dev_dbg(&dev->dev, "%s\n", buf);
#endif
}
