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:
Marcus Overhagen 2008-01-05 02:23:39 +00:00
parent e50610ed49
commit 56f0b1a01a
2 changed files with 205 additions and 0 deletions

View 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;
}

View 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