Implemented a identify device command for further testing, works on Intel, doesn't work on Jmicron.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22312 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen
2007-09-25 21:33:15 +00:00
parent e4bbf18b3f
commit 4af29ec0bd
3 changed files with 95 additions and 9 deletions
@@ -170,16 +170,16 @@ typedef struct {
typedef struct { typedef struct {
union { union {
struct { struct {
uint16 prdtl; // physical region description table length;
uint16 pmp : 4; // Port Multiplier Port
uint16 : 1;
uint16 c : 1; // Clear Busy upon R_OK
uint16 b : 1; // Build In Self Test
uint16 r : 1; // Reset
uint16 p : 1; // Prefetchable
uint16 w : 1; // Write
uint16 a : 1; // ATAPI
uint16 cfl : 5; // command FIS length uint16 cfl : 5; // command FIS length
uint16 a : 1; // ATAPI
uint16 w : 1; // Write
uint16 p : 1; // Prefetchable
uint16 r : 1; // Reset
uint16 b : 1; // Build In Self Test
uint16 c : 1; // Clear Busy upon R_OK
uint16 : 1;
uint16 pmp : 4; // Port Multiplier Port
uint16 prdtl; // physical region description table length;
} _PACKED; } _PACKED;
uint32 prdtl_flags_cfl; uint32 prdtl_flags_cfl;
} _PACKED; } _PACKED;
@@ -260,6 +260,89 @@ AHCIPort::Interrupt()
fRegs->is = is; fRegs->is = is;
} }
char c(int i)
{
if (i == '\n' || i == '\r' || i == '\b')
return '?';
return i;
}
void
AHCIPort::IdentifyDevice()
{
TRACE("AHCIPort::IdentifyDevice port %d\n", fIndex);
void *phy;
uint8 *data;
int size = 512;
area_id id = alloc_mem((void **)&data, &phy, size, 0, "identify device");
TRACE("virt 0x%08lx\n", data);
TRACE("phys 0x%08lx\n", phy);
memset(data, 0, size);
TRACE("ci 0x%08lx\n", fRegs->ci);
TRACE("ie 0x%08lx\n", fRegs->ie);
TRACE("is 0x%08lx\n", fRegs->is);
TRACE("cmd 0x%08lx\n", fRegs->cmd);
TRACE("ssts 0x%08lx\n", fRegs->ssts);
TRACE("sctl 0x%08lx\n", fRegs->sctl);
TRACE("serr 0x%08lx\n", fRegs->serr);
TRACE("sact 0x%08lx\n", fRegs->sact);
TRACE("tfd 0x%08lx\n", fRegs->tfd);
memset((void *)fCommandTable->cfis, 0, 5 * 4);
fCommandTable->cfis[0] = 0x27;
fCommandTable->cfis[1] = 0x80;
fCommandTable->cfis[2] = 0xec;
fCommandList->prdtl_flags_cfl = 0;
fCommandList->prdtl = 1;
// fCommandList->c = 1;
fCommandList->cfl = 5;
fCommandList->prdbc = 0;
TRACE("prdtl_flags_cfl %08x\n", fCommandList->prdtl_flags_cfl);
TRACE("prdbc %08x\n", fCommandList->prdbc);
fPRDTable->dba = LO32(phy);
fPRDTable->dbau = HI32(phy);
fPRDTable->dbc = DBC_I | (size - 1);
TRACE("dba %08x\n", fPRDTable->dba);
TRACE("dbau %08x\n", fPRDTable->dbau);
TRACE("dbc %08x\n", fPRDTable->dbc);
fRegs->ci |= 1;
FlushPostedWrites();
snooze(500000);
TRACE("prdbc %ld\n", fCommandList->prdbc);
TRACE("ci 0x%08lx\n", fRegs->ci);
TRACE("ie 0x%08lx\n", fRegs->ie);
TRACE("is 0x%08lx\n", fRegs->is);
TRACE("cmd 0x%08lx\n", fRegs->cmd);
TRACE("ssts 0x%08lx\n", fRegs->ssts);
TRACE("sctl 0x%08lx\n", fRegs->sctl);
TRACE("serr 0x%08lx\n", fRegs->serr);
TRACE("sact 0x%08lx\n", fRegs->sact);
TRACE("tfd 0x%08lx\n", fRegs->tfd);
for (int i = 0; i < size; i += 8) {
TRACE(" %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
// TRACE(" %c%c%c%c%c%c%c%c\n", c(data[i]), c(data[i+1]), c(data[i+2]), c(data[i+3]), c(data[i+4]), c(data[i+5]), c(data[i+6]), c(data[i+7]));
}
delete_area(id);
}
void void
AHCIPort::ScsiExecuteRequest(scsi_ccb *request) AHCIPort::ScsiExecuteRequest(scsi_ccb *request)
@@ -267,6 +350,8 @@ AHCIPort::ScsiExecuteRequest(scsi_ccb *request)
TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode %u, length %u\n", fIndex, request->cdb[0], request->cdb_length); TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode %u, length %u\n", fIndex, request->cdb[0], request->cdb_length);
if (request->cdb[0] == 18)
IdentifyDevice();
request->subsys_status = SCSI_DEV_NOT_THERE; request->subsys_status = SCSI_DEV_NOT_THERE;
gSCSI->finished(request, 1); gSCSI->finished(request, 1);
@@ -31,6 +31,7 @@ private:
status_t PostResetDevice(); status_t PostResetDevice();
void FlushPostedWrites(); void FlushPostedWrites();
void DumpD2HFis(); void DumpD2HFis();
void IdentifyDevice();
private: private:
int fIndex; int fIndex;