Annotation of embedaddon/pciutils/lib/obsd-device.c, revision 1.1.1.1
1.1 misho 1: /*
2: * The PCI Library -- OpenBSD /dev/pci access
3: *
4: * Adapted from fbsd-device.c by Matthieu Herrb <matthieu.herrb@laas.fr>, 2006
5: *
6: * Can be freely distributed and used under the terms of the GNU GPL.
7: */
8:
9: #include <fcntl.h>
10: #include <string.h>
11: #include <unistd.h>
12: #include <errno.h>
13: #include <sys/endian.h>
14: #include <sys/types.h>
15: #include <sys/ioctl.h>
16: #include <sys/pciio.h>
17: #include "internal.h"
18:
19: static void
20: obsd_config(struct pci_access *a)
21: {
22: pci_define_param(a, "obsd.path", PCI_PATH_OBSD_DEVICE, "Path to the OpenBSD PCI device");
23: }
24:
25: static int
26: obsd_detect(struct pci_access *a)
27: {
28: char *name = pci_get_param(a, "obsd.path");
29:
30: if (access(name, R_OK))
31: {
32: a->warning("Cannot open %s", name);
33: return 0;
34: }
35: a->debug("...using %s", name);
36: return 1;
37: }
38:
39: static void
40: obsd_init(struct pci_access *a)
41: {
42: char *name = pci_get_param(a, "obsd.path");
43:
44: a->fd = open(name, O_RDWR, 0);
45: if (a->fd < 0)
46: a->error("obsd_init: %s open failed", name);
47: }
48:
49: static void
50: obsd_cleanup(struct pci_access *a)
51: {
52: close(a->fd);
53: }
54:
55: static int
56: obsd_read(struct pci_dev *d, int pos, byte *buf, int len)
57: {
58: struct pci_io pi;
59: union {
60: u_int32_t u32;
61: u_int16_t u16[2];
62: u_int8_t u8[4];
63: } u;
64:
65: if (!(len == 1 || len == 2 || len == 4))
66: return pci_generic_block_read(d, pos, buf, len);
67:
68: if (pos >= 256)
69: return 0;
70:
71: pi.pi_sel.pc_bus = d->bus;
72: pi.pi_sel.pc_dev = d->dev;
73: pi.pi_sel.pc_func = d->func;
74:
75: pi.pi_reg = pos - (pos % 4);
76: pi.pi_width = 4;
77:
78: if (ioctl(d->access->fd, PCIOCREAD, &pi) < 0) {
79: if (errno == ENXIO)
80: pi.pi_data = 0xffffffff;
81: else
82: d->access->error("obsd_read: ioctl(PCIOCREAD) failed");
83: }
84: u.u32 = pi.pi_data;
85:
86: switch (len)
87: {
88: case 1:
89: buf[0] = (u8) u.u8[pos % 4];
90: break;
91: case 2:
92: ((u16 *) buf)[0] = letoh16(u.u16[(pos % 4) / 2]);
93: break;
94: case 4:
95: ((u32 *) buf)[0] = (u32) letoh32(pi.pi_data);
96: break;
97: }
98: return 1;
99: }
100:
101: static int
102: obsd_write(struct pci_dev *d, int pos, byte *buf, int len)
103: {
104: struct pci_io pi;
105:
106: if (!(len == 1 || len == 2 || len == 4))
107: return pci_generic_block_write(d, pos, buf, len);
108:
109: if (pos >= 256)
110: return 0;
111:
112: pi.pi_sel.pc_bus = d->bus;
113: pi.pi_sel.pc_dev = d->dev;
114: pi.pi_sel.pc_func = d->func;
115:
116: pi.pi_reg = pos;
117: pi.pi_width = len;
118:
119: switch (len)
120: {
121: case 1:
122: pi.pi_data = buf[0];
123: break;
124: case 2:
125: pi.pi_data = ((u16 *) buf)[0];
126: break;
127: case 4:
128: pi.pi_data = ((u32 *) buf)[0];
129: break;
130: }
131:
132: if (ioctl(d->access->fd, PCIOCWRITE, &pi) < 0)
133: d->access->error("obsd_write: ioctl(PCIOCWRITE) failed");
134:
135: return 1;
136: }
137:
138: struct pci_methods pm_obsd_device = {
139: "obsd-device",
140: "/dev/pci on OpenBSD",
141: obsd_config,
142: obsd_detect,
143: obsd_init,
144: obsd_cleanup,
145: pci_generic_scan,
146: pci_generic_fill_info,
147: obsd_read,
148: obsd_write,
149: NULL, /* read_vpd */
150: NULL, /* dev_init */
151: NULL /* dev_cleanup */
152: };
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>