]> mj.ucw.cz Git - pciutils.git/blob - lib/fbsd-device.c
b770c58a220ed5ba1e7237c38e81dde98b16745a
[pciutils.git] / lib / fbsd-device.c
1 /*
2  *      The PCI Library -- FreeBSD /dev/pci access
3  *
4  *      Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
5  *      Updated in 2003 by Samy Al Bahra <samy@kerneled.com>
6  *
7  *      Can be freely distributed and used under the terms of the GNU GPL.
8  */
9
10 #include <fcntl.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <osreldate.h>
14 #include <stdint.h>
15
16 #ifdef __FreeBSD_kernel_version
17 #  ifndef __FreeBSD_version
18 #    define __FreeBSD_version __FreeBSD_kernel_version
19 #  endif
20 #endif
21
22 #if defined(__DragonFly__)
23 #  include <bus/pci/pcivar.h>
24 #elif __FreeBSD_version < 500000
25 #  include <pci/pcivar.h>
26 #else
27 #  include <dev/pci/pcivar.h>
28 #endif
29
30 #if __FreeBSD_version < 430000 && !defined(__DragonFly__)
31 #  include <pci/pci_ioctl.h>
32 #else
33 #  include <sys/pciio.h>
34 #endif
35
36 #include "internal.h"
37
38 static void
39 fbsd_config(struct pci_access *a)
40 {
41   a->method_params[PCI_ACCESS_FBSD_DEVICE] = PCI_PATH_FBSD_DEVICE;
42 }
43
44 static int
45 fbsd_detect(struct pci_access *a)
46 {
47   char *name = a->method_params[PCI_ACCESS_FBSD_DEVICE];
48
49   if (access(name, R_OK))
50     {
51       a->warning("Cannot open %s", name);
52       return 0;
53     }
54   a->debug("...using %s", name);
55   return 1;
56 }
57
58 static void
59 fbsd_init(struct pci_access *a)
60 {
61   char *name = a->method_params[PCI_ACCESS_FBSD_DEVICE];
62
63   a->fd = open(name, O_RDWR, 0);
64   if (a->fd < 0)
65     {
66       a->error("fbsd_init: %s open failed", name);
67     }
68 }
69
70 static void
71 fbsd_cleanup(struct pci_access *a)
72 {
73   close(a->fd);
74 }
75
76 static int
77 fbsd_read(struct pci_dev *d, int pos, byte *buf, int len)
78 {
79   struct pci_io pi;
80
81   if (!(len == 1 || len == 2 || len == 4))
82     {
83       return pci_generic_block_read(d, pos, buf, len);
84     }
85
86   if (pos >= 256)
87     return 0;
88
89   pi.pi_sel.pc_bus = d->bus;
90   pi.pi_sel.pc_dev = d->dev;
91   pi.pi_sel.pc_func = d->func;
92
93   pi.pi_reg = pos;
94   pi.pi_width = len;
95
96   if (ioctl(d->access->fd, PCIOCREAD, &pi) < 0)
97     d->access->error("fbsd_read: ioctl(PCIOCREAD) failed");
98
99   switch (len)
100     {
101     case 1:
102       buf[0] = (u8) pi.pi_data;
103       break;
104     case 2:
105       ((u16 *) buf)[0] = (u16) pi.pi_data;
106       break;
107     case 4:
108       ((u32 *) buf)[0] = (u32) pi.pi_data;
109       break;
110     }
111   return 1;
112 }
113
114 static int
115 fbsd_write(struct pci_dev *d, int pos, byte *buf, int len)
116 {
117   struct pci_io pi;
118
119   if (!(len == 1 || len == 2 || len == 4))
120     {
121       return pci_generic_block_write(d, pos, buf, len);
122     }
123
124   if (pos >= 256)
125     return 0;
126
127   pi.pi_sel.pc_bus = d->bus;
128   pi.pi_sel.pc_dev = d->dev;
129   pi.pi_sel.pc_func = d->func;
130
131   pi.pi_reg = pos;
132   pi.pi_width = len;
133
134   switch (len)
135     {
136     case 1:
137       pi.pi_data = buf[0];
138       break;
139     case 2:
140       pi.pi_data = ((u16 *) buf)[0];
141       break;
142     case 4:
143       pi.pi_data = ((u32 *) buf)[0];
144       break;
145     }
146
147   if (ioctl(d->access->fd, PCIOCWRITE, &pi) < 0)
148     {
149       d->access->error("fbsd_write: ioctl(PCIOCWRITE) failed");
150     }
151
152   return 1;
153 }
154
155 struct pci_methods pm_fbsd_device = {
156   "FreeBSD-device",
157   fbsd_config,
158   fbsd_detect,
159   fbsd_init,
160   fbsd_cleanup,
161   pci_generic_scan,
162   pci_generic_fill_info,
163   fbsd_read,
164   fbsd_write,
165   NULL,                                 /* dev_init */
166   NULL                                  /* dev_cleanup */
167 };