diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp index 5bebd3d639..afbacf1745 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp @@ -286,8 +286,13 @@ AHCIPort::Interrupt() RWTRACE("AHCIPort::Interrupt port %d, fCommandsActive 0x%08lx, is 0x%08lx, ci 0x%08lx\n", fIndex, fCommandsActive, is, ci); - if (is & PORT_INT_ERROR) + if (is & PORT_INT_ERROR) { TRACE("AHCIPort::Interrupt port %d, fCommandsActive 0x%08lx, is 0x%08lx, ci 0x%08lx\n", fIndex, fCommandsActive, is, ci); + 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); + } if (is & PORT_INT_FATAL) panic("ahci fatal error, is 0x%08lx", is); @@ -565,11 +570,6 @@ AHCIPort::ScsiReadWrite(scsi_ccb *request, uint64 lba, size_t sectorCount, bool } #endif - if (fIsATAPI) { - ScsiReadWriteATAPI(request, lba, sectorCount, isWrite); - return; - } - ASSERT(request->data_length == sectorCount * 512); sata_request *sreq = new(std::nothrow) sata_request(request); @@ -591,24 +591,6 @@ AHCIPort::ScsiReadWrite(scsi_ccb *request, uint64 lba, size_t sectorCount, bool } -void -AHCIPort::ScsiReadWriteATAPI(scsi_ccb *request, uint64 lba, size_t sectorCount, bool isWrite) -{ - TRACE("ScsiReadWriteATAPI lba %lld, sectorCount %ld, isWrite %d\n", lba, sectorCount, isWrite); - - sata_request *sreq = new(std::nothrow) sata_request(request); - - sreq->set_atapi12_cmd(request->cdb); - - uint8 *data = (uint8*) sreq->fis(); - 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]); - } - - ExecuteSataRequest(sreq, isWrite); -} - - void AHCIPort::ExecuteSataRequest(sata_request *request, bool isWrite) { @@ -628,14 +610,13 @@ AHCIPort::ExecuteSataRequest(sata_request *request, bool isWrite) FLOW("prdEntrys %d\n", prdEntrys); fCommandList->prdtl_flags_cfl = 0; - fCommandList->cfl = request->fis_length() / 4; // length in DWORDS + fCommandList->cfl = 5; // 20 bytes, length in DWORDS + memcpy((char *)fCommandTable->cfis, request->fis(), 20); - if (request->fis_length() == 20) { - // command fis is always 20 byte - memcpy((char *)fCommandTable->cfis, request->fis(), 20); - } else { + if (request->is_atapi()) { // ATAPI PACKET is a 12 or 16 byte SCSI command - memcpy((char *)fCommandTable->acmd, request->fis(), request->fis_length()); + memset((char *)fCommandTable->acmd, 0, 32); + memcpy((char *)fCommandTable->acmd, request->ccb()->cdb, request->ccb()->cdb_length); fCommandList->a = 1; } @@ -698,6 +679,30 @@ AHCIPort::ScsiExecuteRequest(scsi_ccb *request) // TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length); + if (fIsATAPI && request->cdb[0] != SCSI_OP_INQUIRY) { + bool isWrite; + switch (request->cdb[0]) { + case SCSI_OP_WRITE_6: + case SCSI_OP_WRITE_10: + case SCSI_OP_WRITE_12: + isWrite = true; + break; + default: + isWrite = false; + } + + 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); + sreq->set_atapi_cmd(); + uint8 *data = (uint8*) sreq->ccb()->cdb; + 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]); + } + ExecuteSataRequest(sreq, isWrite); + return; + } + if (request->cdb[0] == SCSI_OP_REQUEST_SENSE) { panic("ahci: SCSI_OP_REQUEST_SENSE not yet supported\n"); return; diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h index 176d0b5631..d640b4c933 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h @@ -33,7 +33,6 @@ private: void ScsiInquiry(scsi_ccb *request); void ScsiReadCapacity(scsi_ccb *request); void ScsiReadWrite(scsi_ccb *request, uint64 lba, size_t sectorCount, bool isWrite); - void ScsiReadWriteATAPI(scsi_ccb *request, uint64 lba, size_t sectorCount, bool isWrite); void ScsiSynchronizeCache(scsi_ccb *request); void ExecuteSataRequest(sata_request *request, bool isWrite = false); diff --git a/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp b/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp index 8b17d67a1e..e1dd6b4095 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp @@ -8,7 +8,7 @@ sata_request::sata_request() : fCcb(NULL) - , fFisLength(20) + , fIsATAPI(false) , fCompletionSem(create_sem(0, "sata completion")) , fCompletionStatus(0) , fData(NULL) @@ -19,7 +19,7 @@ sata_request::sata_request() sata_request::sata_request(scsi_ccb *ccb) : fCcb(ccb) - , fFisLength(20) + , fIsATAPI(false) , fCompletionSem(-1) , fCompletionStatus(0) , fData(NULL) @@ -83,36 +83,12 @@ sata_request::set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount) void -sata_request::set_atapi6_cmd(const void *cmd) +sata_request::set_atapi_cmd() { - memcpy(fFis, cmd, 6); - memset(fFis + 6, 0, 6); - fFisLength = 12; -} - - -void -sata_request::set_atapi10_cmd(const void *cmd) -{ - memcpy(fFis, cmd, 10); - memset(fFis + 10, 0, 2); - fFisLength = 12; -} - - -void -sata_request::set_atapi12_cmd(const void *cmd) -{ - memcpy(fFis, cmd, 12); - fFisLength = 12; -} - - -void -sata_request::set_atapi16_cmd(const void *cmd) -{ - memcpy(fFis, cmd, 16); - fFisLength = 16; + fIsATAPI = true; + set_ata_cmd(0xa0); + fFis[5] = 0xfe; + fFis[6] = 0xff; } diff --git a/src/add-ons/kernel/busses/scsi/ahci/sata_request.h b/src/add-ons/kernel/busses/scsi/ahci/sata_request.h index 3a21846da6..9873fa8579 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/sata_request.h +++ b/src/add-ons/kernel/busses/scsi/ahci/sata_request.h @@ -20,14 +20,11 @@ public: void set_ata28_cmd(uint8 command, uint32 lba, uint8 sectorCount); void set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount); - void set_atapi6_cmd(const void *cmd); - void set_atapi10_cmd(const void *cmd); - void set_atapi12_cmd(const void *cmd); - void set_atapi16_cmd(const void *cmd); + void set_atapi_cmd(); + bool is_atapi(); scsi_ccb * ccb(); const void * fis(); - int fis_length(); void * data(); int size(); void finish(int tfd, size_t bytesTransfered); @@ -39,7 +36,7 @@ public: private: scsi_ccb * fCcb; uint8 fFis[20]; - int fFisLength; + bool fIsATAPI; sem_id fCompletionSem; int fCompletionStatus; void * fData; @@ -61,10 +58,10 @@ sata_request::fis() } -inline int -sata_request::fis_length() +inline bool +sata_request::is_atapi() { - return fFisLength; + return fIsATAPI; }