// SPDX-License-Identifier: GPL-2.0
/*
 * 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";
	case IORESOURCE_BUS:
		return "bus";
	}
	return "unknown";
}

void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
{
	struct pnp_resource *pnp_res;

	if (list_empty(&dev->resources))
		pnp_dbg(&dev->dev, "%s: no current resources\n", desc);
	else {
		pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
		list_for_each_entry(pnp_res, &dev->resources, list)
			pnp_dbg(&dev->dev, "%pr\n", &pnp_res->res);
	}
}

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)
{
	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 += scnprintf(buf + len, sizeof(buf) - len,
				 "  dependent set %d (%s) ",
				 pnp_option_set(option),
				 pnp_option_priority_name(option));
	else
		len += scnprintf(buf + len, sizeof(buf) - len,
				 "  independent ");

	switch (option->type) {
	case IORESOURCE_IO:
		port = &option->u.port;
		len += scnprintf(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 += scnprintf(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 += scnprintf(buf + len, sizeof(buf) - len, "irq");
		if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
			len += scnprintf(buf + len, sizeof(buf) - len,
					 " <none>");
		else {
			for (i = 0; i < PNP_IRQ_NR; i++)
				if (test_bit(i, irq->map.bits))
					len += scnprintf(buf + len,
							 sizeof(buf) - len,
							 " %d", i);
		}
		len += scnprintf(buf + len, sizeof(buf) - len, " flags %#x",
				 irq->flags);
		if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
			len += scnprintf(buf + len, sizeof(buf) - len,
					 " (optional)");
		break;
	case IORESOURCE_DMA:
		dma = &option->u.dma;
		len += scnprintf(buf + len, sizeof(buf) - len, "dma");
		if (!dma->map)
			len += scnprintf(buf + len, sizeof(buf) - len,
					 " <none>");
		else {
			for (i = 0; i < 8; i++)
				if (dma->map & (1 << i))
					len += scnprintf(buf + len,
							 sizeof(buf) - len,
							 " %d", i);
		}
		len += scnprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) "
				 "flags %#x", dma->map, dma->flags);
		break;
	}
	pnp_dbg(&dev->dev, "%s\n", buf);
}
