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