A helper class to easier support Native Command Qeueuing and ATAPI support.
This class either encapsulates scsi_ccb or can be used stand alone. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23249 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e50610ed49
commit
56f0b1a01a
134
src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp
Normal file
134
src/add-ons/kernel/busses/scsi/ahci/sata_request.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2008, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "sata_request.h"
|
||||
#include <string.h>
|
||||
|
||||
sata_request::sata_request()
|
||||
: fCcb(NULL)
|
||||
, fCompletionSem(create_sem(0, "sata completion"))
|
||||
, fCompletionStatus(0)
|
||||
, fData(NULL)
|
||||
, fDataSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
sata_request::sata_request(scsi_ccb *ccb)
|
||||
: fCcb(ccb)
|
||||
, fCompletionSem(-1)
|
||||
, fCompletionStatus(0)
|
||||
, fData(NULL)
|
||||
, fDataSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
sata_request::~sata_request()
|
||||
{
|
||||
if (fCompletionSem >= 0)
|
||||
delete_sem(fCompletionSem);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sata_request::set_data(void *data, size_t dataSize)
|
||||
{
|
||||
if (fCcb) panic("wrong usage");
|
||||
fData = data;
|
||||
fDataSize = dataSize;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sata_request::set_ata_cmd(uint8 command)
|
||||
{
|
||||
memset(fFis, 0, sizeof(fFis));
|
||||
fFis[0] = 0x27;
|
||||
fFis[1] = 0x80;
|
||||
fFis[2] = command;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sata_request::set_ata28_cmd(uint8 command, uint32 lba, uint8 sectorCount)
|
||||
{
|
||||
set_ata_cmd(command);
|
||||
fFis[4] = lba & 0xff;
|
||||
fFis[5] = (lba >> 8) & 0xff;
|
||||
fFis[6] = (lba >> 16) & 0xff;
|
||||
fFis[7] = 0x40 | ((lba >> 24) & 0x0f);
|
||||
fFis[12] = sectorCount & 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sata_request::set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount)
|
||||
{
|
||||
set_ata_cmd(command);
|
||||
fFis[4] = lba & 0xff;
|
||||
fFis[5] = (lba >> 8) & 0xff;
|
||||
fFis[6] = (lba >> 16) & 0xff;
|
||||
fFis[7] = 0x40;
|
||||
fFis[8] = (lba >> 24) & 0xff;
|
||||
fFis[9] = (lba >> 32) & 0xff;
|
||||
fFis[10] = (lba >> 40) & 0xff;
|
||||
fFis[12] = sectorCount & 0xff;
|
||||
fFis[13] = (sectorCount >> 8) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sata_request::finish(int tfd, size_t bytesTransfered)
|
||||
{
|
||||
if (tfd & ATA_ERR)
|
||||
dprintf("ahci: sata_request::finish ATA_ERR set for command 0x%02x\n", fFis[2]);
|
||||
if (fCcb) {
|
||||
fCcb->data_resid = fCcb->data_length - bytesTransfered;
|
||||
fCcb->subsys_status = (tfd & ATA_ERR) ? SCSI_REQ_CMP_ERR : SCSI_REQ_CMP;
|
||||
gSCSI->finished(fCcb, 1);
|
||||
delete this;
|
||||
} else {
|
||||
fCompletionStatus = tfd;
|
||||
release_sem(fCompletionSem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sata_request::abort()
|
||||
{
|
||||
dprintf("ahci: sata_request::abort called for command 0x%02x\n", fFis[2]);
|
||||
if (fCcb) {
|
||||
fCcb->subsys_status = SCSI_REQ_ABORTED;
|
||||
gSCSI->finished(fCcb, 1);
|
||||
delete this;
|
||||
} else {
|
||||
fCompletionStatus = -1;
|
||||
release_sem(fCompletionSem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sata_request::wait_for_completition()
|
||||
{
|
||||
if (fCcb) panic("wrong usage");
|
||||
acquire_sem(fCompletionSem);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sata_request::completition_status()
|
||||
{
|
||||
if (fCcb) panic("wrong usage");
|
||||
return fCompletionStatus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
71
src/add-ons/kernel/busses/scsi/ahci/sata_request.h
Normal file
71
src/add-ons/kernel/busses/scsi/ahci/sata_request.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2008, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SATA_REQUEST_H
|
||||
#define _SATA_REQUEST_H
|
||||
|
||||
#include "ahci_defs.h"
|
||||
|
||||
class sata_request
|
||||
{
|
||||
public:
|
||||
sata_request();
|
||||
sata_request(scsi_ccb *ccb);
|
||||
~sata_request();
|
||||
|
||||
void set_data(void *data, size_t dataSize);
|
||||
|
||||
void set_ata_cmd(uint8 command);
|
||||
void set_ata28_cmd(uint8 command, uint32 lba, uint8 sectorCount);
|
||||
void set_ata48_cmd(uint8 command, uint64 lba, uint16 sectorCount);
|
||||
|
||||
scsi_ccb * ccb();
|
||||
const void * fis();
|
||||
void * data();
|
||||
int size();
|
||||
void finish(int tfd, size_t bytesTransfered);
|
||||
void abort();
|
||||
|
||||
void wait_for_completition();
|
||||
int completition_status();
|
||||
|
||||
private:
|
||||
scsi_ccb * fCcb;
|
||||
uint8 fFis[20];
|
||||
sem_id fCompletionSem;
|
||||
int fCompletionStatus;
|
||||
void * fData;
|
||||
size_t fDataSize;
|
||||
};
|
||||
|
||||
|
||||
inline scsi_ccb *
|
||||
sata_request::ccb()
|
||||
{
|
||||
return fCcb;
|
||||
}
|
||||
|
||||
|
||||
inline const void *
|
||||
sata_request::fis()
|
||||
{
|
||||
return fFis;
|
||||
}
|
||||
|
||||
|
||||
inline void *
|
||||
sata_request::data()
|
||||
{
|
||||
return fData;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
sata_request::size()
|
||||
{
|
||||
return fDataSize;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user