forward scsi request to the ports

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22146 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen
2007-09-01 20:26:07 +00:00
parent 4f733fe93b
commit 25f926d8e4
4 changed files with 71 additions and 37 deletions
@@ -18,7 +18,6 @@
AHCIController::AHCIController(device_node_handle node, pci_device_info *device) AHCIController::AHCIController(device_node_handle node, pci_device_info *device)
: fNode(node) : fNode(node)
, fPCIDevice(device) , fPCIDevice(device)
, fDevicePresentMask(0)
, fPCIVendorID(0xffff) , fPCIVendorID(0xffff)
, fPCIDeviceID(0xffff) , fPCIDeviceID(0xffff)
, fCommandSlotCount(0) , fCommandSlotCount(0)
@@ -27,7 +26,7 @@ AHCIController::AHCIController(device_node_handle node, pci_device_info *device)
, fIRQ(0) , fIRQ(0)
, fInstanceCheck(-1) , fInstanceCheck(-1)
{ {
memset(fPorts, 0, sizeof(fPorts)); memset(fPort, 0, sizeof(fPort));
} }
@@ -135,16 +134,16 @@ AHCIController::Init()
for (int i = 0; i <= fPortMax; i++) { for (int i = 0; i <= fPortMax; i++) {
if (fRegs->pi & (1 << i)) { if (fRegs->pi & (1 << i)) {
fPorts[i] = new (std::nothrow)AHCIPort(this, i); fPort[i] = new (std::nothrow)AHCIPort(this, i);
if (!fPorts[i]) { if (!fPort[i]) {
TRACE("out of memory creating port %d", i); TRACE("out of memory creating port %d", i);
break; break;
} }
status_t status = fPorts[i]->Init(); status_t status = fPort[i]->Init();
if (status < B_OK) { if (status < B_OK) {
TRACE("init port %d failed", i); TRACE("init port %d failed", i);
delete fPorts[i]; delete fPort[i];
fPorts[i] = NULL; fPort[i] = NULL;
break; break;
} }
} }
@@ -164,9 +163,9 @@ AHCIController::Uninit()
TRACE("AHCIController::Uninit\n"); TRACE("AHCIController::Uninit\n");
for (int i = 0; i <= fPortMax; i++) { for (int i = 0; i <= fPortMax; i++) {
if (fPorts[i]) { if (fPort[i]) {
fPorts[i]->Uninit(); fPort[i]->Uninit();
delete fPorts[i]; delete fPort[i];
} }
} }
@@ -229,8 +228,8 @@ AHCIController::Interrupt(void *data)
for (int i = 0; i < self->fPortMax; i++) { for (int i = 0; i < self->fPortMax; i++) {
if (int_stat & (1 << i)) { if (int_stat & (1 << i)) {
if (self->fPorts[i]) { if (self->fPort[i]) {
self->fPorts[i]->Interrupt(); self->fPort[i]->Interrupt();
} else { } else {
FLOW("interrupt on non-existent port %d\n", i); FLOW("interrupt on non-existent port %d\n", i);
} }
@@ -247,49 +246,42 @@ AHCIController::Interrupt(void *data)
void void
AHCIController::ExecuteRequest(scsi_ccb *request) AHCIController::ExecuteRequest(scsi_ccb *request)
{ {
if (request->target_lun || !IsDevicePresent(request->target_id)) { if (request->target_lun || !fPort[request->target_id]) {
request->subsys_status = SCSI_DEV_NOT_THERE; request->subsys_status = SCSI_DEV_NOT_THERE;
gSCSI->finished(request, 1); gSCSI->finished(request, 1);
return; return;
} }
TRACE("AHCIController::ExecuteRequest opcode %u, length %u\n", request->cdb[0], request->cdb_length); fPort[request->target_id]->ExecuteRequest(request);
request->subsys_status = SCSI_DEV_NOT_THERE;
gSCSI->finished(request, 1);
return;
request->subsys_status = SCSI_REQ_CMP;
gSCSI->finished(request, 1);
} }
uchar uchar
AHCIController::AbortRequest(scsi_ccb *request) AHCIController::AbortRequest(scsi_ccb *request)
{ {
if (request->target_lun || !IsDevicePresent(request->target_id)) if (request->target_lun || !fPort[request->target_id])
return SCSI_DEV_NOT_THERE; return SCSI_DEV_NOT_THERE;
return SCSI_REQ_CMP; return fPort[request->target_id]->AbortRequest(request);
} }
uchar uchar
AHCIController::TerminateRequest(scsi_ccb *request) AHCIController::TerminateRequest(scsi_ccb *request)
{ {
if (request->target_lun || !IsDevicePresent(request->target_id)) if (request->target_lun || !fPort[request->target_id])
return SCSI_DEV_NOT_THERE; return SCSI_DEV_NOT_THERE;
return SCSI_REQ_CMP; return fPort[request->target_id]->TerminateRequest(request);
} }
uchar uchar
AHCIController::ResetDevice(uchar targetID, uchar targetLUN) AHCIController::ResetDevice(uchar targetID, uchar targetLUN)
{ {
if (targetLUN || !IsDevicePresent(targetID)) if (targetLUN || !fPort[targetID])
return SCSI_DEV_NOT_THERE; return SCSI_DEV_NOT_THERE;
return SCSI_REQ_CMP; return fPort[targetID]->ResetDevice();
} }
@@ -33,10 +33,11 @@ private:
static int32 Interrupt(void *data); static int32 Interrupt(void *data);
friend class AHCIPort;
private: private:
device_node_handle fNode; device_node_handle fNode;
pci_device_info* fPCIDevice; pci_device_info* fPCIDevice;
uint32 fDevicePresentMask;
uint16 fPCIVendorID; uint16 fPCIVendorID;
uint16 fPCIDeviceID; uint16 fPCIDeviceID;
@@ -46,7 +47,7 @@ private:
int fPortCount; int fPortCount;
int fPortMax; int fPortMax;
uint8 fIRQ; uint8 fIRQ;
AHCIPort * fPorts[32]; AHCIPort * fPort[32];
// --- Instance check workaround begin // --- Instance check workaround begin
@@ -56,13 +57,6 @@ private:
}; };
inline bool
AHCIController::IsDevicePresent(uint device)
{
return fDevicePresentMask & (1 << device);
}
inline void inline void
AHCIController::RegsFlush() AHCIController::RegsFlush()
{ {
@@ -4,6 +4,7 @@
*/ */
#include "ahci_port.h" #include "ahci_port.h"
#include "ahci_controller.h"
#include <KernelExport.h> #include <KernelExport.h>
#include <stdio.h> #include <stdio.h>
@@ -14,6 +15,7 @@
AHCIPort::AHCIPort(AHCIController *controller, int index) AHCIPort::AHCIPort(AHCIController *controller, int index)
: fIndex(index) : fIndex(index)
, fRegs(&controller->fRegs->port[index])
{ {
} }
@@ -43,3 +45,41 @@ AHCIPort::Interrupt()
{ {
TRACE("AHCIPort::Interrupt port %d\n", fIndex); TRACE("AHCIPort::Interrupt port %d\n", fIndex);
} }
void
AHCIPort::ExecuteRequest(scsi_ccb *request)
{
TRACE("AHCIPort::ExecuteRequest port %d, opcode %u, length %u\n", fIndex, request->cdb[0], request->cdb_length);
request->subsys_status = SCSI_DEV_NOT_THERE;
gSCSI->finished(request, 1);
return;
request->subsys_status = SCSI_REQ_CMP;
gSCSI->finished(request, 1);
}
uchar
AHCIPort::AbortRequest(scsi_ccb *request)
{
return SCSI_REQ_CMP;
}
uchar
AHCIPort::TerminateRequest(scsi_ccb *request)
{
return SCSI_REQ_CMP;
}
uchar
AHCIPort::ResetDevice()
{
return SCSI_REQ_CMP;
}
@@ -19,8 +19,16 @@ public:
void Interrupt(); void Interrupt();
void ExecuteRequest(scsi_ccb *request);
uchar AbortRequest(scsi_ccb *request);
uchar TerminateRequest(scsi_ccb *request);
uchar ResetDevice();
private: private:
int fIndex; int fIndex;
volatile ahci_port * fRegs;
}; };
#endif // _AHCI_PORT_H #endif // _AHCI_PORT_H