Fix channel initialization in FBS mode.

Due to reading initialized variable, FIS receive area was always allocated
as 256 bytes, suitable for command-based switching, instead of 4096 bytes,
required for FIS-based switching.  This caused memory corruption in case of
port multipliers used on FBS-capable HBAs (Marvell).

MFC after:	1 week
This commit is contained in:
Alexander Motin 2016-09-07 13:51:34 +00:00
parent 9626ccde7f
commit 07c3504304
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305536

View File

@ -715,6 +715,21 @@ ahci_ch_attach(device_t dev)
if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE)))
return (ENXIO);
ch->chcaps = ATA_INL(ch->r_mem, AHCI_P_CMD);
version = ATA_INL(ctlr->r_mem, AHCI_VS);
if (version < 0x00010200 && (ctlr->caps & AHCI_CAP_FBSS))
ch->chcaps |= AHCI_P_CMD_FBSCP;
if (ch->caps2 & AHCI_CAP2_SDS)
ch->chscaps = ATA_INL(ch->r_mem, AHCI_P_DEVSLP);
if (bootverbose) {
device_printf(dev, "Caps:%s%s%s%s%s%s\n",
(ch->chcaps & AHCI_P_CMD_HPCP) ? " HPCP":"",
(ch->chcaps & AHCI_P_CMD_MPSP) ? " MPSP":"",
(ch->chcaps & AHCI_P_CMD_CPD) ? " CPD":"",
(ch->chcaps & AHCI_P_CMD_ESP) ? " ESP":"",
(ch->chcaps & AHCI_P_CMD_FBSCP) ? " FBSCP":"",
(ch->chscaps & AHCI_P_DEVSLP_DSP) ? " DSP":"");
}
ahci_dmainit(dev);
ahci_slotsalloc(dev);
mtx_lock(&ch->mtx);
@ -733,21 +748,6 @@ ahci_ch_attach(device_t dev)
error = ENXIO;
goto err1;
}
ch->chcaps = ATA_INL(ch->r_mem, AHCI_P_CMD);
version = ATA_INL(ctlr->r_mem, AHCI_VS);
if (version < 0x00010200 && (ctlr->caps & AHCI_CAP_FBSS))
ch->chcaps |= AHCI_P_CMD_FBSCP;
if (ch->caps2 & AHCI_CAP2_SDS)
ch->chscaps = ATA_INL(ch->r_mem, AHCI_P_DEVSLP);
if (bootverbose) {
device_printf(dev, "Caps:%s%s%s%s%s%s\n",
(ch->chcaps & AHCI_P_CMD_HPCP) ? " HPCP":"",
(ch->chcaps & AHCI_P_CMD_MPSP) ? " MPSP":"",
(ch->chcaps & AHCI_P_CMD_CPD) ? " CPD":"",
(ch->chcaps & AHCI_P_CMD_ESP) ? " ESP":"",
(ch->chcaps & AHCI_P_CMD_FBSCP) ? " FBSCP":"",
(ch->chscaps & AHCI_P_DEVSLP_DSP) ? " DSP":"");
}
/* Create the device queue for our SIM. */
devq = cam_simq_alloc(ch->numslots);
if (devq == NULL) {