Subversion Repositories HelenOS-historic

Rev

Rev 1301 | Rev 1307 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1301 Rev 1302
Line 14... Line 14...
14
#include <string.h>
14
#include <string.h>
15
 
15
 
16
#include "internal.h"
16
#include "internal.h"
17
 
17
 
18
static struct pci_methods *pci_methods[PCI_ACCESS_MAX] = {
18
static struct pci_methods *pci_methods[PCI_ACCESS_MAX] = {
19
  &pm_intel_conf1,
19
    &pm_intel_conf1,
20
  &pm_intel_conf2,
20
    &pm_intel_conf2,
21
};
21
};
22
 
22
 
23
struct pci_access *
23
struct pci_access *pci_alloc(void)
24
pci_alloc(void)
-
 
25
{
24
{
26
  struct pci_access *a = malloc(sizeof(struct pci_access));
25
    struct pci_access *a = malloc(sizeof(struct pci_access));
27
  int i;
26
    int i;
28
 
27
 
29
  bzero(a, sizeof(*a));
28
    bzero(a, sizeof(*a));
30
  for(i=0; i<PCI_ACCESS_MAX; i++)
29
    for (i = 0; i < PCI_ACCESS_MAX; i++)
31
    if (pci_methods[i] && pci_methods[i]->config)
30
        if (pci_methods[i] && pci_methods[i]->config)
32
      pci_methods[i]->config(a);
31
            pci_methods[i]->config(a);
33
  return a;
32
    return a;
34
}
33
}
35
 
34
 
36
void *
-
 
37
pci_malloc(struct pci_access *a, int size)
35
void *pci_malloc(struct pci_access *a, int size)
38
{
36
{
39
  void *x = malloc(size);
37
    void *x = malloc(size);
40
 
38
 
41
  if (!x)
39
    if (!x)
42
    a->error("Out of memory (allocation of %d bytes failed)", size);
40
        a->error("Out of memory (allocation of %d bytes failed)",
-
 
41
             size);
43
  return x;
42
    return x;
44
}
43
}
45
 
44
 
46
void
-
 
47
pci_mfree(void *x)
45
void pci_mfree(void *x)
48
{
46
{
49
  if (x)
47
    if (x)
50
    free(x);
48
        free(x);
51
}
49
}
52
 
50
 
53
static void
-
 
54
pci_generic_error(char *msg, ...)
51
static void pci_generic_error(char *msg, ...)
55
{
52
{
56
  va_list args;
53
    va_list args;
57
 
54
 
58
  va_start(args, msg);
55
    va_start(args, msg);
59
  puts("pcilib: ");
56
    puts("pcilib: ");
60
  vprintf(msg, args);
57
    vprintf(msg, args);
61
  putchar('\n');
58
    putchar('\n');
62
  exit(1);
59
    exit(1);
63
}
60
}
64
 
61
 
65
static void
-
 
66
pci_generic_warn(char *msg, ...)
62
static void pci_generic_warn(char *msg, ...)
67
{
63
{
68
  va_list args;
64
    va_list args;
69
 
65
 
70
  va_start(args, msg);
66
    va_start(args, msg);
71
  puts("pcilib: ");
67
    puts("pcilib: ");
72
  vprintf(msg, args);
68
    vprintf(msg, args);
73
  putchar('\n');
69
    putchar('\n');
74
}
70
}
75
 
71
 
76
static void
-
 
77
pci_generic_debug(char *msg, ...)
72
static void pci_generic_debug(char *msg, ...)
78
{
73
{
79
  va_list args;
74
    va_list args;
80
 
75
 
81
  va_start(args, msg);
76
    va_start(args, msg);
82
  vprintf(msg, args);
77
    vprintf(msg, args);
83
  va_end(args);
78
    va_end(args);
84
}
79
}
85
 
80
 
86
static void
-
 
87
pci_null_debug(char *msg UNUSED, ...)
81
static void pci_null_debug(char *msg UNUSED, ...)
88
{
82
{
89
}
83
}
90
 
84
 
91
void
-
 
92
pci_init(struct pci_access *a)
85
void pci_init(struct pci_access *a)
93
{
86
{
94
  if (!a->error)
87
    if (!a->error)
95
    a->error = pci_generic_error;
88
        a->error = pci_generic_error;
96
  if (!a->warning)
89
    if (!a->warning)
97
    a->warning = pci_generic_warn;
90
        a->warning = pci_generic_warn;
98
  if (!a->debug)
91
    if (!a->debug)
99
    a->debug = pci_generic_debug;
92
        a->debug = pci_generic_debug;
100
  if (!a->debugging)
93
    if (!a->debugging)
101
    a->debug = pci_null_debug;
94
        a->debug = pci_null_debug;
102
 
95
 
103
  if (a->method)
96
    if (a->method) {
104
    {
-
 
105
      if (a->method >= PCI_ACCESS_MAX || !pci_methods[a->method])
97
        if (a->method >= PCI_ACCESS_MAX || !pci_methods[a->method])
106
    a->error("This access method is not supported.");
98
            a->error("This access method is not supported.");
107
      a->methods = pci_methods[a->method];
99
        a->methods = pci_methods[a->method];
108
    }
-
 
109
  else
100
    } else {
110
    {
-
 
111
      unsigned int i;
101
        unsigned int i;
112
      for(i=0; i<PCI_ACCESS_MAX; i++)
102
        for (i = 0; i < PCI_ACCESS_MAX; i++)
113
    if (pci_methods[i])
103
            if (pci_methods[i]) {
114
      {
-
 
115
        a->debug("Trying method %d...", i);
104
                a->debug("Trying method %d...", i);
116
        if (pci_methods[i]->detect(a))
105
                if (pci_methods[i]->detect(a)) {
117
          {
-
 
118
        a->debug("...OK\n");
106
                    a->debug("...OK\n");
119
        a->methods = pci_methods[i];
107
                    a->methods = pci_methods[i];
120
        a->method = i;
108
                    a->method = i;
121
        break;
109
                    break;
122
          }
110
                }
123
        a->debug("...No.\n");
111
                a->debug("...No.\n");
124
      }
112
            }
125
      if (!a->methods)
113
        if (!a->methods)
126
    a->error("Cannot find any working access method.");
114
            a->error("Cannot find any working access method.");
127
    }
115
    }
128
  a->debug("Decided to use %s\n", a->methods->name);
116
    a->debug("Decided to use %s\n", a->methods->name);
129
  a->methods->init(a);
117
    a->methods->init(a);
130
}
118
}
131
 
119
 
132
void
-
 
133
pci_cleanup(struct pci_access *a)
120
void pci_cleanup(struct pci_access *a)
134
{
121
{
135
  struct pci_dev *d, *e;
122
    struct pci_dev *d, *e;
136
 
123
 
137
  for(d=a->devices; d; d=e)
124
    for (d = a->devices; d; d = e) {
138
    {
-
 
139
      e = d->next;
125
        e = d->next;
140
      pci_free_dev(d);
126
        pci_free_dev(d);
141
    }
127
    }
142
  if (a->methods)
128
    if (a->methods)
143
    a->methods->cleanup(a);
129
        a->methods->cleanup(a);
144
  pci_free_name_list(a);
130
    pci_free_name_list(a);
145
  pci_mfree(a);
131
    pci_mfree(a);
146
}
132
}
147
 
133
 
148
void
-
 
149
pci_scan_bus(struct pci_access *a)
134
void pci_scan_bus(struct pci_access *a)
150
{
135
{
151
  a->methods->scan(a);
136
    a->methods->scan(a);
152
}
137
}
153
 
138
 
154
struct pci_dev *
-
 
155
pci_alloc_dev(struct pci_access *a)
139
struct pci_dev *pci_alloc_dev(struct pci_access *a)
156
{
140
{
157
  struct pci_dev *d = pci_malloc(a, sizeof(struct pci_dev));
141
    struct pci_dev *d = pci_malloc(a, sizeof(struct pci_dev));
158
 
142
 
159
  bzero(d, sizeof(*d));
143
    bzero(d, sizeof(*d));
160
  d->access = a;
144
    d->access = a;
161
  d->methods = a->methods;
145
    d->methods = a->methods;
162
  d->hdrtype = -1;
146
    d->hdrtype = -1;
163
  if (d->methods->init_dev)
147
    if (d->methods->init_dev)
164
    d->methods->init_dev(d);
148
        d->methods->init_dev(d);
165
  return d;
149
    return d;
166
}
150
}
167
 
151
 
168
int
-
 
169
pci_link_dev(struct pci_access *a, struct pci_dev *d)
152
int pci_link_dev(struct pci_access *a, struct pci_dev *d)
170
{
153
{
171
  d->next = a->devices;
154
    d->next = a->devices;
172
  a->devices = d;
155
    a->devices = d;
173
 
156
 
174
  return 1;
157
    return 1;
175
}
158
}
176
 
159
 
177
struct pci_dev *
-
 
178
pci_get_dev(struct pci_access *a, int domain, int bus, int dev, int func)
160
struct pci_dev *pci_get_dev(struct pci_access *a, int domain, int bus,
-
 
161
                int dev, int func)
179
{
162
{
180
  struct pci_dev *d = pci_alloc_dev(a);
163
    struct pci_dev *d = pci_alloc_dev(a);
181
 
164
 
182
  d->domain = domain;
165
    d->domain = domain;
183
  d->bus = bus;
166
    d->bus = bus;
184
  d->dev = dev;
167
    d->dev = dev;
185
  d->func = func;
168
    d->func = func;
186
  return d;
169
    return d;
187
}
170
}
188
 
171
 
189
void pci_free_dev(struct pci_dev *d)
172
void pci_free_dev(struct pci_dev *d)
190
{
173
{
191
  if (d->methods->cleanup_dev)
174
    if (d->methods->cleanup_dev)
192
    d->methods->cleanup_dev(d);
175
        d->methods->cleanup_dev(d);
193
  pci_mfree(d);
176
    pci_mfree(d);
194
}
177
}
195
 
178
 
196
static inline void
179
static inline void
197
pci_read_data(struct pci_dev *d, void *buf, int pos, int len)
180
pci_read_data(struct pci_dev *d, void *buf, int pos, int len)
198
{
181
{
199
  if (pos & (len-1))
182
    if (pos & (len - 1))
200
    d->access->error("Unaligned read: pos=%02x, len=%d", pos, len);
183
        d->access->error("Unaligned read: pos=%02x, len=%d", pos,
-
 
184
                 len);
201
  if (pos + len <= d->cache_len)
185
    if (pos + len <= d->cache_len)
202
    memcpy(buf, d->cache + pos, len);
186
        memcpy(buf, d->cache + pos, len);
203
  else if (!d->methods->read(d, pos, buf, len))
187
    else if (!d->methods->read(d, pos, buf, len))
204
    memset(buf, 0xff, len);
188
        memset(buf, 0xff, len);
205
}
189
}
206
 
190
 
207
byte
-
 
208
pci_read_byte(struct pci_dev *d, int pos)
191
byte pci_read_byte(struct pci_dev *d, int pos)
209
{
192
{
210
  byte buf;
193
    byte buf;
211
  pci_read_data(d, &buf, pos, 1);
194
    pci_read_data(d, &buf, pos, 1);
212
  return buf;
195
    return buf;
213
}
196
}
214
 
197
 
215
word
-
 
216
pci_read_word(struct pci_dev *d, int pos)
198
word pci_read_word(struct pci_dev * d, int pos)
217
{
199
{
218
  word buf;
200
    word buf;
219
  pci_read_data(d, &buf, pos, 2);
201
    pci_read_data(d, &buf, pos, 2);
220
  return le16_to_cpu(buf);
202
    return le16_to_cpu(buf);
221
}
203
}
222
 
204
 
223
u32
-
 
224
pci_read_long(struct pci_dev *d, int pos)
205
u32 pci_read_long(struct pci_dev * d, int pos)
225
{
206
{
226
  u32 buf;
207
    u32 buf;
227
  pci_read_data(d, &buf, pos, 4);
208
    pci_read_data(d, &buf, pos, 4);
228
  return le32_to_cpu(buf);
209
    return le32_to_cpu(buf);
229
}
210
}
230
 
211
 
231
int
-
 
232
pci_read_block(struct pci_dev *d, int pos, byte *buf, int len)
212
int pci_read_block(struct pci_dev *d, int pos, byte * buf, int len)
233
{
213
{
234
  return d->methods->read(d, pos, buf, len);
214
    return d->methods->read(d, pos, buf, len);
235
}
215
}
236
 
216
 
237
static inline int
217
static inline int
238
pci_write_data(struct pci_dev *d, void *buf, int pos, int len)
218
pci_write_data(struct pci_dev *d, void *buf, int pos, int len)
239
{
219
{
240
  if (pos & (len-1))
220
    if (pos & (len - 1))
241
    d->access->error("Unaligned write: pos=%02x,len=%d", pos, len);
221
        d->access->error("Unaligned write: pos=%02x,len=%d", pos,
-
 
222
                 len);
242
  if (pos + len <= d->cache_len)
223
    if (pos + len <= d->cache_len)
243
    memcpy(d->cache + pos, buf, len);
224
        memcpy(d->cache + pos, buf, len);
244
  return d->methods->write(d, pos, buf, len);
225
    return d->methods->write(d, pos, buf, len);
245
}
226
}
246
 
227
 
247
int
-
 
248
pci_write_byte(struct pci_dev *d, int pos, byte data)
228
int pci_write_byte(struct pci_dev *d, int pos, byte data)
249
{
229
{
250
  return pci_write_data(d, &data, pos, 1);
230
    return pci_write_data(d, &data, pos, 1);
251
}
231
}
252
 
232
 
253
int
-
 
254
pci_write_word(struct pci_dev *d, int pos, word data)
233
int pci_write_word(struct pci_dev *d, int pos, word data)
255
{
234
{
256
  word buf = cpu_to_le16(data);
235
    word buf = cpu_to_le16(data);
257
  return pci_write_data(d, &buf, pos, 2);
236
    return pci_write_data(d, &buf, pos, 2);
258
}
237
}
259
 
238
 
260
int
-
 
261
pci_write_long(struct pci_dev *d, int pos, u32 data)
239
int pci_write_long(struct pci_dev *d, int pos, u32 data)
262
{
240
{
263
  u32 buf = cpu_to_le32(data);
241
    u32 buf = cpu_to_le32(data);
264
  return pci_write_data(d, &buf, pos, 4);
242
    return pci_write_data(d, &buf, pos, 4);
265
}
243
}
266
 
244
 
267
int
-
 
268
pci_write_block(struct pci_dev *d, int pos, byte *buf, int len)
245
int pci_write_block(struct pci_dev *d, int pos, byte * buf, int len)
269
{
246
{
270
  if (pos < d->cache_len)
247
    if (pos < d->cache_len) {
271
    {
248
        int l =
-
 
249
            (pos + len >=
272
      int l = (pos + len >= d->cache_len) ? (d->cache_len - pos) : len;
250
             d->cache_len) ? (d->cache_len - pos) : len;
273
      memcpy(d->cache + pos, buf, l);
251
        memcpy(d->cache + pos, buf, l);
274
    }
252
    }
275
  return d->methods->write(d, pos, buf, len);
253
    return d->methods->write(d, pos, buf, len);
276
}
254
}
277
 
255
 
278
int
-
 
279
pci_fill_info(struct pci_dev *d, int flags)
256
int pci_fill_info(struct pci_dev *d, int flags)
280
{
257
{
281
  if (flags & PCI_FILL_RESCAN)
258
    if (flags & PCI_FILL_RESCAN) {
282
    {
-
 
283
      flags &= ~PCI_FILL_RESCAN;
259
        flags &= ~PCI_FILL_RESCAN;
284
      d->known_fields = 0;
260
        d->known_fields = 0;
285
    }
261
    }
286
  if (flags & ~d->known_fields)
262
    if (flags & ~d->known_fields)
-
 
263
        d->known_fields |=
287
    d->known_fields |= d->methods->fill_info(d, flags & ~d->known_fields);
264
            d->methods->fill_info(d, flags & ~d->known_fields);
288
  return d->known_fields;
265
    return d->known_fields;
289
}
266
}
290
 
267
 
291
void
-
 
292
pci_setup_cache(struct pci_dev *d, byte *cache, int len)
268
void pci_setup_cache(struct pci_dev *d, byte * cache, int len)
293
{
269
{
294
  d->cache = cache;
270
    d->cache = cache;
295
  d->cache_len = len;
271
    d->cache_len = len;
296
}
272
}