void AHCIPort::ScsiReadWrite(scsi_ccb *request, uint64 lba, size_t sectorCount, bool isWrite) { RWTRACE("[%lld] %ld ScsiReadWrite: position %llu, size %lu, isWrite %d\n", system_time(), find_thread(NULL), lba * 512, sectorCount * 512, isWrite); #if 0 if (isWrite) { TRACE("write request ignored\n"); request->subsys_status = SCSI_REQ_CMP; request->data_resid = 0; gSCSI->finished(request, 1); return; } #endif ASSERT(request->data_length == sectorCount * 512); sata_request *sreq = new(std::nothrow) sata_request(request); if (fUse48BitCommands) { if (sectorCount > 65536) panic("ahci: ScsiReadWrite length too large, %lu sectors", sectorCount); if (lba > MAX_SECTOR_LBA_48) panic("achi: ScsiReadWrite position too large for 48-bit LBA\n"); sreq->set_ata48_cmd(isWrite ? 0x35 : 0x25, lba, sectorCount); } else { if (sectorCount > 256) panic("ahci: ScsiReadWrite length too large, %lu sectors", sectorCount); if (lba > MAX_SECTOR_LBA_28) panic("achi: ScsiReadWrite position too large for normal LBA\n"); sreq->set_ata28_cmd(isWrite ? 0xca : 0xc8, lba, sectorCount); } ExecuteSataRequest(sreq, isWrite); }
void AHCIPort::ScsiReadWrite(scsi_ccb* request, uint64 lba, size_t sectorCount, bool isWrite) { RWTRACE("[%lld] %ld ScsiReadWrite: position %llu, size %lu, isWrite %d\n", system_time(), find_thread(NULL), lba * 512, sectorCount * 512, isWrite); #if 0 if (isWrite) { TRACE("write request ignored\n"); request->subsys_status = SCSI_REQ_CMP; request->data_resid = 0; gSCSI->finished(request, 1); return; } #endif ASSERT(request->data_length == sectorCount * 512); sata_request* sreq = new(std::nothrow) sata_request(request); if (sreq == NULL) { TRACE("out of memory when allocating read/write request\n"); request->subsys_status = SCSI_REQ_ABORTED; gSCSI->finished(request, 1); return; } if (fUse48BitCommands) { if (sectorCount > 65536) { panic("ahci: ScsiReadWrite length too large, %lu sectors", sectorCount); } if (lba > MAX_SECTOR_LBA_48) panic("achi: ScsiReadWrite position too large for 48-bit LBA\n"); sreq->SetATA48Command( isWrite ? ATA_COMMAND_WRITE_DMA_EXT : ATA_COMMAND_READ_DMA_EXT, lba, sectorCount); } else { if (sectorCount > 256) { panic("ahci: ScsiReadWrite length too large, %lu sectors", sectorCount); } if (lba > MAX_SECTOR_LBA_28) panic("achi: ScsiReadWrite position too large for normal LBA\n"); sreq->SetATA28Command(isWrite ? ATA_COMMAND_WRITE_DMA : ATA_COMMAND_READ_DMA, lba, sectorCount); } ExecuteSataRequest(sreq, isWrite); }
void AHCIPort::Interrupt() { uint32 is = fRegs->is; fRegs->is = is; // clear interrupts if (is & PORT_INT_ERROR) { InterruptErrorHandler(is); return; } uint32 ci = fRegs->ci; RWTRACE("[%lld] %ld AHCIPort::Interrupt port %d, fCommandsActive 0x%08" B_PRIx32 ", " "is 0x%08" B_PRIx32 ", ci 0x%08" B_PRIx32 "\n", system_time(), find_thread(NULL), fIndex, fCommandsActive, is, ci); acquire_spinlock(&fSpinlock); if ((fCommandsActive & 1) && !(ci & 1)) { fCommandsActive &= ~1; release_sem_etc(fResponseSem, 1, B_DO_NOT_RESCHEDULE); } release_spinlock(&fSpinlock); }