Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * support.c - standard functions for the use of pnp protocol drivers
4 : : *
5 : : * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
6 : : * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 : : * Bjorn Helgaas <bjorn.helgaas@hp.com>
8 : : */
9 : :
10 : : #include <linux/module.h>
11 : : #include <linux/ctype.h>
12 : : #include <linux/pnp.h>
13 : : #include "base.h"
14 : :
15 : : /**
16 : : * pnp_is_active - Determines if a device is active based on its current
17 : : * resources
18 : : * @dev: pointer to the desired PnP device
19 : : */
20 : 0 : int pnp_is_active(struct pnp_dev *dev)
21 : : {
22 : : /*
23 : : * I don't think this is very reliable because pnp_disable_dev()
24 : : * only clears out auto-assigned resources.
25 : : */
26 [ # # # # : 0 : if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 &&
# # ]
27 [ # # # # ]: 0 : !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 &&
28 [ # # ]: 0 : pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1)
29 : : return 0;
30 : : else
31 : 0 : return 1;
32 : : }
33 : :
34 : : EXPORT_SYMBOL(pnp_is_active);
35 : :
36 : : /*
37 : : * Functionally similar to acpi_ex_eisa_id_to_string(), but that's
38 : : * buried in the ACPI CA, and we can't depend on it being present.
39 : : */
40 : 0 : void pnp_eisa_id_to_string(u32 id, char *str)
41 : : {
42 : 0 : id = be32_to_cpu(id);
43 : :
44 : : /*
45 : : * According to the specs, the first three characters are five-bit
46 : : * compressed ASCII, and the left-over high order bit should be zero.
47 : : * However, the Linux ISAPNP code historically used six bits for the
48 : : * first character, and there seem to be IDs that depend on that,
49 : : * e.g., "nEC8241" in the Linux 8250_pnp serial driver and the
50 : : * FreeBSD sys/pc98/cbus/sio_cbus.c driver.
51 : : */
52 : 0 : str[0] = 'A' + ((id >> 26) & 0x3f) - 1;
53 : 0 : str[1] = 'A' + ((id >> 21) & 0x1f) - 1;
54 : 0 : str[2] = 'A' + ((id >> 16) & 0x1f) - 1;
55 : 0 : str[3] = hex_asc_hi(id >> 8);
56 : 0 : str[4] = hex_asc_lo(id >> 8);
57 : 0 : str[5] = hex_asc_hi(id);
58 : 0 : str[6] = hex_asc_lo(id);
59 : 0 : str[7] = '\0';
60 : 0 : }
61 : :
62 : 0 : char *pnp_resource_type_name(struct resource *res)
63 : : {
64 [ # # # # : 0 : switch (pnp_resource_type(res)) {
# # ]
65 : : case IORESOURCE_IO:
66 : : return "io";
67 : 0 : case IORESOURCE_MEM:
68 : 0 : return "mem";
69 : 0 : case IORESOURCE_IRQ:
70 : 0 : return "irq";
71 : 0 : case IORESOURCE_DMA:
72 : 0 : return "dma";
73 : 0 : case IORESOURCE_BUS:
74 : 0 : return "bus";
75 : : }
76 : 0 : return "unknown";
77 : : }
78 : :
79 : 0 : void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
80 : : {
81 : 0 : struct pnp_resource *pnp_res;
82 : :
83 [ # # ]: 0 : if (list_empty(&dev->resources))
84 [ # # ]: 0 : pnp_dbg(&dev->dev, "%s: no current resources\n", desc);
85 : : else {
86 [ # # ]: 0 : pnp_dbg(&dev->dev, "%s: current resources:\n", desc);
87 [ # # ]: 0 : list_for_each_entry(pnp_res, &dev->resources, list)
88 [ # # ]: 0 : pnp_dbg(&dev->dev, "%pr\n", &pnp_res->res);
89 : : }
90 : 0 : }
91 : :
92 : 0 : char *pnp_option_priority_name(struct pnp_option *option)
93 : : {
94 [ # # ]: 0 : switch (pnp_option_priority(option)) {
95 : : case PNP_RES_PRIORITY_PREFERRED:
96 : : return "preferred";
97 : : case PNP_RES_PRIORITY_ACCEPTABLE:
98 : : return "acceptable";
99 : : case PNP_RES_PRIORITY_FUNCTIONAL:
100 : : return "functional";
101 : : }
102 : : return "invalid";
103 : : }
104 : :
105 : 0 : void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
106 : : {
107 : 0 : char buf[128];
108 : 0 : int len = 0, i;
109 : 0 : struct pnp_port *port;
110 : 0 : struct pnp_mem *mem;
111 : 0 : struct pnp_irq *irq;
112 : 0 : struct pnp_dma *dma;
113 : :
114 [ # # ]: 0 : if (pnp_option_is_dependent(option))
115 [ # # ]: 0 : len += scnprintf(buf + len, sizeof(buf) - len,
116 : : " dependent set %d (%s) ",
117 : : pnp_option_set(option),
118 : : pnp_option_priority_name(option));
119 : : else
120 : 0 : len += scnprintf(buf + len, sizeof(buf) - len,
121 : : " independent ");
122 : :
123 [ # # # # : 0 : switch (option->type) {
# ]
124 : 0 : case IORESOURCE_IO:
125 : 0 : port = &option->u.port;
126 : 0 : len += scnprintf(buf + len, sizeof(buf) - len, "io min %#llx "
127 : : "max %#llx align %lld size %lld flags %#x",
128 : 0 : (unsigned long long) port->min,
129 : 0 : (unsigned long long) port->max,
130 : 0 : (unsigned long long) port->align,
131 : 0 : (unsigned long long) port->size, port->flags);
132 : 0 : break;
133 : 0 : case IORESOURCE_MEM:
134 : 0 : mem = &option->u.mem;
135 : 0 : len += scnprintf(buf + len, sizeof(buf) - len, "mem min %#llx "
136 : : "max %#llx align %lld size %lld flags %#x",
137 : 0 : (unsigned long long) mem->min,
138 : 0 : (unsigned long long) mem->max,
139 : 0 : (unsigned long long) mem->align,
140 : 0 : (unsigned long long) mem->size, mem->flags);
141 : 0 : break;
142 : 0 : case IORESOURCE_IRQ:
143 : 0 : irq = &option->u.irq;
144 : 0 : len += scnprintf(buf + len, sizeof(buf) - len, "irq");
145 [ # # ]: 0 : if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
146 : 0 : len += scnprintf(buf + len, sizeof(buf) - len,
147 : : " <none>");
148 : : else {
149 [ # # ]: 0 : for (i = 0; i < PNP_IRQ_NR; i++)
150 [ # # ]: 0 : if (test_bit(i, irq->map.bits))
151 : 0 : len += scnprintf(buf + len,
152 : : sizeof(buf) - len,
153 : : " %d", i);
154 : : }
155 : 0 : len += scnprintf(buf + len, sizeof(buf) - len, " flags %#x",
156 : 0 : irq->flags);
157 [ # # ]: 0 : if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
158 : 0 : len += scnprintf(buf + len, sizeof(buf) - len,
159 : : " (optional)");
160 : : break;
161 : 0 : case IORESOURCE_DMA:
162 : 0 : dma = &option->u.dma;
163 : 0 : len += scnprintf(buf + len, sizeof(buf) - len, "dma");
164 [ # # ]: 0 : if (!dma->map)
165 : 0 : len += scnprintf(buf + len, sizeof(buf) - len,
166 : : " <none>");
167 : : else {
168 [ # # ]: 0 : for (i = 0; i < 8; i++)
169 [ # # ]: 0 : if (dma->map & (1 << i))
170 : 0 : len += scnprintf(buf + len,
171 : : sizeof(buf) - len,
172 : : " %d", i);
173 : : }
174 : 0 : len += scnprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) "
175 : 0 : "flags %#x", dma->map, dma->flags);
176 : 0 : break;
177 : : }
178 [ # # ]: 0 : pnp_dbg(&dev->dev, "%s\n", buf);
179 : 0 : }
|