Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
588 giacomo 1
#include <ll/i386/hw-instr.h>
2
#include <ll/i386/hw-data.h>
3
#include <ll/i386/hw-arch.h>
4
#include <ll/i386/hw-io.h>
5
#include <ll/i386/cons.h>
6
#include <ll/i386/mem.h>
7
#include <ll/stdlib.h>
8
#include <drivers/llpci.h>
9
#include <drivers/pci.h>
10
#include <drivers/linuxpci.h>
11
#include <kernel/log.h>
12
 
13
//#define DEBUG_PCISCAN
14
 
15
static struct pci_dev pci_devs[N_MAX_DEVS];
16
 
17
static struct pci_bus pci_root;
18
static struct pci_dev *pci_devices = NULL;
19
 
20
#if 0
21
/* scan the bus to find all the connected devices */
22
DWORD pci_scan_bus(struct pci_bus *bus)
23
{
24
    int ndev;
25
    DWORD tmp;
26
    DWORD max, class;
27
    BYTE hdr;
28
    int ok;
29
    WORD dev;
30
    struct pci_dev **bus_last;
31
    struct pci_dev *device = NULL;
32
    int present;
33
 
34
    max = bus->secondary;
35
    bus_last = &bus->devices;
36
 
37
    if (pcibios_present() == 0) return -1;
38
    ndev = 0;
39
 
40
    for (dev = 0; dev <= 0xFF; dev++) {
41
        present = 0;
42
        if ((dev & 0x07) == 0) {
43
            present = pcibios_read_config_byte(bus->number, dev, 0x0e, &hdr);
44
        }
45
        if (hdr & 0x80) {
46
            present = 1;
47
        }
48
        if (present) {
49
            ok = pcibios_read_config_dword(bus->number, dev, 0, &tmp);
50
            if ( ok && (((tmp & 0xFFFF) != 0xFFFF) && ((tmp >> 16) != 0xFFFF))) {
51
                /* Got a PCI Device!!! */
52
                device = &(pci_devs[ndev++]);
53
                device->bus = bus;
54
                device->devfn  = dev;
55
                device->vendor = tmp & 0xffff;
56
                device->device = (tmp >> 16) & 0xffff;
57
 
58
                /* PJ: non-destructively determine if device can be a master: */
59
                pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND, &cmd);
60
                pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER);
61
                pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND, &tmp);
62
                dev->master = ((tmp & PCI_COMMAND_MASTER) != 0);
63
                pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND, cmd);
64
 
65
                /* This is by Luca... We need to set base_addr */
66
                pcibios_read_config_dword(bus->number, dev, PCI_BASE_ADDRESS_0, &(device->base_address[0]));
67
 
68
 
69
 
70
                pcibios_read_config_byte(bus->number, dev, PCI_INTERRUPT_LINE, &irq1);
71
                device->irq = irq1;
72
 
73
                pcibios_read_config_dword(bus->number, dev, PCI_CLASS_REVISION, &class);
74
                class >>= 8;                                /* upper 3 bytes */
75
                //printk(KERN_INFO "pci_scan_bus: dev=%d, class=%ld", dev, class);
76
                device->class = class;
77
                class >>= 8;
78
                device->hdr_type = hdr;
79
 
80
 
81
 
82
 
83
#if 0
84
                switch (hdr & 0x7f) {                  /* header type */
85
                case PCI_HEADER_TYPE_NORMAL:                /* standard header */
86
                        if (class == PCI_CLASS_BRIDGE_PCI)
87
                                goto bad;
88
                        /*
89
                         * If the card generates interrupts, read IRQ number
90
                         * (some architectures change it during pcibios_fixup())
91
                         */
92
                        pcibios_read_config_byte(bus->number, device->devfn, PCI_INTERRUPT_PIN, &irq1);
93
                        if (irq1)
94
                                pcibios_read_config_byte(bus->number, device->devfn, PCI_INTERRUPT_LINE, &irq1);
95
                        device->irq = irq1;
96
                        /*
97
                         * read base address registers, again pcibios_fixup() can
98
                         * tweak these
99
                         */
100
                        pci_read_bases(device, 6);
101
                        pcibios_read_config_dword(bus->number, dev, PCI_ROM_ADDRESS, &l);
102
                        device->rom_address = (l == 0xffffffff) ? 0 : l;
103
                        break;
104
                case PCI_HEADER_TYPE_BRIDGE:                /* bridge header */
105
                        if (class != PCI_CLASS_BRIDGE_PCI)
106
                                goto bad;
107
                        pci_read_bases(device, 2);
108
                        pcibios_read_config_dword(bus->number, dev, PCI_ROM_ADDRESS1, &l);
109
                        device->rom_address = (l == 0xffffffff) ? 0 : l;
110
                        break;
111
                        case PCI_HEADER_TYPE_CARDBUS:               /* CardBus bridge header */
112
                        if (class != PCI_CLASS_BRIDGE_CARDBUS)
113
                                goto bad;
114
                        pci_read_bases(device, 1);
115
                        break;
116
                default:                                    /* unknown header */
117
                bad:
118
                        printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n",
119
                               bus->number, device->devfn, device->vendor, device->device, class, hdr);
120
                        continue;
121
                }
122
#endif
123
 
124
 
125
 
126
 
127
                //printk(KERN_DEBUG "PCI: %02x:%02x [%04x/%04x]\n", bus->number, device->devfn, device->vendor, device->device);
128
 
129
                device->next = pci_devices;
130
                pci_devices = device;
131
 
132
                /*
133
                 * Now insert it into the list of devices held
134
                 * by the parent bus.
135
                 */
136
                *bus_last = device;
137
                bus_last = &device->sibling;
138
 
139
 
140
 
141
            }
142
        }
143
    }
144
 
145
    // PJ: PCI bridges not supported???
146
#if 0
147
    for(device = bus->devices; device; device = device->sibling) {
148
        /*
149
        * If it's a bridge, scan the bus behind it.
150
        */
151
        if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
152
            unsigned int buses;
153
            unsigned int devfn = dev->devfn;
154
            unsigned short cr;
155
 
156
            /*
157
             * Insert it into the tree of buses.
158
             */
159
            child = kmalloc(sizeof(*child), GFP_ATOMIC);
160
            if(child==NULL) {
161
#ifdef DEBUG_PCISCAN
162
            printk(KERN_ERR "pci: out of memory for bridge.\n");
163
#endif
164
                continue;
165
            }
166
            memset(child, 0, sizeof(*child));
167
            child->next = bus->children;
168
            bus->children = child;
169
            child->self = dev;
170
            child->parent = bus;
171
 
172
            /*
173
             * Set up the primary, secondary and subordinate
174
             * bus numbers.
175
             */
176
            child->number = child->secondary = ++max;
177
            child->primary = bus->secondary;
178
            child->subordinate = 0xff;
179
            /*
180
             * Clear all status bits and turn off memory,
181
             * I/O and master enables.
182
             */
183
            pcibios_read_config_word(bus->number, devfn, PCI_COMMAND, &cr);
184
            pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000);
185
            pcibios_write_config_word(bus->number, devfn, PCI_STATUS, 0xffff);
186
            /*
187
             * Read the existing primary/secondary/subordinate bus
188
             * number configuration to determine if the PCI bridge
189
             * has already been configured by the system.  If so,
190
             * do not modify the configuration, merely note it.
191
             */
192
            pcibios_read_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, &buses);
193
            if ((buses & 0xFFFFFF) != 0) {
194
                unsigned int cmax;
195
 
196
                child->primary = buses & 0xFF;
197
                child->secondary = (buses >> 8) & 0xFF;
198
                child->subordinate = (buses >> 16) & 0xFF;
199
                child->number = child->secondary;
200
                cmax = pci_scan_bus(child);
201
                if (cmax > max) max = cmax;
202
            } else {
203
                /*
204
                 * Configure the bus numbers for this bridge:
205
                 */
206
                buses &= 0xff000000;
207
                buses |= (((unsigned int)(child->primary)     <<  0) |
208
                        ((unsigned int)(child->secondary)   <<  8) |
209
                        ((unsigned int)(child->subordinate) << 16));
210
                pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
211
                /*
212
                 * Now we can scan all subordinate buses:
213
                 */
214
                max = pci_scan_bus(child);
215
                /*
216
                 * Set the subordinate bus number to its real
217
                 * value:
218
                 */
219
                child->subordinate = max;
220
                buses = (buses & 0xff00ffff)
221
                | ((unsigned int)(child->subordinate) << 16);
222
                pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
223
            }
224
            pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr);
225
        }
226
    }
227
#endif
228
 
229
    return max;
230
}
231
 
232
 
233
#endif
234
 
235
 
236
 
237
 
238
 
239
 
240
 
241
 
242
 
243
 
244
 
245
 
246
 
247
 
248
 
249
 
250
 
251
 
252
 
253
 
254
 
255
 
256
 
257
 
258
 
259
 
260
 
261
 
262
 
263
 
264
 
265
 
266
 
267
 
268
 
269
 
270
 
271
 
272
 
273
/* scan the bus to find all the connected devices */
274
DWORD pci_scan_bus(struct pci_bus *bus)
275
{
276
    int ndev;
277
    DWORD tmp;
278
    DWORD max, class;
279
    BYTE hdr, irq1;
280
    int ok;
281
    WORD dev;
282
    struct pci_dev **bus_last;
283
    struct pci_dev *device = NULL;
284
    int present;
285
 
286
    max = bus->secondary;
287
    bus_last = &bus->devices;
288
 
289
    if (pcibios_present() == 0) return -1;
290
    ndev = 0;
291
 
292
    for (dev = 0; dev <= 0xFF; dev++) {
293
        present = 0;
294
        if ((dev & 0x07) == 0) {
295
            present = pcibios_read_config_byte(bus->number, dev, 0x0e, &hdr);
296
        }
297
        if (hdr & 0x80) {
298
            present = 1;
299
        }
300
        if (present) {
301
            ok = pcibios_read_config_dword(bus->number, dev, 0, &tmp);
302
            if ( ok && (((tmp & 0xFFFF) != 0xFFFF) && ((tmp >> 16) != 0xFFFF))) {
303
                /* Got a PCI Device!!! */
304
                device = &(pci_devs[ndev++]);
305
                device->bus = bus;
306
                device->devfn  = dev;
307
                device->vendor = tmp & 0xffff;
308
                device->device = (tmp >> 16) & 0xffff;
309
 
310
 
311
                /* This is by Luca... We need to set base_addr */
312
                pcibios_read_config_dword(bus->number, dev, PCI_BASE_ADDRESS_0, &(device->base_address[0]));
313
 
314
 
315
                /* ...and also the interrupt number!!! */
316
                pcibios_read_config_byte(bus->number, dev, PCI_INTERRUPT_LINE, &irq1);
317
                device->irq = irq1;
318
 
319
                pcibios_read_config_dword(bus->number, dev, PCI_CLASS_REVISION, &class);
320
                class >>= 8;                                /* upper 3 bytes */
321
                device->class = class;
322
                class >>= 8;
323
                device->hdr_type = hdr;
324
 
325
#if 0
326
                switch (hdr_type & 0x7f) {                  /* header type */
327
                case PCI_HEADER_TYPE_NORMAL:                /* standard header */
328
                        if (class == PCI_CLASS_BRIDGE_PCI)
329
                                goto bad;
330
                        /*
331
                         * If the card generates interrupts, read IRQ number
332
                         * (some architectures change it during pcibios_fixup())
333
                         */
334
                        pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_PIN, &irq);
335
                        if (irq)
336
                                pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_LINE, &irq);
337
                        dev->irq = irq;
338
                        /*
339
                         * read base address registers, again pcibios_fixup() can
340
                         * tweak these
341
                         */
342
                        pci_read_bases(dev, 6);
343
                        pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS, &l);
344
                        dev->rom_address = (l == 0xffffffff) ? 0 : l;
345
                        break;
346
                case PCI_HEADER_TYPE_BRIDGE:                /* bridge header */
347
                        if (class != PCI_CLASS_BRIDGE_PCI)
348
                                goto bad;
349
                        pci_read_bases(dev, 2);
350
                        pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l);
351
                        dev->rom_address = (l == 0xffffffff) ? 0 : l;
352
                        break;
353
                        case PCI_HEADER_TYPE_CARDBUS:               /* CardBus bridge header */
354
                        if (class != PCI_CLASS_BRIDGE_CARDBUS)
355
                                goto bad;
356
                        pci_read_bases(dev, 1);
357
                        break;
358
                default:                                    /* unknown header */
359
                bad:
360
                        printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n",
361
                               bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
362
                        continue;
363
                }
364
 
365
                DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
366
#endif
367
 
368
                device->next = pci_devices;
369
                pci_devices = device;
370
 
371
                /*
372
                 * Now insert it into the list of devices held
373
                 * by the parent bus.
374
                 */
375
                *bus_last = device;
376
                bus_last = &device->sibling;
377
 
378
 
379
 
380
            }
381
        }
382
    }
383
 
384
 
385
    for(device = bus->devices; device; device = device->sibling) {
386
#if 0
387
        /*
388
        * If it's a bridge, scan the bus behind it.
389
        */
390
        if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
391
            unsigned int buses;
392
            unsigned int devfn = dev->devfn;
393
            unsigned short cr;
394
 
395
            /*
396
             * Insert it into the tree of buses.
397
             */
398
            child = kmalloc(sizeof(*child), GFP_ATOMIC);
399
            if(child==NULL) {
400
#ifdef DEBUG_PCISCAN
401
            printk(KERN_ERR "pci: out of memory for bridge.\n");
402
#endif
403
                continue;
404
            }
405
            memset(child, 0, sizeof(*child));
406
            child->next = bus->children;
407
            bus->children = child;
408
            child->self = dev;
409
            child->parent = bus;
410
 
411
            /*
412
             * Set up the primary, secondary and subordinate
413
             * bus numbers.
414
             */
415
            child->number = child->secondary = ++max;
416
            child->primary = bus->secondary;
417
            child->subordinate = 0xff;
418
            /*
419
             * Clear all status bits and turn off memory,
420
             * I/O and master enables.
421
             */
422
            pcibios_read_config_word(bus->number, devfn, PCI_COMMAND, &cr);
423
            pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000);
424
            pcibios_write_config_word(bus->number, devfn, PCI_STATUS, 0xffff);
425
            /*
426
             * Read the existing primary/secondary/subordinate bus
427
             * number configuration to determine if the PCI bridge
428
             * has already been configured by the system.  If so,
429
             * do not modify the configuration, merely note it.
430
             */
431
            pcibios_read_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, &buses);
432
            if ((buses & 0xFFFFFF) != 0) {
433
                unsigned int cmax;
434
 
435
                child->primary = buses & 0xFF;
436
                child->secondary = (buses >> 8) & 0xFF;
437
                child->subordinate = (buses >> 16) & 0xFF;
438
                child->number = child->secondary;
439
                cmax = pci_scan_bus(child);
440
                if (cmax > max) max = cmax;
441
            } else {
442
                /*
443
                 * Configure the bus numbers for this bridge:
444
                 */
445
                buses &= 0xff000000;
446
                buses |= (((unsigned int)(child->primary)     <<  0) |
447
                        ((unsigned int)(child->secondary)   <<  8) |
448
                        ((unsigned int)(child->subordinate) << 16));
449
                pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
450
                /*
451
                 * Now we can scan all subordinate buses:
452
                 */
453
                max = pci_scan_bus(child);
454
                /*
455
                 * Set the subordinate bus number to its real
456
                 * value:
457
                 */
458
                child->subordinate = max;
459
                buses = (buses & 0xff00ffff)
460
                | ((unsigned int)(child->subordinate) << 16);
461
                pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses);
462
            }
463
            pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr);
464
        }
465
#endif
466
    }
467
 
468
    return max;
469
}
470
 
471
 
472
void linuxpci_init(void)
473
{
474
    pcibios_init();
475
 
476
    if (!pci_present()) {
477
#ifdef DEBUG_PCISCAN
478
        printk("PCI: No PCI bus detected\n");
479
#endif
480
        return;
481
    }
482
 
483
#ifdef DEBUG_PCISCAN
484
    printk("PCI: Probing PCI hardware\n");
485
#endif
486
    memset(&pci_root, 0, sizeof(pci_root));
487
    pci_root.subordinate = pci_scan_bus(&pci_root);
488
}
489
 
490
struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
491
{
492
        if (!from)
493
                from = pci_devices;
494
        else
495
                from = from->next;
496
        while (from && (from->vendor != vendor || from->device != device))
497
                from = from->next;
498
        return from;
499
}
500
 
501
struct pci_dev *pci_find_class(unsigned int class, struct pci_dev *from)
502
{
503
        if (!from)
504
                from = pci_devices;
505
        else
506
                from = from->next;
507
        while (from && from->class != class)
508
                from = from->next;
509
        return from;
510
}
511
 
512
struct pci_dev *
513
pci_find_slot(unsigned int bus, unsigned int devfn)
514
{
515
        struct pci_dev *dev;
516
 
517
        for(dev=pci_devices; dev; dev=dev->next)
518
                if (dev->bus->number == bus && dev->devfn == devfn)
519
                        break;
520
        return dev;
521
}
522
 
523
 
524
void
525
pci_set_master(struct pci_dev *dev)
526
{
527
  unsigned short cmd;  // was: u16
528
  unsigned char lat;  // was: u8
529
 
530
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
531
        if (! (cmd & PCI_COMMAND_MASTER)) {
532
                printk("PCI: Enabling bus mastering for device %02x:%02x\n",
533
                        dev->bus->number, dev->devfn);
534
                cmd |= PCI_COMMAND_MASTER;
535
                pci_write_config_word(dev, PCI_COMMAND, cmd);
536
        }
537
        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
538
        if (lat < 16) {
539
                printk("PCI: Increasing latency timer of device %02x:%02x to 64\n",
540
                        dev->bus->number, dev->devfn);
541
                pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
542
        }
543
}