Subversion Repositories Kolibri OS

Rev

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

Rev 1404 Rev 1630
Line -... Line 1...
-
 
1
#include 
1
#include 
2
#include 
2
#include 
-
 
3
#include 
3
#include 
-
 
4
#include 
-
 
5
#include 
4
#include 
6
#include 
Line 5... Line 7...
5
 
7
 
Line 6... Line 8...
6
static LIST_HEAD(devices);
8
static LIST_HEAD(devices);
Line 91... Line 93...
91
 
93
 
Line 92... Line 94...
92
        res  = &dev->resource[pos];
94
        res  = &dev->resource[pos];
Line 93... Line 95...
93
 
95
 
94
        reg = PCI_BASE_ADDRESS_0 + (pos << 2);
96
        reg = PCI_BASE_ADDRESS_0 + (pos << 2);
95
        l = PciRead32(dev->bus, dev->devfn, reg);
97
        l = PciRead32(dev->busnr, dev->devfn, reg);
96
        PciWrite32(dev->bus, dev->devfn, reg, ~0);
98
        PciWrite32(dev->busnr, dev->devfn, reg, ~0);
97
        sz = PciRead32(dev->bus, dev->devfn, reg);
99
        sz = PciRead32(dev->busnr, dev->devfn, reg);
Line 98... Line 100...
98
        PciWrite32(dev->bus, dev->devfn, reg, l);
100
        PciWrite32(dev->busnr, dev->devfn, reg, l);
99
 
101
 
Line 100... Line 102...
100
        if (!sz || sz == 0xffffffff)
102
        if (!sz || sz == 0xffffffff)
Line 130... Line 132...
130
        if (is_64bit_memory(l))
132
        if (is_64bit_memory(l))
131
        {
133
        {
132
            u32_t szhi, lhi;
134
            u32_t szhi, lhi;
133
 
135
 
Line 134... Line 136...
134
            lhi = PciRead32(dev->bus, dev->devfn, reg+4);
136
            lhi = PciRead32(dev->busnr, dev->devfn, reg+4);
135
            PciWrite32(dev->bus, dev->devfn, reg+4, ~0);
137
            PciWrite32(dev->busnr, dev->devfn, reg+4, ~0);
136
            szhi = PciRead32(dev->bus, dev->devfn, reg+4);
138
            szhi = PciRead32(dev->busnr, dev->devfn, reg+4);
137
            PciWrite32(dev->bus, dev->devfn, reg+4, lhi);
139
            PciWrite32(dev->busnr, dev->devfn, reg+4, lhi);
138
            sz64 = ((u64_t)szhi << 32) | raw_sz;
140
            sz64 = ((u64_t)szhi << 32) | raw_sz;
139
            l64 = ((u64_t)lhi << 32) | l;
141
            l64 = ((u64_t)lhi << 32) | l;
140
            sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
142
            sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
141
            next++;
143
            next++;
Line 158... Line 160...
158
            }
160
            }
159
            else if (lhi)
161
            else if (lhi)
160
            {
162
            {
161
                /* 64-bit wide address, treat as disabled */
163
                /* 64-bit wide address, treat as disabled */
162
                PciWrite32(dev->bus, dev->devfn, reg,
164
                PciWrite32(dev->busnr, dev->devfn, reg,
163
                        l & ~(u32_t)PCI_BASE_ADDRESS_MEM_MASK);
165
                        l & ~(u32_t)PCI_BASE_ADDRESS_MEM_MASK);
164
                PciWrite32(dev->bus, dev->devfn, reg+4, 0);
166
                PciWrite32(dev->busnr, dev->devfn, reg+4, 0);
165
                res->start = 0;
167
                res->start = 0;
166
                res->end = sz;
168
                res->end = sz;
167
            }
169
            }
168
#endif
170
#endif
169
        }
171
        }
170
    }
172
    }
Line 173... Line 175...
173
    {
175
    {
174
        dev->rom_base_reg = rom;
176
        dev->rom_base_reg = rom;
175
        res = &dev->resource[PCI_ROM_RESOURCE];
177
        res = &dev->resource[PCI_ROM_RESOURCE];
176
 
178
 
Line 177... Line 179...
177
        l = PciRead32(dev->bus, dev->devfn, rom);
179
        l = PciRead32(dev->busnr, dev->devfn, rom);
178
        PciWrite32(dev->bus, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE);
180
        PciWrite32(dev->busnr, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE);
179
        sz = PciRead32(dev->bus, dev->devfn, rom);
181
        sz = PciRead32(dev->busnr, dev->devfn, rom);
180
        PciWrite32(dev->bus, dev->devfn, rom, l);
182
        PciWrite32(dev->busnr, dev->devfn, rom, l);
Line 181... Line 183...
181
 
183
 
182
        if (l == 0xffffffff)
184
        if (l == 0xffffffff)
Line 183... Line 185...
183
            l = 0;
185
            l = 0;
Line 201... Line 203...
201
static void pci_read_irq(struct pci_dev *dev)
203
static void pci_read_irq(struct pci_dev *dev)
202
{
204
{
203
    u8_t irq;
205
    u8_t irq;
Line 204... Line 206...
204
 
206
 
205
    irq = PciRead8(dev->bus, dev->devfn, PCI_INTERRUPT_PIN);
207
    irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_PIN);
206
    dev->pin = irq;
208
    dev->pin = irq;
207
    if (irq)
209
    if (irq)
208
        PciRead8(dev->bus, dev->devfn, PCI_INTERRUPT_LINE);
210
        PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_LINE);
209
    dev->irq = irq;
211
    dev->irq = irq;
Line 210... Line 212...
210
};
212
};
211
 
213
 
212
 
214
 
Line 213... Line 215...
213
static int pci_setup_device(struct pci_dev *dev)
215
static int pci_setup_device(struct pci_dev *dev)
214
{
216
{
215
    u32_t  class;
217
    u32_t  class;
216
 
218
 
Line 217... Line 219...
217
    class = PciRead32(dev->bus, dev->devfn, PCI_CLASS_REVISION);
219
    class = PciRead32(dev->busnr, dev->devfn, PCI_CLASS_REVISION);
Line 232... Line 234...
232
            if (class == PCI_CLASS_BRIDGE_PCI)
234
            if (class == PCI_CLASS_BRIDGE_PCI)
233
                goto bad;
235
                goto bad;
234
            pci_read_irq(dev);
236
            pci_read_irq(dev);
235
            pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
237
            pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
236
            dev->subsystem_vendor = PciRead16(dev->bus, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID);
238
            dev->subsystem_vendor = PciRead16(dev->busnr, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID);
237
            dev->subsystem_device = PciRead16(dev->bus, dev->devfn, PCI_SUBSYSTEM_ID);
239
            dev->subsystem_device = PciRead16(dev->busnr, dev->devfn, PCI_SUBSYSTEM_ID);
238
 
240
 
Line 239... Line 241...
239
            /*
241
            /*
240
             *      Do the ugly legacy mode stuff here rather than broken chip
242
             *      Do the ugly legacy mode stuff here rather than broken chip
241
             *      quirk code. Legacy mode ATA controllers have fixed
243
             *      quirk code. Legacy mode ATA controllers have fixed
242
             *      addresses. These are not always echoed in BAR0-3, and
244
             *      addresses. These are not always echoed in BAR0-3, and
Line 245... Line 247...
245
            if (class == PCI_CLASS_STORAGE_IDE)
247
            if (class == PCI_CLASS_STORAGE_IDE)
246
            {
248
            {
247
                u8_t progif;
249
                u8_t progif;
248
 
250
 
Line 249... Line 251...
249
                progif = PciRead8(dev->bus, dev->devfn,PCI_CLASS_PROG);
251
                progif = PciRead8(dev->busnr, dev->devfn,PCI_CLASS_PROG);
250
                if ((progif & 1) == 0)
252
                if ((progif & 1) == 0)
251
                {
253
                {
252
                    dev->resource[0].start = 0x1F0;
254
                    dev->resource[0].start = 0x1F0;
253
                    dev->resource[0].end = 0x1F7;
255
                    dev->resource[0].end = 0x1F7;
254
                    dev->resource[0].flags = LEGACY_IO_RESOURCE;
256
                    dev->resource[0].flags = LEGACY_IO_RESOURCE;
Line 283... Line 285...
283
                if (class != PCI_CLASS_BRIDGE_CARDBUS)
285
                if (class != PCI_CLASS_BRIDGE_CARDBUS)
284
                        goto bad;
286
                        goto bad;
285
                pci_read_irq(dev);
287
                pci_read_irq(dev);
286
                pci_read_bases(dev, 1, 0);
288
                pci_read_bases(dev, 1, 0);
287
                dev->subsystem_vendor = PciRead16(dev->bus,
289
                dev->subsystem_vendor = PciRead16(dev->busnr,
288
                                                  dev->devfn,
290
                                                  dev->devfn,
289
                                                  PCI_CB_SUBSYSTEM_VENDOR_ID);
291
                                                  PCI_CB_SUBSYSTEM_VENDOR_ID);
290
 
292
 
Line 291... Line 293...
291
                dev->subsystem_device = PciRead16(dev->bus,
293
                dev->subsystem_device = PciRead16(dev->busnr,
292
                                                  dev->devfn,
294
                                                  dev->devfn,
293
                                                  PCI_CB_SUBSYSTEM_ID);
295
                                                  PCI_CB_SUBSYSTEM_ID);
294
                break;
296
                break;
Line 295... Line 297...
295
 
297
 
Line 350... Line 352...
350
 
352
 
Line 351... Line 353...
351
    if(unlikely(dev == NULL))
353
    if(unlikely(dev == NULL))
352
        return NULL;
354
        return NULL;
Line 353... Line 355...
353
 
355
 
354
    dev->pci_dev.bus      = bus;
356
    dev->pci_dev.busnr      = bus;
355
    dev->pci_dev.devfn    = devfn;
357
    dev->pci_dev.devfn    = devfn;
356
    dev->pci_dev.hdr_type = hdr & 0x7f;
358
    dev->pci_dev.hdr_type = hdr & 0x7f;
357
    dev->pci_dev.multifunction    = !!(hdr & 0x80);
359
    dev->pci_dev.multifunction    = !!(hdr & 0x80);
358
    dev->pci_dev.vendor   = id & 0xffff;
360
    dev->pci_dev.vendor   = id & 0xffff;
Line 501... Line 503...
501
int pci_find_capability(struct pci_dev *dev, int cap)
503
int pci_find_capability(struct pci_dev *dev, int cap)
502
{
504
{
503
    int pos;
505
    int pos;
Line 504... Line 506...
504
 
506
 
505
    pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
507
    pos = __pci_bus_find_cap_start(dev->busnr, dev->devfn, dev->hdr_type);
506
    if (pos)
508
    if (pos)
Line 507... Line 509...
507
        pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
509
        pos = __pci_find_next_cap(dev->busnr, dev->devfn, pos, cap);
508
 
510
 
Line 509... Line -...
509
    return pos;
-
 
510
}
-
 
511
 
-
 
512
 
-
 
513
#if 0
-
 
514
/**
-
 
515
 * pci_set_power_state - Set the power state of a PCI device
-
 
516
 * @dev: PCI device to be suspended
-
 
517
 * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
-
 
518
 *
-
 
519
 * Transition a device to a new power state, using the Power Management
-
 
520
 * Capabilities in the device's config space.
-
 
521
 *
-
 
522
 * RETURN VALUE:
-
 
523
 * -EINVAL if trying to enter a lower state than we're already in.
-
 
524
 * 0 if we're already in the requested state.
-
 
525
 * -EIO if device does not support PCI PM.
-
 
526
 * 0 if we can successfully change the power state.
-
 
527
 */
-
 
528
int
-
 
529
pci_set_power_state(struct pci_dev *dev, pci_power_t state)
-
 
530
{
-
 
531
        int pm, need_restore = 0;
-
 
532
        u16 pmcsr, pmc;
-
 
533
 
-
 
534
        /* bound the state we're entering */
-
 
535
        if (state > PCI_D3hot)
-
 
536
                state = PCI_D3hot;
-
 
537
 
-
 
538
        /*
-
 
539
         * If the device or the parent bridge can't support PCI PM, ignore
-
 
540
         * the request if we're doing anything besides putting it into D0
-
 
541
         * (which would only happen on boot).
-
 
542
         */
-
 
543
        if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
-
 
544
                return 0;
-
 
545
 
-
 
546
        /* find PCI PM capability in list */
-
 
547
        pm = pci_find_capability(dev, PCI_CAP_ID_PM);
-
 
548
 
-
 
549
        /* abort if the device doesn't support PM capabilities */
-
 
550
        if (!pm)
-
 
551
                return -EIO;
-
 
552
 
-
 
553
        /* Validate current state:
-
 
554
         * Can enter D0 from any state, but if we can only go deeper
-
 
555
         * to sleep if we're already in a low power state
-
 
556
         */
-
 
557
        if (state != PCI_D0 && dev->current_state > state) {
-
 
558
                printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n",
-
 
559
                        __FUNCTION__, pci_name(dev), state, dev->current_state);
-
 
560
                return -EINVAL;
-
 
561
        } else if (dev->current_state == state)
-
 
562
                return 0;        /* we're already there */
-
 
563
 
-
 
564
 
-
 
565
        pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
-
 
566
        if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
-
 
567
                printk(KERN_DEBUG
-
 
568
                       "PCI: %s has unsupported PM cap regs version (%u)\n",
-
 
569
                       pci_name(dev), pmc & PCI_PM_CAP_VER_MASK);
-
 
570
                return -EIO;
-
 
571
        }
-
 
572
 
-
 
573
        /* check if this device supports the desired state */
-
 
574
        if (state == PCI_D1 && !(pmc & PCI_PM_CAP_D1))
-
 
575
                return -EIO;
-
 
576
        else if (state == PCI_D2 && !(pmc & PCI_PM_CAP_D2))
-
 
577
                return -EIO;
-
 
578
 
-
 
579
        pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
-
 
580
 
-
 
581
        /* If we're (effectively) in D3, force entire word to 0.
-
 
582
         * This doesn't affect PME_Status, disables PME_En, and
-
 
583
         * sets PowerState to 0.
-
 
584
         */
-
 
585
        switch (dev->current_state) {
-
 
586
        case PCI_D0:
-
 
587
        case PCI_D1:
-
 
588
        case PCI_D2:
-
 
589
                pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
-
 
590
                pmcsr |= state;
-
 
591
                break;
-
 
592
        case PCI_UNKNOWN: /* Boot-up */
-
 
593
                if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
-
 
594
                 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
-
 
595
                        need_restore = 1;
-
 
596
                /* Fall-through: force to D0 */
-
 
597
        default:
-
 
598
                pmcsr = 0;
-
 
599
                break;
-
 
600
        }
-
 
601
 
-
 
602
        /* enter specified state */
-
 
603
        pci_write_config_word(dev, pm + PCI_PM_CTRL, pmcsr);
-
 
604
 
-
 
605
        /* Mandatory power management transition delays */
-
 
606
        /* see PCI PM 1.1 5.6.1 table 18 */
-
 
607
        if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
-
 
608
                msleep(pci_pm_d3_delay);
-
 
609
        else if (state == PCI_D2 || dev->current_state == PCI_D2)
-
 
610
                udelay(200);
-
 
611
 
-
 
612
        /*
-
 
613
         * Give firmware a chance to be called, such as ACPI _PRx, _PSx
-
 
614
         * Firmware method after native method ?
-
 
615
         */
-
 
616
        if (platform_pci_set_power_state)
-
 
617
                platform_pci_set_power_state(dev, state);
-
 
618
 
-
 
619
        dev->current_state = state;
-
 
620
 
-
 
621
        /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
-
 
622
         * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
-
 
623
         * from D3hot to D0 _may_ perform an internal reset, thereby
-
 
624
         * going to "D0 Uninitialized" rather than "D0 Initialized".
-
 
625
         * For example, at least some versions of the 3c905B and the
-
 
626
         * 3c556B exhibit this behaviour.
-
 
627
         *
-
 
628
         * At least some laptop BIOSen (e.g. the Thinkpad T21) leave
-
 
629
         * devices in a D3hot state at boot.  Consequently, we need to
-
 
630
         * restore at least the BARs so that the device will be
-
 
631
         * accessible to its driver.
-
 
632
         */
-
 
633
        if (need_restore)
-
 
634
                pci_restore_bars(dev);
-
 
Line 635... Line 511...
635
 
511
    return pos;
636
        return 0;
512
}
637
}
513
 
638
#endif
514
 
639
 
515
 
Line 640... Line 516...
640
int pcibios_enable_resources(struct pci_dev *dev, int mask)
516
int pcibios_enable_resources(struct pci_dev *dev, int mask)
641
{
517
{
642
    u16_t cmd, old_cmd;
518
    u16_t cmd, old_cmd;
643
    int  idx;
519
    int  idx;
644
    struct resource *r;
520
    struct resource *r;
645
 
521
 
Line 670... Line 546...
670
    }
546
    }
671
    if (cmd != old_cmd) {
547
    if (cmd != old_cmd) {
672
        printk("PCI: Enabling device %s (%04x -> %04x)\n",
548
        printk("PCI: Enabling device %s (%04x -> %04x)\n",
673
                pci_name(dev), old_cmd, cmd);
549
                pci_name(dev), old_cmd, cmd);
674
        PciWrite16(dev->bus, dev->devfn, PCI_COMMAND, cmd);
550
        PciWrite16(dev->busnr, dev->devfn, PCI_COMMAND, cmd);
675
    }
551
    }
676
    return 0;
552
    return 0;
677
}
553
}
678
 
554
 
Line 764... Line 640...
764
                return  ent;
640
                return  ent;
765
            }
641
            }
766
        };
642
        };
767
    }
643
    }
768
 
644
    return NULL;
769
    return NULL;
-
 
770
};
645
};
771
 
646
 
Line 791... Line 666...
791
    u32_t start;
666
    u32_t start;
792
    void  *rom;
667
    void  *rom;
793
 
668
 
Line 794... Line 669...
794
#if 0
669
#if 0
795
    /*
-
 
796
     * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
-
 
797
     * memory map if the VGA enable bit of the Bridge Control register is
-
 
798
     * set for embedded VGA.
-
 
799
     */
-
 
800
    if (res->flags & IORESOURCE_ROM_SHADOW) {
-
 
801
        /* primary video rom always starts here */
-
 
802
        start = (u32_t)0xC0000;
-
 
803
        *size = 0x20000; /* cover C000:0 through E000:0 */
-
 
804
    } else {
-
 
805
        if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) {
-
 
806
            *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-
 
807
             return (void *)(unsigned long)
-
 
808
                     pci_resource_start(pdev, PCI_ROM_RESOURCE);
-
 
809
        } else {
-
 
810
                /* assign the ROM an address if it doesn't have one */
-
 
811
            //if (res->parent == NULL &&
-
 
812
            //     pci_assign_resource(pdev,PCI_ROM_RESOURCE))
-
 
813
            //         return NULL;
-
 
814
             start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
-
 
815
             *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-
 
816
             if (*size == 0)
-
 
817
                     return NULL;
-
 
818
 
-
 
819
             /* Enable ROM space decodes */
-
 
820
             if (pci_enable_rom(pdev))
-
 
821
                     return NULL;
-
 
822
        }
-
 
823
    }
-
 
824
 
-
 
825
    rom = ioremap(start, *size);
-
 
826
    if (!rom) {
-
 
827
            /* restore enable if ioremap fails */
-
 
828
            if (!(res->flags & (IORESOURCE_ROM_ENABLE |
-
 
829
                                IORESOURCE_ROM_SHADOW |
-
 
830
                                IORESOURCE_ROM_COPY)))
-
 
831
                    pci_disable_rom(pdev);
-
 
832
            return NULL;
-
 
833
    }
-
 
834
 
-
 
835
    /*
-
 
836
     * Try to find the true size of the ROM since sometimes the PCI window
-
 
837
     * size is much larger than the actual size of the ROM.
-
 
838
     * True size is important if the ROM is going to be copied.
-
 
839
     */
-
 
840
    *size = pci_get_rom_size(rom, *size);
-
 
841
 
-
 
842
#endif
670
#endif
Line 843... Line 671...
843
 
671
 
844
    unsigned char tmp[32];
672
    unsigned char tmp[32];