]> mj.ucw.cz Git - pciutils.git/blob - lib/nbsd-libpci.c
Arguments now correspond to the format string
[pciutils.git] / lib / nbsd-libpci.c
1 /*
2  *      The PCI Library -- NetBSD libpci access
3  *         (based on FreeBSD /dev/pci access)
4  *
5  *      Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
6  *      Copyright (c) 2002 Quentin Garnier <cube@cubidou.net>
7  *      Copyright (c) 2002 Martin Mares <mj@ucw.cz>
8  *
9  *      Can be freely distributed and used under the terms of the GNU GPL.
10  */
11
12 /*
13  *      Read functionality of this driver is briefly tested, and seems
14  *      to supply basic information correctly, but I promise no more.
15  */
16
17 #include <fcntl.h>
18 #include <string.h>
19 #include <unistd.h>
20
21 #include <pci.h>
22
23 #include "internal.h"
24
25 static void
26 nbsd_config(struct pci_access *a)
27 {
28   a->method_params[PCI_ACCESS_NBSD_LIBPCI] = PATH_NBSD_DEVICE;
29 }
30
31 static int
32 nbsd_detect(struct pci_access *a)
33 {
34   char *name = a->method_params[PCI_ACCESS_NBSD_LIBPCI];
35
36   if (access(name, R_OK))
37     {
38       a->warning("Cannot open %s", name);
39       return 0;
40     }
41   a->debug("...using %s", name);
42   return 1;
43 }
44
45 static void
46 nbsd_init(struct pci_access *a)
47 {
48   char *name = a->method_params[PCI_ACCESS_NBSD_LIBPCI];
49
50   a->fd = open(name, O_RDWR, 0);
51   if (a->fd < 0)
52     a->error("nbsd_init: %s open failed", name);
53 }
54
55 static void
56 nbsd_cleanup(struct pci_access *a)
57 {
58   close(a->fd);
59 }
60
61 static int
62 nbsd_read(struct pci_dev *d, int pos, byte *buf, int len)
63 {
64   pcireg_t val;
65   int shift;
66
67   if (!(len == 1 || len == 2 || len == 4))
68     return pci_generic_block_read(d, pos, buf, len);
69
70   if (pos >= 256)
71     return 0;
72
73   shift = 8*(pos % 4);
74   pos &= ~3;
75         
76   if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
77     d->access->error("nbsd_read: pci_bus_conf_read() failed");
78
79   switch (len)
80     {
81     case 1:
82       *buf = val >> shift;
83       break;
84     case 2:
85       *(u16*)buf = cpu_to_le16(val >> shift);
86       break;
87     case 4:
88       *(u32*)buf = cpu_to_le32(val);
89       break;
90     }
91   return 1;
92 }
93
94 static int
95 nbsd_write(struct pci_dev *d, int pos, byte *buf, int len)
96 {
97   pcireg_t val = 0;
98   int shift;
99
100   if (!(len == 1 || len == 2 || len == 4))
101     return pci_generic_block_write(d, pos, buf, len);
102
103   if (pos >= 256)
104     return 0;
105
106   /*
107    *  BEWARE: NetBSD seems to support only 32-bit access, so we have
108    *  to emulate byte and word writes by read-modify-write, possibly
109    *  causing troubles.
110    */
111
112   shift = 8*(pos % 4);
113   pos &= ~3;
114   if (len != 4)
115     {
116       if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
117         d->access->error("nbsd_write: pci_bus_conf_read() failed");
118     }
119
120   switch (len)
121     {
122     case 1:
123       val = (val & ~(0xff << shift)) | (buf[0] << shift);
124       break;
125     case 2:
126       val = (val & ~(0xffff << shift)) | (le16_to_cpu(*(u16*)buf) << shift);
127       break;
128     case 4:
129       val = le32_to_cpu(*(u32*)buf);
130       break;
131     }
132   
133   if (pcibus_conf_write(d->access->fd, d->bus, d->dev, d->func, pos, val) < 0)
134     d->access->error("nbsd_write: pci_bus_conf_write() failed");
135
136   return 1;
137 }
138
139 struct pci_methods pm_nbsd_libpci = {
140   "NetBSD-libpci",
141   nbsd_config,
142   nbsd_detect,
143   nbsd_init,
144   nbsd_cleanup,
145   pci_generic_scan,
146   pci_generic_fill_info,
147   nbsd_read,
148   nbsd_write,
149   NULL,                                 /* dev_init */
150   NULL                                  /* dev_cleanup */
151 };