// 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);
}
