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