Set transfer length when doing ATAPI transfers.
Dump ATAPI command packet on error. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26205 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -790,7 +790,7 @@ AHCIPort::ScsiExecuteRequest(scsi_ccb *request)
|
|||||||
// TRACE("AHCIPort::ScsiExecuteRequest ATAPI: port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);
|
// TRACE("AHCIPort::ScsiExecuteRequest ATAPI: port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);
|
||||||
|
|
||||||
sata_request *sreq = new(std::nothrow) sata_request(request);
|
sata_request *sreq = new(std::nothrow) sata_request(request);
|
||||||
sreq->set_atapi_cmd();
|
sreq->set_atapi_cmd(request->data_length);
|
||||||
// uint8 *data = (uint8*) sreq->ccb()->cdb;
|
// uint8 *data = (uint8*) sreq->ccb()->cdb;
|
||||||
// for (int i = 0; i < 16; i += 8) {
|
// for (int i = 0; i < 16; 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(" %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]);
|
||||||
|
|||||||
@@ -84,35 +84,50 @@ sata_request::set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sata_request::set_atapi_cmd()
|
sata_request::set_atapi_cmd(size_t transferLength)
|
||||||
{
|
{
|
||||||
fIsATAPI = true;
|
fIsATAPI = true;
|
||||||
set_ata_cmd(0xa0);
|
set_ata_cmd(0xa0);
|
||||||
fFis[5] = 0xfe;
|
if (1 /* isPIO */) {
|
||||||
fFis[6] = 0xff;
|
if (transferLength == 0)
|
||||||
|
transferLength = 2;
|
||||||
|
else if (transferLength > 0xfffe)
|
||||||
|
transferLength = 0xfffe;
|
||||||
|
fFis[5] = transferLength & 0xff;
|
||||||
|
fFis[6] = (transferLength >> 8) & 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sata_request::finish(int tfd, size_t bytesTransfered)
|
sata_request::finish(int tfd, size_t bytesTransfered)
|
||||||
{
|
{
|
||||||
if (tfd & ATA_ERR)
|
if (tfd & (ATA_ERR | ATA_DF)) {
|
||||||
dprintf("ahci: sata_request::finish ATA_ERR set for command 0x%02x\n", fFis[2]);
|
uint8 status = tfd & 0xff;
|
||||||
|
uint8 error = (tfd >> 8) & 0xff;
|
||||||
|
dprintf("ahci: sata_request::finish ATA command 0x%02x failed\n", fFis[2]);
|
||||||
|
dprintf("ahci: sata_request::finish status 0x%02x, error 0x%02x\n", status, error);
|
||||||
|
}
|
||||||
|
|
||||||
if (fCcb) {
|
if (fCcb) {
|
||||||
fCcb->data_resid = fCcb->data_length - bytesTransfered;
|
fCcb->data_resid = fCcb->data_length - bytesTransfered;
|
||||||
fCcb->subsys_status = SCSI_REQ_CMP;
|
fCcb->subsys_status = SCSI_REQ_CMP;
|
||||||
if (tfd & (ATA_ERR | ATA_DF)) {
|
if (tfd & (ATA_ERR | ATA_DF)) {
|
||||||
uint8 error = (tfd >> 8) & 0xff;
|
|
||||||
dprintf("ahci: sata_request::finish status 0x%02x, error 0x%02x\n", tfd & 0xff, error);
|
|
||||||
if (fIsATAPI) {
|
|
||||||
fCcb->subsys_status = SCSI_REQ_CMP_ERR;
|
fCcb->subsys_status = SCSI_REQ_CMP_ERR;
|
||||||
|
if (fIsATAPI) {
|
||||||
|
dprintf("ahci: sata_request::finish ATAPI packet %02x %02x %02x %02x "
|
||||||
|
"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x (len %d)\n",
|
||||||
|
fCcb->cdb[0], fCcb->cdb[1], fCcb->cdb[2], fCcb->cdb[3],
|
||||||
|
fCcb->cdb[4], fCcb->cdb[5], fCcb->cdb[6], fCcb->cdb[7],
|
||||||
|
fCcb->cdb[8], fCcb->cdb[9], fCcb->cdb[10], fCcb->cdb[11],
|
||||||
|
fCcb->cdb[12], fCcb->cdb[13], fCcb->cdb[14], fCcb->cdb[15],
|
||||||
|
fCcb->cdb_length);
|
||||||
fCcb->device_status = SCSI_STATUS_CHECK_CONDITION;
|
fCcb->device_status = SCSI_STATUS_CHECK_CONDITION;
|
||||||
} else {
|
} else {
|
||||||
fCcb->subsys_status = SCSI_REQ_CMP_ERR;
|
// TODO ATA error handling goes here
|
||||||
// TODO error handling goes here
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
if (error & 0x04) { // ABRT
|
// TODO check ABORT bit if this is useful
|
||||||
|
if ((tfd >> 8) & 0x04) { // ABRT
|
||||||
fCcb->subsys_status = SCSI_REQ_ABORTED;
|
fCcb->subsys_status = SCSI_REQ_ABORTED;
|
||||||
} else {
|
} else {
|
||||||
fCcb->device_status = SCSI_STATUS_CHECK_CONDITION;
|
fCcb->device_status = SCSI_STATUS_CHECK_CONDITION;
|
||||||
@@ -126,6 +141,7 @@ sata_request::finish(int tfd, size_t bytesTransfered)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
}
|
||||||
gSCSI->finished(fCcb, 1);
|
gSCSI->finished(fCcb, 1);
|
||||||
delete this;
|
delete this;
|
||||||
} else {
|
} else {
|
||||||
@@ -144,7 +160,7 @@ sata_request::abort()
|
|||||||
gSCSI->finished(fCcb, 1);
|
gSCSI->finished(fCcb, 1);
|
||||||
delete this;
|
delete this;
|
||||||
} else {
|
} else {
|
||||||
fCompletionStatus = -1;
|
fCompletionStatus = ATA_ERR;
|
||||||
release_sem(fCompletionSem);
|
release_sem(fCompletionSem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
void set_ata28_cmd(uint8 command, uint32 lba, uint8 sectorCount);
|
void set_ata28_cmd(uint8 command, uint32 lba, uint8 sectorCount);
|
||||||
void set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount);
|
void set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount);
|
||||||
|
|
||||||
void set_atapi_cmd();
|
void set_atapi_cmd(size_t transferLength);
|
||||||
bool is_atapi();
|
bool is_atapi();
|
||||||
|
|
||||||
scsi_ccb * ccb();
|
scsi_ccb * ccb();
|
||||||
|
|||||||
Reference in New Issue
Block a user