ICH7 SATA controller in legacy mode can provide access to SATA registers
via AHCI-like memory resource at BAR(5). Use it if BIOS was so kind to allocate memory for that BAR. This allows hot-plug support and connection speed reporting. MFC after: 2 weeks
This commit is contained in:
parent
6987b09f93
commit
f1bfc8aba8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=217774
@ -60,10 +60,14 @@ static int ata_intel_new_setmode(device_t dev, int target, int mode);
|
|||||||
static int ata_intel_sch_setmode(device_t dev, int target, int mode);
|
static int ata_intel_sch_setmode(device_t dev, int target, int mode);
|
||||||
static int ata_intel_sata_getrev(device_t dev, int target);
|
static int ata_intel_sata_getrev(device_t dev, int target);
|
||||||
static int ata_intel_sata_status(device_t dev);
|
static int ata_intel_sata_status(device_t dev);
|
||||||
|
static int ata_intel_sata_ahci_read(device_t dev, int port,
|
||||||
|
int reg, u_int32_t *result);
|
||||||
static int ata_intel_sata_cscr_read(device_t dev, int port,
|
static int ata_intel_sata_cscr_read(device_t dev, int port,
|
||||||
int reg, u_int32_t *result);
|
int reg, u_int32_t *result);
|
||||||
static int ata_intel_sata_sidpr_read(device_t dev, int port,
|
static int ata_intel_sata_sidpr_read(device_t dev, int port,
|
||||||
int reg, u_int32_t *result);
|
int reg, u_int32_t *result);
|
||||||
|
static int ata_intel_sata_ahci_write(device_t dev, int port,
|
||||||
|
int reg, u_int32_t result);
|
||||||
static int ata_intel_sata_cscr_write(device_t dev, int port,
|
static int ata_intel_sata_cscr_write(device_t dev, int port,
|
||||||
int reg, u_int32_t result);
|
int reg, u_int32_t result);
|
||||||
static int ata_intel_sata_sidpr_write(device_t dev, int port,
|
static int ata_intel_sata_sidpr_write(device_t dev, int port,
|
||||||
@ -79,6 +83,7 @@ static void ata_intel_31244_reset(device_t dev);
|
|||||||
#define INTEL_ICH5 2
|
#define INTEL_ICH5 2
|
||||||
#define INTEL_6CH 4
|
#define INTEL_6CH 4
|
||||||
#define INTEL_6CH2 8
|
#define INTEL_6CH2 8
|
||||||
|
#define INTEL_ICH7 16
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intel chipset support functions
|
* Intel chipset support functions
|
||||||
@ -113,11 +118,11 @@ ata_intel_probe(device_t dev)
|
|||||||
{ ATA_I82801FB_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6" },
|
{ ATA_I82801FB_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6" },
|
||||||
{ ATA_I82801FBM, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6M" },
|
{ ATA_I82801FBM, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6M" },
|
||||||
{ ATA_I82801GB, 0, 0, 1, ATA_UDMA5, "ICH7" },
|
{ ATA_I82801GB, 0, 0, 1, ATA_UDMA5, "ICH7" },
|
||||||
{ ATA_I82801GB_S1, 0, 0, 0, ATA_SA300, "ICH7" },
|
{ ATA_I82801GB_S1, 0, INTEL_ICH7, 0, ATA_SA300, "ICH7" },
|
||||||
{ ATA_I82801GB_R1, 0, 0, 0, ATA_SA300, "ICH7" },
|
{ ATA_I82801GB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" },
|
||||||
{ ATA_I82801GB_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" },
|
{ ATA_I82801GB_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" },
|
||||||
{ ATA_I82801GBM_S1, 0, 0, 0, ATA_SA150, "ICH7M" },
|
{ ATA_I82801GBM_S1, 0, INTEL_ICH7, 0, ATA_SA150, "ICH7M" },
|
||||||
{ ATA_I82801GBM_R1, 0, 0, 0, ATA_SA150, "ICH7M" },
|
{ ATA_I82801GBM_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" },
|
||||||
{ ATA_I82801GBM_AH, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" },
|
{ ATA_I82801GBM_AH, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" },
|
||||||
{ ATA_I63XXESB2, 0, 0, 1, ATA_UDMA5, "63XXESB2" },
|
{ ATA_I63XXESB2, 0, 0, 1, ATA_UDMA5, "63XXESB2" },
|
||||||
{ ATA_I63XXESB2_S1, 0, 0, 0, ATA_SA300, "63XXESB2" },
|
{ ATA_I63XXESB2_S1, 0, 0, 0, ATA_SA300, "63XXESB2" },
|
||||||
@ -250,14 +255,30 @@ ata_intel_chipinit(device_t dev)
|
|||||||
(pci_read_config(dev, 0x90, 1) & 0xc0) &&
|
(pci_read_config(dev, 0x90, 1) & 0xc0) &&
|
||||||
(ata_ahci_chipinit(dev) != ENXIO))
|
(ata_ahci_chipinit(dev) != ENXIO))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* if BAR(5) is IO it should point to SATA interface registers */
|
/* BAR(5) may point to SATA interface registers */
|
||||||
ctlr->r_type2 = SYS_RES_IOPORT;
|
if ((ctlr->chip->cfg1 & INTEL_ICH7)) {
|
||||||
ctlr->r_rid2 = PCIR_BAR(5);
|
ctlr->r_type2 = SYS_RES_MEMORY;
|
||||||
if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
|
ctlr->r_rid2 = PCIR_BAR(5);
|
||||||
&ctlr->r_rid2, RF_ACTIVE))
|
ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
|
||||||
|| (ctlr->chip->cfg1 & INTEL_ICH5))
|
&ctlr->r_rid2, RF_ACTIVE);
|
||||||
ctlr->getrev = ata_intel_sata_getrev;
|
if (ctlr->r_res2 != NULL) {
|
||||||
|
/* Set SCRAE bit to enable registers access. */
|
||||||
|
pci_write_config(dev, 0x94,
|
||||||
|
pci_read_config(dev, 0x94, 4) | (1 << 9), 4);
|
||||||
|
/* Set Ports Implemented register bits. */
|
||||||
|
ATA_OUTL(ctlr->r_res2, 0x0C,
|
||||||
|
ATA_INL(ctlr->r_res2, 0x0C) | 0xf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctlr->r_type2 = SYS_RES_IOPORT;
|
||||||
|
ctlr->r_rid2 = PCIR_BAR(5);
|
||||||
|
ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
|
||||||
|
&ctlr->r_rid2, RF_ACTIVE);
|
||||||
|
}
|
||||||
|
if (ctlr->r_res2 != NULL ||
|
||||||
|
(ctlr->chip->cfg1 & INTEL_ICH5))
|
||||||
|
ctlr->getrev = ata_intel_sata_getrev;
|
||||||
ctlr->setmode = ata_sata_setmode;
|
ctlr->setmode = ata_sata_setmode;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -336,8 +357,13 @@ ata_intel_ch_attach(device_t dev)
|
|||||||
} else if (ctlr->r_res2) {
|
} else if (ctlr->r_res2) {
|
||||||
ch->flags |= ATA_PERIODIC_POLL;
|
ch->flags |= ATA_PERIODIC_POLL;
|
||||||
ch->hw.status = ata_intel_sata_status;
|
ch->hw.status = ata_intel_sata_status;
|
||||||
ch->hw.pm_read = ata_intel_sata_sidpr_read;
|
if ((ctlr->chip->cfg1 & INTEL_ICH7)) {
|
||||||
ch->hw.pm_write = ata_intel_sata_sidpr_write;
|
ch->hw.pm_read = ata_intel_sata_ahci_read;
|
||||||
|
ch->hw.pm_write = ata_intel_sata_ahci_write;
|
||||||
|
} else {
|
||||||
|
ch->hw.pm_read = ata_intel_sata_sidpr_read;
|
||||||
|
ch->hw.pm_write = ata_intel_sata_sidpr_write;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (ch->hw.pm_write != NULL) {
|
if (ch->hw.pm_write != NULL) {
|
||||||
ata_sata_scr_write(ch, 0,
|
ata_sata_scr_write(ch, 0,
|
||||||
@ -536,6 +562,38 @@ ata_intel_sata_status(device_t dev)
|
|||||||
return ata_pci_status(dev);
|
return ata_pci_status(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ata_intel_sata_ahci_read(device_t dev, int port, int reg, u_int32_t *result)
|
||||||
|
{
|
||||||
|
struct ata_pci_controller *ctlr;
|
||||||
|
struct ata_channel *ch;
|
||||||
|
device_t parent;
|
||||||
|
u_char *smap;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
parent = device_get_parent(dev);
|
||||||
|
ctlr = device_get_softc(parent);
|
||||||
|
ch = device_get_softc(dev);
|
||||||
|
port = (port == 1) ? 1 : 0;
|
||||||
|
smap = (u_char *)&ctlr->chipset_data + ch->unit * 2;
|
||||||
|
offset = 0x100 + smap[port] * 0x80;
|
||||||
|
switch (reg) {
|
||||||
|
case ATA_SSTATUS:
|
||||||
|
reg = 0x28;
|
||||||
|
break;
|
||||||
|
case ATA_SCONTROL:
|
||||||
|
reg = 0x2c;
|
||||||
|
break;
|
||||||
|
case ATA_SERROR:
|
||||||
|
reg = 0x30;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
*result = ATA_INL(ctlr->r_res2, offset + reg);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ata_intel_sata_cscr_read(device_t dev, int port, int reg, u_int32_t *result)
|
ata_intel_sata_cscr_read(device_t dev, int port, int reg, u_int32_t *result)
|
||||||
{
|
{
|
||||||
@ -597,6 +655,38 @@ ata_intel_sata_sidpr_read(device_t dev, int port, int reg, u_int32_t *result)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ata_intel_sata_ahci_write(device_t dev, int port, int reg, u_int32_t value)
|
||||||
|
{
|
||||||
|
struct ata_pci_controller *ctlr;
|
||||||
|
struct ata_channel *ch;
|
||||||
|
device_t parent;
|
||||||
|
u_char *smap;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
parent = device_get_parent(dev);
|
||||||
|
ctlr = device_get_softc(parent);
|
||||||
|
ch = device_get_softc(dev);
|
||||||
|
port = (port == 1) ? 1 : 0;
|
||||||
|
smap = (u_char *)&ctlr->chipset_data + ch->unit * 2;
|
||||||
|
offset = 0x100 + smap[port] * 0x80;
|
||||||
|
switch (reg) {
|
||||||
|
case ATA_SSTATUS:
|
||||||
|
reg = 0x28;
|
||||||
|
break;
|
||||||
|
case ATA_SCONTROL:
|
||||||
|
reg = 0x2c;
|
||||||
|
break;
|
||||||
|
case ATA_SERROR:
|
||||||
|
reg = 0x30;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
ATA_OUTL(ctlr->r_res2, offset + reg, value);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ata_intel_sata_cscr_write(device_t dev, int port, int reg, u_int32_t value)
|
ata_intel_sata_cscr_write(device_t dev, int port, int reg, u_int32_t value)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user