Subversion Repositories HelenOS-historic

Rev

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

Rev 1301 Rev 1302
Line 10... Line 10...
10
 
10
 
11
#include <string.h>
11
#include <string.h>
12
 
12
 
13
#include "internal.h"
13
#include "internal.h"
14
 
14
 
15
void
-
 
16
pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
15
void pci_generic_scan_bus(struct pci_access *a, byte * busmap, int bus)
17
{
16
{
18
  int dev, multi, ht;
17
    int dev, multi, ht;
19
  struct pci_dev *t;
18
    struct pci_dev *t;
20
 
19
 
21
  a->debug("Scanning bus %02x for devices...\n", bus);
20
    a->debug("Scanning bus %02x for devices...\n", bus);
22
  if (busmap[bus])
21
    if (busmap[bus]) {
23
    {
-
 
24
      a->warning("Bus %02x seen twice (firmware bug). Ignored.", bus);
22
        a->warning("Bus %02x seen twice (firmware bug). Ignored.",
-
 
23
               bus);
25
      return;
24
        return;
26
    }
25
    }
27
  busmap[bus] = 1;
26
    busmap[bus] = 1;
28
  t = pci_alloc_dev(a);
27
    t = pci_alloc_dev(a);
29
  t->bus = bus;
28
    t->bus = bus;
30
  for(dev=0; dev<32; dev++)
29
    for (dev = 0; dev < 32; dev++) {
31
    {
-
 
32
      t->dev = dev;
30
        t->dev = dev;
33
      multi = 0;
31
        multi = 0;
34
      for(t->func=0; !t->func || multi && t->func<8; t->func++)
32
        for (t->func = 0; !t->func || multi && t->func < 8;
35
    {
33
             t->func++) {
36
      u32 vd = pci_read_long(t, PCI_VENDOR_ID);
34
            u32 vd = pci_read_long(t, PCI_VENDOR_ID);
37
      struct pci_dev *d;
35
            struct pci_dev *d;
38
 
36
 
39
      if (!vd || vd == 0xffffffff)
37
            if (!vd || vd == 0xffffffff)
40
        continue;
38
                continue;
Line 49... Line 47...
49
      d->vendor_id = vd & 0xffff;
47
            d->vendor_id = vd & 0xffff;
50
      d->device_id = vd >> 16U;
48
            d->device_id = vd >> 16U;
51
      d->known_fields = PCI_FILL_IDENT;
49
            d->known_fields = PCI_FILL_IDENT;
52
      d->hdrtype = ht;
50
            d->hdrtype = ht;
53
      pci_link_dev(a, d);
51
            pci_link_dev(a, d);
54
      switch (ht)
52
            switch (ht) {
55
        {
-
 
56
        case PCI_HEADER_TYPE_NORMAL:
53
            case PCI_HEADER_TYPE_NORMAL:
57
          break;
54
                break;
58
        case PCI_HEADER_TYPE_BRIDGE:
55
            case PCI_HEADER_TYPE_BRIDGE:
59
        case PCI_HEADER_TYPE_CARDBUS:
56
            case PCI_HEADER_TYPE_CARDBUS:
60
          pci_generic_scan_bus(a, busmap, pci_read_byte(t, PCI_SECONDARY_BUS));
57
                pci_generic_scan_bus(a, busmap,
-
 
58
                             pci_read_byte(t,
-
 
59
                                   PCI_SECONDARY_BUS));
61
          break;
60
                break;
62
        default:
61
            default:
-
 
62
                a->debug
63
          a->debug("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", d->domain, d->bus, d->dev, d->func, ht);
63
                    ("Device %04x:%02x:%02x.%d has unknown header type %02x.\n",
-
 
64
                     d->domain, d->bus, d->dev, d->func,
-
 
65
                     ht);
64
        }
66
            }
65
    }
67
        }
66
    }
68
    }
67
  pci_free_dev(t);
69
    pci_free_dev(t);
68
}
70
}
69
 
71
 
70
void
-
 
71
pci_generic_scan(struct pci_access *a)
72
void pci_generic_scan(struct pci_access *a)
72
{
73
{
73
  byte busmap[256];
74
    byte busmap[256];
74
 
75
 
75
  bzero(busmap, sizeof(busmap));
76
    bzero(busmap, sizeof(busmap));
76
  pci_generic_scan_bus(a, busmap, 0);
77
    pci_generic_scan_bus(a, busmap, 0);
77
}
78
}
78
 
79
 
79
int
-
 
80
pci_generic_fill_info(struct pci_dev *d, int flags)
80
int pci_generic_fill_info(struct pci_dev *d, int flags)
81
{
81
{
82
  struct pci_access *a = d->access;
82
    struct pci_access *a = d->access;
83
 
83
 
84
  if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0)
84
    if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE))
-
 
85
        && d->hdrtype < 0)
85
    d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
86
        d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
86
  if (flags & PCI_FILL_IDENT)
87
    if (flags & PCI_FILL_IDENT) {
87
    {
-
 
88
      d->vendor_id = pci_read_word(d, PCI_VENDOR_ID);
88
        d->vendor_id = pci_read_word(d, PCI_VENDOR_ID);
89
      d->device_id = pci_read_word(d, PCI_DEVICE_ID);
89
        d->device_id = pci_read_word(d, PCI_DEVICE_ID);
90
    }
90
    }
91
  if (flags & PCI_FILL_IRQ)
91
    if (flags & PCI_FILL_IRQ)
92
    d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);
92
        d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);
93
  if (flags & PCI_FILL_BASES)
93
    if (flags & PCI_FILL_BASES) {
94
    {
-
 
95
      int cnt = 0, i;
94
        int cnt = 0, i;
96
      bzero(d->base_addr, sizeof(d->base_addr));
95
        bzero(d->base_addr, sizeof(d->base_addr));
97
      switch (d->hdrtype)
96
        switch (d->hdrtype) {
98
    {
-
 
99
    case PCI_HEADER_TYPE_NORMAL:
97
        case PCI_HEADER_TYPE_NORMAL:
100
      cnt = 6;
98
            cnt = 6;
101
      break;
99
            break;
102
    case PCI_HEADER_TYPE_BRIDGE:
100
        case PCI_HEADER_TYPE_BRIDGE:
103
      cnt = 2;
101
            cnt = 2;
104
      break;
102
            break;
105
    case PCI_HEADER_TYPE_CARDBUS:
103
        case PCI_HEADER_TYPE_CARDBUS:
106
      cnt = 1;
104
            cnt = 1;
107
      break;
105
            break;
108
    }
106
        }
109
      if (cnt)
107
        if (cnt) {
110
    {
-
 
111
      for(i=0; i<cnt; i++)
108
            for (i = 0; i < cnt; i++) {
112
        {
109
                u32 x =
-
 
110
                    pci_read_long(d,
113
          u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
111
                          PCI_BASE_ADDRESS_0 +
-
 
112
                          i * 4);
114
          if (!x || x == (u32) ~0)
113
                if (!x || x == (u32) ~ 0)
115
        continue;
114
                    continue;
116
          if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
115
                if ((x & PCI_BASE_ADDRESS_SPACE) ==
-
 
116
                    PCI_BASE_ADDRESS_SPACE_IO)
117
        d->base_addr[i] = x;
117
                    d->base_addr[i] = x;
118
          else
118
                else {
-
 
119
                    if ((x &
-
 
120
                         PCI_BASE_ADDRESS_MEM_TYPE_MASK)
119
        {
121
                        !=
120
          if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
122
                        PCI_BASE_ADDRESS_MEM_TYPE_64)
121
            d->base_addr[i] = x;
123
                        d->base_addr[i] = x;
122
          else if (i >= cnt-1)
124
                    else if (i >= cnt - 1)
-
 
125
                        a->warning
123
            a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i);
126
                            ("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.",
-
 
127
                             d->domain, d->bus,
-
 
128
                             d->dev, d->func, i);
124
          else
129
                    else {
125
            {
130
                        u32 y =
-
 
131
                            pci_read_long(d,
126
              u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
132
                                  PCI_BASE_ADDRESS_0
-
 
133
                                  +
-
 
134
                                  (++i) *
-
 
135
                                  4);
127
#ifdef PCI_HAVE_64BIT_ADDRESS
136
#ifdef PCI_HAVE_64BIT_ADDRESS
-
 
137
                        d->base_addr[i - 1] =
128
              d->base_addr[i-1] = x | (((pciaddr_t) y) << 32);
138
                            x | (((pciaddr_t) y) <<
-
 
139
                             32);
129
#else
140
#else
130
              if (y)
141
                        if (y)
-
 
142
                            a->warning
131
            a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
143
                                ("%04x:%02x:%02x.%d 64-bit device address ignored.",
-
 
144
                                 d->domain,
-
 
145
                                 d->bus,
-
 
146
                                 d->dev,
-
 
147
                                 d->func);
132
              else
148
                        else
133
            d->base_addr[i-1] = x;
149
                            d->base_addr[i -
-
 
150
                                     1] =
-
 
151
                                x;
134
#endif
152
#endif
135
            }
153
                    }
136
        }
154
                }
137
        }
155
            }
138
    }
156
        }
139
    }
157
    }
140
  if (flags & PCI_FILL_ROM_BASE)
158
    if (flags & PCI_FILL_ROM_BASE) {
141
    {
-
 
142
      int reg = 0;
159
        int reg = 0;
143
      d->rom_base_addr = 0;
160
        d->rom_base_addr = 0;
144
      switch (d->hdrtype)
161
        switch (d->hdrtype) {
145
    {
-
 
146
    case PCI_HEADER_TYPE_NORMAL:
162
        case PCI_HEADER_TYPE_NORMAL:
147
      reg = PCI_ROM_ADDRESS;
163
            reg = PCI_ROM_ADDRESS;
148
      break;
164
            break;
149
    case PCI_HEADER_TYPE_BRIDGE:
165
        case PCI_HEADER_TYPE_BRIDGE:
150
      reg = PCI_ROM_ADDRESS1;
166
            reg = PCI_ROM_ADDRESS1;
151
      break;
167
            break;
152
    }
168
        }
153
      if (reg)
169
        if (reg) {
154
    {
-
 
155
      u32 u = pci_read_long(d, reg);
170
            u32 u = pci_read_long(d, reg);
156
      if (u != 0xffffffff)
171
            if (u != 0xffffffff)
157
        d->rom_base_addr = u;
172
                d->rom_base_addr = u;
158
    }
173
        }
159
    }
174
    }
160
  return flags & ~PCI_FILL_SIZES;
175
    return flags & ~PCI_FILL_SIZES;
161
}
176
}
162
 
177
 
163
static int
178
static int
164
pci_generic_block_op(struct pci_dev *d, int pos, byte *buf, int len,
179
pci_generic_block_op(struct pci_dev *d, int pos, byte * buf, int len,
165
         int (*r)(struct pci_dev *d, int pos, byte *buf, int len))
180
             int (*r) (struct pci_dev * d, int pos, byte * buf,
166
{
-
 
167
  if ((pos & 1) && len >= 1)
181
                   int len))
168
    {
182
{
-
 
183
    if ((pos & 1) && len >= 1) {
169
      if (!r(d, pos, buf, 1))
184
        if (!r(d, pos, buf, 1))
170
    return 0;
185
            return 0;
-
 
186
        pos++;
-
 
187
        buf++;
171
      pos++; buf++; len--;
188
        len--;
172
    }
189
    }
173
  if ((pos & 3) && len >= 2)
190
    if ((pos & 3) && len >= 2) {
174
    {
-
 
175
      if (!r(d, pos, buf, 2))
191
        if (!r(d, pos, buf, 2))
176
    return 0;
192
            return 0;
-
 
193
        pos += 2;
-
 
194
        buf += 2;
177
      pos += 2; buf += 2; len -= 2;
195
        len -= 2;
178
    }
196
    }
179
  while (len >= 4)
197
    while (len >= 4) {
180
    {
-
 
181
      if (!r(d, pos, buf, 4))
198
        if (!r(d, pos, buf, 4))
182
    return 0;
199
            return 0;
-
 
200
        pos += 4;
-
 
201
        buf += 4;
183
      pos += 4; buf += 4; len -= 4;
202
        len -= 4;
184
    }
203
    }
185
  if (len >= 2)
204
    if (len >= 2) {
186
    {
-
 
187
      if (!r(d, pos, buf, 2))
205
        if (!r(d, pos, buf, 2))
188
    return 0;
206
            return 0;
-
 
207
        pos += 2;
-
 
208
        buf += 2;
189
      pos += 2; buf += 2; len -= 2;
209
        len -= 2;
190
    }
210
    }
191
  if (len && !r(d, pos, buf, 1))
211
    if (len && !r(d, pos, buf, 1))
192
    return 0;
212
        return 0;
193
  return 1;
213
    return 1;
194
}
214
}
195
 
215
 
196
int
-
 
197
pci_generic_block_read(struct pci_dev *d, int pos, byte *buf, int len)
216
int pci_generic_block_read(struct pci_dev *d, int pos, byte * buf, int len)
198
{
217
{
199
  return pci_generic_block_op(d, pos, buf, len, d->access->methods->read);
218
    return pci_generic_block_op(d, pos, buf, len,
-
 
219
                    d->access->methods->read);
200
}
220
}
201
 
221
 
202
int
-
 
203
pci_generic_block_write(struct pci_dev *d, int pos, byte *buf, int len)
222
int pci_generic_block_write(struct pci_dev *d, int pos, byte * buf, int len)
204
{
223
{
205
  return pci_generic_block_op(d, pos, buf, len, d->access->methods->write);
224
    return pci_generic_block_op(d, pos, buf, len,
-
 
225
                    d->access->methods->write);
206
}
226
}