ahci: Replace use of bit field with shifts and masks.
It's a 32 bit register which needs properly aligned 32 bit writes. Using a bit field does not guarantee that, so replace it with shifts and masks. Should fix #12338.
This commit is contained in:
parent
d316ccc7e3
commit
cccf804d96
@ -78,19 +78,24 @@ enum {
|
|||||||
// Interrupt/Enable
|
// Interrupt/Enable
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16 reserved : 12;
|
// Device Detection Initialization
|
||||||
uint8 pmp : 4; // Port Multiplier Port: Not used by AHCI
|
#define SATA_CONTROL_DET_SHIFT 0
|
||||||
uint8 spm : 4; // Select Power Management: Not used by AHCI
|
#define SATA_CONTROL_DET_MASK 0x0000000f
|
||||||
uint8 ipm : 4; // Interface Power Management Transitions Allowed
|
|
||||||
uint8 spd : 4; // Speed Allowed
|
#define DET_NO_INITIALIZATION 0x0
|
||||||
uint8 det : 4; // Device Detection Initialization
|
#define DET_INITIALIZATION 0x1
|
||||||
} _PACKED scontrol;
|
|
||||||
|
// Speed Allowed
|
||||||
|
#define SATA_CONTROL_SPD_SHIFT 4
|
||||||
|
#define SATA_CONTROL_SPD_MASK 0x000000f0
|
||||||
|
|
||||||
|
// Interface Power Management Transitions Allowed
|
||||||
|
#define SATA_CONTROL_IPM_SHIFT 8
|
||||||
|
#define SATA_CONTROL_IPM_MASK 0x00000f00
|
||||||
|
|
||||||
#define IPM_TRANSITIONS_TO_PARTIAL_DISABLED 0x1
|
#define IPM_TRANSITIONS_TO_PARTIAL_DISABLED 0x1
|
||||||
#define IPM_TRANSITIONS_TO_SLUMBER_DISABLED 0x2
|
#define IPM_TRANSITIONS_TO_SLUMBER_DISABLED 0x2
|
||||||
#define DET_NO_INITIALIZATION 0x0
|
|
||||||
#define DET_INITIALIZATION 0x1
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -106,7 +111,7 @@ typedef struct {
|
|||||||
uint32 tfd; // Task File Data
|
uint32 tfd; // Task File Data
|
||||||
uint32 sig; // Signature
|
uint32 sig; // Signature
|
||||||
uint32 ssts; // Serial ATA Status (SCR0: SStatus)
|
uint32 ssts; // Serial ATA Status (SCR0: SStatus)
|
||||||
scontrol sctl; // Serial ATA Control (SCR2: SControl)
|
uint32 sctl; // Serial ATA Control (SCR2: SControl)
|
||||||
uint32 serr; // Serial ATA Error (SCR1: SError) **RWC**
|
uint32 serr; // Serial ATA Error (SCR1: SError) **RWC**
|
||||||
uint32 sact; // Serial ATA Active (SCR3: SActive) **RW1**
|
uint32 sact; // Serial ATA Active (SCR3: SActive) **RW1**
|
||||||
uint32 ci; // Command Issue **RW1**
|
uint32 ci; // Command Issue **RW1**
|
||||||
|
@ -110,8 +110,9 @@ AHCIPort::Init1()
|
|||||||
// prdt follows after command table
|
// prdt follows after command table
|
||||||
|
|
||||||
// disable transitions to partial or slumber state
|
// disable transitions to partial or slumber state
|
||||||
fRegs->sctl.ipm = IPM_TRANSITIONS_TO_PARTIAL_DISABLED
|
fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_IPM_MASK)
|
||||||
| IPM_TRANSITIONS_TO_SLUMBER_DISABLED;
|
| (IPM_TRANSITIONS_TO_PARTIAL_DISABLED
|
||||||
|
| IPM_TRANSITIONS_TO_SLUMBER_DISABLED) << SATA_CONTROL_IPM_SHIFT;
|
||||||
|
|
||||||
// clear IRQ status bits
|
// clear IRQ status bits
|
||||||
fRegs->is = fRegs->is;
|
fRegs->is = fRegs->is;
|
||||||
@ -157,12 +158,12 @@ AHCIPort::Init2()
|
|||||||
TRACE("is 0x%08" B_PRIx32 "\n", fRegs->is);
|
TRACE("is 0x%08" B_PRIx32 "\n", fRegs->is);
|
||||||
TRACE("cmd 0x%08" B_PRIx32 "\n", fRegs->cmd);
|
TRACE("cmd 0x%08" B_PRIx32 "\n", fRegs->cmd);
|
||||||
TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts);
|
TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts);
|
||||||
TRACE("sctl.reserved 0x%04" B_PRIx16 "\n", fRegs->sctl.reserved);
|
TRACE("sctl.ipm 0x%02" B_PRIx32 "\n",
|
||||||
TRACE("sctl.pmp 0x%02" B_PRIx8 "\n", fRegs->sctl.pmp);
|
(fRegs->sctl & SATA_CONTROL_IPM_MASK) >> SATA_CONTROL_IPM_SHIFT);
|
||||||
TRACE("sctl.spm 0x%02" B_PRIx8 "\n", fRegs->sctl.spm);
|
TRACE("sctl.spd 0x%02" B_PRIx32 "\n",
|
||||||
TRACE("sctl.ipm 0x%02" B_PRIx8 "\n", fRegs->sctl.ipm);
|
(fRegs->sctl & SATA_CONTROL_SPD_MASK) >> SATA_CONTROL_SPD_SHIFT);
|
||||||
TRACE("sctl.spd 0x%02" B_PRIx8 "\n", fRegs->sctl.spd);
|
TRACE("sctl.det 0x%02" B_PRIx32 "\n",
|
||||||
TRACE("sctl.det 0x%02" B_PRIx8 "\n", fRegs->sctl.det);
|
(fRegs->sctl & SATA_CONTROL_DET_MASK) >> SATA_CONTROL_DET_SHIFT);
|
||||||
TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr);
|
TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr);
|
||||||
TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact);
|
TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact);
|
||||||
TRACE("tfd 0x%08" B_PRIx32 "\n", fRegs->tfd);
|
TRACE("tfd 0x%08" B_PRIx32 "\n", fRegs->tfd);
|
||||||
@ -359,12 +360,12 @@ AHCIPort::InterruptErrorHandler(uint32 is)
|
|||||||
B_PRIx32 ", is 0x%08" B_PRIx32 ", ci 0x%08" B_PRIx32 "\n", fIndex,
|
B_PRIx32 ", is 0x%08" B_PRIx32 ", ci 0x%08" B_PRIx32 "\n", fIndex,
|
||||||
fCommandsActive, is, ci);
|
fCommandsActive, is, ci);
|
||||||
TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts);
|
TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts);
|
||||||
TRACE("sctl.reserved 0x%04" B_PRIx16 "\n", fRegs->sctl.reserved);
|
TRACE("sctl.ipm 0x%02" B_PRIx32 "\n",
|
||||||
TRACE("sctl.pmp 0x%02" B_PRIx8 "\n", fRegs->sctl.pmp);
|
(fRegs->sctl & SATA_CONTROL_IPM_MASK) >> SATA_CONTROL_IPM_SHIFT);
|
||||||
TRACE("sctl.spm 0x%02" B_PRIx8 "\n", fRegs->sctl.spm);
|
TRACE("sctl.spd 0x%02" B_PRIx32 "\n",
|
||||||
TRACE("sctl.ipm 0x%02" B_PRIx8 "\n", fRegs->sctl.ipm);
|
(fRegs->sctl & SATA_CONTROL_SPD_MASK) >> SATA_CONTROL_SPD_SHIFT);
|
||||||
TRACE("sctl.spd 0x%02" B_PRIx8 "\n", fRegs->sctl.spd);
|
TRACE("sctl.det 0x%02" B_PRIx32 "\n",
|
||||||
TRACE("sctl.det 0x%02" B_PRIx8 "\n", fRegs->sctl.det);
|
(fRegs->sctl & SATA_CONTROL_DET_MASK) >> SATA_CONTROL_DET_SHIFT);
|
||||||
TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr);
|
TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr);
|
||||||
TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact);
|
TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact);
|
||||||
}
|
}
|
||||||
@ -1239,11 +1240,13 @@ AHCIPort::_HardReset()
|
|||||||
TRACE("AHCIPort::_HardReset() PORT_CMD_ST set, behaviour undefined\n");
|
TRACE("AHCIPort::_HardReset() PORT_CMD_ST set, behaviour undefined\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fRegs->sctl.det = DET_INITIALIZATION;
|
fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
|
||||||
|
| DET_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
|
||||||
FlushPostedWrites();
|
FlushPostedWrites();
|
||||||
spin(1100);
|
spin(1100);
|
||||||
// You must wait 1ms at minimum
|
// You must wait 1ms at minimum
|
||||||
fRegs->sctl.det = DET_NO_INITIALIZATION;
|
fRegs->sctl = (fRegs->sctl & ~SATA_CONTROL_DET_MASK)
|
||||||
|
| DET_NO_INITIALIZATION << SATA_CONTROL_DET_SHIFT;
|
||||||
FlushPostedWrites();
|
FlushPostedWrites();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user