Subversion Repositories Kolibri OS

Rev

Rev 1631 | Rev 2187 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1631 Rev 1633
1
#include 
1
#include 
2
#include 
2
#include 
3
#include 
3
#include 
4
#include 
4
#include 
5
#include 
5
#include 
6
 
6
 
7
 
7
 
8
#define IO_SPACE_LIMIT          0xffff
8
#define IO_SPACE_LIMIT          0xffff
9
#define PCIBIOS_SUCCESSFUL      0x00
9
#define PCIBIOS_SUCCESSFUL      0x00
10
 
10
 
11
struct resource ioport_resource = {
11
struct resource ioport_resource = {
12
    .name   = "PCI IO",
12
    .name   = "PCI IO",
13
    .start  = 0,
13
    .start  = 0,
14
    .end    = IO_SPACE_LIMIT,
14
    .end    = IO_SPACE_LIMIT,
15
    .flags  = IORESOURCE_IO,
15
    .flags  = IORESOURCE_IO,
16
};
16
};
17
 
17
 
18
struct resource iomem_resource = {
18
struct resource iomem_resource = {
19
    .name   = "PCI mem",
19
    .name   = "PCI mem",
20
    .start  = 0,
20
    .start  = 0,
21
    .end    = -1,
21
    .end    = -1,
22
    .flags  = IORESOURCE_MEM,
22
    .flags  = IORESOURCE_MEM,
23
};
23
};
24
 
24
 
25
#define PCI_FIND_CAP_TTL    48
25
#define PCI_FIND_CAP_TTL    48
26
 
26
 
27
static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
27
static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
28
                   u8 pos, int cap, int *ttl)
28
                   u8 pos, int cap, int *ttl)
29
{
29
{
30
    u8 id;
30
    u8 id;
31
 
31
 
32
    while ((*ttl)--) {
32
    while ((*ttl)--) {
33
        pci_bus_read_config_byte(bus, devfn, pos, &pos);
33
        pci_bus_read_config_byte(bus, devfn, pos, &pos);
34
        if (pos < 0x40)
34
        if (pos < 0x40)
35
            break;
35
            break;
36
        pos &= ~3;
36
        pos &= ~3;
37
        pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
37
        pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
38
                     &id);
38
                     &id);
39
        if (id == 0xff)
39
        if (id == 0xff)
40
            break;
40
            break;
41
        if (id == cap)
41
        if (id == cap)
42
            return pos;
42
            return pos;
43
        pos += PCI_CAP_LIST_NEXT;
43
        pos += PCI_CAP_LIST_NEXT;
44
    }
44
    }
45
    return 0;
45
    return 0;
46
}
46
}
47
 
47
 
48
static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
48
static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
49
                   u8 pos, int cap)
49
                   u8 pos, int cap)
50
{
50
{
51
    int ttl = PCI_FIND_CAP_TTL;
51
    int ttl = PCI_FIND_CAP_TTL;
52
 
52
 
53
    return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
53
    return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
54
}
54
}
55
static int __pci_bus_find_cap_start(struct pci_bus *bus,
55
static int __pci_bus_find_cap_start(struct pci_bus *bus,
56
                    unsigned int devfn, u8 hdr_type)
56
                    unsigned int devfn, u8 hdr_type)
57
{
57
{
58
    u16 status;
58
    u16 status;
59
 
59
 
60
    pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
60
    pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
61
    if (!(status & PCI_STATUS_CAP_LIST))
61
    if (!(status & PCI_STATUS_CAP_LIST))
62
        return 0;
62
        return 0;
63
 
63
 
64
    switch (hdr_type) {
64
    switch (hdr_type) {
65
    case PCI_HEADER_TYPE_NORMAL:
65
    case PCI_HEADER_TYPE_NORMAL:
66
    case PCI_HEADER_TYPE_BRIDGE:
66
    case PCI_HEADER_TYPE_BRIDGE:
67
        return PCI_CAPABILITY_LIST;
67
        return PCI_CAPABILITY_LIST;
68
    case PCI_HEADER_TYPE_CARDBUS:
68
    case PCI_HEADER_TYPE_CARDBUS:
69
        return PCI_CB_CAPABILITY_LIST;
69
        return PCI_CB_CAPABILITY_LIST;
70
    default:
70
    default:
71
        return 0;
71
        return 0;
72
    }
72
    }
73
 
73
 
74
    return 0;
74
    return 0;
75
}
75
}
76
 
76
 
77
 
77
 
78
/**
78
/**
79
 * pci_find_capability - query for devices' capabilities
79
 * pci_find_capability - query for devices' capabilities
80
 * @dev: PCI device to query
80
 * @dev: PCI device to query
81
 * @cap: capability code
81
 * @cap: capability code
82
 *
82
 *
83
 * Tell if a device supports a given PCI capability.
83
 * Tell if a device supports a given PCI capability.
84
 * Returns the address of the requested capability structure within the
84
 * Returns the address of the requested capability structure within the
85
 * device's PCI configuration space or 0 in case the device does not
85
 * device's PCI configuration space or 0 in case the device does not
86
 * support it.  Possible values for @cap:
86
 * support it.  Possible values for @cap:
87
 *
87
 *
88
 *  %PCI_CAP_ID_PM           Power Management
88
 *  %PCI_CAP_ID_PM           Power Management
89
 *  %PCI_CAP_ID_AGP          Accelerated Graphics Port
89
 *  %PCI_CAP_ID_AGP          Accelerated Graphics Port
90
 *  %PCI_CAP_ID_VPD          Vital Product Data
90
 *  %PCI_CAP_ID_VPD          Vital Product Data
91
 *  %PCI_CAP_ID_SLOTID       Slot Identification
91
 *  %PCI_CAP_ID_SLOTID       Slot Identification
92
 *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
92
 *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
93
 *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap
93
 *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap
94
 *  %PCI_CAP_ID_PCIX         PCI-X
94
 *  %PCI_CAP_ID_PCIX         PCI-X
95
 *  %PCI_CAP_ID_EXP          PCI Express
95
 *  %PCI_CAP_ID_EXP          PCI Express
96
 */
96
 */
97
int pci_find_capability(struct pci_dev *dev, int cap)
97
int pci_find_capability(struct pci_dev *dev, int cap)
98
{
98
{
99
    int pos;
99
    int pos;
100
 
100
 
101
    pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
101
    pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
102
    if (pos)
102
    if (pos)
103
        pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
103
        pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
104
 
104
 
105
    return pos;
105
    return pos;
106
}
106
}
107
 
107
 
108
 
108
 
109
static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
109
static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
110
{
110
{
111
    struct pci_bus* child;
111
    struct pci_bus* child;
112
    struct list_head *tmp;
112
    struct list_head *tmp;
113
 
113
 
114
    if(bus->number == busnr)
114
    if(bus->number == busnr)
115
        return bus;
115
        return bus;
116
 
116
 
117
    list_for_each(tmp, &bus->children) {
117
    list_for_each(tmp, &bus->children) {
118
        child = pci_do_find_bus(pci_bus_b(tmp), busnr);
118
        child = pci_do_find_bus(pci_bus_b(tmp), busnr);
119
        if(child)
119
        if(child)
120
            return child;
120
            return child;
121
    }
121
    }
122
    return NULL;
122
    return NULL;
123
}
123
}
124
 
124
 
125
 
125
 
126
/**
126
/**
127
 * pci_find_bus - locate PCI bus from a given domain and bus number
127
 * pci_find_bus - locate PCI bus from a given domain and bus number
128
 * @domain: number of PCI domain to search
128
 * @domain: number of PCI domain to search
129
 * @busnr: number of desired PCI bus
129
 * @busnr: number of desired PCI bus
130
 *
130
 *
131
 * Given a PCI bus number and domain number, the desired PCI bus is located
131
 * Given a PCI bus number and domain number, the desired PCI bus is located
132
 * in the global list of PCI buses.  If the bus is found, a pointer to its
132
 * in the global list of PCI buses.  If the bus is found, a pointer to its
133
 * data structure is returned.  If no bus is found, %NULL is returned.
133
 * data structure is returned.  If no bus is found, %NULL is returned.
134
 */
134
 */
135
struct pci_bus * pci_find_bus(int domain, int busnr)
135
struct pci_bus * pci_find_bus(int domain, int busnr)
136
{
136
{
137
    struct pci_bus *bus = NULL;
137
    struct pci_bus *bus = NULL;
138
    struct pci_bus *tmp_bus;
138
    struct pci_bus *tmp_bus;
139
 
139
 
140
    while ((bus = pci_find_next_bus(bus)) != NULL)  {
140
    while ((bus = pci_find_next_bus(bus)) != NULL)  {
141
        if (pci_domain_nr(bus) != domain)
141
        if (pci_domain_nr(bus) != domain)
142
            continue;
142
            continue;
143
        tmp_bus = pci_do_find_bus(bus, busnr);
143
        tmp_bus = pci_do_find_bus(bus, busnr);
144
        if (tmp_bus)
144
        if (tmp_bus)
145
            return tmp_bus;
145
            return tmp_bus;
146
    }
146
    }
147
    return NULL;
147
    return NULL;
148
}
148
}
149
 
149
 
150
/**
150
/**
151
 * pci_find_next_bus - begin or continue searching for a PCI bus
151
 * pci_find_next_bus - begin or continue searching for a PCI bus
152
 * @from: Previous PCI bus found, or %NULL for new search.
152
 * @from: Previous PCI bus found, or %NULL for new search.
153
 *
153
 *
154
 * Iterates through the list of known PCI busses.  A new search is
154
 * Iterates through the list of known PCI busses.  A new search is
155
 * initiated by passing %NULL as the @from argument.  Otherwise if
155
 * initiated by passing %NULL as the @from argument.  Otherwise if
156
 * @from is not %NULL, searches continue from next device on the
156
 * @from is not %NULL, searches continue from next device on the
157
 * global list.
157
 * global list.
158
 */
158
 */
159
struct pci_bus *
159
struct pci_bus *
160
pci_find_next_bus(const struct pci_bus *from)
160
pci_find_next_bus(const struct pci_bus *from)
161
{
161
{
162
    struct list_head *n;
162
    struct list_head *n;
163
    struct pci_bus *b = NULL;
163
    struct pci_bus *b = NULL;
164
 
164
 
165
//    WARN_ON(in_interrupt());
165
//    WARN_ON(in_interrupt());
166
//    down_read(&pci_bus_sem);
166
//    down_read(&pci_bus_sem);
167
    n = from ? from->node.next : pci_root_buses.next;
167
    n = from ? from->node.next : pci_root_buses.next;
168
    if (n != &pci_root_buses)
168
    if (n != &pci_root_buses)
169
        b = pci_bus_b(n);
169
        b = pci_bus_b(n);
170
//    up_read(&pci_bus_sem);
170
//    up_read(&pci_bus_sem);
171
    return b;
171
    return b;
172
}
172
}
173
 
173
 
174
 
174
 
175
/**
175
/**
176
 * pci_get_slot - locate PCI device for a given PCI slot
176
 * pci_get_slot - locate PCI device for a given PCI slot
177
 * @bus: PCI bus on which desired PCI device resides
177
 * @bus: PCI bus on which desired PCI device resides
178
 * @devfn: encodes number of PCI slot in which the desired PCI
178
 * @devfn: encodes number of PCI slot in which the desired PCI
179
 * device resides and the logical device number within that slot
179
 * device resides and the logical device number within that slot
180
 * in case of multi-function devices.
180
 * in case of multi-function devices.
181
 *
181
 *
182
 * Given a PCI bus and slot/function number, the desired PCI device
182
 * Given a PCI bus and slot/function number, the desired PCI device
183
 * is located in the list of PCI devices.
183
 * is located in the list of PCI devices.
184
 * If the device is found, its reference count is increased and this
184
 * If the device is found, its reference count is increased and this
185
 * function returns a pointer to its data structure.  The caller must
185
 * function returns a pointer to its data structure.  The caller must
186
 * decrement the reference count by calling pci_dev_put().
186
 * decrement the reference count by calling pci_dev_put().
187
 * If no device is found, %NULL is returned.
187
 * If no device is found, %NULL is returned.
188
 */
188
 */
189
struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
189
struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
190
{
190
{
191
    struct list_head *tmp;
191
    struct list_head *tmp;
192
    struct pci_dev *dev;
192
    struct pci_dev *dev;
193
 
193
 
194
//    WARN_ON(in_interrupt());
194
//    WARN_ON(in_interrupt());
195
//    down_read(&pci_bus_sem);
195
//    down_read(&pci_bus_sem);
196
 
196
 
197
    list_for_each(tmp, &bus->devices) {
197
    list_for_each(tmp, &bus->devices) {
198
        dev = pci_dev_b(tmp);
198
        dev = pci_dev_b(tmp);
199
        if (dev->devfn == devfn)
199
        if (dev->devfn == devfn)
200
            goto out;
200
            goto out;
201
    }
201
    }
202
 
202
 
203
    dev = NULL;
203
    dev = NULL;
204
 out:
204
 out:
205
//    pci_dev_get(dev);
205
//    pci_dev_get(dev);
206
//    up_read(&pci_bus_sem);
206
//    up_read(&pci_bus_sem);
207
    return dev;
207
    return dev;
208
}
208
}
209
 
209
 
210
 
210
 
211
 
211
 
212
 
212
 
213
/**
213
/**
214
 * pci_find_ext_capability - Find an extended capability
214
 * pci_find_ext_capability - Find an extended capability
215
 * @dev: PCI device to query
215
 * @dev: PCI device to query
216
 * @cap: capability code
216
 * @cap: capability code
217
 *
217
 *
218
 * Returns the address of the requested extended capability structure
218
 * Returns the address of the requested extended capability structure
219
 * within the device's PCI configuration space or 0 if the device does
219
 * within the device's PCI configuration space or 0 if the device does
220
 * not support it.  Possible values for @cap:
220
 * not support it.  Possible values for @cap:
221
 *
221
 *
222
 *  %PCI_EXT_CAP_ID_ERR     Advanced Error Reporting
222
 *  %PCI_EXT_CAP_ID_ERR     Advanced Error Reporting
223
 *  %PCI_EXT_CAP_ID_VC      Virtual Channel
223
 *  %PCI_EXT_CAP_ID_VC      Virtual Channel
224
 *  %PCI_EXT_CAP_ID_DSN     Device Serial Number
224
 *  %PCI_EXT_CAP_ID_DSN     Device Serial Number
225
 *  %PCI_EXT_CAP_ID_PWR     Power Budgeting
225
 *  %PCI_EXT_CAP_ID_PWR     Power Budgeting
226
 */
226
 */
227
int pci_find_ext_capability(struct pci_dev *dev, int cap)
227
int pci_find_ext_capability(struct pci_dev *dev, int cap)
228
{
228
{
229
    u32 header;
229
    u32 header;
230
    int ttl;
230
    int ttl;
231
    int pos = PCI_CFG_SPACE_SIZE;
231
    int pos = PCI_CFG_SPACE_SIZE;
232
 
232
 
233
    /* minimum 8 bytes per capability */
233
    /* minimum 8 bytes per capability */
234
    ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
234
    ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
235
 
235
 
236
    if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
236
    if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
237
        return 0;
237
        return 0;
238
 
238
 
239
    if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
239
    if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
240
        return 0;
240
        return 0;
241
 
241
 
242
    /*
242
    /*
243
     * If we have no capabilities, this is indicated by cap ID,
243
     * If we have no capabilities, this is indicated by cap ID,
244
     * cap version and next pointer all being 0.
244
     * cap version and next pointer all being 0.
245
     */
245
     */
246
    if (header == 0)
246
    if (header == 0)
247
        return 0;
247
        return 0;
248
 
248
 
249
    while (ttl-- > 0) {
249
    while (ttl-- > 0) {
250
        if (PCI_EXT_CAP_ID(header) == cap)
250
        if (PCI_EXT_CAP_ID(header) == cap)
251
            return pos;
251
            return pos;
252
 
252
 
253
        pos = PCI_EXT_CAP_NEXT(header);
253
        pos = PCI_EXT_CAP_NEXT(header);
254
        if (pos < PCI_CFG_SPACE_SIZE)
254
        if (pos < PCI_CFG_SPACE_SIZE)
255
            break;
255
            break;
256
 
256
 
257
        if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
257
        if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
258
            break;
258
            break;
259
    }
259
    }
260
 
260
 
261
    return 0;
261
    return 0;
262
}
262
}
263
 
263
 
-
 
264
 
-
 
265
/**
-
 
266
 * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
-
 
267
 * @dev: the PCI device
-
 
268
 * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD)
-
 
269
 *
-
 
270
 * Perform INTx swizzling for a device behind one level of bridge.  This is
-
 
271
 * required by section 9.1 of the PCI-to-PCI bridge specification for devices
-
 
272
 * behind bridges on add-in cards.  For devices with ARI enabled, the slot
-
 
273
 * number is always 0 (see the Implementation Note in section 2.2.8.1 of
-
 
274
 * the PCI Express Base Specification, Revision 2.1)
-
 
275
 */
-
 
276
u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin)
-
 
277
{
-
 
278
    int slot;
-
 
279
 
-
 
280
 //   if (pci_ari_enabled(dev->bus))
-
 
281
 //       slot = 0;
-
 
282
 //   else
-
 
283
        slot = PCI_SLOT(dev->devfn);
-
 
284
 
-
 
285
    return (((pin - 1) + slot) % 4) + 1;
-
 
286
}
-
 
287
 
-
 
288
 
264
#if 0
289
#if 0
265
 
290
 
266
u32 pci_probe = 0;
291
u32 pci_probe = 0;
267
 
292
 
268
#define PCI_NOASSIGN_ROMS   0x80000
293
#define PCI_NOASSIGN_ROMS   0x80000
269
#define PCI_NOASSIGN_BARS   0x200000
294
#define PCI_NOASSIGN_BARS   0x200000
270
 
295
 
271
static void pcibios_fixup_device_resources(struct pci_dev *dev)
296
static void pcibios_fixup_device_resources(struct pci_dev *dev)
272
{
297
{
273
    struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
298
    struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
274
    struct resource *bar_r;
299
    struct resource *bar_r;
275
    int bar;
300
    int bar;
276
 
301
 
277
    if (pci_probe & PCI_NOASSIGN_BARS) {
302
    if (pci_probe & PCI_NOASSIGN_BARS) {
278
        /*
303
        /*
279
        * If the BIOS did not assign the BAR, zero out the
304
        * If the BIOS did not assign the BAR, zero out the
280
        * resource so the kernel doesn't attmept to assign
305
        * resource so the kernel doesn't attmept to assign
281
        * it later on in pci_assign_unassigned_resources
306
        * it later on in pci_assign_unassigned_resources
282
        */
307
        */
283
        for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) {
308
        for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) {
284
            bar_r = &dev->resource[bar];
309
            bar_r = &dev->resource[bar];
285
            if (bar_r->start == 0 && bar_r->end != 0) {
310
            if (bar_r->start == 0 && bar_r->end != 0) {
286
                bar_r->flags = 0;
311
                bar_r->flags = 0;
287
                bar_r->end = 0;
312
                bar_r->end = 0;
288
            }
313
            }
289
        }
314
        }
290
    }
315
    }
291
 
316
 
292
    if (pci_probe & PCI_NOASSIGN_ROMS) {
317
    if (pci_probe & PCI_NOASSIGN_ROMS) {
293
        if (rom_r->parent)
318
        if (rom_r->parent)
294
            return;
319
            return;
295
        if (rom_r->start) {
320
        if (rom_r->start) {
296
            /* we deal with BIOS assigned ROM later */
321
            /* we deal with BIOS assigned ROM later */
297
            return;
322
            return;
298
        }
323
        }
299
        rom_r->start = rom_r->end = rom_r->flags = 0;
324
        rom_r->start = rom_r->end = rom_r->flags = 0;
300
    }
325
    }
301
}
326
}
302
 
327
 
303
/*
328
/*
304
 *  Called after each bus is probed, but before its children
329
 *  Called after each bus is probed, but before its children
305
 *  are examined.
330
 *  are examined.
306
 */
331
 */
307
 
332
 
308
void pcibios_fixup_bus(struct pci_bus *b)
333
void pcibios_fixup_bus(struct pci_bus *b)
309
{
334
{
310
    struct pci_dev *dev;
335
    struct pci_dev *dev;
311
 
336
 
312
    /* root bus? */
337
    /* root bus? */
313
//    if (!b->parent)
338
//    if (!b->parent)
314
//        x86_pci_root_bus_res_quirks(b);
339
//        x86_pci_root_bus_res_quirks(b);
315
    pci_read_bridge_bases(b);
340
    pci_read_bridge_bases(b);
316
    list_for_each_entry(dev, &b->devices, bus_list)
341
    list_for_each_entry(dev, &b->devices, bus_list)
317
        pcibios_fixup_device_resources(dev);
342
        pcibios_fixup_device_resources(dev);
318
}
343
}
319
 
344
 
320
#endif
345
#endif