Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1029 serge 1
 
2
 
1600 serge 3
    bool retval = false;
1029 serge 4
    u32_t bus, last_bus;
1600 serge 5
    PCITAG tag;
1029 serge 6
7
    if( (last_bus = PciApi(1))==-1)
8
 
9
10
    for(bus=0;bus<=last_bus;bus++)
11
 
12
        u32_t devfn;
13
14
        for(devfn=0;devfn<256;devfn++)
15
 
16
            hc_t *hc;
17
18
            u32_t id;
19
 
20
            u16_t devclass;
21
            u8_t  interface;
22
            int i;
1430 serge 23
1029 serge 24
            interface = PciRead8(bus,devfn, 0x09);
25
 
1430 serge 26
            if( devclass != 0x0C03)
1029 serge 27
                continue;
28
29
            if( interface != 0)
30
 
1430 serge 31
32
            pcicmd = PciRead16(bus,devfn, PCI_COMMAND);
33
 
1029 serge 34
                continue;
35
36
            hc = (hc_t*)kmalloc(sizeof(hc_t), 0);
37
 
1600 serge 38
39
            hc->pciId  = PciRead32(bus,devfn, 0);
1029 serge 40
 
41
42
            hc->irq_line = PciRead32(bus,devfn, 0x3C) & 0xFF;
43
 
1605 serge 44
45
            for (i = 0; i < 6; i++)
46
 
1029 serge 47
                u32_t base;
48
                bool validSize;
49
1600 serge 50
                base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2));
1029 serge 51
 
52
                {
53
                    if (base & PCI_MAP_IO) {
54
                        hc->ioBase[i] = (addr_t)PCIGETIO(base);
55
                        hc->memType[i]   = base & PCI_MAP_IO_ATTR_MASK;
56
                    } else {
57
                        hc->memBase[i] = (u32_t)PCIGETMEMORY(base);
58
                        hc->memType[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
59
                    }
60
                }
61
            };
62
            list_add_tail(&hc->list, &hc_list);
63
            retval = true;
1600 serge 64
        };
65
    };
1029 serge 66
    return retval;
67
};
68
69
1600 serge 70
 
71
 
72
/* these helpers provide future and backwards compatibility
73
 
74
#define pci_resource_start(dev, bar)    ((dev)->resource[(bar)].start)
75
#define pci_resource_end(dev, bar)  ((dev)->resource[(bar)].end)
76
#define pci_resource_flags(dev, bar)    ((dev)->resource[(bar)].flags)
77
#define pci_resource_len(dev,bar) \
78
    ((pci_resource_start((dev), (bar)) == 0 &&  \
79
      pci_resource_end((dev), (bar)) ==     \
80
      pci_resource_start((dev), (bar))) ? 0 :   \
81
                            \
82
     (pci_resource_end((dev), (bar)) -      \
83
      pci_resource_start((dev), (bar)) + 1))
84
85
static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
86
 
87
    return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
88
}
89
90
static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
91
 
92
    int wait_time, delta;
93
    void __iomem *base, *op_reg_base;
94
    u32 hcc_params, val;
95
    u8  offset, cap_length;
96
    int count = 256/4;
97
    int tried_handoff = 0;
98
99
    if (!mmio_resource_enabled(pdev, 0))
100
 
101
102
    base = pci_ioremap_bar(pdev, 0);
103
 
104
        return;
105
106
    cap_length = readb(base);
107
 
108
109
    /* EHCI 0.96 and later may have "extended capabilities"
110
 
111
     * booting from USB disk or using a usb keyboard
112
     */
113
    hcc_params = readl(base + EHCI_HCC_PARAMS);
114
    offset = (hcc_params >> 8) & 0xff;
115
    while (offset && --count) {
116
        u32     cap;
117
        int     msec;
118
119
        pci_read_config_dword(pdev, offset, &cap);
120
 
121
        case 1:         /* BIOS/SMM/... handoff support */
122
            if ((cap & EHCI_USBLEGSUP_BIOS)) {
123
                dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
124
125
#if 0
126
 
127
 * but that seems dubious in general (the BIOS left it off intentionally)
128
 * and is known to prevent some systems from booting.  so we won't do this
129
 * unless maybe we can determine when we're on a system that needs SMI forced.
130
 */
131
                /* BIOS workaround (?): be sure the
132
                 * pre-Linux code receives the SMI
133
                 */
134
                pci_read_config_dword(pdev,
135
                        offset + EHCI_USBLEGCTLSTS,
136
                        &val);
137
                pci_write_config_dword(pdev,
138
                        offset + EHCI_USBLEGCTLSTS,
139
                        val | EHCI_USBLEGCTLSTS_SOOE);
140
#endif
141
142
                /* some systems get upset if this semaphore is
143
 
144
                 * handoff..
145
                 */
146
                pci_write_config_byte(pdev, offset + 3, 1);
147
            }
148
149
            /* if boot firmware now owns EHCI, spin till
150
 
151
             */
152
            msec = 1000;
153
            while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
154
                tried_handoff = 1;
155
                msleep(10);
156
                msec -= 10;
157
                pci_read_config_dword(pdev, offset, &cap);
158
            }
159
160
            if (cap & EHCI_USBLEGSUP_BIOS) {
161
 
162
                 * it down, and hope nothing goes too wrong
163
                 */
164
                dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
165
                        " (BIOS bug?) %08x\n", cap);
166
                pci_write_config_byte(pdev, offset + 2, 0);
167
            }
168
169
            /* just in case, always disable EHCI SMIs */
170
 
171
                    offset + EHCI_USBLEGCTLSTS,
172
                    0);
173
174
            /* If the BIOS ever owned the controller then we
175
 
176
             */
177
            if (tried_handoff)
178
                writel(0, op_reg_base + EHCI_CONFIGFLAG);
179
            break;
180
        case 0:         /* illegal reserved capability */
181
            cap = 0;
182
            /* FALLTHROUGH */
183
        default:
184
            dev_warn(&pdev->dev, "EHCI: unrecognized capability "
185
                    "%02x\n", cap & 0xff);
186
            break;
187
        }
188
        offset = (cap >> 8) & 0xff;
189
    }
190
    if (!count)
191
        dev_printk(KERN_DEBUG, &pdev->dev, "EHCI: capability loop?\n");
192
193
    /*
194
 
195
     */
196
    val = readl(op_reg_base + EHCI_USBSTS);
197
    if ((val & EHCI_USBSTS_HALTED) == 0) {
198
        val = readl(op_reg_base + EHCI_USBCMD);
199
        val &= ~EHCI_USBCMD_RUN;
200
        writel(val, op_reg_base + EHCI_USBCMD);
201
202
        wait_time = 2000;
203
 
204
        do {
205
            writel(0x3f, op_reg_base + EHCI_USBSTS);
206
            udelay(delta);
207
            wait_time -= delta;
208
            val = readl(op_reg_base + EHCI_USBSTS);
209
            if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
210
                break;
211
            }
212
        } while (wait_time > 0);
213
    }
214
    writel(0, op_reg_base + EHCI_USBINTR);
215
    writel(0x3f, op_reg_base + EHCI_USBSTS);
216
217
    iounmap(base);
218
 
219
    return;
220
 
221
222
#endif
223
 
224
>