2004-06-07 03:52:08 +04:00
|
|
|
/*
|
2007-11-06 05:26:44 +03:00
|
|
|
* Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
2005-01-12 02:19:41 +03:00
|
|
|
* Copyright 2002-04, Thomas Kurschel. All rights reserved.
|
|
|
|
*
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
|
|
|
#ifndef _IDE_PCI_H
|
|
|
|
#define _IDE_PCI_H
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
IDE adapter library
|
|
|
|
|
|
|
|
Module to simplify writing an IDE adapter driver.
|
2007-11-06 05:26:44 +03:00
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
The interface is not very abstract, i.e. the actual driver is
|
|
|
|
free to access any controller or channel data of this library.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <bus/PCI.h>
|
|
|
|
#include <bus/IDE.h>
|
2007-09-28 18:53:42 +04:00
|
|
|
#include <ide_types.h>
|
2004-06-07 03:52:08 +04:00
|
|
|
#include <device_manager.h>
|
|
|
|
|
|
|
|
|
|
|
|
// one Physical Region Descriptor (PRD)
|
2008-05-26 20:52:27 +04:00
|
|
|
// (one region must not cross 64K boundary;
|
2004-06-07 03:52:08 +04:00
|
|
|
// the PRD table must not cross a 64K boundary)
|
|
|
|
typedef struct prd_entry {
|
|
|
|
uint32 address; // physical address of block (must be even)
|
|
|
|
uint16 count; // size of block, 0 stands for 65536 (must be even)
|
|
|
|
uint8 res6;
|
|
|
|
LBITFIELD8_2(
|
|
|
|
res7_0 : 7,
|
|
|
|
EOT : 1 // 1 for last entry
|
|
|
|
);
|
|
|
|
} prd_entry;
|
|
|
|
|
2007-11-06 05:26:44 +03:00
|
|
|
// IDE bus master command register
|
|
|
|
#define IDE_BM_COMMAND_START_STOP 0x01
|
|
|
|
#define IDE_BM_COMMAND_READ_FROM_DEVICE 0x08
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2007-11-06 05:26:44 +03:00
|
|
|
// IDE bus master status register
|
|
|
|
#define IDE_BM_STATUS_ACTIVE 0x01
|
|
|
|
#define IDE_BM_STATUS_ERROR 0x02
|
|
|
|
#define IDE_BM_STATUS_INTERRUPT 0x04
|
|
|
|
#define IDE_BM_STATUS_MASTER_DMA 0x20
|
|
|
|
#define IDE_BM_STATUS_SLAVE_DMA 0x40
|
|
|
|
#define IDE_BM_STATUS_SIMPLEX_DMA 0x80
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// offset of bus master registers
|
|
|
|
enum {
|
2007-11-06 05:26:44 +03:00
|
|
|
IDE_BM_COMMAND_REG = 0,
|
|
|
|
IDE_BM_STATUS_REG = 2,
|
|
|
|
IDE_BM_PRDT_ADDRESS = 4
|
|
|
|
// offset of PRDT register; content must be dword-aligned
|
2004-06-07 03:52:08 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
// bit mask in class_api of PCI configuration
|
|
|
|
// (for adapters that can run in compatability mode)
|
|
|
|
enum {
|
2007-11-06 05:26:44 +03:00
|
|
|
IDE_API_PRIMARY_NATIVE = 1, // primary channel is in native mode
|
|
|
|
IDE_API_PRIMARY_FIXED = 2, // primary channel can be switched to native mode
|
|
|
|
IDE_API_SECONDARY_NATIVE = 4, // secondary channel is in native mode
|
|
|
|
IDE_API_SECONDARY_FIXED = 8 // secondary channel can be switched to native mode
|
2004-06-07 03:52:08 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// (maximum) size of S/G table
|
|
|
|
// there are so many restrictions that we want to keep it inside one page
|
|
|
|
// to be sure that we fulfill them all
|
|
|
|
#define IDE_ADAPTER_MAX_SG_COUNT (B_PAGE_SIZE / sizeof( prd_entry ))
|
|
|
|
|
|
|
|
|
|
|
|
// channel node items
|
|
|
|
// io address of command block (uint16)
|
|
|
|
#define IDE_ADAPTER_COMMAND_BLOCK_BASE "ide_adapter/command_block_base"
|
|
|
|
// io address of control block (uint16)
|
|
|
|
#define IDE_ADAPTER_CONTROL_BLOCK_BASE "ide_adapter/control_block_base"
|
|
|
|
// interrupt number (uint8)
|
|
|
|
// can also be defined in controller node if both channels use same IRQ!
|
|
|
|
#define IDE_ADAPTER_INTNUM "ide_adapter/irq"
|
2008-01-01 23:31:14 +03:00
|
|
|
// 0 if primary channel, 1 if secondary channel, 2 if tertiary, ... (uint8)
|
|
|
|
#define IDE_ADAPTER_CHANNEL_INDEX "ide_adapter/channel_index"
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// controller node items
|
|
|
|
// io address of bus master registers (uint16)
|
|
|
|
#define IDE_ADAPTER_BUS_MASTER_BASE "ide_adapter/bus_master_base"
|
|
|
|
|
|
|
|
|
|
|
|
// info about one channel
|
|
|
|
typedef struct ide_adapter_channel_info {
|
|
|
|
pci_device_module_info *pci;
|
2008-05-26 20:52:27 +04:00
|
|
|
pci_device *device;
|
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
uint16 command_block_base; // io address command block
|
|
|
|
uint16 control_block_base; // io address control block
|
|
|
|
uint16 bus_master_base;
|
2008-05-26 20:52:27 +04:00
|
|
|
int intnum; // interrupt number
|
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
uint32 lost; // != 0 if device got removed, i.e. if it must not
|
|
|
|
// be accessed anymore
|
2008-05-26 20:52:27 +04:00
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
ide_channel ide_channel;
|
2008-05-26 20:52:27 +04:00
|
|
|
device_node *node;
|
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
int32 (*inthand)( void *arg );
|
2008-05-26 20:52:27 +04:00
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
area_id prd_area;
|
|
|
|
prd_entry *prdt;
|
|
|
|
uint32 prdt_phys;
|
|
|
|
uint32 dmaing;
|
|
|
|
} ide_adapter_channel_info;
|
|
|
|
|
|
|
|
|
|
|
|
// info about controller
|
|
|
|
typedef struct ide_adapter_controller_info {
|
|
|
|
pci_device_module_info *pci;
|
2008-05-26 20:52:27 +04:00
|
|
|
pci_device *device;
|
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
uint16 bus_master_base;
|
2008-05-26 20:52:27 +04:00
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
uint32 lost; // != 0 if device got removed, i.e. if it must not
|
|
|
|
// be accessed anymore
|
2008-05-26 20:52:27 +04:00
|
|
|
|
|
|
|
device_node *node;
|
2004-06-07 03:52:08 +04:00
|
|
|
} ide_adapter_controller_info;
|
|
|
|
|
|
|
|
|
|
|
|
// interface of IDE adapter library
|
|
|
|
typedef struct {
|
2005-01-12 02:19:41 +03:00
|
|
|
module_info info;
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2008-05-26 20:52:27 +04:00
|
|
|
void (*set_channel)(ide_adapter_channel_info *channel,
|
|
|
|
ide_channel ideChannel);
|
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
// function calls that can be forwarded from actual driver
|
2005-01-12 02:19:41 +03:00
|
|
|
status_t (*write_command_block_regs)(ide_adapter_channel_info *channel,
|
|
|
|
ide_task_file *tf, ide_reg_mask mask);
|
|
|
|
status_t (*read_command_block_regs)(ide_adapter_channel_info *channel,
|
|
|
|
ide_task_file *tf, ide_reg_mask mask);
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
uint8 (*get_altstatus) (ide_adapter_channel_info *channel);
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*write_device_control) (ide_adapter_channel_info *channel, uint8 val);
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2005-01-12 02:19:41 +03:00
|
|
|
status_t (*write_pio)(ide_adapter_channel_info *channel, uint16 *data, int count, bool force_16bit);
|
|
|
|
status_t (*read_pio)(ide_adapter_channel_info *channel, uint16 *data, int count, bool force_16bit);
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2005-01-12 02:19:41 +03:00
|
|
|
status_t (*prepare_dma)(ide_adapter_channel_info *channel, const physical_entry *sg_list,
|
|
|
|
size_t sg_list_count, bool to_device);
|
2004-06-07 03:52:08 +04:00
|
|
|
status_t (*start_dma)(ide_adapter_channel_info *channel);
|
|
|
|
status_t (*finish_dma)(ide_adapter_channel_info *channel);
|
2005-01-12 02:19:41 +03:00
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
// default functions that should be replaced by a more specific version
|
|
|
|
// (copy them from source code of this library and modify them at will)
|
2005-01-12 02:19:41 +03:00
|
|
|
int32 (*inthand)(void *arg);
|
|
|
|
|
2004-06-07 03:52:08 +04:00
|
|
|
// functions that must be called by init/uninit etc. of channel driver
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*init_channel)(device_node *node,
|
2005-01-12 02:19:41 +03:00
|
|
|
ide_adapter_channel_info **cookie, size_t total_data_size,
|
|
|
|
int32 (*inthand)(void *arg));
|
2008-05-26 20:52:27 +04:00
|
|
|
void (*uninit_channel)(ide_adapter_channel_info *channel);
|
|
|
|
void (*channel_removed)(ide_adapter_channel_info *channel);
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// publish channel node
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*publish_channel)(device_node *controller_node,
|
2005-01-12 02:19:41 +03:00
|
|
|
const char *channel_module_name, uint16 command_block_base,
|
|
|
|
uint16 control_block_base, uint8 intnum, bool can_dma,
|
2008-05-26 20:52:27 +04:00
|
|
|
uint8 channel_index, const char *name,
|
|
|
|
const io_resource *resources, device_node **node);
|
2004-06-07 03:52:08 +04:00
|
|
|
// verify channel configuration and publish node on success
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*detect_channel)(pci_device_module_info *pci, pci_device *pciDevice,
|
|
|
|
device_node *controller_node, const char *channel_module_name,
|
2005-01-12 02:19:41 +03:00
|
|
|
bool controller_can_dma, uint16 command_block_base,
|
|
|
|
uint16 control_block_base, uint16 bus_master_base,
|
2008-01-01 23:31:14 +03:00
|
|
|
uint8 intnum, uint8 channel_index, const char *name,
|
2008-05-26 20:52:27 +04:00
|
|
|
device_node **node, bool supports_compatibility_mode);
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// functions that must be called by init/uninit etc. of controller driver
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*init_controller)(device_node *node,
|
2005-01-12 02:19:41 +03:00
|
|
|
ide_adapter_controller_info **cookie, size_t total_data_size);
|
2008-05-26 20:52:27 +04:00
|
|
|
void (*uninit_controller)(ide_adapter_controller_info *controller);
|
|
|
|
void (*controller_removed)(ide_adapter_controller_info *controller);
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// publish controller node
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*publish_controller)(device_node *parent, uint16 bus_master_base,
|
|
|
|
io_resource *resources, const char *controller_driver,
|
2005-01-12 02:19:41 +03:00
|
|
|
const char *controller_driver_type, const char *controller_name,
|
|
|
|
bool can_dma, bool can_cq, uint32 dma_alignment, uint32 dma_boundary,
|
2008-05-26 20:52:27 +04:00
|
|
|
uint32 max_sg_block_size, device_node **node);
|
2004-06-07 03:52:08 +04:00
|
|
|
// verify controller configuration and publish node on success
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*detect_controller)(pci_device_module_info *pci, pci_device *pciDevice,
|
|
|
|
device_node *parent, uint16 bus_master_base,
|
2005-01-12 02:19:41 +03:00
|
|
|
const char *controller_driver, const char *controller_driver_type,
|
|
|
|
const char *controller_name, bool can_dma, bool can_cq,
|
|
|
|
uint32 dma_alignment, uint32 dma_boundary, uint32 max_sg_block_size,
|
2008-05-26 20:52:27 +04:00
|
|
|
device_node **node);
|
2004-06-07 03:52:08 +04:00
|
|
|
// standard master probe for controller that registers controller and channel nodes
|
2008-05-26 20:52:27 +04:00
|
|
|
status_t (*probe_controller)(device_node *parent, const char *controller_driver,
|
2005-01-12 02:19:41 +03:00
|
|
|
const char *controller_driver_type, const char *controller_name,
|
|
|
|
const char *channel_module_name, bool can_dma, bool can_cq,
|
|
|
|
uint32 dma_alignment, uint32 dma_boundary, uint32 max_sg_block_size,
|
|
|
|
bool supports_compatibility_mode);
|
2004-06-07 03:52:08 +04:00
|
|
|
} ide_adapter_interface;
|
|
|
|
|
|
|
|
|
|
|
|
#define IDE_ADAPTER_MODULE_NAME "generic/ide_adapter/v1"
|
|
|
|
|
2005-01-12 02:19:41 +03:00
|
|
|
#endif /* _IDE_PCI_H */
|