Subversion Repositories Kolibri OS

Rev

Rev 2327 | Rev 3031 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2325 Serge 1
 
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
8
 
9
10
 
11
12
 
13
#define IORESOURCE_PCI_FIXED            (1<<4)  /* Do not move resource */
14
15
 
16
17
 
18
 * Translate the low bits of the PCI base
19
 * to the resource type
20
 */
21
static inline unsigned int pci_calc_resource_flags(unsigned int flags)
22
{
23
    if (flags & PCI_BASE_ADDRESS_SPACE_IO)
24
        return IORESOURCE_IO;
25
26
 
27
        return IORESOURCE_MEM | IORESOURCE_PREFETCH;
28
29
 
30
}
31
32
 
33
 
34
{
35
    u32_t size = mask & maxbase;      /* Find the significant bits */
36
37
 
38
        return 0;
39
40
 
41
       from that the extent.  */
42
    size = (size & ~(size-1)) - 1;
43
44
 
45
       already been programmed with all 1s.  */
46
    if (base == maxbase && ((base | size) & mask) != mask)
47
        return 0;
48
49
 
50
}
51
52
 
53
{
54
    u64_t size = mask & maxbase;      /* Find the significant bits */
55
56
 
57
        return 0;
58
59
 
60
       from that the extent.  */
61
    size = (size & ~(size-1)) - 1;
62
63
 
64
       already been programmed with all 1s.  */
65
    if (base == maxbase && ((base | size) & mask) != mask)
66
        return 0;
67
68
 
69
}
70
71
 
72
{
73
    if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
74
        (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64))
75
        return 1;
76
    return 0;
77
}
78
79
 
80
{
81
    u32_t  pos, reg, next;
82
    u32_t  l, sz;
83
    struct resource *res;
84
85
 
86
    {
87
        u64_t  l64;
88
        u64_t  sz64;
89
        u32_t  raw_sz;
90
91
 
92
93
 
94
95
 
96
        l = PciRead32(dev->busnr, dev->devfn, reg);
97
        PciWrite32(dev->busnr, dev->devfn, reg, ~0);
98
        sz = PciRead32(dev->busnr, dev->devfn, reg);
99
        PciWrite32(dev->busnr, dev->devfn, reg, l);
100
101
 
102
            continue;
103
104
 
105
            l = 0;
106
107
 
108
        if ((l & PCI_BASE_ADDRESS_SPACE) ==
109
                        PCI_BASE_ADDRESS_SPACE_MEMORY)
110
        {
111
            sz = pci_size(l, sz, (u32_t)PCI_BASE_ADDRESS_MEM_MASK);
112
            /*
113
             * For 64bit prefetchable memory sz could be 0, if the
114
             * real size is bigger than 4G, so we need to check
115
             * szhi for that.
116
             */
117
            if (!is_64bit_memory(l) && !sz)
118
                    continue;
119
            res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
120
            res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
121
        }
122
        else {
123
            sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
124
            if (!sz)
125
                continue;
126
            res->start = l & PCI_BASE_ADDRESS_IO_MASK;
127
            res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
128
        }
129
        res->end = res->start + (unsigned long) sz;
130
        res->flags |= pci_calc_resource_flags(l);
131
        if (is_64bit_memory(l))
132
        {
133
            u32_t szhi, lhi;
134
135
 
136
            PciWrite32(dev->busnr, dev->devfn, reg+4, ~0);
137
            szhi = PciRead32(dev->busnr, dev->devfn, reg+4);
138
            PciWrite32(dev->busnr, dev->devfn, reg+4, lhi);
139
            sz64 = ((u64_t)szhi << 32) | raw_sz;
140
            l64 = ((u64_t)lhi << 32) | l;
141
            sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
142
            next++;
143
144
 
145
            if (!sz64) {
146
                res->start = 0;
147
                res->end = 0;
148
                res->flags = 0;
149
                continue;
150
            }
151
            res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK;
152
            res->end = res->start + sz64;
153
#else
154
            if (sz64 > 0x100000000ULL) {
155
                printk(KERN_ERR "PCI: Unable to handle 64-bit "
156
                                "BAR for device %s\n", pci_name(dev));
157
                res->start = 0;
158
                res->flags = 0;
159
            }
160
            else if (lhi)
161
            {
162
                /* 64-bit wide address, treat as disabled */
163
                PciWrite32(dev->busnr, dev->devfn, reg,
164
                        l & ~(u32_t)PCI_BASE_ADDRESS_MEM_MASK);
165
                PciWrite32(dev->busnr, dev->devfn, reg+4, 0);
166
                res->start = 0;
167
                res->end = sz;
168
            }
169
#endif
170
        }
171
    }
172
173
 
174
    {
175
        dev->rom_base_reg = rom;
176
        res = &dev->resource[PCI_ROM_RESOURCE];
177
178
 
179
        PciWrite32(dev->busnr, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE);
180
        sz = PciRead32(dev->busnr, dev->devfn, rom);
181
        PciWrite32(dev->busnr, dev->devfn, rom, l);
182
183
 
184
            l = 0;
185
186
 
187
        {
188
            sz = pci_size(l, sz, (u32_t)PCI_ROM_ADDRESS_MASK);
189
190
 
191
            {
192
                res->flags = (l & IORESOURCE_ROM_ENABLE) |
193
                                  IORESOURCE_MEM | IORESOURCE_PREFETCH |
194
                                  IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
195
                res->start = l & PCI_ROM_ADDRESS_MASK;
196
                res->end = res->start + (unsigned long) sz;
197
            }
198
        }
199
    }
200
}
201
202
 
203
{
204
    u8_t irq;
205
206
 
207
    dev->pin = irq;
208
    if (irq)
209
        irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_LINE);
210
    dev->irq = irq;
211
};
212
213
 
214
 
215
{
216
    u32_t  class;
217
218
 
219
    dev->revision = class & 0xff;
220
    class >>= 8;                                /* upper 3 bytes */
221
    dev->class = class;
222
223
 
224
//    dev->current_state = PCI_UNKNOWN;
225
226
 
227
 //   pci_fixup_device(pci_fixup_early, dev);
228
    class = dev->class >> 8;
229
230
 
231
    {
232
        case PCI_HEADER_TYPE_NORMAL:                /* standard header */
233
            if (class == PCI_CLASS_BRIDGE_PCI)
234
                goto bad;
235
            pci_read_irq(dev);
236
            pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
237
            dev->subsystem_vendor = PciRead16(dev->busnr, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID);
238
            dev->subsystem_device = PciRead16(dev->busnr, dev->devfn, PCI_SUBSYSTEM_ID);
239
240
 
241
             *      Do the ugly legacy mode stuff here rather than broken chip
242
             *      quirk code. Legacy mode ATA controllers have fixed
243
             *      addresses. These are not always echoed in BAR0-3, and
244
             *      BAR0-3 in a few cases contain junk!
245
             */
246
            if (class == PCI_CLASS_STORAGE_IDE)
247
            {
248
                u8_t progif;
249
250
 
251
                if ((progif & 1) == 0)
252
                {
253
                    dev->resource[0].start = 0x1F0;
254
                    dev->resource[0].end = 0x1F7;
255
                    dev->resource[0].flags = LEGACY_IO_RESOURCE;
256
                    dev->resource[1].start = 0x3F6;
257
                    dev->resource[1].end = 0x3F6;
258
                    dev->resource[1].flags = LEGACY_IO_RESOURCE;
259
                }
260
                if ((progif & 4) == 0)
261
                {
262
                    dev->resource[2].start = 0x170;
263
                    dev->resource[2].end = 0x177;
264
                    dev->resource[2].flags = LEGACY_IO_RESOURCE;
265
                    dev->resource[3].start = 0x376;
266
                    dev->resource[3].end = 0x376;
267
                    dev->resource[3].flags = LEGACY_IO_RESOURCE;
268
                };
269
            }
270
            break;
271
272
 
273
                if (class != PCI_CLASS_BRIDGE_PCI)
274
                        goto bad;
275
                /* The PCI-to-PCI bridge spec requires that subtractive
276
                   decoding (i.e. transparent) bridge must have programming
277
                   interface code of 0x01. */
278
                pci_read_irq(dev);
279
                dev->transparent = ((dev->class & 0xff) == 1);
280
                pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
281
                break;
282
283
 
284
                if (class != PCI_CLASS_BRIDGE_CARDBUS)
285
                        goto bad;
286
                pci_read_irq(dev);
287
                pci_read_bases(dev, 1, 0);
288
                dev->subsystem_vendor = PciRead16(dev->busnr,
289
                                                  dev->devfn,
290
                                                  PCI_CB_SUBSYSTEM_VENDOR_ID);
291
292
 
293
                                                  dev->devfn,
294
                                                  PCI_CB_SUBSYSTEM_ID);
295
                break;
296
297
 
298
                printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
299
                        pci_name(dev), dev->hdr_type);
300
                return -1;
301
302
 
303
                printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
304
                       pci_name(dev), class, dev->hdr_type);
305
                dev->class = PCI_CLASS_NOT_DEFINED;
306
    }
307
308
 
309
310
 
311
};
312
313
 
314
{
315
    pci_dev_t  *dev;
316
317
 
318
    u8_t    hdr;
319
320
 
321
322
 
323
324
 
325
    if (id == 0xffffffff || id == 0x00000000 ||
326
        id == 0x0000ffff || id == 0xffff0000)
327
        return NULL;
328
329
 
330
    {
331
332
 
333
        timeout *= 2;
334
335
 
336
337
 
338
        if (timeout > 60 * 100)
339
        {
340
            printk(KERN_WARNING "Device %04x:%02x:%02x.%d not "
341
                   "responding\n", busnr,PCI_SLOT(devfn),PCI_FUNC(devfn));
342
            return NULL;
343
        }
344
    };
345
346
 
347
        return NULL;
348
349
 
350
351
 
352
    if(unlikely(dev == NULL))
2351 Serge 353
        return NULL;
354
2325 Serge 355
 
356
357
 
358
 
359
    dev->pci_dev.devfn    = devfn;
360
    dev->pci_dev.hdr_type = hdr & 0x7f;
361
    dev->pci_dev.multifunction    = !!(hdr & 0x80);
362
    dev->pci_dev.vendor   = id & 0xffff;
363
    dev->pci_dev.device   = (id >> 16) & 0xffff;
364
365
 
366
367
 
368
369
 
370
371
 
372
 
373
 
374
 
375
{
376
    int  func, nr = 0;
377
378
 
379
    {
380
        pci_dev_t  *dev;
381
382
 
383
        if( dev )
384
        {
385
            list_add(&dev->link, &devices);
386
387
 
388
389
 
390
             * If this is a single function device,
391
             * don't scan past the first function.
392
             */
393
            if (!dev->pci_dev.multifunction)
394
            {
395
                if (func > 0) {
396
                    dev->pci_dev.multifunction = 1;
397
                }
398
                else {
399
                    break;
400
                }
401
             }
402
        }
403
        else {
404
            if (func == 0)
405
                break;
406
        }
407
    };
408
409
 
410
};
411
412
 
413
414
 
415
                   u8 pos, int cap, int *ttl)
416
{
417
    u8 id;
418
419
 
420
        pos = PciRead8(bus, devfn, pos);
421
        if (pos < 0x40)
422
            break;
423
        pos &= ~3;
424
        id = PciRead8(bus, devfn, pos + PCI_CAP_LIST_ID);
425
        if (id == 0xff)
426
            break;
427
        if (id == cap)
428
            return pos;
429
        pos += PCI_CAP_LIST_NEXT;
430
    }
431
    return 0;
432
}
433
434
 
435
                   u8 pos, int cap)
436
{
437
    int ttl = PCI_FIND_CAP_TTL;
438
439
 
440
}
441
442
 
443
                    unsigned int devfn, u8 hdr_type)
444
{
445
    u16 status;
446
447
 
448
    if (!(status & PCI_STATUS_CAP_LIST))
449
        return 0;
450
451
 
452
    case PCI_HEADER_TYPE_NORMAL:
453
    case PCI_HEADER_TYPE_BRIDGE:
454
        return PCI_CAPABILITY_LIST;
455
    case PCI_HEADER_TYPE_CARDBUS:
456
        return PCI_CB_CAPABILITY_LIST;
457
    default:
458
        return 0;
459
    }
460
461
 
462
}
463
464
 
465
 
466
{
467
    int pos;
468
469
 
470
    if (pos)
471
        pos = __pci_find_next_cap(dev->busnr, dev->devfn, pos, cap);
472
473
 
474
}
475
476
 
477
 
478
 
479
 
480
{
481
    pci_dev_t  *dev;
482
    u32_t       last_bus;
483
    u32_t       bus = 0 , devfn = 0;
484
485
 
486
 
487
488
 
489
 
490
        return -1;
491
492
 
493
    {
494
        for (devfn = 0; devfn < 0x100; devfn += 8)
495
            pci_scan_slot(bus, devfn);
496
497
 
498
 
499
    for(dev = (pci_dev_t*)devices.next;
500
        &dev->link != &devices;
501
        dev = (pci_dev_t*)dev->link.next)
502
    {
503
        dbgprintf("PCI device %x:%x bus:%x devfn:%x\n",
504
                dev->pci_dev.vendor,
505
                dev->pci_dev.device,
506
                dev->pci_dev.busnr,
2326 Serge 507
                dev->pci_dev.devfn);
2325 Serge 508
509
 
510
    return 0;
511
}
512
513
 
514
{
515
    pci_dev_t *dev;
516
    const struct pci_device_id *ent;
517
518
 
519
        &dev->link != &devices;
520
        dev = (pci_dev_t*)dev->link.next)
521
    {
522
        if( dev->pci_dev.vendor != idlist->vendor )
523
            continue;
524
525
 
526
        {
527
            if(unlikely(ent->device == dev->pci_dev.device))
528
            {
529
                pdev->pci_dev = dev->pci_dev;
530
                return  ent;
531
            }
532
        };
533
    }
534
535
 
536
};
537
538
 
539
pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
540
{
541
    pci_dev_t *dev;
542
543
 
544
545
 
546
    {
547
        for(; &dev->link != &devices;
548
            dev = (pci_dev_t*)dev->link.next)
549
        {
550
            if( &dev->pci_dev == from)
551
            {
552
                dev = (pci_dev_t*)dev->link.next;
553
                break;
554
            };
555
        }
556
    };
557
558
 
559
        dev = (pci_dev_t*)dev->link.next)
560
    {
561
        if( dev->pci_dev.vendor != vendor )
562
            continue;
563
564
 
565
        {
566
            return &dev->pci_dev;
567
        }
568
    }
569
    return NULL;
570
};
571
2326 Serge 572
 
573
 
574
{
575
    pci_dev_t *dev;
576
577
 
578
        &dev->link != &devices;
579
        dev = (pci_dev_t*)dev->link.next)
580
    {
581
        if ( dev->pci_dev.busnr == bus && dev->pci_dev.devfn == devfn)
582
            return &dev->pci_dev;
583
    }
584
    return NULL;
585
}
586
587
 
588
{
589
    pci_dev_t *dev;
590
591
 
592
593
 
594
    {
595
        for(; &dev->link != &devices;
596
            dev = (pci_dev_t*)dev->link.next)
597
        {
598
            if( &dev->pci_dev == from)
599
            {
600
                dev = (pci_dev_t*)dev->link.next;
601
                break;
602
            };
603
        }
604
    };
605
606
 
607
        dev = (pci_dev_t*)dev->link.next)
608
    {
609
        if( dev->pci_dev.class == class)
610
        {
611
            return &dev->pci_dev;
612
        }
613
    }
614
615
 
616
}
617
618
 
619
 
620
#define PIO_MASK        0x0ffffUL
621
#define PIO_RESERVED    0x40000UL
622
623
 
624
    unsigned long port = (unsigned long __force)addr;  \
625
    if (port >= PIO_RESERVED) {                        \
626
        is_mmio;                                       \
627
    } else if (port > PIO_OFFSET) {                    \
628
        port &= PIO_MASK;                              \
629
        is_pio;                                        \
630
    };                                                 \
631
} while (0)
632
633
 
634
void __iomem *ioport_map(unsigned long port, unsigned int nr)
635
{
636
    if (port > PIO_MASK)
637
        return NULL;
638
    return (void __iomem *) (unsigned long) (port + PIO_OFFSET);
639
}
640
641
 
642
{
643
    resource_size_t start = pci_resource_start(dev, bar);
644
    resource_size_t len = pci_resource_len(dev, bar);
645
    unsigned long flags = pci_resource_flags(dev, bar);
646
647
 
648
        return NULL;
649
    if (maxlen && len > maxlen)
650
        len = maxlen;
651
    if (flags & IORESOURCE_IO)
652
        return ioport_map(start, len);
653
    if (flags & IORESOURCE_MEM) {
654
        return ioremap(start, len);
655
    }
656
    /* What? */
657
    return NULL;
658
}
659
660
 
661
{
662
    IO_COND(addr, /* nothing */, iounmap(addr));
663
}
664
665
 
2327 Serge 666
 
667
    resource_size_t start;
668
    resource_size_t end;
669
};
670
671
 
672
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
673
                         struct resource *res)
674
{
675
    region->start = res->start;
676
    region->end = res->end;
677
}
678
679
 
680
                    u32 *val)
681
{
682
    *val = PciRead32(dev->busnr, dev->devfn, where);
683
    return 1;
684
}
685
686
 
687
                    u32 val)
688
{
689
    PciWrite32(dev->busnr, dev->devfn, where, val);
690
    return 1;
691
}
692
693
 
694
{
695
    struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
696
    struct pci_bus_region region;
697
    u32 rom_addr;
698
699
 
700
            return -1;
701
702
 
703
    pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
704
    rom_addr &= ~PCI_ROM_ADDRESS_MASK;
705
    rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE;
706
    pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
707
    return 0;
708
}
709
710
 
711
{
712
    u32 rom_addr;
713
    pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
714
    rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
715
    pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
716
}
717
718
 
719
 * pci_get_rom_size - obtain the actual size of the ROM image
720
 * @pdev: target PCI device
721
 * @rom: kernel virtual pointer to image of ROM
722
 * @size: size of PCI window
723
 *  return: size of actual ROM image
724
 *
725
 * Determine the actual length of the ROM image.
726
 * The PCI window size could be much larger than the
727
 * actual image size.
728
 */
729
size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
730
{
731
        void __iomem *image;
732
        int last_image;
733
734
 
735
        do {
736
                void __iomem *pds;
737
                /* Standard PCI ROMs start out with these bytes 55 AA */
738
                if (readb(image) != 0x55) {
739
                        dev_err(&pdev->dev, "Invalid ROM contents\n");
740
                        break;
741
                }
742
                if (readb(image + 1) != 0xAA)
743
                        break;
744
                /* get the PCI data structure and check its signature */
745
                pds = image + readw(image + 24);
746
                if (readb(pds) != 'P')
747
                        break;
748
                if (readb(pds + 1) != 'C')
749
                        break;
750
                if (readb(pds + 2) != 'I')
751
                        break;
752
                if (readb(pds + 3) != 'R')
753
                        break;
754
                last_image = readb(pds + 21) & 0x80;
755
                /* this length is reliable */
756
                image += readw(pds + 16) * 512;
757
        } while (!last_image);
758
759
 
760
        /* there are known ROMs that get the size wrong */
761
        return min((size_t)(image - rom), size);
762
}
763
764
 
765
 
766
 * pci_map_rom - map a PCI ROM to kernel space
767
 * @pdev: pointer to pci device struct
768
 * @size: pointer to receive size of pci window over ROM
769
 *
770
 * Return: kernel virtual pointer to image of ROM
771
 *
772
 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
773
 * the shadow BIOS copy will be returned instead of the
774
 * actual ROM.
775
 */
776
void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
777
{
778
        struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
779
        loff_t start;
780
        void __iomem *rom;
781
782
 
783
         * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
784
         * memory map if the VGA enable bit of the Bridge Control register is
785
         * set for embedded VGA.
786
         */
787
        if (res->flags & IORESOURCE_ROM_SHADOW) {
788
                /* primary video rom always starts here */
789
                start = (loff_t)0xC0000;
790
                *size = 0x20000; /* cover C000:0 through E000:0 */
791
        } else {
792
                if (res->flags &
793
                        (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) {
794
                        *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
795
                        return (void __iomem *)(unsigned long)
796
                                pci_resource_start(pdev, PCI_ROM_RESOURCE);
797
                } else {
798
                        /* assign the ROM an address if it doesn't have one */
799
//                        if (res->parent == NULL &&
800
//                            pci_assign_resource(pdev,PCI_ROM_RESOURCE))
801
                                return NULL;
802
//                        start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
803
//                        *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
804
//                        if (*size == 0)
805
//                                return NULL;
806
807
 
808
//                        if (pci_enable_rom(pdev))
809
//                                return NULL;
810
                }
811
        }
812
813
 
814
        if (!rom) {
815
                /* restore enable if ioremap fails */
816
                if (!(res->flags & (IORESOURCE_ROM_ENABLE |
817
                                    IORESOURCE_ROM_SHADOW |
818
                                    IORESOURCE_ROM_COPY)))
819
                        pci_disable_rom(pdev);
820
                return NULL;
821
        }
822
823
 
824
         * Try to find the true size of the ROM since sometimes the PCI window
825
         * size is much larger than the actual size of the ROM.
826
         * True size is important if the ROM is going to be copied.
827
         */
828
        *size = pci_get_rom_size(pdev, rom, *size);
829
        return rom;
830
}
831
832
 
833
{
834
    struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
835
836
 
837
            return;
838
839
 
840
841
 
842
    if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
843
            pci_disable_rom(pdev);
844
}
845