Polish AHCI disk identify data and fix speed negotiation.
MFC after: 2 weeks
This commit is contained in:
+20
-2
@@ -96,13 +96,14 @@
|
||||
#define ATA_SS_SPD_NO_SPEED 0x00000000
|
||||
#define ATA_SS_SPD_GEN1 0x00000010
|
||||
#define ATA_SS_SPD_GEN2 0x00000020
|
||||
#define ATA_SS_SPD_GEN3 0x00000040
|
||||
#define ATA_SS_SPD_GEN3 0x00000030
|
||||
|
||||
#define ATA_SS_IPM_MASK 0x00000f00
|
||||
#define ATA_SS_IPM_NO_DEVICE 0x00000000
|
||||
#define ATA_SS_IPM_ACTIVE 0x00000100
|
||||
#define ATA_SS_IPM_PARTIAL 0x00000200
|
||||
#define ATA_SS_IPM_SLUMBER 0x00000600
|
||||
#define ATA_SS_IPM_DEVSLEEP 0x00000800
|
||||
|
||||
#define ATA_SERROR 14
|
||||
#define ATA_SE_DATA_CORRECTED 0x00000001
|
||||
@@ -133,17 +134,19 @@
|
||||
#define ATA_SC_SPD_NO_SPEED 0x00000000
|
||||
#define ATA_SC_SPD_SPEED_GEN1 0x00000010
|
||||
#define ATA_SC_SPD_SPEED_GEN2 0x00000020
|
||||
#define ATA_SC_SPD_SPEED_GEN3 0x00000040
|
||||
#define ATA_SC_SPD_SPEED_GEN3 0x00000030
|
||||
|
||||
#define ATA_SC_IPM_MASK 0x00000f00
|
||||
#define ATA_SC_IPM_NONE 0x00000000
|
||||
#define ATA_SC_IPM_DIS_PARTIAL 0x00000100
|
||||
#define ATA_SC_IPM_DIS_SLUMBER 0x00000200
|
||||
#define ATA_SC_IPM_DIS_DEVSLEEP 0x00000400
|
||||
|
||||
#define ATA_SACTIVE 16
|
||||
|
||||
#define AHCI_MAX_PORTS 32
|
||||
#define AHCI_MAX_SLOTS 32
|
||||
#define AHCI_MAX_IRQS 16
|
||||
|
||||
/* SATA AHCI v1.0 register defines */
|
||||
#define AHCI_CAP 0x00
|
||||
@@ -208,6 +211,9 @@
|
||||
#define AHCI_CAP2_BOH 0x00000001
|
||||
#define AHCI_CAP2_NVMP 0x00000002
|
||||
#define AHCI_CAP2_APST 0x00000004
|
||||
#define AHCI_CAP2_SDS 0x00000008
|
||||
#define AHCI_CAP2_SADM 0x00000010
|
||||
#define AHCI_CAP2_DESO 0x00000020
|
||||
|
||||
#define AHCI_OFFSET 0x100
|
||||
#define AHCI_STEP 0x80
|
||||
@@ -265,6 +271,7 @@
|
||||
#define AHCI_P_CMD_ACTIVE 0x10000000
|
||||
#define AHCI_P_CMD_PARTIAL 0x20000000
|
||||
#define AHCI_P_CMD_SLUMBER 0x60000000
|
||||
#define AHCI_P_CMD_DEVSLEEP 0x80000000
|
||||
|
||||
#define AHCI_P_TFD 0x20
|
||||
#define AHCI_P_SIG 0x24
|
||||
@@ -284,6 +291,17 @@
|
||||
#define AHCI_P_FBS_ADO_SHIFT 12
|
||||
#define AHCI_P_FBS_DWE 0x000f0000
|
||||
#define AHCI_P_FBS_DWE_SHIFT 16
|
||||
#define AHCI_P_DEVSLP 0x44
|
||||
#define AHCI_P_DEVSLP_ADSE 0x00000001
|
||||
#define AHCI_P_DEVSLP_DSP 0x00000002
|
||||
#define AHCI_P_DEVSLP_DETO 0x000003fc
|
||||
#define AHCI_P_DEVSLP_DETO_SHIFT 2
|
||||
#define AHCI_P_DEVSLP_MDAT 0x00007c00
|
||||
#define AHCI_P_DEVSLP_MDAT_SHIFT 10
|
||||
#define AHCI_P_DEVSLP_DITO 0x01ff8000
|
||||
#define AHCI_P_DEVSLP_DITO_SHIFT 15
|
||||
#define AHCI_P_DEVSLP_DM 0x0e000000
|
||||
#define AHCI_P_DEVSLP_DM_SHIFT 25
|
||||
|
||||
/* Just to be sure, if building as module. */
|
||||
#if MAXPHYS < 512 * 1024
|
||||
|
||||
+29
-15
@@ -431,7 +431,6 @@ ahci_port_stop(struct ahci_port *p)
|
||||
static void
|
||||
ahci_port_reset(struct ahci_port *pr)
|
||||
{
|
||||
pr->sctl = 0;
|
||||
pr->serr = 0;
|
||||
pr->sact = 0;
|
||||
pr->xfermode = ATA_UDMA6;
|
||||
@@ -443,8 +442,11 @@ ahci_port_reset(struct ahci_port *pr)
|
||||
pr->tfd = 0x7F;
|
||||
return;
|
||||
}
|
||||
pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_SPD_GEN2 |
|
||||
ATA_SS_IPM_ACTIVE;
|
||||
pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_IPM_ACTIVE;
|
||||
if (pr->sctl & ATA_SC_SPD_MASK)
|
||||
pr->ssts |= (pr->sctl & ATA_SC_SPD_MASK);
|
||||
else
|
||||
pr->ssts |= ATA_SS_SPD_GEN3;
|
||||
pr->tfd = (1 << 8) | ATA_S_DSC | ATA_S_DMA;
|
||||
if (!pr->atapi) {
|
||||
pr->sig = PxSIG_ATA;
|
||||
@@ -470,6 +472,7 @@ ahci_reset(struct pci_ahci_softc *sc)
|
||||
for (i = 0; i < sc->ports; i++) {
|
||||
sc->port[i].ie = 0;
|
||||
sc->port[i].is = 0;
|
||||
sc->port[i].sctl = 0;
|
||||
ahci_port_reset(&sc->port[i]);
|
||||
}
|
||||
}
|
||||
@@ -807,26 +810,36 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis)
|
||||
buf[53] = (1 << 1 | 1 << 2);
|
||||
if (p->mult_sectors)
|
||||
buf[59] = (0x100 | p->mult_sectors);
|
||||
buf[60] = sectors;
|
||||
buf[61] = (sectors >> 16);
|
||||
if (sectors <= 0x0fffffff) {
|
||||
buf[60] = sectors;
|
||||
buf[61] = (sectors >> 16);
|
||||
} else {
|
||||
buf[60] = 0xffff;
|
||||
buf[61] = 0x0fff;
|
||||
}
|
||||
buf[63] = 0x7;
|
||||
if (p->xfermode & ATA_WDMA0)
|
||||
buf[63] |= (1 << ((p->xfermode & 7) + 8));
|
||||
buf[64] = 0x3;
|
||||
buf[65] = 100;
|
||||
buf[66] = 100;
|
||||
buf[67] = 100;
|
||||
buf[68] = 100;
|
||||
buf[65] = 120;
|
||||
buf[66] = 120;
|
||||
buf[67] = 120;
|
||||
buf[68] = 120;
|
||||
buf[69] = 0;
|
||||
buf[75] = 31;
|
||||
buf[76] = (1 << 8 | 1 << 2);
|
||||
buf[76] = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3 |
|
||||
ATA_SUPPORT_NCQ);
|
||||
buf[80] = 0x1f0;
|
||||
buf[81] = 0x28;
|
||||
buf[82] = (1 << 5 | 1 << 14);
|
||||
buf[83] = (1 << 10 | 1 << 12 | 1 << 13 | 1 << 14);
|
||||
buf[82] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE|
|
||||
ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP);
|
||||
buf[83] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE |
|
||||
ATA_SUPPORT_FLUSHCACHE48 | 1 << 14);
|
||||
buf[84] = (1 << 14);
|
||||
buf[85] = (1 << 5 | 1 << 14);
|
||||
buf[86] = (1 << 10 | 1 << 12 | 1 << 13);
|
||||
buf[85] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE|
|
||||
ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP);
|
||||
buf[86] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE |
|
||||
ATA_SUPPORT_FLUSHCACHE48);
|
||||
buf[87] = (1 << 14);
|
||||
buf[88] = 0x7f;
|
||||
if (p->xfermode & ATA_UDMA0)
|
||||
@@ -853,6 +866,7 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis)
|
||||
buf[117] = sectsz / 2;
|
||||
buf[118] = ((sectsz / 2) >> 16);
|
||||
}
|
||||
buf[222] = 0x1020;
|
||||
ahci_write_fis_piosetup(p);
|
||||
write_prdt(p, slot, cfis, (void *)buf, sizeof(buf));
|
||||
ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY);
|
||||
@@ -1850,10 +1864,10 @@ pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value)
|
||||
WPRINTF("pci_ahci_port: read only registers 0x%"PRIx64"\n", offset);
|
||||
break;
|
||||
case AHCI_P_SCTL:
|
||||
p->sctl = value;
|
||||
if (!(p->cmd & AHCI_P_CMD_ST)) {
|
||||
if (value & ATA_SC_DET_RESET)
|
||||
ahci_port_reset(p);
|
||||
p->sctl = value;
|
||||
}
|
||||
break;
|
||||
case AHCI_P_SERR:
|
||||
|
||||
Reference in New Issue
Block a user