* Fixed driver initialization - you are supposed to call init_driver()
and uninit_driver() yourself. We're also using this to let the controller access the pci_device object. * Fixed some style violations for your pleasure ;-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22082 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ff308b0b49
commit
4f6fa362cf
@ -17,17 +17,13 @@
|
|||||||
#define AHCI_ID_GENERATOR "ahci/id"
|
#define AHCI_ID_GENERATOR "ahci/id"
|
||||||
#define AHCI_ID_ITEM "ahci/id"
|
#define AHCI_ID_ITEM "ahci/id"
|
||||||
|
|
||||||
static device_manager_info *sDeviceManager;
|
device_manager_info *gDeviceManager;
|
||||||
|
|
||||||
|
|
||||||
// HACK! this device manager stuff just sucks!
|
|
||||||
extern pci_device pd;
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
register_sim(device_node_handle parent)
|
register_sim(device_node_handle parent)
|
||||||
{
|
{
|
||||||
int32 id = sDeviceManager->create_id(AHCI_ID_GENERATOR);
|
int32 id = gDeviceManager->create_id(AHCI_ID_GENERATOR);
|
||||||
if (id < 0)
|
if (id < 0)
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
@ -50,10 +46,10 @@ register_sim(device_node_handle parent)
|
|||||||
};
|
};
|
||||||
|
|
||||||
device_node_handle node;
|
device_node_handle node;
|
||||||
status_t status = sDeviceManager->register_device(parent, attrs, NULL,
|
status_t status = gDeviceManager->register_device(parent, attrs, NULL,
|
||||||
&node);
|
&node);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
sDeviceManager->free_id(AHCI_ID_GENERATOR, id);
|
gDeviceManager->free_id(AHCI_ID_GENERATOR, id);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -73,17 +69,17 @@ ahci_supports_device(device_node_handle parent, bool *_noConnection)
|
|||||||
|
|
||||||
TRACE("ahci_supports_device\n");
|
TRACE("ahci_supports_device\n");
|
||||||
|
|
||||||
if (sDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus,
|
if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus,
|
||||||
false) != B_OK
|
false) != B_OK
|
||||||
|| sDeviceManager->get_attr_uint8(parent,
|
|| gDeviceManager->get_attr_uint8(parent,
|
||||||
PCI_DEVICE_BASE_CLASS_ID_ITEM, &baseClass, false) != B_OK
|
PCI_DEVICE_BASE_CLASS_ID_ITEM, &baseClass, false) != B_OK
|
||||||
|| sDeviceManager->get_attr_uint8(parent,
|
|| gDeviceManager->get_attr_uint8(parent,
|
||||||
PCI_DEVICE_SUB_CLASS_ID_ITEM, &subClass, false) != B_OK
|
PCI_DEVICE_SUB_CLASS_ID_ITEM, &subClass, false) != B_OK
|
||||||
|| sDeviceManager->get_attr_uint8(parent,
|
|| gDeviceManager->get_attr_uint8(parent,
|
||||||
PCI_DEVICE_API_ID_ITEM, &classAPI, false) != B_OK
|
PCI_DEVICE_API_ID_ITEM, &classAPI, false) != B_OK
|
||||||
|| sDeviceManager->get_attr_uint16(parent,
|
|| gDeviceManager->get_attr_uint16(parent,
|
||||||
PCI_DEVICE_VENDOR_ID_ITEM, &vendorID, false) != B_OK
|
PCI_DEVICE_VENDOR_ID_ITEM, &vendorID, false) != B_OK
|
||||||
|| sDeviceManager->get_attr_uint16(parent,
|
|| gDeviceManager->get_attr_uint16(parent,
|
||||||
PCI_DEVICE_DEVICE_ID_ITEM, &deviceID, false) != B_OK)
|
PCI_DEVICE_DEVICE_ID_ITEM, &deviceID, false) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@ -113,7 +109,6 @@ static status_t
|
|||||||
ahci_register_device(device_node_handle parent)
|
ahci_register_device(device_node_handle parent)
|
||||||
{
|
{
|
||||||
device_node_handle node;
|
device_node_handle node;
|
||||||
pci_device *pciDevice;
|
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
device_attr attrs[] = {
|
device_attr attrs[] = {
|
||||||
@ -141,31 +136,38 @@ ahci_register_device(device_node_handle parent)
|
|||||||
|
|
||||||
TRACE("ahci_register_device\n");
|
TRACE("ahci_register_device\n");
|
||||||
|
|
||||||
// initialize parent (the bus) to get the PCI interface and device
|
status = gDeviceManager->register_device(parent, attrs,
|
||||||
status = sDeviceManager->init_driver(parent, NULL,
|
|
||||||
(driver_module_info **)&gPCI, (void **)&pciDevice);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = sDeviceManager->register_device(parent, attrs,
|
|
||||||
NULL, &node);
|
NULL, &node);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// HACK! this device manager stuff just sucks!
|
|
||||||
pd = *pciDevice;
|
|
||||||
|
|
||||||
// TODO: register SIM for every controller we find!
|
// TODO: register SIM for every controller we find!
|
||||||
return register_sim(node);
|
return register_sim(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
ahci_init_driver(device_node_handle node, void *user_cookie, void **_cookie)
|
ahci_init_driver(device_node_handle node, void *userCookie, void **_cookie)
|
||||||
{
|
{
|
||||||
TRACE("ahci_init_driver, user_cookie %p\n", user_cookie);
|
pci_device *_userCookie = userCookie;
|
||||||
*_cookie = (void *)0x5678;
|
pci_device pciDevice;
|
||||||
TRACE("cookie = %p\n", *_cookie);
|
device_node_handle parent;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
TRACE("ahci_init_driver, userCookie %p\n", userCookie);
|
||||||
|
|
||||||
|
parent = gDeviceManager->get_parent(node);
|
||||||
|
|
||||||
|
// initialize parent (the bus) to get the PCI interface and device
|
||||||
|
status = gDeviceManager->init_driver(parent, NULL,
|
||||||
|
(driver_module_info **)&gPCI, (void **)&pciDevice);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
gDeviceManager->put_device_node(parent);
|
||||||
|
|
||||||
|
*_userCookie = pciDevice;
|
||||||
|
*_cookie = node;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +175,14 @@ ahci_init_driver(device_node_handle node, void *user_cookie, void **_cookie)
|
|||||||
static status_t
|
static status_t
|
||||||
ahci_uninit_driver(void *cookie)
|
ahci_uninit_driver(void *cookie)
|
||||||
{
|
{
|
||||||
|
device_node_handle node = cookie;
|
||||||
|
device_node_handle parent;
|
||||||
|
|
||||||
TRACE("ahci_uninit_driver, cookie %p\n", cookie);
|
TRACE("ahci_uninit_driver, cookie %p\n", cookie);
|
||||||
|
|
||||||
|
parent = gDeviceManager->get_parent(node);
|
||||||
|
gDeviceManager->uninit_driver(parent);
|
||||||
|
gDeviceManager->put_device_node(parent);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +244,7 @@ driver_module_info sAHCIDevice = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module_dependency module_dependencies[] = {
|
module_dependency module_dependencies[] = {
|
||||||
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
|
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
|
||||||
{ SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSI },
|
{ SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSI },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* Copyright 2007, Marcus Overhagen. All rights reserved.
|
* Copyright 2007, Marcus Overhagen. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ahci_controller.h"
|
#include "ahci_controller.h"
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
@ -9,34 +10,29 @@
|
|||||||
#define TRACE(a...) dprintf("\33[34mahci:\33[0m " a)
|
#define TRACE(a...) dprintf("\33[34mahci:\33[0m " a)
|
||||||
#define FLOW(a...) dprintf("ahci: " a)
|
#define FLOW(a...) dprintf("ahci: " a)
|
||||||
|
|
||||||
// HACK! this device manager stuff just sucks!
|
|
||||||
pci_device pd;
|
|
||||||
|
|
||||||
AHCIController::AHCIController(device_node_handle node, pci_device_module_info *pci, scsi_for_sim_interface *scsi)
|
AHCIController::AHCIController(device_node_handle node, pci_device_info *device)
|
||||||
: fNode(node)
|
: fNode(node)
|
||||||
, fPCI(pci)
|
, fPCIDevice(device)
|
||||||
, fSCSI(scsi)
|
, fDevicePresentMask(0)
|
||||||
, fPCIDevice(0)
|
|
||||||
, fDevicePresentMask(0)
|
|
||||||
{
|
{
|
||||||
// HACK! this device manager stuff just sucks!
|
|
||||||
fPCIDevice = pd;
|
|
||||||
|
|
||||||
fDevicePresentMask = (1 << 7) | (1 << 19);
|
fDevicePresentMask = (1 << 7) | (1 << 19);
|
||||||
|
|
||||||
uint16 vendorID = fPCI->read_pci_config(fPCIDevice, PCI_vendor_id, 2);
|
uint16 vendorID = gPCI->read_pci_config(fPCIDevice, PCI_vendor_id, 2);
|
||||||
uint16 deviceID = fPCI->read_pci_config(fPCIDevice, PCI_device_id, 2);
|
uint16 deviceID = gPCI->read_pci_config(fPCIDevice, PCI_device_id, 2);
|
||||||
|
|
||||||
TRACE("AHCIController::AHCIController vendor %04x, device %04x\n", vendorID, deviceID);
|
TRACE("AHCIController::AHCIController vendor %04x, device %04x\n",
|
||||||
|
vendorID, deviceID);
|
||||||
|
|
||||||
uchar cap_ofs;
|
uchar capabilityOffset;
|
||||||
status_t res = fPCI->find_pci_capability(fPCIDevice, PCI_cap_id_sata, &cap_ofs);
|
status_t res = gPCI->find_pci_capability(fPCIDevice, PCI_cap_id_sata,
|
||||||
|
&capabilityOffset);
|
||||||
if (res == B_OK) {
|
if (res == B_OK) {
|
||||||
uint32 satacr0;
|
uint32 satacr0;
|
||||||
uint32 satacr1;
|
uint32 satacr1;
|
||||||
TRACE("PCI SATA capability found at offset 0x%x\n", cap_ofs);
|
TRACE("PCI SATA capability found at offset 0x%x\n", capabilityOffset);
|
||||||
satacr0 = fPCI->read_pci_config(fPCIDevice, cap_ofs, 4);
|
satacr0 = gPCI->read_pci_config(fPCIDevice, capabilityOffset, 4);
|
||||||
satacr1 = fPCI->read_pci_config(fPCIDevice, cap_ofs + 4, 4);
|
satacr1 = gPCI->read_pci_config(fPCIDevice, capabilityOffset + 4, 4);
|
||||||
TRACE("satacr0 = 0x%08lx, satacr1 = 0x%08lx\n", satacr0, satacr1);
|
TRACE("satacr0 = 0x%08lx, satacr1 = 0x%08lx\n", satacr0, satacr1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,18 +48,18 @@ AHCIController::ExecuteRequest(scsi_ccb *request)
|
|||||||
{
|
{
|
||||||
if (request->target_lun || !IsDevicePresent(request->target_id)) {
|
if (request->target_lun || !IsDevicePresent(request->target_id)) {
|
||||||
request->subsys_status = SCSI_DEV_NOT_THERE;
|
request->subsys_status = SCSI_DEV_NOT_THERE;
|
||||||
fSCSI->finished(request, 1);
|
gSCSI->finished(request, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("AHCIController::ExecuteRequest opcode %u, length %u\n", request->cdb[0], request->cdb_length);
|
TRACE("AHCIController::ExecuteRequest opcode %u, length %u\n", request->cdb[0], request->cdb_length);
|
||||||
|
|
||||||
request->subsys_status = SCSI_DEV_NOT_THERE;
|
request->subsys_status = SCSI_DEV_NOT_THERE;
|
||||||
fSCSI->finished(request, 1);
|
gSCSI->finished(request, 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
request->subsys_status = SCSI_REQ_CMP;
|
request->subsys_status = SCSI_REQ_CMP;
|
||||||
fSCSI->finished(request, 1);
|
gSCSI->finished(request, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,28 +8,26 @@
|
|||||||
|
|
||||||
#include "ahci_defs.h"
|
#include "ahci_defs.h"
|
||||||
|
|
||||||
class AHCIController
|
|
||||||
{
|
class AHCIController {
|
||||||
public:
|
public:
|
||||||
AHCIController(device_node_handle node, pci_device_module_info *pci, scsi_for_sim_interface * scsi);
|
AHCIController(device_node_handle node,
|
||||||
|
pci_device_info *pciDevice);
|
||||||
~AHCIController();
|
~AHCIController();
|
||||||
|
|
||||||
|
|
||||||
void ExecuteRequest(scsi_ccb *request);
|
void ExecuteRequest(scsi_ccb *request);
|
||||||
uchar AbortRequest(scsi_ccb *request);
|
uchar AbortRequest(scsi_ccb *request);
|
||||||
uchar TerminateRequest(scsi_ccb *request);
|
uchar TerminateRequest(scsi_ccb *request);
|
||||||
uchar ResetDevice(uchar targetID, uchar targetLUN);
|
uchar ResetDevice(uchar targetID, uchar targetLUN);
|
||||||
|
|
||||||
|
device_node_handle DeviceNode() { return fNode; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsDevicePresent(uint device);
|
bool IsDevicePresent(uint device);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
device_node_handle fNode;
|
device_node_handle fNode;
|
||||||
pci_device_module_info * fPCI;
|
pci_device_info* fPCIDevice;
|
||||||
scsi_for_sim_interface * fSCSI;
|
|
||||||
pci_device fPCIDevice;
|
|
||||||
uint32 fDevicePresentMask;
|
uint32 fDevicePresentMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,4 +39,4 @@ AHCIController::IsDevicePresent(uint device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif // _AHCI_CONTROLLER_H
|
||||||
|
@ -51,6 +51,7 @@ typedef struct {
|
|||||||
} ahci_hba;
|
} ahci_hba;
|
||||||
|
|
||||||
extern scsi_sim_interface gAHCISimInterface;
|
extern scsi_sim_interface gAHCISimInterface;
|
||||||
|
extern device_manager_info *gDeviceManager;
|
||||||
extern pci_device_module_info *gPCI;
|
extern pci_device_module_info *gPCI;
|
||||||
extern scsi_for_sim_interface *gSCSI;
|
extern scsi_for_sim_interface *gSCSI;
|
||||||
|
|
||||||
|
@ -122,11 +122,22 @@ ahci_ioctl(scsi_sim_cookie cookie, uint8 targetID, uint32 op, void *buffer,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
ahci_sim_init_bus(device_node_handle node, void *user_cookie, void **_cookie)
|
ahci_sim_init_bus(device_node_handle node, void *userCookie, void **_cookie)
|
||||||
{
|
{
|
||||||
TRACE("ahci_sim_init_bus, user_cookie %p\n", user_cookie);
|
TRACE("ahci_sim_init_bus, userCookie %p\n", userCookie);
|
||||||
// *_cookie = (void *)0x1234;
|
|
||||||
*_cookie = new(std::nothrow) AHCIController(node, gPCI, gSCSI);
|
device_node_handle parent = gDeviceManager->get_parent(node);
|
||||||
|
|
||||||
|
// initialize parent (the bus) to get the PCI interface and device
|
||||||
|
pci_device_info *pciDevice;
|
||||||
|
status_t status = gDeviceManager->init_driver(parent, &pciDevice,
|
||||||
|
NULL, NULL);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
gDeviceManager->put_device_node(parent);
|
||||||
|
|
||||||
|
*_cookie = new(std::nothrow) AHCIController(node, pciDevice);
|
||||||
if (!*_cookie)
|
if (!*_cookie)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
TRACE("cookie = %p\n", *_cookie);
|
TRACE("cookie = %p\n", *_cookie);
|
||||||
@ -138,7 +149,14 @@ static status_t
|
|||||||
ahci_sim_uninit_bus(void *cookie)
|
ahci_sim_uninit_bus(void *cookie)
|
||||||
{
|
{
|
||||||
TRACE("ahci_sim_uninit_bus, cookie %p\n", cookie);
|
TRACE("ahci_sim_uninit_bus, cookie %p\n", cookie);
|
||||||
delete static_cast<AHCIController *>(cookie);
|
AHCIController *controller = static_cast<AHCIController *>(cookie);
|
||||||
|
|
||||||
|
device_node_handle parent = gDeviceManager->get_parent(
|
||||||
|
controller->DeviceNode());
|
||||||
|
gDeviceManager->uninit_driver(parent);
|
||||||
|
gDeviceManager->put_device_node(parent);
|
||||||
|
|
||||||
|
delete controller;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user