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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user