mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Update the special handling code for ATA devices to allow usage of
PCI native addressing. That means that if the HW says that using "real" addresses instead of the hardwired legacy compat ones is allowed, we will use them.
This commit is contained in:
parent
b6101dafe9
commit
d485c7bcf3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=131288
@ -24,11 +24,11 @@
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_bus.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -837,70 +837,55 @@ pci_add_map(device_t pcib, device_t bus, device_t dev,
|
||||
return ((ln2range == 64) ? 2 : 1);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_is_ata_legacy(device_t dev)
|
||||
{
|
||||
/*
|
||||
* ATA PCI in compatibility mode are hard wired to certain
|
||||
* compatibility addresses. Such entries does not contain
|
||||
* valid resources as they are at fixed positions to be
|
||||
* compatible with old ISA requirements.
|
||||
*/
|
||||
if ((pci_get_class(dev) == PCIC_STORAGE) &&
|
||||
(pci_get_subclass(dev) == PCIS_STORAGE_IDE) &&
|
||||
(pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The ATA PCI spec specifies that in legacy mode, the device shall
|
||||
* decode the resources listed below. The ata driver allocates
|
||||
* resources in this order, and many atapci devices actually have
|
||||
* values similar to these in the actual underlying bars. Part of the
|
||||
* problem is that the floppy controller and ata overlap for 1 byte,
|
||||
* which makes it difficult to properly allocate things.
|
||||
*
|
||||
* My reading of the pci spec is such that this appears to be the only
|
||||
* allowed exception to the rule that devices only decode the addresses
|
||||
* presented in their BARs. We also ensure that the bits that take
|
||||
* the device out of legacy mode are set to 0 before making this
|
||||
* reservation.
|
||||
* For ATA devices we need to decide early what addressing mode to use.
|
||||
* Legacy demands that the primary and secondary ATA ports sits on the
|
||||
* same addresses that old ISA hardware did. This dictates that we use
|
||||
* those addresses and ignore the BAR's if we cannot set PCI native
|
||||
* addressing mode.
|
||||
*/
|
||||
static void
|
||||
pci_add_ata_legacy_maps(device_t pcib, device_t bus, device_t dev, int b,
|
||||
int s, int f, struct resource_list *rl)
|
||||
pci_ata_maps(device_t pcib, device_t bus, device_t dev, int b,
|
||||
int s, int f, struct resource_list *rl)
|
||||
{
|
||||
int rid;
|
||||
int type;
|
||||
|
||||
int rid, type, progif;
|
||||
#if 1
|
||||
/* if this device supports PCI native addressing use it */
|
||||
progif = pci_read_config(dev, PCIR_PROGIF, 1);
|
||||
if ((progif & 0x8a) == 0x8a) {
|
||||
if (pci_mapbase(pci_read_config(dev, PCIR_BAR(0), 4)) &&
|
||||
pci_mapbase(pci_read_config(dev, PCIR_BAR(2), 4))) {
|
||||
printf("Trying ATA native PCI addressing mode\n");
|
||||
pci_write_config(dev, PCIR_PROGIF, progif | 0x05, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
progif = pci_read_config(dev, PCIR_PROGIF, 1);
|
||||
type = SYS_RES_IOPORT;
|
||||
if ((pci_get_progif(dev) & PCIP_STORAGE_IDE_MODEPRIM) == 0) {
|
||||
rid = PCIR_BAR(0);
|
||||
resource_list_add(rl, type, rid, 0x1f0, 0x1f7, 8);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x1f0, 0x1f7, 8,
|
||||
0);
|
||||
rid = PCIR_BAR(1);
|
||||
resource_list_add(rl, type, rid, 0x3f6, 0x3f6, 1);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x3f6, 0x3f6, 1,
|
||||
0);
|
||||
} else {
|
||||
if (progif & PCIP_STORAGE_IDE_MODEPRIM) {
|
||||
pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(0), rl);
|
||||
pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(1), rl);
|
||||
}
|
||||
if ((pci_get_progif(dev) & PCIP_STORAGE_IDE_MODESEC) == 0) {
|
||||
rid = PCIR_BAR(2);
|
||||
resource_list_add(rl, type, rid, 0x170, 0x177, 8);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x170, 0x177, 8,
|
||||
0);
|
||||
rid = PCIR_BAR(3);
|
||||
resource_list_add(rl, type, rid, 0x376, 0x376, 1);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x376, 0x376, 1,
|
||||
0);
|
||||
} else {
|
||||
else {
|
||||
rid = PCIR_BAR(0);
|
||||
resource_list_add(rl, type, rid, 0x1f0, 0x1f7, 8);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x1f0, 0x1f7,8,0);
|
||||
rid = PCIR_BAR(1);
|
||||
resource_list_add(rl, type, rid, 0x3f6, 0x3f6, 1);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x3f6, 0x3f6,1,0);
|
||||
}
|
||||
if (progif & PCIP_STORAGE_IDE_MODESEC) {
|
||||
pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(2), rl);
|
||||
pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(3), rl);
|
||||
}
|
||||
else {
|
||||
rid = PCIR_BAR(2);
|
||||
resource_list_add(rl, type, rid, 0x170, 0x177, 8);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x170, 0x177,8,0);
|
||||
rid = PCIR_BAR(3);
|
||||
resource_list_add(rl, type, rid, 0x376, 0x376, 1);
|
||||
resource_list_alloc(rl, bus, dev, type, &rid, 0x376, 0x376,1,0);
|
||||
}
|
||||
pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(4), rl);
|
||||
}
|
||||
|
||||
@ -917,8 +902,11 @@ pci_add_resources(device_t pcib, device_t bus, device_t dev)
|
||||
s = cfg->slot;
|
||||
f = cfg->func;
|
||||
|
||||
if (pci_is_ata_legacy(dev))
|
||||
pci_add_ata_legacy_maps(pcib, bus, dev, b, s, f, rl);
|
||||
/* ATA devices needs special map treatment */
|
||||
if ((pci_get_class(dev) == PCIC_STORAGE) &&
|
||||
(pci_get_subclass(dev) == PCIS_STORAGE_IDE) &&
|
||||
(pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV))
|
||||
pci_ata_maps(pcib, bus, dev, b, s, f, rl);
|
||||
else
|
||||
for (i = 0; i < cfg->nummaps;)
|
||||
i += pci_add_map(pcib, bus, dev, b, s, f, PCIR_BAR(i),
|
||||
|
Loading…
Reference in New Issue
Block a user