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:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user