Subversion Repositories Kolibri OS

Rev

Rev 9079 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9079 turbocat 1
#include 
2
#include 
3
 
4
LIST_HEAD(devices);
5
 
6
/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
7
#define IORESOURCE_PCI_FIXED            (1<<4)  /* Do not move resource */
8
 
9
#define LEGACY_IO_RESOURCE      (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
10
 
11
#define IORESOURCE_ROM_COPY             (1<<2)  /* ROM is alloc'd copy, resource field overlaid */
12
#define IORESOURCE_ROM_BIOS_COPY        (1<<3)  /* ROM is BIOS copy, resource field overlaid */
13
 
14
 
15
static inline unsigned int pci_calc_resource_flags(unsigned int flags)
16
{
17
    if (flags & PCI_BASE_ADDRESS_SPACE_IO)
18
        return IORESOURCE_IO;
19
 
20
    if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
21
        return IORESOURCE_MEM | IORESOURCE_PREFETCH;
22
 
23
    return IORESOURCE_MEM;
24
}
25
 
26
static u32 pci_size(u32 base, u32 maxbase, u32 mask)
27
{
28
    u32 size = mask & maxbase;      /* Find the significant bits */
29
 
30
    if (!size)
31
        return 0;
32
 
33
    /* Get the lowest of them to find the decode size, and
34
       from that the extent.  */
35
    size = (size & ~(size-1)) - 1;
36
 
37
    /* base == maxbase can be valid only if the BAR has
38
       already been programmed with all 1s.  */
39
    if (base == maxbase && ((base | size) & mask) != mask)
40
        return 0;
41
 
42
    return size;
43
}
44
 
45
static u64 pci_size64(u64 base, u64 maxbase, u64 mask)
46
{
47
    u64 size = mask & maxbase;      /* Find the significant bits */
48
 
49
    if (!size)
50
        return 0;
51
 
52
    /* Get the lowest of them to find the decode size, and
53
       from that the extent.  */
54
    size = (size & ~(size-1)) - 1;
55
 
56
    /* base == maxbase can be valid only if the BAR has
57
       already been programmed with all 1s.  */
58
    if (base == maxbase && ((base | size) & mask) != mask)
59
        return 0;
60
 
61
    return size;
62
}
63
 
64
static inline int is_64bit_memory(u32 mask)
65
{
66
    if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
67
        (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64))
68
        return 1;
69
    return 0;
70
}
71
 
72
static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
73
{
74
    u32  pos, reg, next;
75
    u32  l, sz;
76
    struct resource *res;
77
 
78
    for(pos=0; pos < howmany; pos = next)
79
    {
80
        u64  l64;
81
        u64  sz64;
82
        u32  raw_sz;
83
 
84
        next = pos + 1;
85
 
86
        res  = &dev->resource[pos];
87
 
88
        reg = PCI_BASE_ADDRESS_0 + (pos << 2);
89
        l = PciRead32(dev->busnr, dev->devfn, reg);
90
        PciWrite32(dev->busnr, dev->devfn, reg, ~0);
91
        sz = PciRead32(dev->busnr, dev->devfn, reg);
92
        PciWrite32(dev->busnr, dev->devfn, reg, l);
93
 
94
        if (!sz || sz == 0xffffffff)
95
            continue;
96
 
97
        if (l == 0xffffffff)
98
            l = 0;
99
 
100
        raw_sz = sz;
101
        if ((l & PCI_BASE_ADDRESS_SPACE) ==
102
                        PCI_BASE_ADDRESS_SPACE_MEMORY)
103
        {
104
            sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
105
            /*
106
             * For 64bit prefetchable memory sz could be 0, if the
107
             * real size is bigger than 4G, so we need to check
108
             * szhi for that.
109
             */
110
            if (!is_64bit_memory(l) && !sz)
111
                    continue;
112
            res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
113
            res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
114
        }
115
        else {
116
            sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
117
            if (!sz)
118
                continue;
119
            res->start = l & PCI_BASE_ADDRESS_IO_MASK;
120
            res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
121
        }
122
        res->end = res->start + (unsigned long) sz;
123
        res->flags |= pci_calc_resource_flags(l);
124
        if (is_64bit_memory(l))
125
        {
126
            u32 szhi, lhi;
127
 
128
            lhi = PciRead32(dev->busnr, dev->devfn, reg+4);
129
            PciWrite32(dev->busnr, dev->devfn, reg+4, ~0);
130
            szhi = PciRead32(dev->busnr, dev->devfn, reg+4);
131
            PciWrite32(dev->busnr, dev->devfn, reg+4, lhi);
132
            sz64 = ((u64)szhi << 32) | raw_sz;
133
            l64 = ((u64)lhi << 32) | l;
134
            sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
135
            next++;
136
 
137
#if BITS_PER_LONG == 64
138
            if (!sz64) {
139
                res->start = 0;
140
                res->end = 0;
141
                res->flags = 0;
142
                continue;
143
            }
144
            res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK;
145
            res->end = res->start + sz64;
146
#else
147
            if (sz64 > 0x100000000ULL) {
148
                printk(KERN_ERR "PCI: Unable to handle 64-bit "
149
                                "BAR for device %s\n", pci_name(dev));
150
                res->start = 0;
151
                res->flags = 0;
152
            }
153
            else if (lhi)
154
            {
155
                /* 64-bit wide address, treat as disabled */
156
                PciWrite32(dev->busnr, dev->devfn, reg,
157
                        l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
158
                PciWrite32(dev->busnr, dev->devfn, reg+4, 0);
159
                res->start = 0;
160
                res->end = sz;
161
            }
162
#endif
163
        }
164
    }
165
 
166
    if ( rom )
167
    {
168
        dev->rom_base_reg = rom;
169
        res = &dev->resource[PCI_ROM_RESOURCE];
170
 
171
        l = PciRead32(dev->busnr, dev->devfn, rom);
172
        PciWrite32(dev->busnr, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE);
173
        sz = PciRead32(dev->busnr, dev->devfn, rom);
174
        PciWrite32(dev->busnr, dev->devfn, rom, l);
175
 
176
        if (l == 0xffffffff)
177
            l = 0;
178
 
179
        if (sz && sz != 0xffffffff)
180
        {
181
            sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK);
182
 
183
            if (sz)
184
            {
185
                res->flags = (l & IORESOURCE_ROM_ENABLE) |
186
                                  IORESOURCE_MEM | IORESOURCE_PREFETCH |
187
                                  IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
188
                res->start = l & PCI_ROM_ADDRESS_MASK;
189
                res->end = res->start + (unsigned long) sz;
190
            }
191
        }
192
    }
193
}
194
 
195
static void pci_read_irq(struct pci_dev *dev)
196
{
197
    u8 irq;
198
 
199
    irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_PIN);
200
    dev->pin = irq;
201
    if (irq)
202
        irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_LINE);
203
    dev->irq = irq;
204
};
205
 
206
 
207
int pci_setup_device(struct pci_dev *dev)
208
{
209
    u32  class;
210
 
211
    class = PciRead32(dev->busnr, dev->devfn, PCI_CLASS_REVISION);
212
    dev->revision = class & 0xff;
213
    class >>= 8;                                /* upper 3 bytes */
214
    dev->class = class;
215
 
216
    /* "Unknown power state" */
217
//    dev->current_state = PCI_UNKNOWN;
218
 
219
    /* Early fixups, before probing the BARs */
220
 //   pci_fixup_device(pci_fixup_early, dev);
221
    class = dev->class >> 8;
222
 
223
    switch (dev->hdr_type)
224
    {
225
        case PCI_HEADER_TYPE_NORMAL:                /* standard header */
226
            if (class == PCI_CLASS_BRIDGE_PCI)
227
                goto bad;
228
            pci_read_irq(dev);
229
            pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
230
            dev->subsystem_vendor = PciRead16(dev->busnr, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID);
231
            dev->subsystem_device = PciRead16(dev->busnr, dev->devfn, PCI_SUBSYSTEM_ID);
232
 
233
            /*
234
             *      Do the ugly legacy mode stuff here rather than broken chip
235
             *      quirk code. Legacy mode ATA controllers have fixed
236
             *      addresses. These are not always echoed in BAR0-3, and
237
             *      BAR0-3 in a few cases contain junk!
238
             */
239
            if (class == PCI_CLASS_STORAGE_IDE)
240
            {
241
                u8 progif;
242
 
243
                progif = PciRead8(dev->busnr, dev->devfn,PCI_CLASS_PROG);
244
                if ((progif & 1) == 0)
245
                {
246
                    dev->resource[0].start = 0x1F0;
247
                    dev->resource[0].end = 0x1F7;
248
                    dev->resource[0].flags = LEGACY_IO_RESOURCE;
249
                    dev->resource[1].start = 0x3F6;
250
                    dev->resource[1].end = 0x3F6;
251
                    dev->resource[1].flags = LEGACY_IO_RESOURCE;
252
                }
253
                if ((progif & 4) == 0)
254
                {
255
                    dev->resource[2].start = 0x170;
256
                    dev->resource[2].end = 0x177;
257
                    dev->resource[2].flags = LEGACY_IO_RESOURCE;
258
                    dev->resource[3].start = 0x376;
259
                    dev->resource[3].end = 0x376;
260
                    dev->resource[3].flags = LEGACY_IO_RESOURCE;
261
                };
262
            }
263
            break;
264
 
265
        case PCI_HEADER_TYPE_BRIDGE:                /* bridge header */
266
                if (class != PCI_CLASS_BRIDGE_PCI)
267
                        goto bad;
268
                /* The PCI-to-PCI bridge spec requires that subtractive
269
                   decoding (i.e. transparent) bridge must have programming
270
                   interface code of 0x01. */
271
                pci_read_irq(dev);
272
                dev->transparent = ((dev->class & 0xff) == 1);
273
                pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
274
                break;
275
 
276
        case PCI_HEADER_TYPE_CARDBUS:               /* CardBus bridge header */
277
                if (class != PCI_CLASS_BRIDGE_CARDBUS)
278
                        goto bad;
279
                pci_read_irq(dev);
280
                pci_read_bases(dev, 1, 0);
281
                dev->subsystem_vendor = PciRead16(dev->busnr,
282
                                                  dev->devfn,
283
                                                  PCI_CB_SUBSYSTEM_VENDOR_ID);
284
 
285
                dev->subsystem_device = PciRead16(dev->busnr,
286
                                                  dev->devfn,
287
                                                  PCI_CB_SUBSYSTEM_ID);
288
                break;
289
 
290
        default:                                    /* unknown header */
291
                printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
292
                        pci_name(dev), dev->hdr_type);
293
                return -1;
294
 
295
        bad:
296
                printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
297
                       pci_name(dev), class, dev->hdr_type);
298
                dev->class = PCI_CLASS_NOT_DEFINED;
299
    }
300
 
301
    /* We found a fine healthy device, go go go... */
302
 
303
    return 0;
304
};
305
 
306
static pci_dev_t* pci_scan_device(u32 busnr, int devfn)
307
{
308
    pci_dev_t  *dev;
309
 
310
    u32   id;
311
    u8    hdr;
312
 
313
    int     timeout = 10;
314
 
315
    id = PciRead32(busnr, devfn, PCI_VENDOR_ID);
316
    /* some broken boards return 0 or ~0 if a slot is empty: */
317
    if (id == 0xffffffff || id == 0x00000000 ||
318
        id == 0x0000ffff || id == 0xffff0000)
319
        return NULL;
320
 
321
    while (id == 0xffff0001)
322
    {
323
 
324
        delay(timeout/10);
325
        timeout *= 2;
326
 
327
        id = PciRead32(busnr, devfn, PCI_VENDOR_ID);
328
 
329
        /* Card hasn't responded in 60 seconds?  Must be stuck. */
330
        if (timeout > 60 * 100)
331
        {
332
            printk(KERN_WARNING "Device %04x:%02x:%02x.%d not "
333
                   "responding\n", busnr,PCI_SLOT(devfn),PCI_FUNC(devfn));
334
            return NULL;
335
        }
336
    };
337
 
338
  /* if( pci_scan_filter(id, busnr, devfn) == 0)
339
        return NULL;*/
340
 
341
    hdr = PciRead8(busnr, devfn, PCI_HEADER_TYPE);
342
 
9827 turbocat 343
    dev = (pci_dev_t*)KernelZeroAlloc(sizeof(pci_dev_t));
9079 turbocat 344
    if(unlikely(dev == NULL))
345
        return NULL;
346
 
347
    INIT_LIST_HEAD(&dev->link);
348
 
349
    dev->pci_dev.busnr    = busnr;
350
    dev->pci_dev.devfn    = devfn;
351
    dev->pci_dev.hdr_type = hdr & 0x7f;
352
    dev->pci_dev.multifunction    = !!(hdr & 0x80);
353
    dev->pci_dev.vendor   = id & 0xffff;
354
    dev->pci_dev.device   = (id >> 16) & 0xffff;
355
 
356
    pci_setup_device(&dev->pci_dev);
357
 
358
    return dev;
359
 
360
};
361
 
362
 
363
 
364
int _pci_scan_slot(u32 bus, int devfn)
365
{
366
    int  func, nr = 0;
367
 
368
    for (func = 0; func < 8; func++, devfn++)
369
    {
370
        pci_dev_t  *dev;
371
 
372
        dev = pci_scan_device(bus, devfn);
373
        if( dev )
374
        {
375
            list_add(&dev->link, &devices);
376
            nr++;
377
 
378
            /*
379
             * If this is a single function device,
380
             * don't scan past the first function.
381
             */
382
            if (!dev->pci_dev.multifunction)
383
            {
384
                if (func > 0) {
385
                    dev->pci_dev.multifunction = 1;
386
                }
387
                else {
388
                    break;
389
                }
390
             }
391
        }
392
        else {
393
            if (func == 0)
394
                break;
395
        }
396
    };
397
 
398
    return nr;
399
};
400
 
401
#define PCI_FIND_CAP_TTL    48
402
 
403
static int __pci_find_next_cap_ttl(unsigned int bus, unsigned int devfn,
404
                   u8 pos, int cap, int *ttl)
405
{
406
    u8 id;
407
 
408
    while ((*ttl)--) {
409
        pos = PciRead8(bus, devfn, pos);
410
        if (pos < 0x40)
411
            break;
412
        pos &= ~3;
413
        id = PciRead8(bus, devfn, pos + PCI_CAP_LIST_ID);
414
        if (id == 0xff)
415
            break;
416
        if (id == cap)
417
            return pos;
418
        pos += PCI_CAP_LIST_NEXT;
419
    }
420
    return 0;
421
}
422
 
423
static int __pci_find_next_cap(unsigned int bus, unsigned int devfn,
424
                   u8 pos, int cap)
425
{
426
    int ttl = PCI_FIND_CAP_TTL;
427
 
428
    return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
429
}
430
 
431
static int __pci_bus_find_cap_start(unsigned int bus,
432
                    unsigned int devfn, u8 hdr_type)
433
{
434
    u16 status;
435
 
436
    status = PciRead16(bus, devfn, PCI_STATUS);
437
    if (!(status & PCI_STATUS_CAP_LIST))
438
        return 0;
439
 
440
    switch (hdr_type) {
441
    case PCI_HEADER_TYPE_NORMAL:
442
    case PCI_HEADER_TYPE_BRIDGE:
443
        return PCI_CAPABILITY_LIST;
444
    case PCI_HEADER_TYPE_CARDBUS:
445
        return PCI_CB_CAPABILITY_LIST;
446
    default:
447
        return 0;
448
    }
449
 
450
    return 0;
451
}
452
 
453
 
454
int pci_find_capability(struct pci_dev *dev, int cap)
455
{
456
    int pos;
457
 
458
    pos = __pci_bus_find_cap_start(dev->busnr, dev->devfn, dev->hdr_type);
459
    if (pos)
460
        pos = __pci_find_next_cap(dev->busnr, dev->devfn, pos, cap);
461
 
462
    return pos;
463
}
464
 
465
 
9827 turbocat 466
int enum_pci_devices(void)
9079 turbocat 467
{
468
    pci_dev_t  *dev;
469
    u32       last_bus;
470
    u32       bus = 0 , devfn = 0;
471
 
472
    last_bus = PciApi(1);
473
 
474
    if( unlikely(last_bus == -1))
475
        return -1;
476
 
477
    for(;bus <= last_bus; bus++)
478
    {
479
        for (devfn = 0; devfn < 0x100; devfn += 8){
480
            _pci_scan_slot(bus, devfn);
481
        }
482
    }
483
    dev = (pci_dev_t*)devices.next;
484
 
485
    while(&dev->link != &devices)
486
    {
487
        /*printk("PCI device %x:%x bus:%x devfn:%x\n",
488
                dev->pci_dev.vendor,
489
                dev->pci_dev.device,
490
                dev->pci_dev.busnr,
491
                dev->pci_dev.devfn);*/
492
        dev = (pci_dev_t*)dev->link.next;
493
    }
494
    return 0;
495
}
496
 
9827 turbocat 497
void free_pci_devices(void)
498
{
499
    pci_dev_t *dev = (pci_dev_t*)devices.next;
500
    while(&dev->link != &devices) {
501
        pci_dev_t *temp = dev;
502
        dev = (pci_dev_t*)dev->link.next;
503
        KernelFree(temp);
504
    }
505
}
506
 
9079 turbocat 507
const struct pci_device_id* find_pci_device(pci_dev_t* pdev, const struct pci_device_id *idlist)
508
{
509
    pci_dev_t *dev;
510
    const struct pci_device_id *ent;
511
 
512
    for(dev = (pci_dev_t*)devices.next;
513
        &dev->link != &devices;
514
        dev = (pci_dev_t*)dev->link.next)
515
    {
516
        if( dev->pci_dev.vendor != idlist->vendor )
517
            continue;
518
 
519
        for(ent = idlist; ent->vendor != 0; ent++)
520
        {
521
            if(unlikely(ent->device == dev->pci_dev.device))
522
            {
523
                pdev->pci_dev = dev->pci_dev;
524
                return  ent;
525
            }
526
        };
527
    }
528
 
529
    return NULL;
530
};
531
 
532
struct pci_dev *
533
pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
534
{
535
    pci_dev_t *dev;
536
 
537
    dev = (pci_dev_t*)devices.next;
538
 
539
    if(from != NULL)
540
    {
541
        for(; &dev->link != &devices;
542
            dev = (pci_dev_t*)dev->link.next)
543
        {
544
            if( &dev->pci_dev == from)
545
            {
546
                dev = (pci_dev_t*)dev->link.next;
547
                break;
548
            };
549
        }
550
    };
551
 
552
    for(; &dev->link != &devices;
553
        dev = (pci_dev_t*)dev->link.next)
554
    {
555
        if((dev->pci_dev.vendor != vendor) && (vendor != PCI_ANY_ID))
556
                continue;
557
 
558
        if((dev->pci_dev.device == device || device == PCI_ANY_ID))
559
        {
560
            return &dev->pci_dev;
561
        }
562
    }
563
    return NULL;
564
};
565
 
566
 
567
struct pci_dev * _pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
568
{
569
    pci_dev_t *dev;
570
 
571
    for(dev = (pci_dev_t*)devices.next;
572
        &dev->link != &devices;
573
        dev = (pci_dev_t*)dev->link.next)
574
    {
575
        if ( dev->pci_dev.busnr == bus && dev->pci_dev.devfn == devfn)
576
            return &dev->pci_dev;
577
    }
578
    return NULL;
579
}
580
 
581
struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
582
{
583
    pci_dev_t *dev;
584
 
585
    dev = (pci_dev_t*)devices.next;
586
 
587
    if(from != NULL)
588
    {
589
        for(; &dev->link != &devices;
590
            dev = (pci_dev_t*)dev->link.next)
591
        {
592
            if( &dev->pci_dev == from)
593
            {
594
                dev = (pci_dev_t*)dev->link.next;
595
                break;
596
            };
597
        }
598
    };
599
 
600
    for(; &dev->link != &devices;
601
        dev = (pci_dev_t*)dev->link.next)
602
    {
603
        if( dev->pci_dev.class == class)
604
        {
605
            return &dev->pci_dev;
606
        }
607
    }
608
 
609
   return NULL;
610
}
611
 
9827 turbocat 612
 
9079 turbocat 613
int pci_bus_read_config_byte (struct pci_bus *bus, u32 devfn, int pos, u8 *value)
614
{
615
//    raw_spin_lock_irqsave(&pci_lock, flags);
616
    *value = PciRead8(bus->number, devfn, pos);
617
//    raw_spin_unlock_irqrestore(&pci_lock, flags);
618
    return 0;
619
}
620
 
621
int pci_bus_read_config_word (struct pci_bus *bus, u32 devfn, int pos, u16 *value)
622
{
623
    if ( pos & 1)
624
        return PCIBIOS_BAD_REGISTER_NUMBER;
625
//    raw_spin_lock_irqsave(&pci_lock, flags);
626
    *value = PciRead16(bus->number, devfn, pos);
627
//    raw_spin_unlock_irqrestore(&pci_lock, flags);
628
    return 0;
629
}
630
 
631
 
632
int pci_bus_read_config_dword (struct pci_bus *bus, u32 devfn, int pos, u32 *value)
633
{
634
    if ( pos & 3)
635
        return PCIBIOS_BAD_REGISTER_NUMBER;
636
    *value = PciRead32(bus->number, devfn, pos);
637
    return 0;
638
}
639
 
640
int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
641
{
642
    if ( where & 3)
643
        return PCIBIOS_BAD_REGISTER_NUMBER;
644
    PciWrite32(bus->number, devfn,where, val);
645
    return 0;
646
}