* ahci.c
* - Driver core
*/
-#define DEBUG 1
-#define VERSION 0x0001
+#define DEBUG 0
+#define VERSION VER2(1,0)
#include <acess.h>
#include <timers.h>
#include <modules.h>
while( (id = PCI_GetDeviceByClass(0x010601, 0xFFFFFF, id)) >= 0 && i < MAX_CONTROLLERS )
{
tAHCI_Ctrlr *ctrlr = &gaAHCI_Controllers[i];
+ ctrlr->ID = i;
ctrlr->PMemBase = PCI_GetBAR(id, 5);
//
if( !ctrlr->PMemBase )
#if PHYS_BITS > 32
if(Ctrlr->Supports64Bit)
Addr[1] = PAddr >> 32;
+ else if( PAddr >> 32 )
+ Log_Notice("AHCI", "Bug: 64-bit address used with 32-bit only controller");
else
#endif
Addr[1] = 0;
tATA_Identify data;
AHCI_SendLBA28Cmd(Port, false, 0, 0, 0, ATA_CMD_IDENTIFY_DEVICE, sizeof(data), &data);
- AHCI_WaitForInterrupt(Port, 1000);
+ if( AHCI_WaitForInterrupt(Port, 1000) ) {
+ Log_Error("AHCI", "Port %i:%i ATA IDENTIFY_DEVICE timed out", Ctrlr->ID, PortNum);
+ return ;
+ }
// TODO: Check status from command
-
// TODO: on error, mark device as bad and return
_flipChars(data.SerialNum, 20/2);
LOG("data.FirmwareVer = '%.8s'", data.FirmwareVer);
LOG("data.ModelNumber = '%.40s'", data.ModelNumber);
- Uint64 sector_count;
if( data.Sectors48 != 0 ) {
// Use LBA48 size
LOG("Size[48] = 0x%X", (Uint64)data.Sectors48);
- sector_count = data.Sectors48;
+ Port->SectorCount = data.Sectors48;
}
else {
// Use LBA28 size
LOG("Size[28] = 0x%x", data.Sectors28);
- sector_count = data.Sectors28;
+ Port->SectorCount = data.Sectors28;
}
// Create LVM name
+ #if AHCI_VOLNAME_SERIAL
char lvmname[4+1+20+1];
- strcpy(lvmname, "AHCI:");
+ strcpy(lvmname, "ahci:");
memcpy(lvmname+5, data.SerialNum, 20);
for(int i = 20+5; i-- && lvmname[i] == ' '; )
lvmname[i] = '\0';
+ #else
+ char lvmname[5+3+4+1];
+ snprintf(lvmname, sizeof(lvmname), "ahci:%i-%i", Ctrlr->ID, PortNum);
+ #endif
// Register with LVM
- Port->LVMHandle = LVM_AddVolume(&gAHCI_VolumeType, lvmname, Port, 512, sector_count);
+ Port->LVMHandle = LVM_AddVolume(&gAHCI_VolumeType, lvmname, Port, 512, Port->SectorCount);
}
void AHCI_IRQHandler(int UNUSED(IRQ), void *Data)
Uint32 IS = Ctrlr->MMIO->IS;
Uint32 PI = Ctrlr->MMIO->PI;
- LOG("Ctrlr->MMIO->IS = %x", IS);
for( int i = 0; i < 32; i ++ )
{
void AHCI_int_IRQHandlerPort(tAHCI_Port *Port)
{
Uint32 PxIS = Port->MMIO->PxIS;
- LOG("port->MMIO->PxIS = %x", PxIS);
+ LOG("port[%i]->MMIO->PxIS = %x", Port->Idx, PxIS);
Port->LastIS |= PxIS;
if( PxIS & AHCI_PxIS_CPDS ) {
- // Port change detected
+ // Cold port detect change detected
+ // TODO: Handle removal of a device by poking LVM.
}
if( PxIS & AHCI_PxIS_DHRS ) {
- LOG("Port->RcvdFIS->RFIS = {");
- LOG(".Status = 0x%02x", Port->RcvdFIS->RFIS.Status);
- LOG(".Error = 0x%02x", Port->RcvdFIS->RFIS.Error);
- LOG("}");
+ // LOG("Port->RcvdFIS->RFIS = {");
+ // LOG(".Status = 0x%02x", Port->RcvdFIS->RFIS.Status);
+ // LOG(".Error = 0x%02x", Port->RcvdFIS->RFIS.Error);
+ // LOG("}");
}
// Get bitfield of completed commands (Issued but no activity)
Uint32 done_commands = Port->IssuedCommands ^ Port->MMIO->PxSACT;
- LOG("done_commands = %x", done_commands);
+ //LOG("done_commands = %x", done_commands);
for( int i = 0; i < 32; i ++ )
{
if( !(done_commands & (1 << i)) )
{
tAHCI_Port *Port = Ptr;
+ ENTER("pPtr XAddress xCount pBuffer",
+ Ptr, Address, Count, Buffer);
+
memset(Buffer, 0xFF, Count*512);
ASSERT(Count <= 8096/512);
AHCI_SendLBA28Cmd(Port, 0, 0, Count, Address, ATA_CMD_READDMA28, Count*512, Buffer);
else
AHCI_SendLBA48Cmd(Port, 0, 0, Count, Address, ATA_CMD_READDMA48, Count*512, Buffer);
- if( AHCI_WaitForInterrupt(Port, 1000) )
+ if( AHCI_WaitForInterrupt(Port, 1000) ) {
+ Log_Notice("AHCI", "Timeout reading from disk");
+ LEAVE('i', 0);
return 0;
+ }
+ if( Port->RcvdFIS->RFIS.Status & ATA_STATUS_ERR )
+ {
+ LOG("Error detected = 0x%02x", Port->RcvdFIS->RFIS.Error);
+ LEAVE('i', 0);
+ return 0;
+ }
//Debug_HexDump("AHCI_ReadSectors", Buffer, Count*512);
// TODO: Check status from command
+ LEAVE('i', Count);
return Count;
}
regs.SectorCountExp = 0;
regs.Control = 0;
- LOG("Sending command %02x with %p+0x%x", Cmd, Data, Size);
+ LOG("Sending command %02x : 0x%llx with %p+0x%x", Cmd, LBA, Data, Size);
AHCI_DoFIS(Port, bWrite, sizeof(regs), ®s, 0, NULL, Size, Data);
return 0;
regs.SectorCountExp = 0;
regs.Control = 0;
- LOG("Sending command %02x with %p+0x%x", Cmd, Data, Size);
+ LOG("Sending command %02x : 0x%llx with %p+0x%x", Cmd, LBA, Data, Size);
AHCI_DoFIS(Port, bWrite, sizeof(regs), ®s, 0, NULL, Size, Data);
return 0;