Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #3
0
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);
}