Subversion Repositories Kolibri OS

Rev

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