Subversion Repositories Kolibri OS

Rev

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