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