2 * Copyright 2007, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
11 #include <KernelExport.h>
15 * We need to force controllers that have both SATA and PATA controllers to use
16 * the split mode with the SATA controller at function 0 and the PATA
17 * controller at function 1. This way the SATA controller will be picked up by
18 * the AHCI driver and the IDE controller by the generic IDE driver.
20 * TODO(bga): This does not work when the SATA controller is configured for IDE
21 * mode but this seems to be a problem with the device manager (it tries to load
22 * the IDE driver for the AHCI controller for some reason).
25 jmicron_fixup_ahci(PCI
*pci
, uint8 domain
, uint8 bus
, uint8 device
,
26 uint8 function
, uint16 deviceId
)
28 // We only care about function 0.
32 // And only devices with combined SATA/PATA.
34 case 0x2361: // 1 SATA, 1 PATA
35 case 0x2363: // 2 SATA, 1 PATA
36 case 0x2366: // 2 SATA, 2 PATA
42 dprintf("jmicron_fixup_ahci: domain %u, bus %u, device %u, function %u, "
43 "deviceId 0x%04x\n", domain
, bus
, device
, function
, deviceId
);
45 // Read controller control register (0x40).
46 uint32 val
= pci
->ReadConfig(domain
, bus
, device
, function
, 0x40, 4);
47 dprintf("jmicron_fixup_ahci: Register 0x40 : 0x%08" B_PRIx32
"\n", val
);
70 dprintf("jmicron_fixup_ahci: Register 0x40 : 0x%08" B_PRIx32
"\n", val
);
71 pci
->WriteConfig(domain
, bus
, device
, function
, 0x40, 4, val
);
73 // Read IRQ from controller at function 0 and assign this IRQ to the
74 // controller at function 1.
75 uint8 irq
= pci
->ReadConfig(domain
, bus
, device
, function
, 0x3c, 1);
76 dprintf("jmicron_fixup_ahci: Assigning IRQ %d at device "
77 "function 1.\n", irq
);
78 pci
->WriteConfig(domain
, bus
, device
, 1, 0x3c, 1, irq
);
83 intel_fixup_ahci(PCI
*pci
, uint8 domain
, uint8 bus
, uint8 device
,
84 uint8 function
, uint16 deviceId
)
86 // TODO(bga): disabled until the PCI manager can assign new resources.
90 case 0x2825: // ICH8 Desktop when in IDE emulation mode
91 dprintf("intel_fixup_ahci: WARNING found ICH8 device id 0x2825\n");
93 case 0x2926: // ICH9 Desktop when in IDE emulation mode
94 dprintf("intel_fixup_ahci: WARNING found ICH9 device id 0x2926\n");
97 case 0x27c0: // ICH7 Desktop non-AHCI and non-RAID mode
98 case 0x27c4: // ICH7 Mobile non-AHCI and non-RAID mode
99 case 0x2820: // ICH8 Desktop non-AHCI and non-RAID mode
100 case 0x2828: // ICH8 Mobile non-AHCI and non-RAID mode
101 case 0x2920: // ICH9 Desktop non-AHCI and non-RAID mode (4 ports)
102 case 0x2921: // ICH9 Desktop non-AHCI and non-RAID mode (2 ports)
108 dprintf("intel_fixup_ahci: domain %u, bus %u, device %u, function %u, "
109 "deviceId 0x%04x\n", domain
, bus
, device
, function
, deviceId
);
111 dprintf("intel_fixup_ahci: 0x24: 0x%08" B_PRIx32
"\n",
112 pci
->ReadConfig(domain
, bus
, device
, function
, 0x24, 4));
113 dprintf("intel_fixup_ahci: 0x90: 0x%02" B_PRIx32
"\n",
114 pci
->ReadConfig(domain
, bus
, device
, function
, 0x90, 1));
116 uint8 map
= pci
->ReadConfig(domain
, bus
, device
, function
, 0x90, 1);
117 if ((map
>> 6) == 0) {
118 uint32 bar5
= pci
->ReadConfig(domain
, bus
, device
, function
, 0x24, 4);
119 uint16 pcicmd
= pci
->ReadConfig(domain
, bus
, device
, function
,
122 dprintf("intel_fixup_ahci: switching from IDE to AHCI mode\n");
124 pci
->WriteConfig(domain
, bus
, device
, function
, PCI_command
, 2,
125 pcicmd
& ~(PCI_command_io
| PCI_command_memory
));
127 pci
->WriteConfig(domain
, bus
, device
, function
, 0x24, 4, 0xffffffff);
128 dprintf("intel_fixup_ahci: ide-bar5 bits-1: 0x%08" B_PRIx32
"\n",
129 pci
->ReadConfig(domain
, bus
, device
, function
, 0x24, 4));
130 pci
->WriteConfig(domain
, bus
, device
, function
, 0x24, 4, 0);
131 dprintf("intel_fixup_ahci: ide-bar5 bits-0: 0x%08" B_PRIx32
"\n",
132 pci
->ReadConfig(domain
, bus
, device
, function
, 0x24, 4));
136 pci
->WriteConfig(domain
, bus
, device
, function
, 0x90, 1, map
);
138 pci
->WriteConfig(domain
, bus
, device
, function
, 0x24, 4, 0xffffffff);
139 dprintf("intel_fixup_ahci: ahci-bar5 bits-1: 0x%08" B_PRIx32
"\n",
140 pci
->ReadConfig(domain
, bus
, device
, function
, 0x24, 4));
141 pci
->WriteConfig(domain
, bus
, device
, function
, 0x24, 4, 0);
142 dprintf("intel_fixup_ahci: ahci-bar5 bits-0: 0x%08" B_PRIx32
"\n",
143 pci
->ReadConfig(domain
, bus
, device
, function
, 0x24, 4));
145 if (deviceId
== 0x27c0 || deviceId
== 0x27c4) // restore on ICH7
146 pci
->WriteConfig(domain
, bus
, device
, function
, 0x24, 4, bar5
);
148 pci
->WriteConfig(domain
, bus
, device
, function
, PCI_command
, 2, pcicmd
);
151 dprintf("intel_fixup_ahci: 0x24: 0x%08" B_PRIx32
"\n",
152 pci
->ReadConfig(domain
, bus
, device
, function
, 0x24, 4));
153 dprintf("intel_fixup_ahci: 0x90: 0x%02" B_PRIx32
"\n",
154 pci
->ReadConfig(domain
, bus
, device
, function
, 0x90, 1));
159 ati_fixup_ixp(PCI
*pci
, uint8 domain
, uint8 bus
, uint8 device
, uint8 function
,
162 #if defined(__INTEL__) || defined(__x86_64__)
163 /* ATI Technologies Inc, IXP chipset:
164 * This chipset seems broken, at least on my laptop I must force
165 * the timer IRQ trigger mode, else no interrupt comes in.
168 // XXX: should I use host or isa bridges for detection ??
171 case 0x5950: // RS480 Host Bridge
175 case 0x4377: // IXP SB400 PCI-ISA Bridge
179 dprintf("ati_fixup_ixp: domain %u, bus %u, device %u, function %u, deviceId 0x%04x\n",
180 domain
, bus
, device
, function
, deviceId
);
182 dprintf("ati_fixup_ixp: found IXP chipset, forcing IRQ 0 as level triggered.\n");
183 // XXX: maybe use pic_*() ?
184 arch_int_configure_io_interrupt(0, B_LEVEL_TRIGGERED
);
191 pci_fixup_device(PCI
*pci
, uint8 domain
, uint8 bus
, uint8 device
,
194 uint16 vendorId
= pci
->ReadConfig(domain
, bus
, device
, function
,
196 uint16 deviceId
= pci
->ReadConfig(domain
, bus
, device
, function
,
199 // dprintf("pci_fixup_device: domain %u, bus %u, device %u, function %u\n",
200 // domain, bus, device, function);
204 jmicron_fixup_ahci(pci
, domain
, bus
, device
, function
, deviceId
);
208 intel_fixup_ahci(pci
, domain
, bus
, device
, function
, deviceId
);
212 ati_fixup_ixp(pci
, domain
, bus
, device
, function
, deviceId
);