ATA: Support for Highpoint HPT36x/37x PCI controller
Signed-off-by: Augustin Cavalier <[email protected]> Fixes #13819. Some style fixes by me.
This commit is contained in:
committed by
Augustin Cavalier
parent
841d719fc8
commit
5797d59f94
@@ -31,7 +31,7 @@ AddFilesToPackage add-ons kernel bus_managers : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ;
|
|||||||
AddFilesToPackage add-ons kernel busses agp_gart : <agp_gart>intel@x86,x86_64 ;
|
AddFilesToPackage add-ons kernel busses agp_gart : <agp_gart>intel@x86,x86_64 ;
|
||||||
|
|
||||||
AddFilesToPackage add-ons kernel busses ata
|
AddFilesToPackage add-ons kernel busses ata
|
||||||
: generic_ide_pci it8211 legacy_sata silicon_image_3112 ide_isa@x86 ;
|
: generic_ide_pci it8211 legacy_sata silicon_image_3112 highpoint_ide_pci ide_isa@x86 ;
|
||||||
|
|
||||||
AddFilesToPackage add-ons kernel busses random : virtio_rng ;
|
AddFilesToPackage add-ons kernel busses random : virtio_rng ;
|
||||||
AddFilesToPackage add-ons kernel busses scsi : ahci virtio_scsi ;
|
AddFilesToPackage add-ons kernel busses scsi : ahci virtio_scsi ;
|
||||||
@@ -198,7 +198,7 @@ AddBootModuleSymlinksToPackage
|
|||||||
legacy_sata locked_pool
|
legacy_sata locked_pool
|
||||||
openpic@ppc
|
openpic@ppc
|
||||||
packagefs pci
|
packagefs pci
|
||||||
scsi scsi_cd scsi_disk scsi_periph silicon_image_3112
|
scsi scsi_cd scsi_disk scsi_periph silicon_image_3112 highpoint_ide_pci
|
||||||
usb usb_disk <usb>ehci <usb>ohci <usb>uhci <usb>xhci
|
usb usb_disk <usb>ehci <usb>ohci <usb>uhci <usb>xhci
|
||||||
virtio virtio_block virtio_pci virtio_scsi
|
virtio virtio_block virtio_pci virtio_scsi
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ AddFilesToPackage add-ons kernel bus_managers : $(SYSTEM_ADD_ONS_BUS_MANAGERS) ;
|
|||||||
AddFilesToPackage add-ons kernel busses agp_gart : <agp_gart>intel@x86,x86_64 ;
|
AddFilesToPackage add-ons kernel busses agp_gart : <agp_gart>intel@x86,x86_64 ;
|
||||||
|
|
||||||
AddFilesToPackage add-ons kernel busses ata
|
AddFilesToPackage add-ons kernel busses ata
|
||||||
: generic_ide_pci it8211 legacy_sata silicon_image_3112 ide_isa@x86 ;
|
: generic_ide_pci it8211 legacy_sata silicon_image_3112 highpoint_ide_pci ide_isa@x86 ;
|
||||||
|
|
||||||
AddFilesToPackage add-ons kernel busses scsi : ahci virtio_scsi ;
|
AddFilesToPackage add-ons kernel busses scsi : ahci virtio_scsi ;
|
||||||
AddFilesToPackage add-ons kernel busses usb : <usb>uhci <usb>ohci <usb>ehci ;
|
AddFilesToPackage add-ons kernel busses usb : <usb>uhci <usb>ohci <usb>ehci ;
|
||||||
@@ -168,6 +168,7 @@ AddBootModuleSymlinksToPackage
|
|||||||
openpic@ppc
|
openpic@ppc
|
||||||
ata_adapter@ata locked_pool scsi_periph
|
ata_adapter@ata locked_pool scsi_periph
|
||||||
ahci generic_ide_pci it8211 legacy_sata silicon_image_3112
|
ahci generic_ide_pci it8211 legacy_sata silicon_image_3112
|
||||||
|
highpoint_ide_pci
|
||||||
ide_isa@x86
|
ide_isa@x86
|
||||||
<usb>uhci <usb>ohci <usb>ehci
|
<usb>uhci <usb>ohci <usb>ehci
|
||||||
scsi_cd scsi_disk usb_disk
|
scsi_cd scsi_disk usb_disk
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel busses ata ;
|
SubDir HAIKU_TOP src add-ons kernel busses ata ;
|
||||||
|
|
||||||
SubInclude HAIKU_TOP src add-ons kernel busses ata generic_ide_pci ;
|
SubInclude HAIKU_TOP src add-ons kernel busses ata generic_ide_pci ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel busses ata highpoint_ide_pci ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel busses ata ide_isa ;
|
SubInclude HAIKU_TOP src add-ons kernel busses ata ide_isa ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel busses ata it8211 ;
|
SubInclude HAIKU_TOP src add-ons kernel busses ata it8211 ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel busses ata promise_tx2 ;
|
SubInclude HAIKU_TOP src add-ons kernel busses ata promise_tx2 ;
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel busses ata highpoint_ide_pci ;
|
||||||
|
|
||||||
|
UsePrivateHeaders drivers kernel ;
|
||||||
|
|
||||||
|
KernelAddon highpoint_ide_pci :
|
||||||
|
highpoint_ide_pci.cpp
|
||||||
|
;
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017, Alexander Coers. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _HIGHPOINT_ATA_H
|
||||||
|
#define _HIGHPOINT_ATA_H
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ATA_MWORD_DMA0 = 0x00,
|
||||||
|
ATA_MWORD_DMA1 = 0x01,
|
||||||
|
ATA_MWORD_DMA2 = 0x02,
|
||||||
|
ATA_ULTRA_DMA0 = 0x10,
|
||||||
|
ATA_ULTRA_DMA1 = 0x11,
|
||||||
|
ATA_ULTRA_DMA2 = 0x12,
|
||||||
|
ATA_ULTRA_DMA3 = 0x13,
|
||||||
|
ATA_ULTRA_DMA4 = 0x14,
|
||||||
|
ATA_ULTRA_DMA5 = 0x15,
|
||||||
|
ATA_ULTRA_DMA6 = 0x16
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CFG_HPT366_OLD,
|
||||||
|
CFG_HPT366,
|
||||||
|
CFG_HPT370,
|
||||||
|
CFG_HPT372,
|
||||||
|
CFG_HPT374,
|
||||||
|
CFG_HPTUnknown // no supported option found
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ATA_HIGHPOINT_ID 0x1103
|
||||||
|
|
||||||
|
#define ATA_HPT366 0x0004
|
||||||
|
#define ATA_HPT372 0x0005
|
||||||
|
#define ATA_HPT302 0x0006
|
||||||
|
#define ATA_HPT371 0x0007
|
||||||
|
#define ATA_HPT374 0x0008
|
||||||
|
|
||||||
|
struct HPT_controller_info {
|
||||||
|
uint16 deviceID;
|
||||||
|
uint8 revisionID;
|
||||||
|
uint8 function;
|
||||||
|
bool configuredDMA; // is DMA already configured
|
||||||
|
int configOption; // some HPT devices need different settings
|
||||||
|
uint8 maxDMA; // see enum
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _HIGHPOINT_ATA_H
|
||||||
@@ -0,0 +1,444 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017, Alexander Coers. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#include "highpoint_ata.h"
|
||||||
|
|
||||||
|
#include <ata_adapter.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define TRACE(a...) dprintf("Highpoint-IDE: " a)
|
||||||
|
|
||||||
|
//#define TRACE_EXT_HIGHPOINT
|
||||||
|
#ifdef TRACE_EXT_HIGHPOINT
|
||||||
|
#define TRACE_EXT(a...) dprintf("Highpoint-IDE (ext): " a)
|
||||||
|
#else
|
||||||
|
#define TRACE_EXT(a...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define HIGHPOINT_IDE_PCI_CONTROLLER_MODULE_NAME "busses/ata/highpoint_ide_pci/driver_v1"
|
||||||
|
#define HIGHPOINT_IDE_PCI_CHANNEL_MODULE_NAME "busses/ata/highpoint_ide_pci/channel/v1"
|
||||||
|
|
||||||
|
|
||||||
|
static ata_for_controller_interface *sATA;
|
||||||
|
static ata_adapter_interface *sATAAdapter;
|
||||||
|
static device_manager_info *sDeviceManager;
|
||||||
|
|
||||||
|
struct HPT_controller_info *HPT_info;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - helper functions
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_channel(void *cookie, ata_channel channel)
|
||||||
|
{
|
||||||
|
TRACE_EXT("set_channel()\n");
|
||||||
|
|
||||||
|
sATAAdapter->set_channel((ata_adapter_channel_info *)cookie, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
write_command_block_regs(void *channel_cookie, ata_task_file *tf,
|
||||||
|
ata_reg_mask mask)
|
||||||
|
{
|
||||||
|
TRACE_EXT("write_command_block_regs()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->write_command_block_regs(
|
||||||
|
(ata_adapter_channel_info *)channel_cookie, tf, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
read_command_block_regs(void *channel_cookie, ata_task_file *tf,
|
||||||
|
ata_reg_mask mask)
|
||||||
|
{
|
||||||
|
TRACE_EXT("read_command_block_regs()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->read_command_block_regs(
|
||||||
|
(ata_adapter_channel_info *)channel_cookie, tf, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8
|
||||||
|
get_altstatus(void *channel_cookie)
|
||||||
|
{
|
||||||
|
TRACE_EXT("get_altstatus()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->get_altstatus(
|
||||||
|
(ata_adapter_channel_info *)channel_cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
write_device_control(void *channel_cookie, uint8 val)
|
||||||
|
{
|
||||||
|
TRACE_EXT("write_device_control()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->write_device_control(
|
||||||
|
(ata_adapter_channel_info *)channel_cookie, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
write_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit)
|
||||||
|
{
|
||||||
|
TRACE_EXT("write_pio()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->write_pio((ata_adapter_channel_info *)channel_cookie,
|
||||||
|
data, count, force_16bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
read_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit)
|
||||||
|
{
|
||||||
|
TRACE_EXT("read_pio()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->read_pio((ata_adapter_channel_info *)channel_cookie,
|
||||||
|
data, count, force_16bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
prepare_dma(void *channel_cookie, const physical_entry *sg_list,
|
||||||
|
size_t sg_list_count, bool to_device)
|
||||||
|
{
|
||||||
|
TRACE_EXT("prepare_dma()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->prepare_dma((ata_adapter_channel_info *)channel_cookie,
|
||||||
|
sg_list, sg_list_count, to_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
start_dma(void *channel_cookie)
|
||||||
|
{
|
||||||
|
TRACE_EXT("start_dma()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->start_dma((ata_adapter_channel_info *)channel_cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
finish_dma(void *channel_cookie)
|
||||||
|
{
|
||||||
|
TRACE_EXT("finish_dma()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->finish_dma((ata_adapter_channel_info *)channel_cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
init_channel(device_node *node, void **channel_cookie)
|
||||||
|
{
|
||||||
|
status_t result;
|
||||||
|
uint8 channel_index;
|
||||||
|
|
||||||
|
TRACE("init_channel(): node: %p, cookie: %p\n", node, channel_cookie);
|
||||||
|
|
||||||
|
#if 0 /* debug */
|
||||||
|
uint8 bus = 0, device = 0, function = 0;
|
||||||
|
uint16 vendorID=0xffff, deviceID=0xffff;
|
||||||
|
sDeviceManager->get_attr_uint16(node, B_DEVICE_VENDOR_ID, &vendorID, true);
|
||||||
|
sDeviceManager->get_attr_uint16(node, B_DEVICE_ID, &deviceID, true);
|
||||||
|
TRACE("init_channel():init_channel(): bus %3d, device %2d, function %2d: vendor %04x, device %04x\n",
|
||||||
|
bus, device, function, vendorID, deviceID);
|
||||||
|
if (vendorID != ATA_HIGHPOINT_ID) {
|
||||||
|
TRACE ("unsupported! Vendor ID: %x\n",vendorID);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
result = sATAAdapter->init_channel(node,
|
||||||
|
(ata_adapter_channel_info **)channel_cookie,
|
||||||
|
sizeof(ata_adapter_channel_info), sATAAdapter->inthand);
|
||||||
|
// from here we have valid channel...
|
||||||
|
ata_adapter_channel_info *channel=NULL;
|
||||||
|
channel = (ata_adapter_channel_info *)*channel_cookie;
|
||||||
|
|
||||||
|
if (sDeviceManager->get_attr_uint8(node, ATA_ADAPTER_CHANNEL_INDEX,
|
||||||
|
&channel_index, false) != B_OK) {
|
||||||
|
TRACE("init_channel(): channel not set, strange!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("init_channel(): channel command %x, control %x, result: %d \n", channel->command_block_base,channel->control_block_base, (int)result);
|
||||||
|
TRACE("init_channel(): index #%d done. HPT_info deviceID: %04x, config option %x, revision %2d, function %2d \n", channel_index, HPT_info->deviceID, HPT_info->configOption, HPT_info->revisionID, HPT_info->function);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
uninit_channel(void *channel_cookie)
|
||||||
|
{
|
||||||
|
TRACE("uninit_channel()\n");
|
||||||
|
|
||||||
|
sATAAdapter->uninit_channel((ata_adapter_channel_info *)channel_cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
channel_removed(void *channel_cookie)
|
||||||
|
{
|
||||||
|
TRACE("channel_removed()\n");
|
||||||
|
|
||||||
|
sATAAdapter->channel_removed((ata_adapter_channel_info *)channel_cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
init_controller(device_node *node, ata_adapter_controller_info **cookie)
|
||||||
|
{
|
||||||
|
pci_device_module_info *pci;
|
||||||
|
pci_device *pci_device;
|
||||||
|
pci_info info;
|
||||||
|
uint16 devID = 0xffff;
|
||||||
|
uint8 revisionID = 0xff;
|
||||||
|
uint8 function = 0xff;
|
||||||
|
|
||||||
|
status_t result;
|
||||||
|
|
||||||
|
// we need some our info structure here
|
||||||
|
HPT_info = (struct HPT_controller_info *) malloc(sizeof(HPT_controller_info));
|
||||||
|
if (HPT_info == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
result = sATAAdapter->init_controller(node, cookie,
|
||||||
|
sizeof(ata_adapter_controller_info));
|
||||||
|
|
||||||
|
if (result == B_OK) {
|
||||||
|
// get device info
|
||||||
|
device_node *parent = sDeviceManager->get_parent_node(node);
|
||||||
|
sDeviceManager->get_driver(parent, (driver_module_info **)&pci, (void **)&pci_device);
|
||||||
|
// read registers
|
||||||
|
pci->get_pci_info(pci_device,&info);
|
||||||
|
devID = info.device_id;
|
||||||
|
revisionID = info.revision;
|
||||||
|
function = info.function;
|
||||||
|
|
||||||
|
HPT_info->deviceID = devID;
|
||||||
|
HPT_info->revisionID = revisionID;
|
||||||
|
HPT_info->function = function;
|
||||||
|
|
||||||
|
TRACE("init_controller(): found: device: %x, revision: %x, function: %x\n",devID,revisionID,function);
|
||||||
|
|
||||||
|
// setting different config options
|
||||||
|
if (devID == ATA_HPT366) {
|
||||||
|
switch (revisionID) {
|
||||||
|
case 0:
|
||||||
|
HPT_info->configOption = CFG_HPT366_OLD;
|
||||||
|
HPT_info->maxDMA = ATA_ULTRA_DMA4;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
HPT_info->configOption = CFG_HPT366;
|
||||||
|
HPT_info->maxDMA = ATA_ULTRA_DMA4;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
HPT_info->configOption = CFG_HPT370;
|
||||||
|
HPT_info->maxDMA = ATA_ULTRA_DMA5;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
HPT_info->configOption = CFG_HPT372;
|
||||||
|
HPT_info->maxDMA = ATA_ULTRA_DMA6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
HPT_info->configOption = CFG_HPTUnknown;
|
||||||
|
HPT_info->maxDMA = ATA_ULTRA_DMA0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (devID == ATA_HPT374) {
|
||||||
|
HPT_info->configOption = CFG_HPT374;
|
||||||
|
HPT_info->maxDMA = ATA_ULTRA_DMA6;
|
||||||
|
} else {
|
||||||
|
// all other versions use this config
|
||||||
|
HPT_info->configOption = CFG_HPT372;
|
||||||
|
HPT_info->maxDMA = ATA_ULTRA_DMA6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HPT_info->configOption == CFG_HPT366_OLD) {
|
||||||
|
/* disable interrupt prediction */
|
||||||
|
pci->write_pci_config(pci_device, 0x51, 1, (pci->read_pci_config(pci_device, 0x51, 1) & ~0x80));
|
||||||
|
TRACE("Highpoint-ATA: old revision found.\n");
|
||||||
|
} else {
|
||||||
|
/* disable interrupt prediction */
|
||||||
|
pci->write_pci_config(pci_device, 0x51, 1, (pci->read_pci_config(pci_device, 0x51, 1) & ~0x03));
|
||||||
|
pci->write_pci_config(pci_device, 0x55, 1, (pci->read_pci_config(pci_device, 0x55, 1) & ~0x03));
|
||||||
|
|
||||||
|
/* enable interrupts */
|
||||||
|
pci->write_pci_config(pci_device, 0x5a, 1, (pci->read_pci_config(pci_device, 0x5a, 1) & ~0x10));
|
||||||
|
|
||||||
|
/* set clocks etc */
|
||||||
|
if (HPT_info->configOption < CFG_HPT372) {
|
||||||
|
pci->write_pci_config(pci_device, 0x5b, 1, 0x22);
|
||||||
|
} else {
|
||||||
|
pci->write_pci_config(pci_device, 0x5b, 1,
|
||||||
|
(pci->read_pci_config(pci_device, 0x5b, 1) & 0x01) | 0x20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
uninit_controller(ata_adapter_controller_info *controller)
|
||||||
|
{
|
||||||
|
TRACE("uninit_controller()\n");
|
||||||
|
free(HPT_info);
|
||||||
|
sATAAdapter->uninit_controller(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
controller_removed(ata_adapter_controller_info *controller)
|
||||||
|
{
|
||||||
|
TRACE("controller_removed()\n");
|
||||||
|
|
||||||
|
return sATAAdapter->controller_removed(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
probe_controller(device_node *parent)
|
||||||
|
{
|
||||||
|
status_t result;
|
||||||
|
result = sATAAdapter->probe_controller(parent,
|
||||||
|
HIGHPOINT_IDE_PCI_CONTROLLER_MODULE_NAME, "highpoint_ide_pci",
|
||||||
|
"Highpoint IDE PCI Controller",
|
||||||
|
HIGHPOINT_IDE_PCI_CHANNEL_MODULE_NAME,
|
||||||
|
true,
|
||||||
|
true, // assume that command queuing works
|
||||||
|
1, // assume 16 bit alignment is enough
|
||||||
|
0xffff, // boundary is on 64k according to spec
|
||||||
|
0x10000, // up to 64k per S/G block according to spec
|
||||||
|
false); // by default, compatibility mode is used, not for HPT!
|
||||||
|
|
||||||
|
TRACE("probe_controller(): probe result: %x\n",(int)result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static float
|
||||||
|
supports_device(device_node *parent)
|
||||||
|
{
|
||||||
|
TRACE("supports_device()\n");
|
||||||
|
|
||||||
|
const char *bus;
|
||||||
|
uint16 baseClass, subClass;
|
||||||
|
uint16 vendorID;
|
||||||
|
uint16 deviceID;
|
||||||
|
float result = -1.0f;
|
||||||
|
|
||||||
|
// make sure parent is an PCI IDE mass storage host adapter device node
|
||||||
|
if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK
|
||||||
|
|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &baseClass, false) != B_OK
|
||||||
|
|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subClass, false) != B_OK
|
||||||
|
|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_VENDOR_ID, &vendorID, false) != B_OK
|
||||||
|
|| sDeviceManager->get_attr_uint16(parent, B_DEVICE_ID, &deviceID, false) != B_OK)
|
||||||
|
return -1.0f;
|
||||||
|
|
||||||
|
// No PCI bus OR no mass storage OR no Highpoint device = bail out
|
||||||
|
if (vendorID != ATA_HIGHPOINT_ID) {
|
||||||
|
TRACE("supports_device(): unsupported device: vendor ID: %x, deviceID: %x\n",vendorID, deviceID);
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if mass storage controller
|
||||||
|
if ((subClass == PCI_ide) || (subClass == PCI_mass_storage_other)) {
|
||||||
|
switch (deviceID) {
|
||||||
|
case ATA_HPT302:
|
||||||
|
// UDMA 6
|
||||||
|
case ATA_HPT366:
|
||||||
|
// UDMA 4, Rev 0 & 2
|
||||||
|
// UDMA 5, Rev 3
|
||||||
|
// UDMA 6, Rev 5
|
||||||
|
case ATA_HPT371:
|
||||||
|
case ATA_HPT372:
|
||||||
|
case ATA_HPT374:
|
||||||
|
// UDMA 6
|
||||||
|
result = 1.0f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// device not supported, should be covered by generic ata driver
|
||||||
|
result = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("supports_device(): supporting device Vendor ID: %x, deviceID: %x, result %f\n", vendorID, deviceID, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark - module dependencies
|
||||||
|
|
||||||
|
module_dependency module_dependencies[] = {
|
||||||
|
{ ATA_FOR_CONTROLLER_MODULE_NAME, (module_info **)&sATA },
|
||||||
|
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager },
|
||||||
|
{ ATA_ADAPTER_MODULE_NAME, (module_info **)&sATAAdapter },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static ata_controller_interface channel_interface = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
HIGHPOINT_IDE_PCI_CHANNEL_MODULE_NAME,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
|
||||||
|
NULL, // supports device
|
||||||
|
NULL, // register device
|
||||||
|
init_channel,
|
||||||
|
uninit_channel,
|
||||||
|
NULL, // register child devices
|
||||||
|
NULL, // rescan
|
||||||
|
channel_removed,
|
||||||
|
},
|
||||||
|
|
||||||
|
&set_channel,
|
||||||
|
|
||||||
|
&write_command_block_regs,
|
||||||
|
&read_command_block_regs,
|
||||||
|
|
||||||
|
&get_altstatus,
|
||||||
|
&write_device_control,
|
||||||
|
|
||||||
|
&write_pio,
|
||||||
|
&read_pio,
|
||||||
|
|
||||||
|
&prepare_dma,
|
||||||
|
&start_dma,
|
||||||
|
&finish_dma,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static driver_module_info controller_interface = {
|
||||||
|
{
|
||||||
|
HIGHPOINT_IDE_PCI_CONTROLLER_MODULE_NAME,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
|
||||||
|
supports_device,
|
||||||
|
probe_controller,
|
||||||
|
(status_t (*)(device_node *, void **)) init_controller,
|
||||||
|
(void (*)(void *)) uninit_controller,
|
||||||
|
NULL, // register child devices
|
||||||
|
NULL, // rescan
|
||||||
|
(void (*)(void *)) controller_removed,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_info *modules[] = {
|
||||||
|
(module_info *)&controller_interface,
|
||||||
|
(module_info *)&channel_interface,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user