Subversion Repositories Kolibri OS

Rev

Rev 1605 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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