* Integration of the new driver architecture.

* Moved devfs from fs/ to device_manager/, and separated the legacy driver
  support from it.
* Removed fast_log module.
* There are a couple of (temporary) regressions, though:
  - legacy SATA and ISA IDE support is disabled, the drivers haven't been
    ported yet.
  - The not yet used ATA bus manager hasn't been ported yet, either.
  - AHCI changes have not been tested.
  - the listdev command has been removed from the build (as it currently
    doesn't work anymore).
  - device manager generated IDs currently are not freed anymore when a device
    node is removed.
  - generic drivers can't yet use the new driver architecture.
  - simple busses that do not support device types won't work yet.
  - legacy driver publishing/unpublishing (ie. what USB needs) has not been
    tested, and may be broken.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25662 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-05-26 16:52:27 +00:00
parent 113a13d83e
commit 368167ede8
85 changed files with 5993 additions and 7276 deletions
+7 -7
View File
@@ -33,7 +33,7 @@ BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat
funzip #fwcontrol
gawk $(X86_ONLY)gdb grep groups gzip gzexe hd head hey hostname id ident
ideinfo idestatus ifconfig <bin>install installsound iroster isvolume join
keymap kill less lessecho lesskey link listarea listattr listdev listimage
keymap kill less lessecho lesskey link listarea listattr listimage #listdev
listport listres listsem ln locate logger login logname ls lsindex m4 make
makebootable md5sum merge mimeset mkdos mkdir mkfifo mkfs mkindex modifiers mount
mount_nfs mountvolume mv nc netstat nl nohup od open passwd paste patch
@@ -145,7 +145,7 @@ AddFilesToHaikuImage beos system add-ons kernel bus_managers
AddFilesToHaikuImage beos system add-ons kernel busses agp_gart
: $(X86_ONLY)<agp_gart>intel ;
AddFilesToHaikuImage beos system add-ons kernel busses ide
: generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata ;
: generic_ide_pci ; #$(X86_ONLY)ide_isa silicon_image_3112 legacy_sata ;
AddFilesToHaikuImage beos system add-ons kernel busses scsi
: ahci ;
AddFilesToHaikuImage beos system add-ons kernel busses usb
@@ -156,7 +156,7 @@ AddFilesToHaikuImage beos system add-ons kernel debugger
AddFilesToHaikuImage beos system add-ons kernel file_systems
: $(BEOS_ADD_ONS_FILE_SYSTEMS) ;
AddFilesToHaikuImage beos system add-ons kernel generic
: block_io dpc fast_log ide_adapter locked_pool mpu401 scsi_periph ;
: block_io dpc ide_adapter locked_pool mpu401 scsi_periph ;
AddFilesToHaikuImage beos system add-ons kernel partitioning_systems
: intel session ;
AddFilesToHaikuImage beos system add-ons kernel interrupt_controllers
@@ -172,7 +172,7 @@ AddDriversToHaikuImage : console dprintf $(X86_ONLY)keyboard null
AddDriversToHaikuImage audio hmulti : $(BEOS_ADD_ONS_DRIVERS_AUDIO) ;
AddDriversToHaikuImage midi : $(BEOS_ADD_ONS_DRIVERS_MIDI) ;
AddDriversToHaikuImage bus : usb_raw ; # fw_raw
AddDriversToHaikuImage disk scsi : scsi_cd scsi_dsk ;
AddDriversToHaikuImage disk scsi : scsi_dsk ; #scsi_cd;
AddDriversToHaikuImage disk usb : usb_disk ;
AddDriversToHaikuImage disk virtual : nbd ;
AddDriversToHaikuImage dvb : cx23882 ;
@@ -358,9 +358,9 @@ AddFilesToHaikuImage beos system : zbeos ;
AddBootModuleSymlinksToHaikuImage
pci $(X86_ONLY)isa config_manager ide scsi
$(PPC_ONLY)openpic
block_io fast_log ide_adapter locked_pool scsi_periph
ahci generic_ide_pci $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata
scsi_cd scsi_dsk
block_io ide_adapter locked_pool scsi_periph
generic_ide_pci ahci # $(X86_ONLY)ide_isa silicon_image_3112 legacy_sata
scsi_dsk #scsi_cd
intel
bfs
;
+9 -7
View File
@@ -5,9 +5,7 @@
#ifndef __BLOCK_IO_H__
#define __BLOCK_IO_H__
/*
Part of Open block device manager
/*!
Block devices can be easily written by providing the interface
specified hereinafter. The block device manager takes care of
DMA and other restrictions imposed by underlying controller or
@@ -24,7 +22,6 @@ typedef struct block_io_device_info *block_io_device;
typedef struct block_io_handle_info *block_io_handle;
// cookies issued by device driver
typedef struct block_device_device_cookie *block_device_device_cookie;
typedef struct block_device_handle_cookie *block_device_handle_cookie;
@@ -59,15 +56,20 @@ typedef struct phys_vecs {
// maximum number of scatter/gather blocks (uint32, optional, default: unlimited)
#define B_BLOCK_DEVICE_MAX_SG_BLOCKS "block_device/max_sg_blocks"
typedef struct block_device_cookie {
struct device_node *node;
} block_device_cookie;
// interface to be provided by device driver
typedef struct block_device_interface {
driver_module_info info;
void (*set_device)(block_device_cookie *cookie, block_io_device device);
// iovecs are physical address here
// pos and num_blocks are in blocks; bytes_transferred in bytes
// vecs are guaranteed to describe enough data for given block count
status_t (*open)(block_device_device_cookie device, block_device_handle_cookie *handle);
status_t (*open)(block_device_cookie *cookie, block_device_handle_cookie *handle);
status_t (*close)(block_device_handle_cookie handle);
status_t (*free)(block_device_handle_cookie handle);
@@ -79,12 +81,12 @@ typedef struct block_device_interface {
status_t (*ioctl)(block_device_handle_cookie handle, int op, void *buf, size_t len);
} block_device_interface;
#define B_BLOCK_IO_MODULE_NAME "generic/block_io/v1"
#define B_BLOCK_IO_DEVICE_MODULE_NAME "generic/block_io/device_v1"
// Interface for Drivers
// blkman interface used for callbacks done by driver
// interface used for callbacks done by driver
typedef struct block_io_for_driver_interface {
module_info info;
+10 -16
View File
@@ -1,18 +1,11 @@
/*
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/*
Part of Open IDE bus manager
IDE bus manager interface
*/
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef __IDE_H__
#define __IDE_H__
#include <bus_manager.h>
#include <device_manager.h>
#include <KernelExport.h>
@@ -37,10 +30,15 @@
union ide_task_file;
typedef unsigned int ide_reg_mask;
// channel cookie, issued by ide bus manager
typedef struct ide_bus_info *ide_channel;
// interface of controller driver
typedef struct {
driver_module_info info;
void (*set_channel)(void *cookie, ide_channel channel);
status_t (*write_command_block_regs)
(void *channel_cookie, union ide_task_file *tf, ide_reg_mask mask);
status_t (*read_command_block_regs)
@@ -60,10 +58,6 @@ typedef struct {
} ide_controller_interface;
// channel cookie, issued by ide bus manager
typedef struct ide_bus_info *ide_channel;
// Interface for Controller Driver
// interface of bus manager as seen from controller driver
@@ -77,7 +71,7 @@ typedef struct {
} ide_for_controller_interface;
#define IDE_FOR_CONTROLLER_MODULE_NAME "bus_managers/ide/controller/v1"
#define IDE_FOR_CONTROLLER_MODULE_NAME "bus_managers/ide/controller/driver_v1"
#endif /* __IDE_H__ */
+9 -9
View File
@@ -35,17 +35,17 @@
#define B_MAX_ISA_DMA_COUNT 0x10000
typedef struct isa2_module_info {
bus_module_info info;
driver_module_info info;
uint8 (*read_io_8)( int mapped_io_addr );
void (*write_io_8)( int mapped_io_addr, uint8 value );
uint16 (*read_io_16)( int mapped_io_addr );
void (*write_io_16)( int mapped_io_addr, uint16 value );
uint32 (*read_io_32)( int mapped_io_addr );
void (*write_io_32)( int mapped_io_addr, uint32 value );
uint8 (*read_io_8)(int mapped_io_addr);
void (*write_io_8)(int mapped_io_addr, uint8 value);
uint16 (*read_io_16)(int mapped_io_addr);
void (*write_io_16)(int mapped_io_addr, uint16 value);
uint32 (*read_io_32)(int mapped_io_addr);
void (*write_io_32)(int mapped_io_addr, uint32 value);
// don't know what it's for, remains for compatibility
void *(*ram_address)( const void *physical_address_in_system_memory );
void *(*ram_address)(const void *physical_address_in_system_memory);
// start dma transfer (scattered DMA is not supported as it's EISA specific)
status_t (*start_isa_dma)(
@@ -64,4 +64,4 @@ typedef struct isa2_module_info {
#define ISA_DRIVERS_DIR "isa"
#endif
#endif /* _ISA2_H */
+26 -144
View File
@@ -1,164 +1,46 @@
/*
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
* Copyright 2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/*
PCI bus manager
*/
#ifndef _PCI2_H
#define _PCI2_H
#include <device_manager.h>
#include <PCI.h>
// currently, this structure is disabled to avoid collision with R5 header
#if 0
typedef struct pci_info {
ushort vendor_id; /* vendor id */
ushort device_id; /* device id */
uchar bus; /* bus number */
uchar device; /* device number on bus */
uchar function; /* function number in device */
uchar revision; /* revision id */
uchar class_api; /* specific register interface type */
uchar class_sub; /* specific device function */
uchar class_base; /* device type (display vs network, etc) */
uchar line_size; /* cache line size in 32 bit words */
uchar latency; /* latency timer */
uchar header_type; /* header type */
uchar bist; /* built-in self-test */
uchar reserved; /* filler, for alignment */
union {
struct {
ulong cardbus_cis; /* CardBus CIS pointer */
ushort subsystem_id; /* subsystem (add-in card) id */
ushort subsystem_vendor_id; /* subsystem (add-in card) vendor id */
ulong rom_base; /* rom base address, viewed from host */
ulong rom_base_pci; /* rom base addr, viewed from pci */
ulong rom_size; /* rom size */
ulong base_registers[6]; /* base registers, viewed from host */
ulong base_registers_pci[6]; /* base registers, viewed from pci */
ulong base_register_sizes[6]; /* size of what base regs point to */
uchar base_register_flags[6]; /* flags from base address fields */
uchar interrupt_line; /* interrupt line */
uchar interrupt_pin; /* interrupt pin */
uchar min_grant; /* burst period @ 33 Mhz */
uchar max_latency; /* how often PCI access needed */
} h0;
struct {
ulong base_registers[2]; /* base registers, viewed from host */
ulong base_registers_pci[2]; /* base registers, viewed from pci */
ulong base_register_sizes[2]; /* size of what base regs point to */
uchar base_register_flags[2]; /* flags from base address fields */
uchar primary_bus;
uchar secondary_bus;
uchar subordinate_bus;
uchar secondary_latency;
uchar io_base;
uchar io_limit;
ushort secondary_status;
ushort memory_base;
ushort memory_limit;
ushort prefetchable_memory_base;
ushort prefetchable_memory_limit;
ulong prefetchable_memory_base_upper32;
ulong prefetchable_memory_limit_upper32;
ushort io_base_upper16;
ushort io_limit_upper16;
ulong rom_base; /* rom base address, viewed from host */
ulong rom_base_pci; /* rom base addr, viewed from pci */
uchar interrupt_line; /* interrupt line */
uchar interrupt_pin; /* interrupt pin */
ushort bridge_control;
} h1;
} u;
} pci_info;
typedef struct pci_device pci_device;
#endif
typedef struct pci_device_info *pci_device;
// Interface to one PCI device.
// Actually, this is a _function_ of a device only, but
// pci_function_module_info would be a bit non-intuitive
typedef struct pci_device_module_info {
driver_module_info info;
uint8 (*read_io_8)(pci_device device, int mapped_io_addr);
void (*write_io_8)(pci_device device, int mapped_io_addr, uint8 value);
uint16 (*read_io_16)(pci_device device, int mapped_io_addr);
void (*write_io_16)(pci_device device, int mapped_io_addr, uint16 value);
uint32 (*read_io_32)(pci_device device, int mapped_io_addr);
void (*write_io_32)(pci_device device, int mapped_io_addr, uint32 value);
uint8 (*read_io_8)(pci_device *device, addr_t mappedIOAddress);
void (*write_io_8)(pci_device *device, addr_t mappedIOAddress,
uint8 value);
uint16 (*read_io_16)(pci_device *device, addr_t mappedIOAddress);
void (*write_io_16)(pci_device *device, addr_t mappedIOAddress,
uint16 value);
uint32 (*read_io_32)(pci_device *device, addr_t mappedIOAddress);
void (*write_io_32)(pci_device *device, addr_t mappedIOAddress,
uint32 value);
uint32 (*read_pci_config)(pci_device device,
uchar offset, /* offset in configuration space */
uchar size); /* # bytes to read (1, 2 or 4) */
void (*write_pci_config)(pci_device device,
uchar offset, /* offset in configuration space */
uchar size, /* # bytes to write (1, 2 or 4) */
uint32 value); /* value to write */
void *(*ram_address)(pci_device *device, const void *physicalAddress);
void *(*ram_address)(pci_device device, const void *physical_address_in_system_memory);
/* status_t (*allocate_iomem)( void *base, size_t len, const char *name );
status_t (*release_iomem)( void *base, size_t len );
status_t (*allocate_ioports)( uint16 ioport_base, size_t len, const char *name );
status_t (*release_ioports)( uint16 ioport_base, size_t len );*/
status_t (*get_pci_info)(pci_device device, struct pci_info *info);
status_t (*find_pci_capability)(pci_device device,
uchar cap_id,
uchar *offset);
uint32 (*read_pci_config)(pci_device *device, uint8 offset,
uint8 size);
void (*write_pci_config)(pci_device *device, uint8 offset,
uint8 size, uint32 value);
status_t (*find_pci_capability)(pci_device *device, uint8 capID,
uint8 *offset);
void (*get_pci_info)(pci_device *device, struct pci_info *info);
} pci_device_module_info;
// directory of PCI drivers
#define PCI_DRIVERS_DIR "pci"
/* Attributes of PCI device nodes */
#define B_PCI_DEVICE_DOMAIN "pci/domain" /* uint32 */
#define B_PCI_DEVICE_BUS "pci/bus" /* uint8 */
#define B_PCI_DEVICE_DEVICE "pci/device" /* uint8 */
#define B_PCI_DEVICE_FUNCTION "pci/function" /* uint8 */
// attributes of PCI device nodes
// bus idx (uint8)
#define PCI_DEVICE_BUS_ITEM "pci/bus"
// device idx (uint8)
#define PCI_DEVICE_DEVICE_ITEM "pci/device"
// function idx (uint8)
#define PCI_DEVICE_FUNCTION_ITEM "pci/function"
// vendor id (uint16)
#define PCI_DEVICE_VENDOR_ID_ITEM "pci/vendor_id"
// device id (uint16)
#define PCI_DEVICE_DEVICE_ID_ITEM "pci/device_id"
// subsystem id (uint16)
#define PCI_DEVICE_SUBSYSTEM_ID_ITEM "pci/subsystem_id"
// subvendor id (uint16)
#define PCI_DEVICE_SUBVENDOR_ID_ITEM "pci/subvendor_id"
// device base class (uint8)
#define PCI_DEVICE_BASE_CLASS_ID_ITEM "pci/class/base_id"
// device subclass (uint8)
#define PCI_DEVICE_SUB_CLASS_ID_ITEM "pci/class/sub_id"
// device api (uint8)
#define PCI_DEVICE_API_ID_ITEM "pci/class/api_id"
// dynamic consumer patterns for PCI devices
#define PCI_DEVICE_DYNAMIC_CONSUMER_0 \
PCI_DRIVERS_DIR "/" \
"vendor %" PCI_DEVICE_VENDOR_ID_ITEM "%|" \
", device %" PCI_DEVICE_DEVICE_ID_ITEM "%|" \
", subsystem %" PCI_DEVICE_SUBSYSTEM_ID_ITEM "%|" \
", subvendor %" PCI_DEVICE_SUBVENDOR_ID_ITEM "%"
#define PCI_DEVICE_DYNAMIC_CONSUMER_1 \
PCI_DRIVERS_DIR "/" \
"base_class %" PCI_DEVICE_BASE_CLASS_ID_ITEM "%|" \
", sub_class %" PCI_DEVICE_SUB_CLASS_ID_ITEM "%|" \
", api %" PCI_DEVICE_API_ID_ITEM "%"
#endif
#endif /* _PCI2_H */
+16 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2007, Haiku, Inc. All RightsReserved.
* Copyright 2004-2008, Haiku, Inc. All RightsReserved.
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
@@ -320,7 +320,7 @@ typedef struct scsi_device_interface {
status_t (*ioctl)(scsi_device device, uint32 op, void *buffer, size_t length);
} scsi_device_interface;
#define SCSI_DEVICE_MODULE_NAME "bus_managers/scsi/driver/v1"
#define SCSI_DEVICE_MODULE_NAME "bus_managers/scsi/device/driver_v1"
// Bus node
@@ -336,7 +336,7 @@ typedef struct scsi_device_interface {
// This interface can be used by peripheral drivers to access the
// bus directly.
typedef struct scsi_bus_interface {
bus_module_info info;
driver_module_info info;
// get information about host controller
uchar (*path_inquiry)(scsi_bus bus, scsi_path_inquiry *inquiry_data);
@@ -345,7 +345,7 @@ typedef struct scsi_bus_interface {
} scsi_bus_interface;
// name of SCSI bus node driver
#define SCSI_BUS_MODULE_NAME "bus_managers/scsi/bus/v1"
#define SCSI_BUS_MODULE_NAME "bus_managers/scsi/bus/driver_v1"
// Interface for SIM
@@ -404,7 +404,7 @@ typedef struct scsi_for_sim_interface {
} scsi_for_sim_interface;
#define SCSI_FOR_SIM_MODULE_NAME "bus_managers/scsi/sim/v1"
#define SCSI_FOR_SIM_MODULE_NAME "bus_managers/scsi/sim/driver_v1"
// SIM Node
@@ -416,34 +416,35 @@ typedef struct scsi_for_sim_interface {
// controller name (required, string)
#define SCSI_DESCRIPTION_CONTROLLER_NAME "controller_name"
typedef void * scsi_sim_cookie;
typedef void *scsi_sim_cookie;
// SIM interface
// SCSI controller drivers must provide this interface
typedef struct scsi_sim_interface {
driver_module_info info;
void (*set_scsi_bus)(scsi_sim_cookie cookie, scsi_bus bus);
// execute request
void (*scsi_io)( scsi_sim_cookie cookie, scsi_ccb *ccb );
void (*scsi_io)(scsi_sim_cookie cookie, scsi_ccb *ccb);
// abort request
uchar (*abort)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_abort );
uchar (*abort)(scsi_sim_cookie cookie, scsi_ccb *ccb_to_abort);
// reset device
uchar (*reset_device)( scsi_sim_cookie cookie, uchar target_id, uchar target_lun );
uchar (*reset_device)(scsi_sim_cookie cookie, uchar target_id, uchar target_lun);
// terminate request
uchar (*term_io)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_terminate );
uchar (*term_io)(scsi_sim_cookie cookie, scsi_ccb *ccb_to_terminate);
// get information about bus
uchar (*path_inquiry)( scsi_sim_cookie cookie, scsi_path_inquiry *inquiry_data );
uchar (*path_inquiry)(scsi_sim_cookie cookie, scsi_path_inquiry *inquiry_data);
// scan bus
// this is called immediately before the SCSI bus manager scans the bus
uchar (*scan_bus)( scsi_sim_cookie cookie );
uchar (*scan_bus)(scsi_sim_cookie cookie);
// reset bus
uchar (*reset_bus)( scsi_sim_cookie cookie );
uchar (*reset_bus)(scsi_sim_cookie cookie);
// get restrictions of one device
// (used for non-SCSI transport protocols and bug fixes)
void (*get_restrictions)(
scsi_sim_cookie cookie,
void (*get_restrictions)(scsi_sim_cookie cookie,
uchar target_id, // target id
bool *is_atapi, // set to true if this is an ATAPI device that
// needs some commands emulated
+103 -122
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2005, Haiku Inc. All Rights Reserved.
* Copyright 2004-2008, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef _DEVICE_MANAGER_H
@@ -11,189 +11,170 @@
#include <module.h>
// type of I/O resource
/* type of I/O resource */
enum {
IO_MEM = 1,
IO_PORT = 2,
ISA_DMA_CHANNEL = 3
B_IO_MEMORY = 1,
B_IO_PORT = 2,
B_ISA_DMA_CHANNEL = 3
};
// I/O resource description
/* I/O resource description */
typedef struct {
uint32 type;
// type of I/O resource
/* type of I/O resource */
uint32 base;
// I/O memory: first physical address (32 bit)
// I/O port: first port address (16 bit)
// ISA DMA channel: channel number (0-7)
/* I/O memory: first physical address (32 bit)
* I/O port: first port address (16 bit)
* ISA DMA channel: channel number (0-7)
*/
uint32 length;
// I/O memory: size of address range (32 bit)
// I/O port: size of port range (16 bit)
// ISA DMA channel: must be 1
/* I/O memory: size of address range (32 bit)
* I/O port: size of port range (16 bit)
* ISA DMA channel: must be 1
*/
} io_resource;
// attribute of a device node
/* attribute of a device node */
typedef struct {
const char *name;
type_code type; // for supported types, see value
type_code type; /* for supported types, see value */
union {
uint8 ui8; // B_UINT8_TYPE
uint16 ui16; // B_UINT16_TYPE
uint32 ui32; // B_UINT32_TYPE
uint64 ui64; // B_UINT64_TYPE
const char *string; // B_STRING_TYPE
struct { // B_RAW_TYPE
void *data;
uint8 ui8; /* B_UINT8_TYPE */
uint16 ui16; /* B_UINT16_TYPE */
uint32 ui32; /* B_UINT32_TYPE */
uint64 ui64; /* B_UINT64_TYPE */
const char *string; /* B_STRING_TYPE */
struct { /* B_RAW_TYPE */
const void *data;
size_t length;
} raw;
} value;
} device_attr;
typedef struct device_node_info *device_node_handle;
typedef struct io_resource_info *io_resource_handle;
typedef struct device_attr_info *device_attr_handle;
typedef struct device_node device_node;
typedef struct driver_module_info driver_module_info;
// interface of the device manager
/* interface of the device manager */
typedef struct device_manager_info {
module_info info;
status_t (*init_driver)(device_node_handle node, void *userCookie,
driver_module_info **interface, void **cookie);
status_t (*uninit_driver)(device_node_handle node);
status_t (*rescan_node)(device_node *node);
status_t (*rescan)(device_node_handle node);
status_t (*register_node)(device_node *parent, const char *moduleName,
const device_attr *attrs, const io_resource *ioResources,
device_node **_node);
status_t (*unregister_node)(device_node *node);
status_t (*register_device)(device_node_handle parent,
const device_attr *attrs,
const io_resource_handle *io_resources,
device_node_handle *node);
status_t (*unregister_device)(device_node_handle node);
status_t (*get_driver)(device_node *node, driver_module_info **_module,
void **_cookie);
device_node_handle (*get_root)();
status_t (*get_next_child_device)(device_node_handle parent,
device_node_handle *_node, const device_attr *attrs);
device_node_handle (*get_parent)(device_node_handle node);
void (*put_device_node)(device_node_handle node);
device_node *(*get_root_node)();
status_t (*get_next_child_node)(device_node *parent,
const device_attr *attrs, device_node **node);
device_node *(*get_parent_node)(device_node *node);
void (*put_node)(device_node *node);
status_t (*acquire_io_resources)(io_resource *resources,
io_resource_handle *handles);
status_t (*release_io_resources)(const io_resource_handle *handles);
status_t (*publish_device)(device_node *node, const char *path,
const char *deviceModuleName);
status_t (*unpublish_device)(device_node *node, const char *path);
int32 (*create_id)(const char *generator);
status_t (*free_id)(const char *generator, uint32 id);
status_t (*get_attr_uint8)(device_node_handle node,
const char *name, uint8 *value, bool recursive);
status_t (*get_attr_uint16)(device_node_handle node,
const char *name, uint16 *value, bool recursive);
status_t (*get_attr_uint32)(device_node_handle node,
const char *name, uint32 *value, bool recursive);
status_t (*get_attr_uint64)(device_node_handle node,
const char *name, uint64 *value, bool recursive);
status_t (*get_attr_string)(device_node_handle node,
const char *name, char **value, bool recursive);
status_t (*get_attr_raw)(device_node_handle node,
const char *name, void **data, size_t *_size,
bool recursive);
status_t (*get_attr_uint8)(const device_node *node, const char *name,
uint8 *value, bool recursive);
status_t (*get_attr_uint16)(const device_node *node, const char *name,
uint16 *value, bool recursive);
status_t (*get_attr_uint32)(const device_node *node, const char *name,
uint32 *value, bool recursive);
status_t (*get_attr_uint64)(const device_node *node, const char *name,
uint64 *value, bool recursive);
status_t (*get_attr_string)(const device_node *node, const char *name,
const char **_value, bool recursive);
status_t (*get_attr_raw)(const device_node *node, const char *name,
const void **_data, size_t *_size, bool recursive);
status_t (*get_next_attr)(device_node_handle node,
device_attr_handle *attrHandle);
status_t (*release_attr)(device_node_handle node,
device_attr_handle attr_handle);
status_t (*retrieve_attr)(device_attr_handle attr_handle,
const device_attr **attr);
status_t (*write_attr)(device_node_handle node,
const device_attr *attr);
status_t (*remove_attr)(device_node_handle node, const char *name);
status_t (*get_next_attr)(device_node *node, device_attr **_attr);
} device_manager_info;
#define B_DEVICE_MANAGER_MODULE_NAME "system/device_manager/v1"
// interface of device driver
/* interface of device driver */
struct driver_module_info {
module_info info;
float (*supports_device)(device_node_handle parent, bool *_noConnection);
status_t (*register_device)(device_node_handle parent);
float (*supports_device)(device_node *parent);
status_t (*register_device)(device_node *parent);
status_t (*init_driver)(device_node_handle node, void *user_cookie, void **_cookie);
status_t (*uninit_driver)(void *cookie);
status_t (*init_driver)(device_node *node, void **_driverCookie);
void (*uninit_driver)(void *driverCookie);
status_t (*register_child_devices)(void *driverCookie);
status_t (*rescan_child_devices)(void *driverCookie);
void (*device_removed)(device_node_handle node, void *cookie);
void (*device_cleanup)(device_node_handle node);
void (*get_supported_paths)(const char ***_busses, const char ***_devices);
void (*device_removed)(void *driverCookie);
status_t (*suspend)(void *driverCookie, int32 state);
status_t (*resume)(void *driverCookie);
};
// standard device node attributes
/* standard device node attributes */
#define PNP_MANAGER_ID_GENERATOR "id_generator"
// if you are using an id generator (see create_id), you can let the
// manager automatically free the id when the node is deleted by setting
// the following attributes:
// name of generator (string)
#define PNP_MANAGER_AUTO_ID "auto_id"
// generated id (uint32)
#define B_DEVICE_PRETTY_NAME "device/pretty name" /* string */
#define B_DEVICE_MAPPING "device/mapping" /* string */
#define B_DEVICE_BUS "device/bus" /* string */
#define B_DEVICE_FIXED_CHILD "device/fixed child" /* string */
#define B_DEVICE_FLAGS "device/flags" /* uint32 */
#define B_DRIVER_MODULE "driver/module"
#define B_DRIVER_PRETTY_NAME "driver/pretty name"
#define B_DRIVER_FIXED_CHILD "driver/fixed child"
#define B_DRIVER_MAPPING "driver/mapping"
#define B_DRIVER_BUS "driver/bus"
#define B_DRIVER_FIND_DEVICES_ON_DEMAND "driver/on demand"
#define B_DRIVER_EXPLORE_LAST "driver/explore last"
#define B_DEVICE_VENDOR_ID "device/vendor" /* uint16 */
#define B_DEVICE_ID "device/id" /* uint16 */
#define B_DEVICE_TYPE "device/type"
/* uint16, PCI base class */
#define B_DEVICE_SUB_TYPE "device/subtype"
/* uint16, PCI sub type */
#define B_DEVICE_INTERFACE "device/interface"
/* uint16, PCI class API */
#define B_DRIVER_UNIQUE_DEVICE_ID "unique id"
#define B_DRIVER_DEVICE_TYPE "device type"
#define B_DEVICE_UNIQUE_ID "device/unique id" /* string */
#define B_AUDIO_DRIVER_TYPE "audio"
#define B_BUS_DRIVER_TYPE "bus"
#define B_DISK_DRIVER_TYPE "disk"
#define B_GRAPHICS_DRIVER_TYPE "graphics"
#define B_INPUT_DRIVER_TYPE "input"
#define B_MISC_DRIVER_TYPE "misc"
#define B_NETWORK_DRIVER_TYPE "net"
#define B_VIDEO_DRIVER_TYPE "video"
#define B_INTERRUPT_CONTROLLER_DRIVER_TYPE "interrupt controller"
#define PNP_DRIVER_CONNECTION "connection"
// connection of parent the device is attached to (optional, string)
// there can be only one device per connection
/* device flags */
#define B_FIND_CHILD_ON_DEMAND 0x01
#define B_FIND_MULTIPLE_CHILDREN 0x02
#define B_KEEP_DRIVER_LOADED 0x04
// interface of a bus device driver
/* interface of device */
typedef struct bus_module_info {
driver_module_info info;
typedef struct io_request io_request;
// scan the bus and register all devices.
status_t (*register_child_devices)(void *cookie);
struct device_module_info {
module_info info;
// user initiated rescan of the bus - only propagate changes
// you only need to implement this, if you cannot detect device changes yourself
// driver is always loaded during this call, but other hooks may
// be called concurrently
status_t (*rescan_bus)(void *cookie);
} bus_module_info;
status_t (*init_device)(void *driverCookie, void **_deviceCookie);
void (*uninit_device)(void *deviceCookie);
void (*device_removed)(void *deviceCookie);
status_t (*open)(void *deviceCookie, const char *path, int openMode,
void **_cookie);
status_t (*close)(void *cookie);
status_t (*free)(void *cookie);
status_t (*read)(void *cookie, off_t pos, void *buffer, size_t *_length);
status_t (*write)(void *cookie, off_t pos, const void *buffer,
size_t *_length);
status_t (*io)(void *cookie, io_request *request);
status_t (*control)(void *cookie, uint32 op, void *buffer, size_t length);
status_t (*select)(void *cookie, uint8 event, selectsync *sync);
status_t (*deselect)(void *cookie, uint8 event, selectsync *sync);
};
// standard attributes
// PnP bus identification (required, uint8)
// define this to let the PnP manager know that this is a PnP bus
// the actual content is ignored
#define PNP_BUS_IS_BUS "bus/is_bus"
extern struct device_manager_info *gDeviceManager;
#endif /* _DEVICE_MANAGER_H */
-80
View File
@@ -1,80 +0,0 @@
/*
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/*
Fast logging facilities.
This logging is much faster then dprintf and is saver
against buffer overflow conditions.
Clients have to define events by creating an array of
fast_log_type entries, each consisting of a code and the
associated human-readable description. During logging,
only the code is stored to save space and time. Also,
all arguments are stored binary (currently, they must
be of type uint32). Conversion to human-readable text is
post-poned until the logging data is read or a client
connection is closed (as this invalidates the event-
description binding).
The reader interface is /dev/FAST_LOG_DEVFS_NAME. This
device can only be read from (no seeking or further
functionality) and does not block if there is no data.
This is because if you want to store the log into a
file, the file access may lead to further logging data,
so doing a sleep between reads saves logging entries.
*/
#ifndef FAST_LOG_H
#define FAST_LOG_H
#include <module.h>
// one event type as defined by client
typedef struct fast_log_event_type {
// code of event (zero means end-of-list)
int16 event;
// human-readable description
const char *description;
} fast_log_event_type;
// handle of client connection
typedef struct fast_log_connection *fast_log_handle;
// client interface
typedef struct fast_log_info {
module_info minfo;
// open client connection
// prefix - prefix to print in log before each event
// types - array of event types; last entry must have event=0
fast_log_handle (*start_log)(const char *prefix, fast_log_event_type types[]);
// close client connection
void (*stop_log)(fast_log_handle handle);
// log an entry without arguments
void (*log_0)(fast_log_handle handle, int event);
// log an entry with one argument
void (*log_1)(fast_log_handle handle, int event, uint32 param1);
// log an entry with two arguments
void (*log_2)(fast_log_handle handle, int event, uint32 param1, uint32 param2);
// log an entry with three arguments
void (*log_3)(fast_log_handle handle, int event, uint32 param1, uint32 param2, uint32 param3);
// log an entry with four arguments
void (*log_4)(fast_log_handle handle, int event, uint32 param1, uint32 param2, uint32 param3, uint32 param4);
// log an entry with n arguments
// don't cheat on num_params!
void (*log_n)(fast_log_handle handle, int event, int num_params, ...);
} fast_log_info;
// name of client interface module
#define FAST_LOG_MODULE_NAME "generic/fast_log/v1"
// name of device to read logging data from
#define FAST_LOG_DEVFS_NAME "fast_log"
#endif
+25 -22
View File
@@ -91,7 +91,7 @@ enum {
// info about one channel
typedef struct ide_adapter_channel_info {
pci_device_module_info *pci;
pci_device device;
pci_device *device;
uint16 command_block_base; // io address command block
uint16 control_block_base; // io address control block
@@ -102,7 +102,7 @@ typedef struct ide_adapter_channel_info {
// be accessed anymore
ide_channel ide_channel;
device_node_handle node;
device_node *node;
int32 (*inthand)( void *arg );
@@ -116,14 +116,14 @@ typedef struct ide_adapter_channel_info {
// info about controller
typedef struct ide_adapter_controller_info {
pci_device_module_info *pci;
pci_device device;
pci_device *device;
uint16 bus_master_base;
uint32 lost; // != 0 if device got removed, i.e. if it must not
// be accessed anymore
device_node_handle node;
device_node *node;
} ide_adapter_controller_info;
@@ -131,6 +131,9 @@ typedef struct ide_adapter_controller_info {
typedef struct {
module_info info;
void (*set_channel)(ide_adapter_channel_info *channel,
ide_channel ideChannel);
// function calls that can be forwarded from actual driver
status_t (*write_command_block_regs)(ide_adapter_channel_info *channel,
ide_task_file *tf, ide_reg_mask mask);
@@ -153,47 +156,47 @@ typedef struct {
int32 (*inthand)(void *arg);
// functions that must be called by init/uninit etc. of channel driver
status_t (*init_channel)(device_node_handle node, ide_channel ide_channel,
status_t (*init_channel)(device_node *node,
ide_adapter_channel_info **cookie, size_t total_data_size,
int32 (*inthand)(void *arg));
status_t (*uninit_channel)(ide_adapter_channel_info *channel);
void (*channel_removed)(device_node_handle node, ide_adapter_channel_info *channel);
void (*uninit_channel)(ide_adapter_channel_info *channel);
void (*channel_removed)(ide_adapter_channel_info *channel);
// publish channel node
status_t (*publish_channel)(device_node_handle controller_node,
status_t (*publish_channel)(device_node *controller_node,
const char *channel_module_name, uint16 command_block_base,
uint16 control_block_base, uint8 intnum, bool can_dma,
uint8 channel_index, const char *name,
io_resource_handle *resources, device_node_handle *node);
const io_resource *resources, device_node **node);
// verify channel configuration and publish node on success
status_t (*detect_channel)(pci_device_module_info *pci, pci_device pci_device,
device_node_handle controller_node, const char *channel_module_name,
status_t (*detect_channel)(pci_device_module_info *pci, pci_device *pciDevice,
device_node *controller_node, const char *channel_module_name,
bool controller_can_dma, uint16 command_block_base,
uint16 control_block_base, uint16 bus_master_base,
uint8 intnum, uint8 channel_index, const char *name,
device_node_handle *node, bool supports_compatibility_mode);
device_node **node, bool supports_compatibility_mode);
// functions that must be called by init/uninit etc. of controller driver
status_t (*init_controller)(device_node_handle node, void *user_cookie,
status_t (*init_controller)(device_node *node,
ide_adapter_controller_info **cookie, size_t total_data_size);
status_t (*uninit_controller)(ide_adapter_controller_info *controller);
void (*controller_removed)(device_node_handle node, ide_adapter_controller_info *controller);
void (*uninit_controller)(ide_adapter_controller_info *controller);
void (*controller_removed)(ide_adapter_controller_info *controller);
// publish controller node
status_t (*publish_controller)(device_node_handle parent, uint16 bus_master_base,
io_resource_handle *resources, const char *controller_driver,
status_t (*publish_controller)(device_node *parent, uint16 bus_master_base,
io_resource *resources, 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, device_node_handle *node);
uint32 max_sg_block_size, device_node **node);
// verify controller configuration and publish node on success
status_t (*detect_controller)(pci_device_module_info *pci, pci_device pci_device,
device_node_handle parent, uint16 bus_master_base,
status_t (*detect_controller)(pci_device_module_info *pci, pci_device *pciDevice,
device_node *parent, uint16 bus_master_base,
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,
device_node_handle *node);
device_node **node);
// standard master probe for controller that registers controller and channel nodes
status_t (*probe_controller)(device_node_handle parent, const char *controller_driver,
status_t (*probe_controller)(device_node *parent, const char *controller_driver,
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,
+2 -2
View File
@@ -92,7 +92,7 @@ typedef struct scsi_periph_interface {
scsi_periph_callbacks *callbacks,
scsi_device scsi_device,
scsi_device_interface *scsi,
device_node_handle node,
device_node *node,
bool removable,
scsi_periph_device *driver );
status_t (*unregister_device)( scsi_periph_device driver );
@@ -150,7 +150,7 @@ typedef struct scsi_periph_interface {
// compose device name consisting of prefix and path/target/LUN
// (result must be freed by caller)
char *(*compose_device_name)(device_node_handle device_node, const char *prefix);
char *(*compose_device_name)(device_node *device_node, const char *prefix);
// fill data with icon (for B_GET_ICON ioctl)
status_t (*get_icon)( icon_type type, device_icon *data );
-9
View File
@@ -11,20 +11,11 @@
#include <Drivers.h>
struct kernel_args;
#ifdef __cplusplus
extern "C" {
#endif
void devfs_add_preloaded_drivers(struct kernel_args* args);
status_t devfs_add_driver(const char *path);
void devfs_driver_added(const char *path);
void devfs_driver_removed(const char *path);
status_t devfs_unpublish_file_device(const char *path);
status_t devfs_publish_file_device(const char *path, const char *filePath);
+7 -64
View File
@@ -1,85 +1,28 @@
/*
* Copyright 2004-2005, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2004-2008, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_DEVICE_MANAGER_H
#define _KERNEL_DEVICE_MANAGER_H
#include <SupportDefs.h>
#include <device_manager.h>
#include <util/list.h>
typedef struct device_node_info device_node_info;
// info about a device node
struct device_node_info {
struct list_link siblings;
device_node_info *parent;
struct list children;
int32 ref_count;
driver_module_info *driver;
void *cookie;
bool registered; // true, if device is officially existent
bool blocked_by_rescan; // true, if device is blocked because of rescan
int32 num_waiting_hooks; // number of waiting hook calls
sem_id hook_sem; // sem for waiting hook calls
int32 load_block_count; // load-block nest count
int32 num_blocked_loads; // number of waiting load calls
sem_id load_block_sem; // sem for waiting load calls
int32 load_count; // # of finished load_driver() calls
int32 loading; // # of active (un)load_driver() calls
uint32 rescan_depth; // > 0 if scanning is active
struct device_attr_info *attributes; // list of attributes
uint32 num_io_resources; // number of I/O resources
io_resource_handle *io_resources; // array of I/O resource (NULL-terminated)
bool automatically_loaded; // loaded automatically because PNP_DRIVER_ALWAYS_LOADED
uint32 internal_id; // internal identifier
};
struct kernel_args;
#ifdef __cplusplus
extern "C" {
#endif
extern status_t probe_for_device_type(const char *type);
extern status_t device_manager_init(struct kernel_args *args);
extern status_t device_manager_init_post_modules(struct kernel_args *args);
void legacy_driver_add_preloaded(struct kernel_args *args);
// temporary/optional device manager syscall API
#define DEVICE_MANAGER_SYSCALLS "device_manager"
#define DM_GET_ROOT 1
#define DM_GET_CHILD 2
#define DM_GET_NEXT_CHILD 3
#define DM_GET_NEXT_ATTRIBUTE 4
struct dev_attr {
uint32 node_cookie;
uint32 cookie;
char name[255];
type_code type;
union {
uint8 ui8;
uint16 ui16;
uint32 ui32;
uint64 ui64;
char string[255];
struct {
void *data;
size_t length;
} raw;
} value;
};
status_t device_manager_probe(const char *path, uint32 updateCycle);
status_t device_manager_init(struct kernel_args *args);
status_t device_manager_init_post_modules(struct kernel_args *args);
#ifdef __cplusplus
}
#endif
#endif /* _KRENEL_DEVICE_MANAGER_H */
#endif /* _KERNEL_DEVICE_MANAGER_H */
@@ -0,0 +1,38 @@
/*
* Copyright 2004-2008, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _SYSTEM_DEVICE_MANAGER_DEFS_H
#define _SYSTEM_DEVICE_MANAGER_DEFS_H
#include <device_manager.h>
// temporary/optional device manager syscall API
#define DEVICE_MANAGER_SYSCALLS "device_manager"
#define DM_GET_ROOT 1
#define DM_GET_CHILD 2
#define DM_GET_NEXT_CHILD 3
#define DM_GET_NEXT_ATTRIBUTE 4
struct device_attr_info {
uint32 node_cookie;
uint32 cookie;
char name[255];
type_code type;
union {
uint8 ui8;
uint16 ui16;
uint32 ui32;
uint64 ui64;
char string[255];
struct {
void *data;
size_t length;
} raw;
} value;
};
#endif /* _SYSTEM_DEVICE_MANAGER_DEFS_H */
@@ -66,8 +66,6 @@ reset_bus(ide_device_info *device, ide_qrequest *ignore)
dprintf("ide: reset_bus() device %p, bus %p\n", device, bus);
FAST_LOG0(bus->log, ev_ide_reset_bus);
if (device->reconnect_timer_installed) {
cancel_timer(&device->reconnect_timer.te);
device->reconnect_timer_installed = false;
@@ -142,7 +140,6 @@ reset_device(ide_device_info *device, ide_qrequest *ignore)
dprintf("ide: reset_device() device %p\n", device);
FAST_LOG1(bus->log, ev_ide_reset_device, device->is_device1);
SHOW_FLOW0(3, "");
if (!device->is_atapi)
@@ -202,13 +199,6 @@ send_command(ide_device_info *device, ide_qrequest *qrequest,
uint8 num_retries = 0;
bool irq_guard;
FAST_LOGN(bus->log, ev_ide_send_command, 15, device->is_device1, (uint32)qrequest,
device->tf.raw.r[0], device->tf.raw.r[1], device->tf.raw.r[2],
device->tf.raw.r[3], device->tf.raw.r[4], device->tf.raw.r[5],
device->tf.raw.r[6],
device->tf.raw.r[7], device->tf.raw.r[8], device->tf.raw.r[9],
device->tf.raw.r[10], device->tf.raw.r[11]);
retry:
irq_guard = bus->num_running_reqs > 1;
@@ -391,8 +381,6 @@ device_start_service(ide_device_info *device, int *tag)
{
ide_bus_info *bus = device->bus;
FAST_LOG1(bus->log, ev_ide_device_start_service, device->is_device1);
device->tf.write.command = IDE_CMD_SERVICE;
device->tf.queued.mode = ide_mode_lba;
@@ -433,7 +421,6 @@ device_start_service(ide_device_info *device, int *tag)
*tag = device->tf.queued.tag;
FAST_LOG2(bus->log, ev_ide_device_start_service2, device->is_device1, *tag);
return true;
err:
+7 -16
View File
@@ -24,9 +24,9 @@
/** called when an IDE channel was registered by a controller driver */
static status_t
ide_channel_added(device_node_handle parent)
ide_channel_added(device_node *parent)
{
char *controller_name = NULL;
const char *controller_name = NULL;
uint32 channel_id;
SHOW_FLOW0(2, "");
@@ -47,8 +47,7 @@ ide_channel_added(device_node_handle parent)
{
device_attr attrs[] =
{
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: IDE_SIM_MODULE_NAME }},
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: SCSI_FOR_SIM_MODULE_NAME }},
{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE, { string: SCSI_FOR_SIM_MODULE_NAME }},
{ SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE,
{ string: controller_name }},
@@ -65,25 +64,17 @@ ide_channel_added(device_node_handle parent)
// in ide_sim.c!
{ B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: 255 }},
{ IDE_CHANNEL_ID_ITEM, B_UINT32_TYPE, { ui32: channel_id }},
{ PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, { string: IDE_CHANNEL_ID_GENERATOR }},
{ PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: channel_id }},
// { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, { string: IDE_CHANNEL_ID_GENERATOR }},
// { PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: channel_id }},
{ NULL }
};
device_node_handle node;
status_t res;
res = pnp->register_device(parent, attrs, NULL, &node);
free(controller_name);
return res;
return pnp->register_node(parent, IDE_SIM_MODULE_NAME, attrs, NULL,
NULL);
}
err:
free(controller_name);
return B_NO_MEMORY;
}
@@ -5,19 +5,12 @@
#ifndef __IDE_INTERNAL_H__
#define __IDE_INTERNAL_H__
/*
Part of Open IDE bus manager
Internal structures
*/
#include <bus/IDE.h>
#include <bus/SCSI.h>
#include "ide_device_infoblock.h"
#include <ide_types.h>
#include <device_manager.h>
#include <fast_log.h>
#define debug_level_error 2
#define debug_level_info 1
@@ -28,24 +21,6 @@
#include "wrapper.h"
//#define USE_FAST_LOG
#ifdef USE_FAST_LOG
#define FAST_LOG0( handle, event ) fast_log->log_0( handle, event )
#define FAST_LOG1( handle, event, param ) fast_log->log_1( handle, event, param )
#define FAST_LOG2( handle, event, param1, param2 ) fast_log->log_2( handle, event, param1, param2 )
#define FAST_LOG3( handle, event, param1, param2, param3 ) fast_log->log_3( handle, event, param1, param2, param3 )
#define FAST_LOGN( handle, event, num_params... ) fast_log->log_n( handle, event, num_params )
#else
#define FAST_LOG0( handle, event )
#define FAST_LOG1( handle, event, param )
#define FAST_LOG2( handle, event, param1, param2 )
#define FAST_LOG3( handle, event, param1, param2, param3 )
#define FAST_LOGN( handle, event, num_params... )
#endif
#define IDE_STD_TIMEOUT 10
#define IDE_RELEASE_TIMEOUT 10000000
@@ -58,7 +33,6 @@
#define IDE_CHANNEL_ID_ITEM "ide/channel_id"
extern device_manager_info *pnp;
extern fast_log_info *fast_log;
typedef struct ide_bus_info ide_bus_info;
@@ -228,14 +202,13 @@ struct ide_bus_info {
uchar path_id;
device_node_handle node; // our pnp node
device_node *node; // our pnp node
// restrictions, read from controller node
uint8 max_devices;
uint8 can_DMA;
uint8 can_CQ;
fast_log_handle log;
char name[32];
};
@@ -290,8 +263,8 @@ enum {
// get selected device
static inline
ide_device_info *get_current_device(ide_bus_info *bus)
static inline ide_device_info *
get_current_device(ide_bus_info *bus)
{
ide_task_file tf;
+60 -122
View File
@@ -33,41 +33,6 @@
#include <stdio.h>
scsi_for_sim_interface *scsi;
fast_log_info *fast_log;
#ifdef USE_FAST_LOG
static fast_log_event_type ide_events[] =
{
{ ev_ide_send_command, "ev_ide_send_command " },
{ ev_ide_device_start_service, "ev_ide_device_start_service" },
{ ev_ide_device_start_service2, "ev_ide_device_start_service2" },
{ ev_ide_dpc_service, "ev_ide_dpc_service" },
{ ev_ide_dpc_continue, "ev_ide_dpc_continue" },
{ ev_ide_irq_handle, "ev_ide_irq_handle" },
{ ev_ide_cancel_irq_timeout, "ev_ide_cancel_irq_timeout" },
{ ev_ide_start_waiting, "ev_ide_start_waiting" },
{ ev_ide_timeout_dpc, "ev_ide_timeout_dpc" },
{ ev_ide_timeout, "ev_ide_timeout" },
{ ev_ide_reset_bus, "ev_ide_reset_bus" },
{ ev_ide_reset_device, "ev_ide_reset_device" },
{ ev_ide_scsi_io, "ev_ide_scsi_io" },
{ ev_ide_scsi_io_exec, "ev_ide_scsi_io_exec" },
{ ev_ide_scsi_io_invalid_device, "ev_ide_scsi_io_invalid_device" },
{ ev_ide_scsi_io_bus_busy, "ev_ide_scsi_io_bus_busy" },
{ ev_ide_scsi_io_device_busy, "ev_ide_scsi_io_device_busy" },
{ ev_ide_scsi_io_disconnected, "ev_ide_scsi_io_disconnected" },
{ ev_ide_finish_request, "ev_ide_finish_request" },
{ ev_ide_finish_norelease, "ev_ide_finish_norelease" },
{ ev_ide_scan_device_int, "ev_ide_scan_device_int" },
{ ev_ide_scan_device_int_cant_send, "ev_ide_scan_device_int_cant_send" },
{ ev_ide_scan_device_int_keeps_busy, "ev_ide_scan_device_int_keeps_busy" },
{ ev_ide_scan_device_int_found, "ev_ide_scan_device_int_found" },
{}
};
#endif
static void disconnect_worker(ide_bus_info *bus, void *arg);
@@ -96,15 +61,56 @@ is_queuable(ide_device_info *device, scsi_ccb *request)
}
static void
scan_device(ide_bus_info *bus, int device)
{
SHOW_FLOW0(4, "");
// currently, the SCSI bus manager doesn't block the
// bus when a bus or device scan is issued, so we
// have to use a SPC for that to be sure no one else
// is accessing the device or bus concurrently
schedule_synced_pc(bus, &bus->scan_bus_syncinfo, (void *)device);
acquire_sem(bus->scan_device_sem);
}
static uchar
sim_scan_bus(ide_bus_info *bus)
{
int i;
SHOW_FLOW0(4, "");
if (bus->disconnected)
return SCSI_NO_HBA;
for (i = 0; i < bus->max_devices; ++i) {
scan_device(bus, i);
}
return SCSI_REQ_CMP;
}
static void
sim_set_scsi_bus(ide_bus_info *bus, scsi_bus scsi)
{
bus->scsi_cookie = scsi;
// detect devices
sim_scan_bus(bus);
}
static void
sim_scsi_io(ide_bus_info *bus, scsi_ccb *request)
{
ide_device_info *device;
bool queuable;
ide_qrequest *qrequest;
//ide_request_priv *priv;
// FAST_LOG3( bus->log, ev_ide_scsi_io, (uint32)request, request->target_id, request->target_lun );
SHOW_FLOW(3, "%d:%d", request->target_id, request->target_lun);
if (bus->disconnected)
@@ -156,9 +162,6 @@ sim_scsi_io(ide_bus_info *bus, scsi_ccb *request)
++bus->num_running_reqs;
bus->active_qrequest = qrequest;
FAST_LOGN(bus->log, ev_ide_scsi_io_exec, 4, (uint32)qrequest,
(uint32)request, bus->num_running_reqs, device->num_running_reqs);
device->exec_io(device, qrequest);
return;
@@ -166,7 +169,6 @@ sim_scsi_io(ide_bus_info *bus, scsi_ccb *request)
err_inv_device:
SHOW_ERROR(3, "Invalid device %d:%d",
request->target_id, request->target_lun);
FAST_LOG1(bus->log, ev_ide_scsi_io_invalid_device, (uint32)request);
request->subsys_status = SCSI_SEL_TIMEOUT;
scsi->finished(request, 1);
@@ -174,7 +176,6 @@ err_inv_device:
err_bus_busy:
SHOW_FLOW0(3, "Bus busy");
FAST_LOG1(bus->log, ev_ide_scsi_io_bus_busy, (uint32)request);
IDE_UNLOCK(bus);
scsi->requeue(request, true);
@@ -183,7 +184,6 @@ err_bus_busy:
err_device_busy:
SHOW_FLOW0(3, "Device busy");
FAST_LOG1(bus->log, ev_ide_scsi_io_device_busy, (uint32)request);
IDE_UNLOCK(bus);
scsi->requeue(request, false);
@@ -192,7 +192,6 @@ err_device_busy:
err_disconnected:
SHOW_ERROR0(3, "No controller anymore");
FAST_LOG1(bus->log, ev_ide_scsi_io_disconnected, (uint32)request);
request->subsys_status = SCSI_NO_HBA;
scsi->finished(request, 1);
return;
@@ -202,7 +201,7 @@ err_disconnected:
static uchar
sim_path_inquiry(ide_bus_info *bus, scsi_path_inquiry *info)
{
char *controller_name;
const char *controller_name;
SHOW_FLOW0(4, "");
@@ -228,7 +227,6 @@ sim_path_inquiry(ide_bus_info *bus, scsi_path_inquiry *info)
if (pnp->get_attr_string(bus->node, SCSI_DESCRIPTION_CONTROLLER_NAME,
&controller_name, true) == B_OK) {
strlcpy(info->hba_vid, controller_name, SCSI_HBA_ID);
free(controller_name);
} else
strlcpy(info->hba_vid, "", SCSI_HBA_ID);
@@ -241,39 +239,6 @@ sim_path_inquiry(ide_bus_info *bus, scsi_path_inquiry *info)
}
static void
scan_device(ide_bus_info *bus, int device)
{
SHOW_FLOW0(4, "");
// currently, the SCSI bus manager doesn't block the
// bus when a bus or device scan is issued, so we
// have to use a SPC for that to be sure no one else
// is accessing the device or bus concurrently
schedule_synced_pc(bus, &bus->scan_bus_syncinfo, (void *)device);
acquire_sem(bus->scan_device_sem);
}
static uchar
sim_scan_bus(ide_bus_info *bus)
{
int i;
SHOW_FLOW0(4, "");
if (bus->disconnected)
return SCSI_NO_HBA;
for (i = 0; i < bus->max_devices; ++i) {
scan_device(bus, i);
}
return SCSI_REQ_CMP;
}
static uchar
sim_abort(ide_bus_info *bus, scsi_ccb *ccb_to_abort)
{
@@ -371,7 +336,6 @@ finish_request(ide_qrequest *qrequest, bool resubmit)
scsi_ccb *request;
uint num_running;
FAST_LOG2(bus->log, ev_ide_finish_request, (uint32)qrequest, resubmit);
SHOW_FLOW0(3, "");
// save request first, as qrequest can be reused as soon as
@@ -488,8 +452,6 @@ finish_norelease(ide_qrequest *qrequest, bool resubmit)
ide_bus_info *bus = device->bus;
uint num_requests;
FAST_LOG2(bus->log, ev_ide_finish_norelease, (uint32)qrequest, resubmit);
qrequest->running = false;
qrequest->next = device->free_qrequests;
device->free_qrequests = qrequest;
@@ -544,9 +506,8 @@ finish_all_requests(ide_device_info *device, ide_qrequest *ignore,
static status_t
ide_sim_init_bus(device_node_handle node, void *user_cookie, void **cookie)
ide_sim_init_bus(device_node *node, void **cookie)
{
device_node_handle parent;
ide_bus_info *bus;
bool dmaDisabled = false;
status_t status;
@@ -573,18 +534,9 @@ ide_sim_init_bus(device_node_handle node, void *user_cookie, void **cookie)
sprintf(bus->name, "ide_bus %d", (int)channel_id);
}
#if 0
bus->log = fast_log->start_log(bus->name, ide_events);
if (bus->log == NULL) {
res = B_NO_MEMORY;
goto err;
}
#endif
init_synced_pc(&bus->scan_bus_syncinfo, scan_device_worker);
init_synced_pc(&bus->disconnect_syncinfo, disconnect_worker);
bus->scsi_cookie = user_cookie;
bus->state = ide_state_idle;
bus->timer.bus = bus;
bus->synced_pc_list = NULL;
@@ -657,23 +609,18 @@ ide_sim_init_bus(device_node_handle node, void *user_cookie, void **cookie)
bus->can_CQ = false;
}
parent = pnp->get_parent(node);
status = pnp->init_driver(parent, bus, (driver_module_info **)&bus->controller,
{
device_node *parent = pnp->get_parent_node(node);
pnp->get_driver(parent, (driver_module_info **)&bus->controller,
(void **)&bus->channel_cookie);
pnp->put_device_node(parent);
if (status != B_OK)
goto err5;
bus->controller->set_channel(bus->channel_cookie, bus);
pnp->put_node(parent);
}
*cookie = bus;
// detect devices
sim_scan_bus(bus);
return B_OK;
err5:
DELETE_BEN(&bus->status_report_ben);
err4:
delete_sem(bus->scan_device_sem);
err3:
@@ -683,10 +630,6 @@ err2:
err1:
uninit_synced_pc(&bus->scan_bus_syncinfo);
uninit_synced_pc(&bus->disconnect_syncinfo);
#ifdef USE_FAST_LOG
fast_log->stop_log(bus->log);
err:
#endif
free(bus);
return status;
@@ -696,18 +639,12 @@ err:
static status_t
ide_sim_uninit_bus(ide_bus_info *bus)
{
device_node_handle parent = pnp->get_parent(bus->node);
pnp->uninit_driver(parent);
pnp->put_device_node(parent);
DELETE_BEN(&bus->status_report_ben);
delete_sem(bus->scan_device_sem);
delete_sem(bus->sync_wait_sem);
scsi->free_dpc(bus->irq_dpc);
uninit_synced_pc(&bus->scan_bus_syncinfo);
uninit_synced_pc(&bus->disconnect_syncinfo);
// fast_log->stop_log(bus->log);
free(bus);
@@ -732,12 +669,8 @@ disconnect_worker(ide_bus_info *bus, void *arg)
static void
ide_sim_bus_removed(device_node_handle node, ide_bus_info *bus)
ide_sim_bus_removed(ide_bus_info *bus)
{
if (bus == NULL)
// driver not loaded - no manual intervention needed
return;
// XPT must not issue further commands
scsi->block_bus(bus->scsi_cookie);
// make sure, we refuse all new commands
@@ -852,11 +785,16 @@ scsi_sim_interface ide_sim_module = {
NULL, // supported devices
NULL, // register node
(status_t (*)(device_node_handle, void *, void **))ide_sim_init_bus,
(status_t (*)(void *) ) ide_sim_uninit_bus,
(void (*)(device_node_handle, void *)) ide_sim_bus_removed
(status_t (*)(device_node *, void **)) ide_sim_init_bus,
(void (*)(void *)) ide_sim_uninit_bus,
NULL, // register child devices
NULL, // rescan
(void (*)(void *)) ide_sim_bus_removed,
NULL, // suspend
NULL // resume
},
(void (*)(scsi_sim_cookie, scsi_bus)) sim_set_scsi_bus,
(void (*)(scsi_sim_cookie, scsi_ccb *)) sim_scsi_io,
(uchar (*)(scsi_sim_cookie, scsi_ccb *)) sim_abort,
(uchar (*)(scsi_sim_cookie, uchar, uchar)) sim_reset_device,
@@ -42,7 +42,6 @@ ide_dpc(void *arg)
// in idle state, so we just check whether there is an active request,
// which means that we were async_waiting
if (bus->active_qrequest != NULL) {
FAST_LOG1(bus->log, ev_ide_dpc_continue, (uint32)bus->active_qrequest);
TRACE(("continue command\n"));
// cancel timeout
@@ -66,8 +65,6 @@ ide_dpc(void *arg)
// for service requests
TRACE(("irq in idle mode - possible service request\n"));
FAST_LOG0(bus->log, ev_ide_dpc_service);
device = get_current_device(bus);
if (device == NULL) {
// got an interrupt from a non-existing device
@@ -191,8 +188,6 @@ ide_irq_handler(ide_bus_info *bus, uint8 status)
void
cancel_irq_timeout(ide_bus_info *bus)
{
FAST_LOG0(bus->log, ev_ide_cancel_irq_timeout);
IDE_LOCK(bus);
bus->state = ide_state_accessing;
IDE_UNLOCK(bus);
@@ -210,8 +205,6 @@ start_waiting(ide_bus_info *bus, uint32 timeout, int new_state)
{
int res;
FAST_LOG1(bus->log, ev_ide_start_waiting, new_state);
TRACE(("timeout = %u\n", (uint)timeout));
bus->state = new_state;
@@ -260,8 +253,6 @@ ide_timeout_dpc(void *arg)
dprintf("ide: ide_timeout_dpc() bus %p, device %p\n", bus, device);
FAST_LOG1(bus->log, ev_ide_timeout_dpc, (uint32)qrequest);
// this also resets overlapped commands
reset_device(device, qrequest);
@@ -287,8 +278,6 @@ ide_timeout(timer *arg)
{
ide_bus_info *bus = ((ide_bus_timer_info *)arg)->bus;
FAST_LOG0(bus->log, ev_ide_timeout);
TRACE(("ide_timeout(): %p\n", bus));
dprintf("ide: ide_timeout() bus %p\n", bus);
+5 -1
View File
@@ -137,6 +137,7 @@ unlock_isa_dma_channel(long channel)
}
#if 0
static status_t
isa_init_driver(device_node_handle node, void *user_cookie, void **cookie)
{
@@ -202,6 +203,7 @@ isa_get_paths(const char ***_bus, const char ***_device)
*_bus = kBus;
*_device = NULL;
}
#endif
static status_t
@@ -246,6 +248,7 @@ static isa_module_info isa_module = {
&unlock_isa_dma_channel
};
#if 0
static isa2_module_info isa2_module = {
{
{
@@ -278,9 +281,10 @@ static isa2_module_info isa2_module = {
start_isa_dma,
};
#endif
module_info *modules[] = {
(module_info *)&isa_module,
(module_info *)&isa2_module,
// (module_info *)&isa2_module,
NULL
};
+2 -6
View File
@@ -8,15 +8,11 @@ KernelAddon pci :
pci_fixup.cpp
pci_info.cpp
pci_module.c
pci_device.c
kernel_cpp.cpp
pci_root.cpp
pci_device.cpp
: pci_arch_bus_manager.a
;
SEARCH on [ FGristFiles
kernel_cpp.cpp
] = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
# pci_info.cpp currently needs pcihdr.h so we make its path available and adds dependency
ObjectHdrs [ FGristFiles pci_info$(SUFOBJ) ]
: [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR) preferences devices ] ;
@@ -1,12 +1,22 @@
/*
* Copyright 2007, François Revol <[email protected]>.
* Distributed under the terms of the MIT License.
*/
#include "pci_controller.h"
#include <arch_platform.h>
#include "pci_priv.h"
#include "pci_private.h"
/*
* As we don't have any real PCI bus in any of the supported m68k platforms,
* we fake one, with hardcoded devices.
* TODO: this doesn't make any sense, as we can't share any drivers, anyway.
* We should better export dedicated bus managers for Zorro etc. busses on
* these systems.
* TODO: actually, there are several PCI boards for the Amiga.
*/
#include "amiga/pci_amiga.h"
@@ -1,6 +1,13 @@
/*
* Copyright 2007, François Revol <[email protected]>.
* Distributed under the terms of the MIT License.
*/
#include "pci_io.h"
#include "pci_priv.h"
status_t
pci_io_init()
{
@@ -1,8 +1,14 @@
/*
* Copyright 2006, Ingo Weinhold. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "pci_controller.h"
#include <arch_platform.h>
#include "pci_priv.h"
#include "pci_private.h"
#include "openfirmware/pci_openfirmware.h"
@@ -1,5 +1,12 @@
/*
* Copyright 2006, Ingo Weinhold. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "pci_io.h"
#include "pci_priv.h"
#include "pci_private.h"
status_t
pci_io_init()
@@ -1,6 +1,13 @@
#include "pci_priv.h"
/*
* Copyright 2006, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "pci_private.h"
#include "pci_bios.h"
status_t
pci_bios_init(void)
{
@@ -1,13 +1,12 @@
/*
* Copyright 2006, Marcus Overhagen. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <KernelExport.h>
#include "pci_irq.h"
#include "pci_bios.h"
#include "pci_priv.h"
#include "pci_private.h"
#include "pci_controller.h"
#include "arch_cpu.h"
@@ -1,6 +1,13 @@
#include "pci_priv.h"
/*
* Copyright 2006, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "pci_private.h"
#include "arch_cpu.h"
status_t
pci_io_init()
{
+1 -1
View File
@@ -13,7 +13,7 @@
#include "util/kernel_cpp.h"
#include "pci_fixup.h"
#include "pci_priv.h"
#include "pci_private.h"
#include "pci.h"
#define TRACE_CAP(x...) dprintf(x)
@@ -1,239 +0,0 @@
/*
* Copyright 2004-2005, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
/*
PCI bus manager
PCI device layer. There is one node per PCI device.
The common root is the PCI root node.
*/
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include "pci.h"
#include "pci_priv.h"
// information about one PCI device
typedef struct pci_device_info {
uint8 bus; // bus number
uint8 device; // device number
uint8 function; // function number
device_node_handle node;
pci_root_info *root; // parent, i.e. PCI root
char name[32]; // name (for fast log)
} pci_device_info;
static uint8
pci_device_read_io_8(pci_device_info *device, int mapped_io_addr)
{
return pci_read_io_8(mapped_io_addr);
}
static void
pci_device_write_io_8(pci_device_info *device, int mapped_io_addr, uint8 value)
{
pci_write_io_8(mapped_io_addr, value);
}
static uint16
pci_device_read_io_16(pci_device_info *device, int mapped_io_addr)
{
return pci_read_io_16(mapped_io_addr);
}
static void
pci_device_write_io_16(pci_device_info *device, int mapped_io_addr, uint16 value)
{
pci_write_io_16(mapped_io_addr, value);
}
static uint32
pci_device_read_io_32(pci_device_info *device, int mapped_io_addr)
{
return pci_read_io_32(mapped_io_addr);
}
static void
pci_device_write_io_32(pci_device_info *device, int mapped_io_addr, uint32 value)
{
pci_write_io_32(mapped_io_addr, value);
}
static uint32
pci_device_read_pci_config(pci_device_info *device, uint8 offset, uint8 size)
{
return device->root->read_pci_config(device->bus, device->device,
device->function, offset, size);
}
static void
pci_device_write_pci_config(pci_device device, uint8 offset, uint8 size, uint32 value)
{
return device->root->write_pci_config(device->bus, device->device,
device->function, offset, size, value);
}
static void *
pci_device_ram_address(pci_device_info *device,
const void *physical_address_in_system_memory)
{
return pci_ram_address(physical_address_in_system_memory);
}
static status_t
pci_device_get_pci_info(pci_device device, struct pci_info *info)
{
int i;
if (device == NULL || info == NULL)
return B_BAD_VALUE;
// TODO: Implement more efficiently!
for (i = 0; pci_get_nth_pci_info(i, info) == B_OK; i++) {
if (device->bus == info->bus && device->device == info->device
&& device->function == info->function) {
return B_OK;
}
}
return B_ENTRY_NOT_FOUND;
}
static status_t
pci_device_find_capability(pci_device device, uchar cap_id, uchar *offset)
{
return pci_find_capability(device->bus, device->device,
device->function, cap_id, offset);
}
static status_t
pci_device_init_driver(device_node_handle node, void *user_cookie, void **cookie)
{
uint8 bus, deviceNumber, function;
device_node_handle parent;
pci_device_info *device;
pci_root_info *root;
status_t status;
void *dummy;
if (gDeviceManager->get_attr_uint8(node, PCI_DEVICE_BUS_ITEM, &bus, false) != B_OK
|| gDeviceManager->get_attr_uint8(node, PCI_DEVICE_DEVICE_ITEM, &deviceNumber, false) != B_OK
|| gDeviceManager->get_attr_uint8(node, PCI_DEVICE_FUNCTION_ITEM, &function, false) != B_OK)
return B_ERROR;
parent = gDeviceManager->get_parent(node);
status = gDeviceManager->init_driver(parent, NULL, (driver_module_info **)&root, &dummy);
if (status != B_OK)
goto err;
device = malloc(sizeof(*device));
if (device == NULL) {
status = B_NO_MEMORY;
goto err;
}
gDeviceManager->put_device_node(parent);
memset(device, 0, sizeof(*device));
device->bus = bus;
device->device = deviceNumber;
device->function = function;
device->node = node;
device->root = root;
snprintf(device->name, sizeof(device->name), "pci_device %u:%u:%u",
bus, deviceNumber, function);
*cookie = device;
return B_OK;
err:
gDeviceManager->uninit_driver(parent);
gDeviceManager->put_device_node(parent);
return status;
}
static status_t
pci_device_uninit_driver(void *cookie)
{
pci_device_info *device = cookie;
device_node_handle parent;
parent = gDeviceManager->get_parent(device->node);
gDeviceManager->uninit_driver(parent);
gDeviceManager->put_device_node(parent);
free(device);
return B_OK;
}
static status_t
pci_device_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
}
return B_BAD_VALUE;
}
pci_device_module_info gPCIDeviceModule = {
{
{
PCI_DEVICE_MODULE_NAME,
0,
pci_device_std_ops
},
NULL, // supports device
NULL, // register device (our parent registered us)
pci_device_init_driver,
pci_device_uninit_driver,
NULL, // removed
NULL, // cleanup
NULL, // get supported paths
},
pci_device_read_io_8,
pci_device_write_io_8,
pci_device_read_io_16,
pci_device_write_io_16,
pci_device_read_io_32,
pci_device_write_io_32,
pci_device_read_pci_config,
pci_device_write_pci_config,
pci_device_ram_address,
pci_device_get_pci_info,
pci_device_find_capability
};
@@ -0,0 +1,185 @@
/*
* Copyright 2004-2008, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2002-2003, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pci.h"
#include "pci_private.h"
// information about one PCI device
struct pci_device {
PCIDev* device;
device_node* node;
};
static uint8
pci_device_read_io_8(pci_device* device, addr_t mappedIOAddress)
{
return pci_read_io_8(mappedIOAddress);
}
static void
pci_device_write_io_8(pci_device* device, addr_t mappedIOAddress,
uint8 value)
{
pci_write_io_8(mappedIOAddress, value);
}
static uint16
pci_device_read_io_16(pci_device* device, addr_t mappedIOAddress)
{
return pci_read_io_16(mappedIOAddress);
}
static void
pci_device_write_io_16(pci_device* device, addr_t mappedIOAddress,
uint16 value)
{
pci_write_io_16(mappedIOAddress, value);
}
static uint32
pci_device_read_io_32(pci_device* device, addr_t mappedIOAddress)
{
return pci_read_io_32(mappedIOAddress);
}
static void
pci_device_write_io_32(pci_device* device, addr_t mappedIOAddress, uint32 value)
{
pci_write_io_32(mappedIOAddress, value);
}
static uint32
pci_device_read_pci_config(pci_device* device, uint8 offset, uint8 size)
{
return gPCI->ReadConfig(device->device, offset, size);
}
static void
pci_device_write_pci_config(pci_device* device, uint8 offset, uint8 size,
uint32 value)
{
gPCI->WriteConfig(device->device, offset, size, value);
}
static void*
pci_device_ram_address(pci_device* device, const void* physicalAddress)
{
return pci_ram_address(physicalAddress);
}
static status_t
pci_device_find_capability(pci_device* device, uint8 capID, uint8* offset)
{
return gPCI->FindCapability(device->device, capID, offset);
}
static void
pci_device_get_pci_info(pci_device* device, struct pci_info* info)
{
if (info == NULL)
return;
*info = device->device->info;
}
static status_t
pci_device_init_driver(device_node* node, void** _cookie)
{
uint32 domain;
uint8 bus, deviceNumber, function;
if (gDeviceManager->get_attr_uint32(node, B_PCI_DEVICE_DOMAIN, &domain,
false) != B_OK
|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_BUS, &bus,
false) != B_OK
|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_DEVICE,
&deviceNumber, false) != B_OK
|| gDeviceManager->get_attr_uint8(node, B_PCI_DEVICE_FUNCTION,
&function, false) != B_OK)
return B_ERROR;
pci_device* device = (pci_device*)malloc(sizeof(*device));
if (device == NULL)
return B_NO_MEMORY;
device->device = gPCI->FindDevice(domain, bus, deviceNumber, function);
device->node = node;
*_cookie = device;
return B_OK;
}
static void
pci_device_uninit_driver(void* cookie)
{
pci_device* device = (pci_device*)cookie;
free(device);
}
static status_t
pci_device_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
}
return B_BAD_VALUE;
}
pci_device_module_info gPCIDeviceModule = {
{
{
PCI_DEVICE_MODULE_NAME,
0,
pci_device_std_ops
},
NULL, // supports device
NULL, // register device (our parent registered us)
pci_device_init_driver,
pci_device_uninit_driver,
NULL, // register child devices
NULL, // rescan devices
NULL, // device removed
},
pci_device_read_io_8,
pci_device_write_io_8,
pci_device_read_io_16,
pci_device_write_io_16,
pci_device_read_io_32,
pci_device_write_io_32,
pci_device_ram_address,
pci_device_read_pci_config,
pci_device_write_pci_config,
pci_device_find_capability,
pci_device_get_pci_info
};
@@ -1,7 +1,7 @@
/*
** Copyright 2003-2006, Marcus Overhagen. All rights reserved.
** Distributed under the terms of the MIT License.
*/
* Copyright 2003-2006, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <KernelExport.h>
@@ -9,7 +9,7 @@
#include <PCI.h>
#include <string.h>
#include "pci_info.h"
#include "pci_priv.h"
#include "pci_private.h"
#include "pci.h"
#define PCI_VERBOSE 1
@@ -1,20 +1,14 @@
/*
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2003, Marcus Overhagen. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <KernelExport.h>
#include <device_manager.h>
#include <bus_manager.h>
#include <PCI.h>
#include <string.h>
#include <stdlib.h>
#include "pci_priv.h"
#include "pci_private.h"
#include "pci_info.h"
#include "pci.h"
@@ -22,139 +16,6 @@
device_manager_info *gDeviceManager;
// name of PCI root module
#define PCI_ROOT_MODULE_NAME "bus_managers/pci/root/device_v1"
static float
pci_module_supports_device(device_node_handle parent, bool *_noConnection)
{
char *bus;
// make sure parent is really device root
if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false))
return B_ERROR;
if (strcmp(bus, "root")) {
free(bus);
return 0.0;
}
free(bus);
return 1.0;
}
static status_t
pci_module_register_device(device_node_handle parent)
{
// XXX how do we handle this for PPC?
// I/O port for PCI config space address
#define PCI_CONFIG_ADDRESS 0xcf8
io_resource resources[2] = {
{ IO_PORT, PCI_CONFIG_ADDRESS, 8 },
{}
};
device_attr attrs[] = {
// info about ourself
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: PCI_ROOT_MODULE_NAME }},
// unique connection name
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "PCI" }},
// mark as being a bus
{ PNP_BUS_IS_BUS, B_UINT8_TYPE, { ui8: 1 }},
// search for device drivers once all devices are detected
//{ PNP_BUS_DEFER_PROBE, B_UINT8_TYPE, { ui8: 1 }},
// don't scan if loaded as we own I/O resources
//{ PNP_DRIVER_NO_LIVE_RESCAN, B_UINT8_TYPE, { ui8: 1 }},
{}
};
io_resource_handle resourceHandles[2];
device_node_handle node;
// char *parent_type;
status_t res;
res = gDeviceManager->acquire_io_resources(resources, resourceHandles);
if (res < B_OK)
return res;
return gDeviceManager->register_device(parent, attrs, resourceHandles, &node);
}
static status_t
pci_module_register_child_devices(void *cookie)
{
device_node_handle node = cookie;
pci_info device;
int32 i = 0;
while (pci_get_nth_pci_info(i, &device) == B_OK) {
device_attr attrs[] = {
// info about device
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: PCI_DEVICE_MODULE_NAME }},
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string:
"bus: %"PCI_DEVICE_BUS_ITEM
"%, device: %"PCI_DEVICE_DEVICE_ITEM
"%, function: %"PCI_DEVICE_FUNCTION_ITEM"%" }},
// location on PCI bus
{ PCI_DEVICE_BUS_ITEM, B_UINT8_TYPE, { ui8: device.bus }},
{ PCI_DEVICE_DEVICE_ITEM, B_UINT8_TYPE, { ui8: device.device }},
{ PCI_DEVICE_FUNCTION_ITEM, B_UINT8_TYPE, { ui8: device.function }},
// info about the device
{ PCI_DEVICE_VENDOR_ID_ITEM, B_UINT16_TYPE, { ui16: device.vendor_id }},
{ PCI_DEVICE_DEVICE_ID_ITEM, B_UINT16_TYPE, { ui16: device.device_id }},
{ PCI_DEVICE_SUBSYSTEM_ID_ITEM, B_UINT16_TYPE, { ui16: device.u.h0.subsystem_id }},
{ PCI_DEVICE_SUBVENDOR_ID_ITEM, B_UINT16_TYPE, { ui16: device.u.h0.subsystem_vendor_id }},
{ PCI_DEVICE_BASE_CLASS_ID_ITEM, B_UINT8_TYPE, { ui8: device.class_base }},
{ PCI_DEVICE_SUB_CLASS_ID_ITEM, B_UINT8_TYPE, { ui8: device.class_sub }},
{ PCI_DEVICE_API_ID_ITEM, B_UINT8_TYPE, { ui8: device.class_api }},
// consumer specification
{ B_DRIVER_BUS, B_STRING_TYPE, { string: "pci" }},
{ B_DRIVER_MAPPING, B_STRING_TYPE, { string: "%"PCI_DEVICE_VENDOR_ID_ITEM "%|_%" PCI_DEVICE_DEVICE_ID_ITEM "%" }},
// ToDo: this is a hack
{ B_DRIVER_DEVICE_TYPE, B_STRING_TYPE, { string: device.class_base == PCI_mass_storage ? "drivers/dev/disk" : "drivers/dev" }},
{ NULL }
};
device_node_handle deviceNode;
gDeviceManager->register_device(node, attrs, NULL, &deviceNode);
// currently, we don't care about loosing devices as we cannot do
// anything about that but want to register remaining devices (if possible)
i++;
}
return B_OK;
}
static void
pci_module_get_paths(const char ***_bus, const char ***_device)
{
static const char *kBus[] = {"root", NULL};
*_bus = kBus;
*_device = NULL;
}
static status_t
pci_module_init(device_node_handle node, void *user_cookie, void **_cookie)
{
*_cookie = node;
return B_OK;
}
static int32
pci_old_module_std_ops(int32 op, ...)
{
@@ -184,25 +45,6 @@ pci_old_module_std_ops(int32 op, ...)
}
static int32
pci_module_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
{
module_info *module;
return get_module(B_PCI_MODULE_NAME, &module);
// this serializes our module initialization
}
case B_MODULE_UNINIT:
return put_module(B_PCI_MODULE_NAME);
}
return B_BAD_VALUE;
}
static struct pci_module_info sOldPCIModule = {
{
{
@@ -225,32 +67,6 @@ static struct pci_module_info sOldPCIModule = {
&pci_find_capability
};
static struct pci_root_info sPCIModule = {
{
{
{
PCI_ROOT_MODULE_NAME,
0,
pci_module_std_ops
},
pci_module_supports_device,
pci_module_register_device,
pci_module_init,
NULL, // uninit
NULL, // removed
NULL, // cleanup
pci_module_get_paths,
},
pci_module_register_child_devices,
NULL, // rescan bus
},
&pci_read_config,
&pci_write_config
};
module_dependency module_dependencies[] = {
{B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager},
{}
@@ -258,7 +74,7 @@ module_dependency module_dependencies[] = {
module_info *modules[] = {
(module_info *)&sOldPCIModule,
(module_info *)&sPCIModule,
(module_info *)&gPCIRootModule,
(module_info *)&gPCIDeviceModule,
NULL
};
@@ -1,5 +1,5 @@
/*
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2003-2006, Marcus Overhagen. All rights reserved.
*
* Distributed under the terms of the MIT License.
@@ -14,7 +14,7 @@
// name of PCI device modules
#define PCI_DEVICE_MODULE_NAME "bus_managers/pci/device_v1"
#define PCI_DEVICE_MODULE_NAME "bus_managers/pci/driver_v1"
extern device_manager_info *gDeviceManager;
@@ -22,8 +22,8 @@ extern device_manager_info *gDeviceManager;
// PCI root.
// apart from being the common parent of all PCI devices, it
// manages access to PCI config space
typedef struct pci_root_info {
bus_module_info info;
typedef struct pci_root_module_info {
driver_module_info info;
// read PCI config space
uint32 (*read_pci_config)(uint8 bus, uint8 device, uint8 function,
@@ -32,8 +32,9 @@ typedef struct pci_root_info {
// write PCI config space
void (*write_pci_config)(uint8 bus, uint8 device, uint8 function,
uint8 offset, uint8 size, uint32 value);
} pci_root_info;
} pci_root_module_info;
extern pci_root_module_info gPCIRootModule;
extern pci_device_module_info gPCIDeviceModule;
@@ -0,0 +1,149 @@
/*
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2003, Marcus Overhagen. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <device_manager.h>
#include <PCI.h>
#include <string.h>
#include "pci_private.h"
#include "pci.h"
// name of PCI root module
#define PCI_ROOT_MODULE_NAME "bus_managers/pci/root/driver_v1"
static float
pci_root_supports_device(device_node* parent)
{
// make sure parent is really device root
const char* bus;
if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
return B_ERROR;
if (strcmp(bus, "root"))
return 0.0;
return 1.0;
}
static status_t
pci_root_register_device(device_node* parent)
{
// XXX how do we handle this for PPC?
// I/O port for PCI config space address
#define PCI_CONFIG_ADDRESS 0xcf8
io_resource resources[2] = {
{B_IO_PORT, PCI_CONFIG_ADDRESS, 8},
{}
};
device_attr attrs[] = {
{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "PCI"}},
{B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_KEEP_DRIVER_LOADED}},
{}
};
return gDeviceManager->register_node(parent, PCI_ROOT_MODULE_NAME, attrs,
resources, NULL);
}
static status_t
pci_root_register_child_devices(void* cookie)
{
device_node* node = (device_node*)cookie;
pci_info info;
for (int32 i = 0; pci_get_nth_pci_info(i, &info) == B_OK; i++) {
int domain;
uint8 bus;
if (gPCI->ResolveVirtualBus(info.bus, &domain, &bus) != B_OK) {
dprintf("FAILED!!!!\n");
continue;
}
device_attr attrs[] = {
// info about device
{B_DEVICE_BUS, B_STRING_TYPE, {string: "pci"}},
// location on PCI bus
{B_PCI_DEVICE_DOMAIN, B_UINT32_TYPE, {ui8: domain}},
{B_PCI_DEVICE_BUS, B_UINT8_TYPE, {ui8: bus}},
{B_PCI_DEVICE_DEVICE, B_UINT8_TYPE, {ui8: info.device}},
{B_PCI_DEVICE_FUNCTION, B_UINT8_TYPE, {ui8: info.function}},
// info about the device
{B_DEVICE_VENDOR_ID, B_UINT16_TYPE, { ui16: info.vendor_id }},
{B_DEVICE_ID, B_UINT16_TYPE, { ui16: info.device_id }},
{B_DEVICE_TYPE, B_UINT16_TYPE, { ui16: info.class_base }},
{B_DEVICE_SUB_TYPE, B_UINT16_TYPE, { ui16: info.class_sub }},
{B_DEVICE_INTERFACE, B_UINT16_TYPE, { ui16: info.class_api }},
{B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_FIND_CHILD_ON_DEMAND}},
{}
};
gDeviceManager->register_node(node, PCI_DEVICE_MODULE_NAME, attrs,
NULL, NULL);
}
return B_OK;
}
static status_t
pci_root_init(device_node* node, void** _cookie)
{
*_cookie = node;
return B_OK;
}
static int32
pci_root_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
{
module_info *module;
return get_module(B_PCI_MODULE_NAME, &module);
// this serializes our module initialization
}
case B_MODULE_UNINIT:
return put_module(B_PCI_MODULE_NAME);
}
return B_BAD_VALUE;
}
struct pci_root_module_info gPCIRootModule = {
{
{
PCI_ROOT_MODULE_NAME,
0,
pci_root_std_ops
},
pci_root_supports_device,
pci_root_register_device,
pci_root_init,
NULL, // uninit
pci_root_register_child_devices,
NULL, // rescan devices
NULL, // device removed
},
&pci_read_config,
&pci_write_config
};
+34 -107
View File
@@ -3,54 +3,41 @@
* Distributed under the terms of the MIT License.
*/
/*
Part of Open SCSI bus manager
Devfs entry for raw bus access.
This interface will go away. It's used by scsi_probe as
long as we have no proper pnpfs where all the info can
be retrieved from.
*/
//! Devfs entry for raw bus access.
#include "scsi_internal.h"
#include <device/scsi_bus_raw_driver.h>
#include <pnp_devfs.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <device/scsi_bus_raw_driver.h>
// info about bus
// (used both as bus cookie and file handle cookie)
typedef struct bus_raw_info {
scsi_bus_interface *interface;
scsi_bus cookie;
device_node_handle node;
device_node *node;
} bus_raw_info;
static status_t
scsi_bus_raw_init_device(device_node_handle node,
void *userCookie, void **cookie)
scsi_bus_raw_init(device_node *node, void **cookie)
{
device_node_handle parent = pnp->get_parent(node);
device_node *parent;
bus_raw_info *bus;
scsi_bus_interface *interface;
scsi_bus bus_cookie;
status_t res = pnp->init_driver(parent, NULL,
(driver_module_info **)&interface, (void **)&bus_cookie);
pnp->put_device_node(parent);
if (res != B_OK)
return res;
bus = malloc(sizeof(*bus));
bus->interface = interface;
bus->cookie = bus_cookie;
if (bus == NULL)
return B_NO_MEMORY;
parent = pnp->get_parent_node(node);
pnp->get_driver(parent,
(driver_module_info **)&bus->interface, (void **)&bus->cookie);
pnp->put_node(parent);
bus->node = node;
*cookie = bus;
@@ -58,64 +45,19 @@ scsi_bus_raw_init_device(device_node_handle node,
}
static status_t
scsi_bus_raw_uninit_device(bus_raw_info *bus)
static void
scsi_bus_raw_uninit(void *bus)
{
device_node_handle parent = pnp->get_parent(bus->node);
status_t status = pnp->uninit_driver(parent);
pnp->put_device_node(parent);
if (status != B_OK)
return status;
free(bus);
return B_OK;
}
static status_t
scsi_bus_raw_probe(device_node_handle parent)
{
uint8 path_id;
char *name;
if (pnp->get_attr_uint8(parent, SCSI_BUS_PATH_ID_ITEM, &path_id, false) != B_OK)
return B_ERROR;
// put that on heap to not overflow the limited kernel stack
name = malloc(PATH_MAX + 1);
if (name == NULL)
return B_NO_MEMORY;
snprintf(name, PATH_MAX + 1, "bus/scsi/%d/bus_raw", path_id);
{
device_attr attributes[] = {
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: SCSI_BUS_RAW_MODULE_NAME }},
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: PNP_DEVFS_MODULE_NAME }},
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "bus_raw" }},
{ PNP_DEVFS_FILENAME, B_STRING_TYPE, { string: name }},
{}
};
device_node_handle node;
status_t res = pnp->register_device(parent, attributes, NULL, &node);
free(name);
return res;
}
}
static status_t
scsi_bus_raw_open(bus_raw_info *bus, uint32 flags,
bus_raw_info **handle_cookie)
scsi_bus_raw_open(void *bus, const char *path, uint32 flags,
void **handle_cookie)
{
*handle_cookie = bus;
return B_ERROR;
return B_OK;
}
@@ -129,14 +71,15 @@ scsi_bus_raw_close(void *cookie)
static status_t
scsi_bus_raw_free(void *cookie)
{
return B_ERROR;
return B_OK;
}
static status_t
scsi_bus_raw_control(bus_raw_info *bus, uint32 op, void *data,
size_t len)
scsi_bus_raw_control(void *_cookie, int32 op, void *data, size_t length)
{
bus_raw_info *bus = _cookie;
switch (op) {
case B_SCSI_BUS_RAW_RESET:
return bus->interface->reset_bus(bus->cookie);
@@ -167,40 +110,24 @@ scsi_bus_raw_write(void *cookie, off_t position,
}
static status_t
std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
default:
return B_ERROR;
}
}
pnp_devfs_driver_info scsi_bus_raw_module = {
{
struct device_module_info gSCSIBusRawModule = {
{
SCSI_BUS_RAW_MODULE_NAME,
0,
std_ops
},
NULL,
scsi_bus_raw_probe,
scsi_bus_raw_init_device,
(status_t (*) (void *))scsi_bus_raw_uninit_device,
NULL,
NULL
},
(status_t (*) (void *, uint32, void **))scsi_bus_raw_open,
scsi_bus_raw_init,
scsi_bus_raw_uninit,
NULL, // removed
scsi_bus_raw_open,
scsi_bus_raw_close,
scsi_bus_raw_free,
(status_t (*) (void *, uint32, void *, size_t))scsi_bus_raw_control,
scsi_bus_raw_read,
scsi_bus_raw_write
scsi_bus_raw_write,
NULL, // io
scsi_bus_raw_control,
NULL, // select
NULL // deselect
};
+12 -28
View File
@@ -85,7 +85,7 @@ scsi_service_threadproc(void *arg)
static scsi_bus_info *
scsi_create_bus(device_node_handle node, uint8 path_id)
scsi_create_bus(device_node *node, uint8 path_id)
{
scsi_bus_info *bus;
int res;
@@ -153,8 +153,6 @@ err2:
err3:
delete_sem(bus->start_service);
err4:
//scsi_destroy_device(bus->global_device);
//err5:
delete_sem(bus->scan_lun_lock);
err6:
free(bus);
@@ -184,9 +182,8 @@ scsi_destroy_bus(scsi_bus_info *bus)
static status_t
scsi_init_bus(device_node_handle node, void *user_cookie, void **cookie)
scsi_init_bus(device_node *node, void **cookie)
{
device_node_handle parent;
uint8 path_id;
scsi_bus_info *bus;
status_t res;
@@ -244,15 +241,14 @@ scsi_init_bus(device_node_handle node, void *user_cookie, void **cookie)
goto err;
}
parent = pnp->get_parent(node);
{
device_node *parent = pnp->get_parent_node(node);
pnp->get_driver(parent, (driver_module_info **)&bus->interface,
(void **)&bus->sim_cookie);
pnp->put_node(parent);
res = pnp->init_driver(parent, bus,
(driver_module_info **)&bus->interface, (void **)&bus->sim_cookie);
pnp->put_device_node(parent);
if (res != B_OK)
goto err;
bus->interface->set_scsi_bus(bus->sim_cookie, bus);
}
// cache inquiry data
scsi_inquiry_path(bus, &bus->inquiry_data);
@@ -271,16 +267,10 @@ err:
}
static status_t
static void
scsi_uninit_bus(scsi_bus_info *bus)
{
device_node_handle parent = pnp->get_parent(bus->node);
pnp->uninit_driver(parent);
pnp->put_device_node(parent);
scsi_destroy_bus(bus);
return B_OK;
}
@@ -288,7 +278,6 @@ uchar
scsi_inquiry_path(scsi_bus bus, scsi_path_inquiry *inquiry_data)
{
SHOW_FLOW(4, "path_id=%d", bus->path_id);
return bus->interface->path_inquiry(bus->sim_cookie, inquiry_data);
}
@@ -304,7 +293,6 @@ static status_t
scsi_bus_module_init(void)
{
SHOW_FLOW0(4, "");
return init_temp_sg();
}
@@ -315,7 +303,6 @@ scsi_bus_module_uninit(void)
SHOW_INFO0(4, "");
uninit_temp_sg();
return B_OK;
}
@@ -336,7 +323,6 @@ std_ops(int32 op, ...)
scsi_bus_interface scsi_bus_module = {
{
{
{
SCSI_BUS_MODULE_NAME,
@@ -347,10 +333,8 @@ scsi_bus_interface scsi_bus_module = {
NULL, // supported devices
NULL, // register node
scsi_init_bus,
(status_t (*)(void *))scsi_uninit_bus,
NULL
},
(void (*)(void *))scsi_uninit_bus,
(status_t (*)(void *))scsi_scan_bus,
(status_t (*)(void *))scsi_scan_bus,
NULL
},
+34 -90
View File
@@ -22,22 +22,6 @@
#include <stdio.h>
#ifdef USE_FAST_LOG
static fast_log_event_type scsi_device_events[] = {
{ ev_scsi_requeue_request, "ev_scsi_requeue_request" },
{ ev_scsi_resubmit_request, "ev_scsi_resubmit_request" },
{ ev_scsi_submit_autosense, "ev_scsi_submit_autosense" },
{ ev_scsi_finish_autosense, "ev_scsi_finish_autosense" },
{ ev_scsi_device_queue_overflow, "ev_scsi_device_queue_overflow" },
{ ev_scsi_request_finished, "ev_scsi_request_finished" },
{ ev_scsi_async_io, "ev_scsi_async_io" },
{ ev_scsi_do_resend_request, "ev_scsi_do_resend_request" },
{ ev_copy_sg_data, "ev_copy_sg_data" },
{}
};
#endif
/** free autosense request of device */
static void
@@ -74,11 +58,6 @@ scsi_free_device(scsi_device_info *device)
DELETE_BEN(&device->dma_buffer_lock);
delete_sem(device->dma_buffer_owner);
#ifdef USE_FAST_LOG
if (device->log != NULL)
fast_log->stop_log(device->log);
#endif
free(device);
}
@@ -133,15 +112,9 @@ scsi_register_device(scsi_bus_info *bus, uchar target_id,
char product_ident[sizeof( inquiry_data->product_ident ) + 1];
char product_rev[sizeof( inquiry_data->product_rev ) + 1];
device_attr attrs[] = {
// info about driver
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: SCSI_DEVICE_MODULE_NAME }},
// connection
{ SCSI_DEVICE_TARGET_ID_ITEM, B_UINT8_TYPE, { ui8: target_id }},
{ SCSI_DEVICE_TARGET_LUN_ITEM, B_UINT8_TYPE, { ui8: target_lun }},
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string:
"target: %"SCSI_DEVICE_TARGET_ID_ITEM
"%, lun: %"SCSI_DEVICE_TARGET_LUN_ITEM"%" }},
// inquiry data (used for both identification and information)
{ SCSI_DEVICE_INQUIRY_ITEM, B_RAW_TYPE,
@@ -154,8 +127,7 @@ scsi_register_device(scsi_bus_info *bus, uchar target_id,
{ SCSI_DEVICE_REVISION_ITEM, B_STRING_TYPE, { string: product_rev }},
// description of peripheral drivers
{ B_DRIVER_BUS, B_STRING_TYPE, { string: "scsi" }},
// ToDo: mapping is missing
{ B_DEVICE_BUS, B_STRING_TYPE, { string: "scsi" }},
// extra restriction of maximum number of blocks per transfer
{ B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: max_blocks }},
@@ -166,16 +138,13 @@ scsi_register_device(scsi_bus_info *bus, uchar target_id,
{ SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM, B_UINT8_TYPE, { ui8: manual_autosense }},
{ NULL }
};
device_node_handle node;
status_t res;
beautify_string(vendor_ident, inquiry_data->vendor_ident, sizeof(vendor_ident));
beautify_string(product_ident, inquiry_data->product_ident, sizeof(product_ident));
beautify_string(product_rev, inquiry_data->product_rev, sizeof(product_rev));
res = pnp->register_device(bus->node, attrs, NULL, &node);
if (res < 0)
return res;
return pnp->register_node(bus->node, SCSI_DEVICE_MODULE_NAME, attrs,
NULL, NULL);
}
return B_OK;
@@ -184,7 +153,7 @@ scsi_register_device(scsi_bus_info *bus, uchar target_id,
// create data structure for a device
static scsi_device_info *
scsi_create_device(device_node_handle node, scsi_bus_info *bus,
scsi_create_device(device_node *node, scsi_bus_info *bus,
int target_id, int target_lun)
{
scsi_device_info *device;
@@ -289,15 +258,13 @@ err:
#define SET_BIT(field, bit) field[(bit) >> 3] |= 1 << ((bit) & 7)
static status_t
scsi_init_device(device_node_handle node, void *user_cookie, void **cookie)
scsi_init_device(device_node *node, void **cookie)
{
device_node_handle parent = pnp->get_parent(node);
scsi_res_inquiry *inquiry_data = NULL;
const scsi_res_inquiry *inquiry_data = NULL;
uint8 target_id, target_lun, path_id;
scsi_bus_info *bus;
scsi_device_info *device;
status_t res;
driver_module_info *bus_interface;
size_t inquiry_data_len;
uint8 is_atapi, manual_autosense;
@@ -308,38 +275,26 @@ scsi_init_device(device_node_handle node, void *user_cookie, void **cookie)
|| pnp->get_attr_uint8( node, SCSI_DEVICE_IS_ATAPI_ITEM, &is_atapi, false) != B_OK
|| pnp->get_attr_uint8( node, SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM, &manual_autosense, false) != B_OK
|| pnp->get_attr_raw( node, SCSI_DEVICE_INQUIRY_ITEM,
(void **)&inquiry_data, &inquiry_data_len, false) != B_OK
(const void **)&inquiry_data, &inquiry_data_len, false) != B_OK
|| inquiry_data_len != sizeof(*inquiry_data)) {
res = B_ERROR;
goto err1;
return B_ERROR;
}
res = pnp->init_driver(parent, NULL, &bus_interface,
(void **)&bus);
if (res != B_OK)
goto err1;
{
device_node *parent = pnp->get_parent_node(node);
pnp->get_driver(parent, NULL, (void **)&bus);
pnp->put_node(parent);
}
device = scsi_create_device(node, bus, target_id, target_lun);
if (device == NULL) {
res = B_NO_MEMORY;
goto err2;
}
if (device == NULL)
return B_NO_MEMORY;
// never mind if there is no path - it might be an emulated controller
path_id = -1;
pnp->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &path_id, true);
sprintf(device->name, "scsi_device %u:%u:%u", path_id, target_id, target_lun);
#ifdef USE_FAST_LOG
device->log = fast_log->start_log(device->name, scsi_device_events);
if (device->log == NULL) {
res = B_NO_MEMORY;
goto err3;
}
#endif
device->inquiry_data = *inquiry_data;
// save restrictions
@@ -365,14 +320,14 @@ scsi_init_device(device_node_handle node, void *user_cookie, void **cookie)
if (device->manual_autosense) {
if (scsi_create_autosense_request(device) != B_OK) {
res = B_NO_MEMORY;
goto err3;
goto err;
}
}
// if this is an ATAPI device, we need an emulation buffer
if (scsi_init_emulation_buffer(device, SCSI_ATAPI_BUFFER_SIZE) != B_OK) {
res = B_NO_MEMORY;
goto err3;
goto err;
}
memset(device->emulation_map, 0, sizeof(device->emulation_map));
@@ -385,41 +340,26 @@ scsi_init_device(device_node_handle node, void *user_cookie, void **cookie)
SET_BIT(device->emulation_map, SCSI_OP_INQUIRY);
}
free(inquiry_data);
*cookie = device;
return B_OK;
err3:
err:
scsi_free_device(device);
err2:
pnp->uninit_driver(parent);
err1:
pnp->put_device_node(parent);
free(inquiry_data);
return res;
}
static status_t
static void
scsi_uninit_device(scsi_device_info *device)
{
device_node_handle parent = pnp->get_parent(device->node);
SHOW_FLOW0(3, "");
scsi_free_device(device);
// must unload parent at last as scsi_free_device access it
pnp->uninit_driver(parent);
pnp->put_device_node(parent);
return B_OK;
}
static void
scsi_device_removed(device_node_handle node, scsi_device_info *device)
scsi_device_removed(scsi_device_info *device)
{
SHOW_FLOW0(3, "");
@@ -445,7 +385,7 @@ scsi_force_get_device(scsi_bus_info *bus, uchar target_id,
{ SCSI_DEVICE_TARGET_LUN_ITEM, B_UINT8_TYPE, { ui8: target_lun }},
{ NULL }
};
device_node_handle node;
device_node *node;
status_t res;
driver_module_info *driver_interface;
scsi_device device;
@@ -457,15 +397,16 @@ scsi_force_get_device(scsi_bus_info *bus, uchar target_id,
// check whether device registered already
node = NULL;
pnp->get_next_child_device(bus->node, &node, attrs);
pnp->get_next_child_node(bus->node, attrs, &node);
SHOW_FLOW(3, "%p", node);
if (node != NULL) {
// TODO: have a second look a this one!
// there is one - get it
res = pnp->init_driver(node, NULL, &driver_interface,
(void **)&device);
pnp->put_device_node(node);
res = pnp->get_driver(node, &driver_interface, (void **)&device);
if (res != B_OK)
pnp->put_node(node);
} else {
// device doesn't exist yet - create a temporary one
device = scsi_create_device(NULL, bus, target_id, target_lun);
@@ -495,12 +436,13 @@ scsi_put_forced_device(scsi_device_info *device)
SHOW_FLOW0(3, "");
if (device->node != NULL)
if (device->node != NULL) {
// device is registered
pnp->uninit_driver(device->node);
else
pnp->put_node(device->node);
} else {
// device is temporary
scsi_free_device(device);
}
release_sem(bus->scan_lun_lock);
}
@@ -563,8 +505,10 @@ scsi_device_interface scsi_device_module = {
NULL, // supported devices
NULL, // register node
scsi_init_device,
(status_t (*)(void *)) scsi_uninit_device,
(void (*)(device_node_handle, void *)) scsi_device_removed
(void (*)(void *)) scsi_uninit_device,
NULL, // register child devices
NULL, // rescan
(void (*)(void *)) scsi_device_removed
},
scsi_alloc_ccb,
@@ -475,23 +475,6 @@ copy_sg_data(scsi_ccb *request, uint offset, uint allocation_length,
else
memcpy((void *)(virtualAddress + offset), buffer, bytes);
#if 0
{
int i;
for (i = 0; i < bytes; ++i) {
char byte;
if (to_buffer)
byte = ((char *)virtualAddress)[offset + i];
else
byte = ((char *)buffer)[i];
FAST_LOG1( request->device->log, ev_copy_sg_data, byte );
}
}
#endif
vm_put_physical_page(virtualAddress);
buffer = (char *)buffer + bytes;
+1 -7
View File
@@ -3,12 +3,6 @@
* Distributed under the terms of the MIT License.
*/
/*
Part of Open SCSI bus manager
Main file
*/
#include "scsi_internal.h"
#include <pnp_devfs.h>
@@ -25,6 +19,6 @@ module_info *modules[] = {
(module_info *)&scsi_for_sim_module,
(module_info *)&scsi_bus_module,
(module_info *)&scsi_device_module,
(module_info *)&scsi_bus_raw_module,
(module_info *)&gSCSIBusRawModule,
NULL
};
@@ -12,33 +12,14 @@
#include <scsi_cmds.h>
#include <locked_pool.h>
#include <device_manager.h>
#include <fast_log.h>
#define debug_level_error 2
#define debug_level_info 1
#define debug_level_flow 0
#define debug_level_error 4
#define debug_level_info 4
#define debug_level_flow 4
#define DEBUG_MSG_PREFIX "SCSI -- "
#include "wrapper.h"
//#define USE_FAST_LOG
#ifdef USE_FAST_LOG
#define FAST_LOG0( handle, event ) fast_log->log_0( handle, event )
#define FAST_LOG1( handle, event, param ) fast_log->log_1( handle, event, param )
#define FAST_LOG2( handle, event, param1, param2 ) fast_log->log_2( handle, event, param1, param2 )
#define FAST_LOG3( handle, event, param1, param2, param3 ) fast_log->log_3( handle, event, param1, param2, param3 )
#define FAST_LOGN( handle, event, num_params... ) fast_log->log_n( handle, event, num_params )
#else
#define FAST_LOG0( handle, event )
#define FAST_LOG1( handle, event, param )
#define FAST_LOG2( handle, event, param1, param2 )
#define FAST_LOG3( handle, event, param1, param2, param3 )
#define FAST_LOGN( handle, event, num_params... )
#endif
#include "scsi_lock.h"
@@ -77,7 +58,7 @@
#define SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM "scsi/manual_autosense"
// name of internal scsi_bus_raw device driver
#define SCSI_BUS_RAW_MODULE_NAME "bus_managers/scsi/bus/raw"
#define SCSI_BUS_RAW_MODULE_NAME "bus_managers/scsi/bus/raw/device_v1"
// info about DPC
typedef struct scsi_dpc_info {
@@ -127,7 +108,7 @@ typedef struct scsi_bus_info {
locked_pool_cookie ccb_pool; // ccb pool (one per bus)
device_node_handle node; // pnp node of bus
device_node *node; // pnp node of bus
dma_params dma_params; // dma restrictions of controller
@@ -191,17 +172,12 @@ typedef struct scsi_device_info {
// and thus must be emulated
scsi_res_inquiry inquiry_data;
device_node_handle node; // device node
device_node *node; // device node
benaphore dma_buffer_lock; // lock between DMA buffer user and clean-up daemon
sem_id dma_buffer_owner; // to be acquired before using DMA buffer
dma_buffer dma_buffer; // DMA buffer
#ifdef USE_FAST_LOG
fast_log_handle log; // fast log connection
#endif
char name[30]; // name for fast log entries
// buffer used for emulating SCSI commands
char *buffer;
physical_entry *buffer_sg_list;
@@ -240,12 +216,11 @@ enum {
extern locked_pool_interface *locked_pool;
extern device_manager_info *pnp;
extern fast_log_info *fast_log;
extern scsi_for_sim_interface scsi_for_sim_module;
extern scsi_bus_interface scsi_bus_module;
extern scsi_device_interface scsi_device_module;
extern struct pnp_devfs_driver_info scsi_bus_raw_module;
extern struct device_module_info gSCSIBusRawModule;
@@ -23,7 +23,6 @@ scsi_requeue_request(scsi_ccb *request, bool bus_overflow)
scsi_device_info *device = request->device;
bool was_servicable, start_retry;
FAST_LOG1(device->log, ev_scsi_requeue_request, (uint32)request);
SHOW_FLOW0(3, "");
if (request->state != SCSI_STATE_SENT) {
@@ -86,7 +85,6 @@ scsi_resubmit_request(scsi_ccb *request)
scsi_device_info *device = request->device;
bool was_servicable, start_retry;
FAST_LOG1(device->log, ev_scsi_resubmit_request, (uint32)request);
SHOW_FLOW0(3, "");
if (request->state != SCSI_STATE_SENT) {
@@ -141,7 +139,6 @@ submit_autosense(scsi_ccb *request)
{
scsi_device_info *device = request->device;
FAST_LOG1(device->log, ev_scsi_submit_autosense, (uint32)request);
//snooze(1000000);
SHOW_FLOW0(3, "sending autosense");
@@ -174,7 +171,6 @@ finish_autosense(scsi_device_info *device)
scsi_ccb *orig_request = device->auto_sense_originator;
scsi_ccb *request = device->auto_sense_request;
FAST_LOG2(device->log, ev_scsi_finish_autosense, (uint32)request, (uint32)orig_request);
SHOW_FLOW0(3, "");
if (request->subsys_status == SCSI_REQ_CMP) {
@@ -209,8 +205,6 @@ scsi_device_queue_overflow(scsi_ccb *request, uint num_requests)
scsi_device_info *device = request->device;
int diff_max_slots;
FAST_LOG2(device->log, ev_scsi_device_queue_overflow, (uint32)request, num_requests);
// set maximum number of concurrent requests to number of
// requests running when QUEUE FULL condition occurred - 1
// (the "1" is the refused request)
@@ -245,7 +239,6 @@ scsi_request_finished(scsi_ccb *request, uint num_requests)
scsi_bus_info *bus = request->bus;
bool was_servicable, start_service, do_autosense;
FAST_LOG2(device->log, ev_scsi_request_finished, (uint32)request, num_requests);
SHOW_FLOW(3, "%p", request);
if (request->state != SCSI_STATE_SENT) {
@@ -413,14 +406,6 @@ scsi_async_io(scsi_ccb *request)
goto err;
}
FAST_LOGN(request->device->log, ev_scsi_async_io,
func_group_len[request->cdb[0] >> 5] + 2,
(uint32)request, request->data_length,
request->cdb[0], request->cdb[1], request->cdb[2], request->cdb[3],
request->cdb[4], request->cdb[5], request->cdb[6], request->cdb[7],
request->cdb[8], request->cdb[9], request->cdb[10], request->cdb[11],
request->cdb[12], request->cdb[13], request->cdb[14], request->cdb[15]);
if (!request->device->valid) {
SHOW_ERROR0( 3, "device got removed" );
@@ -636,8 +621,6 @@ scsi_check_exec_service(scsi_bus_info *bus)
RELEASE_BEN(&bus->mutex);
FAST_LOG1(request->device->log, ev_scsi_do_resend_request, (uint32)request);
request->state = SCSI_STATE_SENT;
bus->interface->scsi_io(bus->sim_cookie, request);
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2006, Haiku, Inc. All RightsReserved.
* Copyright 2004-2008, Haiku, Inc. All RightsReserved.
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
@@ -13,6 +13,7 @@
#include "scsi_internal.h"
#include "queuing.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -23,10 +24,10 @@
*/
static status_t
scsi_controller_added(device_node_handle parent)
scsi_controller_added(device_node *parent)
{
char *controller_name;
int path_id;
const char *controller_name;
int pathID;
SHOW_FLOW0(4, "");
@@ -36,52 +37,67 @@ scsi_controller_added(device_node_handle parent)
return B_ERROR;
}
path_id = pnp->create_id(SCSI_PATHID_GENERATOR);
if (path_id < 0) {
pathID = pnp->create_id(SCSI_PATHID_GENERATOR);
if (pathID < 0) {
dprintf("scsi: Cannot register SCSI controller %s - out of path IDs\n",
controller_name);
free(controller_name);
return B_ERROR;
}
free(controller_name);
{
device_attr attrs[] = {
// general information
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: SCSI_BUS_MODULE_NAME }},
// we are a bus
{ PNP_BUS_IS_BUS, B_UINT8_TYPE, { ui8: 1 }},
// remember who we are
// (could use the controller name, but probably some software would choke)
{ SCSI_BUS_PATH_ID_ITEM, B_UINT8_TYPE, { ui8: path_id }},
{ SCSI_BUS_PATH_ID_ITEM, B_UINT8_TYPE, { ui8: pathID }},
// tell PnP manager to clean up ID
{ PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, { string: SCSI_PATHID_GENERATOR }},
{ PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: path_id }},
// tell internal bus raw driver to register bus' device in devfs
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: SCSI_BUS_RAW_MODULE_NAME }},
{ NULL, 0 }
// { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, { string: SCSI_PATHID_GENERATOR }},
// { PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: path_id }},
{}
};
device_node_handle node;
return pnp->register_node(parent, SCSI_BUS_MODULE_NAME, attrs, NULL,
NULL);
}
}
static status_t
scsi_controller_init(device_node *node, void **_cookie)
{
*_cookie = node;
return B_OK;
}
static status_t
scsi_controller_register_raw_device(void *_cookie)
{
device_node *node = (device_node *)_cookie;
uint32 channel;
uint8 pathID;
char *name;
#if 1
// TODO: this seems to cause a crash in some configurations, and needs to be investigated!
// see bug #389 and #393.
#if 0
uint32 channel;
if (pnp->get_attr_uint32(parent, "ide/channel_id", &channel, true) == B_OK) {
// TODO: check if the above is still true
if (pnp->get_attr_uint32(node, "ide/channel_id", &channel, true) == B_OK) {
// this is actually an IDE device, we don't need to publish
// a bus device for those
attrs[5].name = NULL;
return B_OK;
}
#endif
pnp->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &pathID, false);
return pnp->register_device(parent, attrs, NULL, &node);
}
// put that on heap to not overflow the limited kernel stack
name = malloc(PATH_MAX + 1);
if (name == NULL)
return B_NO_MEMORY;
snprintf(name, PATH_MAX + 1, "bus/scsi/%d/bus_raw", pathID);
return pnp->publish_device(node, name, SCSI_BUS_RAW_MODULE_NAME);
}
@@ -110,9 +126,11 @@ scsi_for_sim_interface scsi_for_sim_module =
NULL, // supported devices
scsi_controller_added,
NULL,
NULL,
NULL
scsi_controller_init,
NULL, // uninit
scsi_controller_register_raw_device,
NULL, // rescan
NULL, // removed
},
scsi_requeue_request,
@@ -43,7 +43,7 @@
#endif
#ifndef debug_level_flow
# define debug_level_flow 3
# define debug_level_flow 4
#endif
#ifndef debug_level_info
@@ -23,7 +23,7 @@
#include "wrapper.h"
#define GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME "busses/ide/generic_ide_pci/device_v1"
#define GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME "busses/ide/generic_ide_pci/driver_v1"
#define GENERIC_IDE_PCI_CHANNEL_MODULE_NAME "busses/ide/generic_ide_pci/channel/v1"
#define IDE_PCI_CONTROLLER_TYPE_NAME "ide pci controller"
@@ -33,6 +33,13 @@ static ide_adapter_interface *ide_adapter;
device_manager_info *pnp;
static void
set_channel(void *cookie, ide_channel channel)
{
ide_adapter->set_channel((ide_adapter_channel_info *)cookie, channel);
}
static status_t
write_command_block_regs(void *channel_cookie, ide_task_file *tf, ide_reg_mask mask)
{
@@ -99,54 +106,52 @@ finish_dma(void *channel_cookie)
static status_t
init_channel(device_node_handle node, ide_channel ide_channel,
void **channel_cookie)
init_channel(device_node *node, void **channel_cookie)
{
return ide_adapter->init_channel(node, ide_channel,
return ide_adapter->init_channel(node,
(ide_adapter_channel_info **)channel_cookie,
sizeof(ide_adapter_channel_info), ide_adapter->inthand);
}
static status_t
static void
uninit_channel(void *channel_cookie)
{
return ide_adapter->uninit_channel((ide_adapter_channel_info *)channel_cookie);
ide_adapter->uninit_channel((ide_adapter_channel_info *)channel_cookie);
}
static void
channel_removed(device_node_handle node, void *channel_cookie)
channel_removed(void *channel_cookie)
{
return ide_adapter->channel_removed(node, (ide_adapter_channel_info *)channel_cookie);
ide_adapter->channel_removed((ide_adapter_channel_info *)channel_cookie);
}
static status_t
init_controller(device_node_handle node, void *user_cookie,
ide_adapter_controller_info **cookie)
init_controller(device_node *node, ide_adapter_controller_info **cookie)
{
return ide_adapter->init_controller(node, user_cookie, cookie,
return ide_adapter->init_controller(node, cookie,
sizeof( ide_adapter_controller_info));
}
static status_t
static void
uninit_controller(ide_adapter_controller_info *controller)
{
return ide_adapter->uninit_controller(controller);
ide_adapter->uninit_controller(controller);
}
static void
controller_removed(device_node_handle node, ide_adapter_controller_info *controller)
controller_removed(ide_adapter_controller_info *controller)
{
return ide_adapter->controller_removed(node, controller);
return ide_adapter->controller_removed(controller);
}
static status_t
probe_controller(device_node_handle parent)
probe_controller(device_node *parent)
{
return ide_adapter->probe_controller(parent,
GENERIC_IDE_PCI_CONTROLLER_MODULE_NAME, "generic_ide_pci",
@@ -162,35 +167,22 @@ probe_controller(device_node_handle parent)
static float
supports_device(device_node_handle parent, bool *_noConnection)
supports_device(device_node *parent)
{
char *bus;
uint8 baseClass, subClass;
const char *bus;
uint16 baseClass, subClass;
// make sure parent is an PCI IDE mass storage host adapter device node
if (pnp->get_attr_string(parent, B_DRIVER_BUS, &bus, false) != B_OK
|| pnp->get_attr_uint8(parent, PCI_DEVICE_BASE_CLASS_ID_ITEM, &baseClass, false) != B_OK
|| pnp->get_attr_uint8(parent, PCI_DEVICE_SUB_CLASS_ID_ITEM, &subClass, false) != B_OK)
return B_ERROR;
if (pnp->get_attr_string(parent, B_DEVICE_BUS, &bus, false) != B_OK
|| pnp->get_attr_uint16(parent, B_DEVICE_TYPE, &baseClass, false) != B_OK
|| pnp->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subClass, false) != B_OK)
return -1;
if (strcmp(bus, "pci") || baseClass != PCI_mass_storage || subClass != PCI_ide) {
free(bus);
return 0.0;
}
if (strcmp(bus, "pci") || baseClass != PCI_mass_storage
|| subClass != PCI_ide)
return 0.0f;
free(bus);
return 0.3;
}
static void
get_paths(const char ***_bus, const char ***_device)
{
static const char *kBus[] = { "pci", NULL };
static const char *kDevice[] = { "drivers/dev/disk/ide", NULL };
*_bus = kBus;
*_device = kDevice;
return 0.3f;
}
@@ -227,13 +219,15 @@ static ide_controller_interface channel_interface = {
NULL, // supports device
NULL, // register device
(status_t (*)(device_node_handle, void *, void **))init_channel,
(status_t (*)(device_node *, void **))init_channel,
uninit_channel,
NULL, // register child devices
NULL, // rescan
channel_removed,
NULL, // cleanup
NULL, // get_paths
},
&set_channel,
&write_command_block_regs,
&read_command_block_regs,
@@ -258,11 +252,11 @@ static driver_module_info controller_interface = {
supports_device,
probe_controller,
(status_t (*)(device_node_handle, void *, void **)) init_controller,
(status_t (*)(void *)) uninit_controller,
(void (*)(device_node_handle, void *)) controller_removed,
NULL, // cleanup
get_paths,
(status_t (*)(device_node *, void **)) init_controller,
(void (*)(void *)) uninit_controller,
NULL, // register child devices
NULL, // rescan
(void (*)(void *)) controller_removed,
};
module_info *modules[] = {
+65 -120
View File
@@ -131,7 +131,7 @@ get_device_info(uint16 vendorID, uint16 deviceID, const char **name,
static status_t
register_sim(device_node_handle parent)
register_sim(device_node *parent)
{
int32 id = gDeviceManager->create_id(AHCI_ID_GENERATOR);
if (id < 0)
@@ -139,25 +139,22 @@ register_sim(device_node_handle parent)
{
device_attr attrs[] = {
{ B_DRIVER_MODULE, B_STRING_TYPE,
{ string: AHCI_SIM_MODULE_NAME }},
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE,
{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
{ string: SCSI_FOR_SIM_MODULE_NAME }},
{ SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE,
{ string: AHCI_DEVICE_MODULE_NAME }},
{ B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: 255 }},
{ AHCI_ID_ITEM, B_UINT32_TYPE, { ui32: id }},
{ PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE,
{ string: AHCI_ID_GENERATOR }},
{ PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: id }},
// { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE,
// { string: AHCI_ID_GENERATOR }},
// { PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { ui32: id }},
{ NULL }
};
device_node_handle node;
status_t status = gDeviceManager->register_device(parent, attrs, NULL,
&node);
status_t status = gDeviceManager->register_node(parent,
AHCI_SIM_MODULE_NAME, attrs, NULL, NULL);
if (status < B_OK)
gDeviceManager->free_id(AHCI_ID_GENERATOR, id);
@@ -170,33 +167,38 @@ register_sim(device_node_handle parent)
static float
ahci_supports_device(device_node_handle parent, bool *_noConnection)
ahci_supports_device(device_node *parent)
{
uint8 baseClass, subClass, classAPI;
uint16 baseClass, subClass, classAPI;
uint16 vendorID;
uint16 deviceID;
bool isPCI;
const char *name;
char *bus;
const char *bus;
TRACE("ahci_supports_device\n");
if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false) < B_OK)
return 0.0f;
isPCI = !strcmp(bus, "pci");
free(bus);
if (!isPCI)
if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)
< B_OK)
return 0.0f;
if (gDeviceManager->get_attr_uint8(parent, PCI_DEVICE_BASE_CLASS_ID_ITEM, &baseClass, false) < B_OK
|| gDeviceManager->get_attr_uint8(parent, PCI_DEVICE_SUB_CLASS_ID_ITEM, &subClass, false) < B_OK
|| gDeviceManager->get_attr_uint8(parent, PCI_DEVICE_API_ID_ITEM, &classAPI, false) < B_OK
|| gDeviceManager->get_attr_uint16(parent, PCI_DEVICE_VENDOR_ID_ITEM, &vendorID, false) < B_OK
|| gDeviceManager->get_attr_uint16(parent, PCI_DEVICE_DEVICE_ID_ITEM, &deviceID, false) < B_OK)
if (strcmp(bus, "pci"))
return 0.0f;
if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &baseClass,
false) < B_OK
|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subClass,
false) < B_OK
|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_INTERFACE,
&classAPI, false) < B_OK
|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_VENDOR_ID,
&vendorID, false) < B_OK
|| gDeviceManager->get_attr_uint16(parent, B_DEVICE_ID, &deviceID,
false) < B_OK)
return 0.0f;
if (get_device_info(vendorID, deviceID, &name, NULL) < B_OK) {
if (baseClass != PCI_mass_storage || subClass != PCI_sata || classAPI != PCI_sata_ahci)
if (baseClass != PCI_mass_storage || subClass != PCI_sata
|| classAPI != PCI_sata_ahci)
return 0.0f;
TRACE("generic AHCI controller found! vendor 0x%04x, device 0x%04x\n", vendorID, deviceID);
return 0.8f;
@@ -205,23 +207,15 @@ ahci_supports_device(device_node_handle parent, bool *_noConnection)
if (vendorID == PCI_VENDOR_JMICRON) {
// JMicron uses the same device ID for SATA and PATA controllers,
// check if BAR5 exists to determine if it's a AHCI controller
uint8 bus, device, function;
pci_device_module_info *pci;
pci_device *device;
pci_info info;
pci_module_info *pci;
size_t size = 0;
int i;
gDeviceManager->get_attr_uint8(parent, PCI_DEVICE_BUS_ITEM, &bus, false);
gDeviceManager->get_attr_uint8(parent, PCI_DEVICE_DEVICE_ITEM, &device, false);
gDeviceManager->get_attr_uint8(parent, PCI_DEVICE_FUNCTION_ITEM, &function, false);
get_module(B_PCI_MODULE_NAME, (module_info **)&pci);
for (i = 0; B_OK == pci->get_nth_pci_info(i, &info); i++) {
if (info.bus == bus && info.device == device && info.function == function) {
size = info.u.h0.base_register_sizes[5];
break;
}
}
put_module(B_PCI_MODULE_NAME);
if (size == 0)
gDeviceManager->get_driver(parent, (driver_module_info **)&pci,
(void **)&device);
pci->get_pci_info(device, &info);
if (info.u.h0.base_register_sizes[5] == 0)
return 0.0f;
}
@@ -231,15 +225,9 @@ ahci_supports_device(device_node_handle parent, bool *_noConnection)
static status_t
ahci_register_device(device_node_handle parent)
ahci_register_device(device_node *parent)
{
device_node_handle node;
status_t status;
device_attr attrs[] = {
// info about ourself and our consumer
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: AHCI_DEVICE_MODULE_NAME }},
{ SCSI_DEVICE_MAX_TARGET_COUNT, B_UINT32_TYPE,
{ ui32: 33 }},
@@ -261,86 +249,44 @@ ahci_register_device(device_node_handle parent)
TRACE("ahci_register_device\n");
status = gDeviceManager->register_device(parent, attrs,
NULL, &node);
if (status < B_OK)
return status;
return gDeviceManager->register_node(parent, AHCI_DEVICE_MODULE_NAME,
attrs, NULL, NULL);
}
static status_t
ahci_init_driver(device_node *node, void **_cookie)
{
TRACE("ahci_init_driver\n");
*_cookie = node;
return B_OK;
}
static void
ahci_uninit_driver(void *cookie)
{
TRACE("ahci_uninit_driver, cookie %p\n", cookie);
}
static status_t
ahci_register_child_devices(void *cookie)
{
device_node *node = (device_node *)cookie;
// TODO: register SIM for every controller we find!
return register_sim(node);
}
static status_t
ahci_init_driver(device_node_handle node, void *userCookie, void **_cookie)
{
pci_device *_userCookie = userCookie;
pci_device pciDevice;
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;
TRACE("ahci_init_driver: gPCI %p, pciDevice %p\n", gPCI, pciDevice);
gDeviceManager->put_device_node(parent);
*_userCookie = pciDevice;
*_cookie = node;
return B_OK;
}
static status_t
ahci_uninit_driver(void *cookie)
{
device_node_handle node = cookie;
device_node_handle parent;
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;
}
static void
ahci_device_removed(device_node_handle node, void *cookie)
ahci_device_removed(void *cookie)
{
TRACE("ahci_device_removed, cookie %p\n", cookie);
}
static void
ahci_device_cleanup(device_node_handle node)
{
TRACE("ahci_device_cleanup\n");
}
static void
ahci_get_supported_paths(const char ***_busses, const char ***_devices)
{
static const char *kBus[] = { "pci", NULL };
static const char *kDevice[] = { "drivers/dev/disk/sata", NULL };
TRACE("ahci_get_supported_paths\n");
*_busses = kBus;
*_devices = kDevice;
}
static status_t
std_ops(int32 op, ...)
{
@@ -365,15 +311,14 @@ driver_module_info sAHCIDevice = {
ahci_register_device,
ahci_init_driver,
ahci_uninit_driver,
ahci_device_removed,
ahci_device_cleanup,
ahci_get_supported_paths,
ahci_register_child_devices,
NULL, // rescan
ahci_device_removed
};
module_dependency module_dependencies[] = {
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
// { B_PCI_MODULE_NAME, (module_info **)&gPCI },
{ SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSI },
{}
};
@@ -15,7 +15,7 @@
#define FLOW(a...) dprintf("ahci: " a)
AHCIController::AHCIController(device_node_handle node, pci_device_info *device)
AHCIController::AHCIController(device_node *node, pci_device *device)
: fNode(node)
, fPCIDevice(device)
, fPCIVendorID(0xffff)
@@ -48,11 +48,7 @@ status_t
AHCIController::Init()
{
pci_info pciInfo;
if (gPCI->get_pci_info(fPCIDevice, &pciInfo) < B_OK) {
dprintf("AHCIController::Init ERROR: getting PCI info failed!\n");
return B_ERROR;
}
gPCI->get_pci_info(fPCIDevice, &pciInfo);
fPCIVendorID = pciInfo.vendor_id;
fPCIDeviceID = pciInfo.device_id;
@@ -231,7 +227,6 @@ AHCIController::Uninit()
// well...
remove_io_interrupt_handler(fIRQ, Interrupt, this);
delete_area(fRegsArea);
// --- Instance check workaround begin
@@ -12,8 +12,7 @@
class AHCIController {
public:
AHCIController(device_node_handle node,
pci_device_info *pciDevice);
AHCIController(device_node *node, pci_device *pciDevice);
~AHCIController();
status_t Init();
@@ -25,20 +24,20 @@ public:
uchar ResetDevice(uchar targetID, uchar targetLUN);
void GetRestrictions(uchar targetID, bool *isATAPI, bool *noAutoSense, uint32 *maxBlocks);
device_node_handle DeviceNode() { return fNode; }
device_node * DeviceNode() { return fNode; }
private:
bool IsDevicePresent(uint device);
status_t ResetController();
void FlushPostedWrites();
static int32 Interrupt(void *data);
static int32 Interrupt(void *data);
friend class AHCIPort;
private:
device_node_handle fNode;
pci_device_info* fPCIDevice;
device_node * fNode;
pci_device * fPCIDevice;
uint16 fPCIVendorID;
uint16 fPCIDeviceID;
uint32 fFlags;
@@ -22,6 +22,12 @@ scsi_for_sim_interface *gSCSI;
// #pragma mark - SIM module interface
static void
ahci_set_scsi_bus(scsi_sim_cookie cookie, scsi_bus bus)
{
}
//! execute request
static void
ahci_scsi_io(scsi_sim_cookie cookie, scsi_ccb *request)
@@ -122,30 +128,26 @@ ahci_ioctl(scsi_sim_cookie cookie, uint8 targetID, uint32 op, void *buffer,
static status_t
ahci_sim_init_bus(device_node_handle node, void *userCookie, void **_cookie)
ahci_sim_init_bus(device_node *node, void **_cookie)
{
pci_device_info *pciDevice;
device_node_handle parent;
AHCIController *controller;
status_t status;
TRACE("ahci_sim_init_bus\n");
TRACE("ahci_sim_init_bus: userCookie %p\n", userCookie);
// get the PCI device from our parent's parent
device_node *parent = gDeviceManager->get_parent_node(node);
device_node *pciParent = gDeviceManager->get_parent_node(parent);
gDeviceManager->put_node(parent);
TRACE("ahci_sim_init_bus: gPCI %p\n", gPCI);
// initialize parent (the bus) to get the PCI device
parent = gDeviceManager->get_parent(node);
status = gDeviceManager->init_driver(parent, &pciDevice, NULL, NULL);
gDeviceManager->put_device_node(parent);
if (status != B_OK)
return status;
pci_device *pciDevice;
gDeviceManager->get_driver(pciParent, NULL, (void **)&pciDevice);
gDeviceManager->put_node(pciParent);
TRACE("ahci_sim_init_bus: pciDevice %p\n", pciDevice);
controller = new(std::nothrow) AHCIController(node, pciDevice);
AHCIController *controller = new(std::nothrow) AHCIController(node,
pciDevice);
if (!controller)
return B_NO_MEMORY;
status = controller->Init();
status_t status = controller->Init();
if (status < B_OK) {
delete controller;
return status;
@@ -157,27 +159,19 @@ ahci_sim_init_bus(device_node_handle node, void *userCookie, void **_cookie)
}
static status_t
static void
ahci_sim_uninit_bus(void *cookie)
{
TRACE("ahci_sim_uninit_bus, cookie %p\n", cookie);
AHCIController *controller = static_cast<AHCIController *>(cookie);
device_node_handle parent = gDeviceManager->get_parent(
controller->DeviceNode());
controller->Uninit();
delete controller;
gDeviceManager->uninit_driver(parent);
gDeviceManager->put_device_node(parent);
return B_OK;
}
static void
ahci_sim_bus_removed(device_node_handle node, void *cookie)
ahci_sim_bus_removed(void *cookie)
{
TRACE("ahci_sim_bus_removed, cookie %p\n", cookie);
}
@@ -208,10 +202,11 @@ scsi_sim_interface gAHCISimInterface = {
NULL, // register node
ahci_sim_init_bus,
ahci_sim_uninit_bus,
ahci_sim_bus_removed,
NULL, // device cleanup
NULL, // get supported paths
NULL, // register child devices
NULL, // rescan
ahci_sim_bus_removed
},
ahci_set_scsi_bus,
ahci_scsi_io,
ahci_abort_io,
ahci_reset_device,
@@ -222,4 +217,3 @@ scsi_sim_interface gAHCISimInterface = {
ahci_get_restrictions,
ahci_ioctl
};
@@ -17,75 +17,57 @@
status_t
das_init_device(device_node_handle node, void *user_cookie, void **cookie)
das_init_device(device_node *node, void **cookie)
{
das_device_info *device;
status_t res;
scsi_ccb *request;
status_t status;
uint8 removable;
SHOW_FLOW0(3, "");
status = pnp->get_attr_uint8(node, "removable",
&removable, false);
if (status != B_OK)
return status;
device = (das_device_info *)malloc(sizeof(*device));
if (device == NULL)
return B_NO_MEMORY;
memset(device, 0, sizeof(*device));
device->block_io_device = user_cookie;
device->node = node;
device->removable = removable;
res = pnp->get_attr_uint8(node, "removable",
&device->removable, false);
if (res != B_OK)
goto err1;
// register it everywhere
res = pnp->init_driver(pnp->get_parent(node), NULL, (driver_module_info **)&device->scsi,
{
device_node *parent = pnp->get_parent_node(node);
pnp->get_driver(parent, (driver_module_info **)&device->scsi,
(void **)&device->scsi_device);
if (res != B_OK)
goto err2;
res = scsi_periph->register_device((periph_device_cookie)device, &callbacks,
device->scsi_device, device->scsi, device->node, device->removable,
&device->scsi_periph_device);
if (res != B_OK)
goto err3;
// and get (initial) capacity
request = device->scsi->alloc_ccb(device->scsi_device);
if (request == NULL) {
res = B_NO_MEMORY;
goto err4;
pnp->put_node(parent);
}
scsi_periph->check_capacity(device->scsi_periph_device, request);
device->scsi->free_ccb(request);
status = scsi_periph->register_device((periph_device_cookie)device,
&callbacks, device->scsi_device, device->scsi, device->node,
device->removable, &device->scsi_periph_device);
if (status != B_OK) {
free(device);
return status;
}
SHOW_FLOW0(3, "done");
*cookie = device;
return B_OK;
err4:
scsi_periph->unregister_device(device->scsi_periph_device);
err3:
pnp->uninit_driver(pnp->get_parent(node));
err2:
err1:
free(device);
return res;
}
status_t
das_uninit_device(das_device_info *device)
void
das_uninit_device(void *_cookie)
{
scsi_periph->unregister_device(device->scsi_periph_device);
pnp->uninit_driver(pnp->get_parent(device->node));
free(device);
das_device_info *device = (das_device_info *)_cookie;
return B_OK;
scsi_periph->unregister_device(device->scsi_periph_device);
free(device);
}
@@ -95,27 +77,27 @@ das_uninit_device(das_device_info *device)
*/
status_t
das_device_added(device_node_handle node)
das_device_added(device_node *node)
{
scsi_res_inquiry *device_inquiry = NULL;
const scsi_res_inquiry *deviceInquiry = NULL;
uint8 device_type;
size_t inquiry_len;
char *name;
size_t inquiryLength;
uint32 max_blocks;
// check whether it's really a Direct Access Device
if (pnp->get_attr_uint8(node, SCSI_DEVICE_TYPE_ITEM, &device_type, true) != B_OK
|| device_type != scsi_dev_direct_access)
goto err;
return B_ERROR;
// get inquiry data
if (pnp->get_attr_raw(node, SCSI_DEVICE_INQUIRY_ITEM,
(void **)&device_inquiry, &inquiry_len, true) != B_OK
|| inquiry_len < sizeof(device_inquiry))
goto err;
(const void **)&deviceInquiry, &inquiryLength, true) != B_OK
|| inquiryLength < sizeof(deviceInquiry))
return B_ERROR;
// get block limit of underlying hardware to lower it (if necessary)
if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, &max_blocks, true) != B_OK)
if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, &max_blocks,
true) != B_OK)
max_blocks = INT_MAX;
// using 10 byte commands, at most 0xffff blocks can be transmitted at once
@@ -123,23 +105,11 @@ das_device_added(device_node_handle node)
// are supported, but the block_io module can live with that)
max_blocks = min(max_blocks, 0xffff);
name = scsi_periph->compose_device_name(node, "disk/scsi");
if (name == NULL) {
SHOW_ERROR0(2, "Cannot compose device name");
goto err;
}
SHOW_FLOW(3, "name = %s", name);
// ready to register
{
device_attr attrs[] = {
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: SCSI_DSK_MODULE_NAME }},
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: B_BLOCK_IO_MODULE_NAME }},
// tell block_io whether the device is removable
{ "removable", B_UINT8_TYPE, { ui8: device_inquiry->removable_medium }},
// tell which name we want to have in devfs
{ PNP_DEVFS_FILENAME, B_STRING_TYPE, { string: name }},
{ "removable", B_UINT8_TYPE, { ui8: deviceInquiry->removable_medium }},
// impose own max block restriction
{ B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: max_blocks }},
// in general, any disk can be a BIOS drive (even ZIP-disks)
@@ -147,16 +117,7 @@ das_device_added(device_node_handle node)
{ NULL }
};
status_t res = pnp->register_device(node, attrs, NULL, &node);
free(name);
free(device_inquiry);
return res;
return pnp->register_node(node, SCSI_DSK_MODULE_NAME, attrs, NULL,
NULL);
}
err:
free(device_inquiry);
return B_ERROR;
}
@@ -3,12 +3,7 @@
* Distributed under the terms of the MIT License.
*/
/*
Part of Open SCSI Disk Driver
File handle management.
*/
/*! File handle management. */
#include "scsi_dsk_int.h"
@@ -1,13 +1,10 @@
/*
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/*
Part of Open SCSI Disk Driver
Main file.
You'll find das_... all over the place. This stands for
"Direct Access Storage" which is the official SCSI name for
normal (floppy/hard/ZIP)-disk drives.
@@ -28,6 +25,23 @@ device_manager_info *pnp;
block_io_for_driver_interface *gBlockIO;
static void
das_set_device(das_device_info *info, block_io_device device)
{
scsi_ccb *request;
info->block_io_device = device;
// and get (initial) capacity
request = info->scsi->alloc_ccb(info->scsi_device);
if (request == NULL)
return;
scsi_periph->check_capacity(info->scsi_periph_device, request);
info->scsi->free_ccb(request);
}
static status_t
das_read(das_handle_info *handle, const phys_vecs *vecs, off_t pos,
size_t num_blocks, uint32 block_size, size_t *bytes_transferred)
@@ -247,39 +261,43 @@ das_ioctl(das_handle_info *handle, int op, void *buf, size_t len)
static float
das_supports_device(device_node_handle parent, bool *_noConnection)
das_supports_device(device_node *parent)
{
char *bus;
uint8 device_type;
const char *bus;
uint8 deviceType;
// make sure parent is really the SCSI bus manager
if (pnp->get_attr_string(parent, B_DRIVER_BUS, &bus, false))
return B_ERROR;
if (pnp->get_attr_string(parent, B_DEVICE_BUS, &bus, false))
return -1;
if (strcmp(bus, "scsi")) {
free(bus);
if (strcmp(bus, "scsi"))
return 0.0;
}
// check whether it's really a Direct Access Device
if (pnp->get_attr_uint8(parent, SCSI_DEVICE_TYPE_ITEM, &device_type, true) != B_OK
|| device_type != scsi_dev_direct_access) {
free(bus);
if (pnp->get_attr_uint8(parent, SCSI_DEVICE_TYPE_ITEM, &deviceType, true)
!= B_OK || deviceType != scsi_dev_direct_access)
return 0.0;
}
free(bus);
return 0.6;
}
static void
das_get_paths(const char ***_bus, const char ***_device)
static status_t
das_publish_device(void *_cookie)
{
static const char *kBus[] = { "scsi", NULL };
das_device_info *device = (das_device_info *)_cookie;
status_t status;
char *name;
*_bus = kBus;
*_device = NULL;
name = scsi_periph->compose_device_name(device->node, "disk/scsi");
if (name == NULL)
return B_ERROR;
status = pnp->publish_device(device->node, name,
B_BLOCK_IO_DEVICE_MODULE_NAME);
free(name);
return status;
}
@@ -304,7 +322,7 @@ module_dependency module_dependencies[] = {
{}
};
block_device_interface scsi_dsk_module = {
block_device_interface sSCSIDiskModule = {
{
{
SCSI_DSK_MODULE_NAME,
@@ -315,13 +333,13 @@ block_device_interface scsi_dsk_module = {
das_supports_device,
das_device_added,
das_init_device,
(status_t (*) (void *))das_uninit_device,
NULL, // remove device
NULL, // cleanup device
das_get_paths,
das_uninit_device,
das_publish_device,
NULL, // rescan
},
(status_t (*)(block_device_device_cookie, block_device_handle_cookie *))&das_open,
(void (*)(block_device_cookie *, block_io_device)) &das_set_device,
(status_t (*)(block_device_cookie *, block_device_handle_cookie *))&das_open,
(status_t (*)(block_device_handle_cookie)) &das_close,
(status_t (*)(block_device_handle_cookie)) &das_free,
@@ -333,10 +351,7 @@ block_device_interface scsi_dsk_module = {
(status_t (*)(block_device_handle_cookie, int, void *, size_t))&das_ioctl,
};
#if !_BUILDING_kernel && !BOOT
_EXPORT
module_info *modules[] = {
(module_info *)&scsi_dsk_module,
(module_info *)&sSCSIDiskModule,
NULL
};
#endif
@@ -4,8 +4,6 @@
*/
/*
Part of Open SCSI Disk Driver
Peripheral driver to handle any kind of SCSI disks,
i.e. hard disk and floopy disks (ZIP etc.)
@@ -17,6 +15,6 @@
#include <device_manager.h>
#define SCSI_DSK_MODULE_NAME "drivers/disk/scsi/scsi_dsk/device_v1"
#define SCSI_DSK_MODULE_NAME "drivers/disk/scsi/scsi_dsk/driver_v1"
#endif /* _SCSI_DSK_H */
@@ -23,8 +23,9 @@
#include "wrapper.h"
// must start as block_device_cookie
typedef struct das_device_info {
device_node_handle node;
device_node *node;
scsi_periph_device scsi_periph_device;
scsi_device scsi_device;
scsi_device_interface *scsi;
@@ -47,21 +48,18 @@ extern scsi_periph_callbacks callbacks;
extern block_io_for_driver_interface *gBlockIO;
// device_mgr.c
// device.c
status_t das_init_device(device_node_handle node, void *user_cookie, void **cookie);
status_t das_uninit_device(das_device_info *device);
status_t das_device_added(device_node_handle node);
status_t das_device_added(device_node *node);
status_t das_init_device(device_node *node, void **cookie);
void das_uninit_device(void *cookie);
// handle_mgr.c
// scsi_dsk.c
status_t das_open(das_device_info *device, das_handle_info **handle_out);
status_t das_close(das_handle_info *handle);
status_t das_free(das_handle_info *handle);
// scsi_dsk.c
void das_set_capacity(das_device_info *device, uint64 capacity,
uint32 block_size);
-1
View File
@@ -3,7 +3,6 @@ SubDir HAIKU_TOP src add-ons kernel generic ;
SubInclude HAIKU_TOP src add-ons kernel generic atomizer ;
SubInclude HAIKU_TOP src add-ons kernel generic block_io ;
SubInclude HAIKU_TOP src add-ons kernel generic dpc ;
SubInclude HAIKU_TOP src add-ons kernel generic fast_log ;
SubInclude HAIKU_TOP src add-ons kernel generic ide_adapter ;
SubInclude HAIKU_TOP src add-ons kernel generic locked_pool ;
SubInclude HAIKU_TOP src add-ons kernel generic mpu401 ;
+40 -103
View File
@@ -3,16 +3,9 @@
* Distributed under the terms of the MIT License.
*/
/*
Part of Open block device manager
Actual I/O.
Main file.
*/
#include "block_io_private.h"
#include <stdio.h>
@@ -37,7 +30,7 @@ device_manager_info *pnp;
static status_t
block_io_open(block_io_device_info *device, uint32 flags,
block_io_open(block_io_device_info *device, const char *path, int openMode,
block_io_handle_info **res_handle)
{
block_io_handle_info *handle;
@@ -327,31 +320,10 @@ block_io_ioctl(block_io_handle_info *handle, uint32 op, void *buffer, size_t len
}
static status_t
block_io_register_device(device_node_handle parent)
{
TRACE(("block_io_register_device()\n"));
// ready to register at devfs
{
device_attr attrs[] = {
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: B_BLOCK_IO_MODULE_NAME }},
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "block_io" }},
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: PNP_DEVFS_MODULE_NAME }},
{ NULL }
};
device_node_handle node;
return pnp->register_device(parent, attrs, NULL, &node);
}
}
static void
block_io_remove(device_node_handle node, void *cookie)
block_io_remove(void *cookie)
{
#if 0
uint8 bios_id;
//bios_drive *drive;
@@ -361,7 +333,6 @@ block_io_remove(device_node_handle node, void *cookie)
return;
// ToDo: this assumes private R5 kernel functions to be present
#if 0
for (drive = bios_drive_info; drive->bios_id != 0; ++drive) {
if (drive->bios_id == bios_id)
break;
@@ -376,26 +347,28 @@ block_io_remove(device_node_handle node, void *cookie)
static status_t
block_io_init_device(device_node_handle node, void *user_cookie, void **cookie)
block_io_init_device(void *_data, void **cookie)
{
block_device_cookie *data = (block_device_cookie *)_data;
block_io_device_info *device;
block_device_params params;
char *name, *tmp_name;
// const char *name;
// char *tmp_name;
uint8 is_bios_drive;
status_t res;
TRACE(("block_io_init_device()\n"));
// extract controller/protocoll restrictions from node
if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_DMA_ALIGNMENT, &params.alignment, true) != B_OK)
if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_DMA_ALIGNMENT, &params.alignment, true) != B_OK)
params.alignment = 0;
if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, &params.max_blocks, true) != B_OK)
if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, &params.max_blocks, true) != B_OK)
params.max_blocks = 0xffffffff;
if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_DMA_BOUNDARY, &params.dma_boundary, true) != B_OK)
if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_DMA_BOUNDARY, &params.dma_boundary, true) != B_OK)
params.dma_boundary = ~0;
if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, &params.max_sg_block_size, true) != B_OK)
if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, &params.max_sg_block_size, true) != B_OK)
params.max_sg_block_size = 0xffffffff;
if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_SG_BLOCKS, &params.max_sg_blocks, true) != B_OK)
if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_MAX_SG_BLOCKS, &params.max_sg_blocks, true) != B_OK)
params.max_sg_blocks = ~0;
// do some sanity check:
@@ -427,16 +400,9 @@ block_io_init_device(device_node_handle node, void *user_cookie, void **cookie)
// (they consume 4KB and can describe up to 2MB virtual cont. memory!)
params.max_sg_blocks = min(params.max_sg_blocks, 512);
if (pnp->get_attr_uint8(node, B_BLOCK_DEVICE_IS_BIOS_DRIVE, &is_bios_drive, true) != B_OK)
if (pnp->get_attr_uint8(data->node, B_BLOCK_DEVICE_IS_BIOS_DRIVE, &is_bios_drive, true) != B_OK)
is_bios_drive = false;
// we don't really care about /dev name, but if it is
// missing, we will get a problem
if (pnp->get_attr_string(node, PNP_DEVFS_FILENAME, &name, true) != B_OK) {
dprintf("devfs filename is missing.\n");
return B_ERROR;
}
device = (block_io_device_info *)malloc(sizeof(*device));
if (device == NULL) {
res = B_NO_MEMORY;
@@ -445,14 +411,15 @@ block_io_init_device(device_node_handle node, void *user_cookie, void **cookie)
memset(device, 0, sizeof(*device));
device->node = node;
device->node = data->node;
res = benaphore_init(&device->lock, "block_device_mutex");
if (res < 0)
goto err2;
#if 0
// construct a identifiable name for S/G pool
tmp_name = malloc(strlen(name) + strlen(" sg_lists") + 1);
tmp_name = malloc(name + strlen(" sg_lists") + 1);
if (tmp_name == NULL) {
res = B_NO_MEMORY;
goto err3;
@@ -460,16 +427,17 @@ block_io_init_device(device_node_handle node, void *user_cookie, void **cookie)
strcpy(tmp_name, name);
strcat(tmp_name, " sg_lists");
#endif
// create S/G pool with initial size 1
// (else, we may be on the paging path and have no S/G entries at hand)
device->phys_vecs_pool = locked_pool->create(
params.max_sg_blocks * sizeof(physical_entry),
sizeof( physical_entry ) - 1,
0, 16*1024, 32, 1, tmp_name, B_FULL_LOCK | B_CONTIGUOUS,
0, 16*1024, 32, 1, "block io sg lists", B_FULL_LOCK | B_CONTIGUOUS,
NULL, NULL, NULL);
free(tmp_name);
// free(tmp_name);
if (device->phys_vecs_pool == NULL) {
res = B_NO_MEMORY;
@@ -479,41 +447,33 @@ block_io_init_device(device_node_handle node, void *user_cookie, void **cookie)
device->params = params;
device->is_bios_drive = is_bios_drive != 0;
res = pnp->init_driver(pnp->get_parent(node), device,
(driver_module_info **)&device->interface, (void **)&device->cookie);
if (res != B_OK)
goto err4;
pnp->get_driver(device->node, (driver_module_info **)&device->interface,
(void **)&device->cookie);
free(name);
device->interface->set_device(device->cookie, device);
TRACE(("done\n"));
*cookie = device;
return B_OK;
err4:
locked_pool->destroy(device->phys_vecs_pool);
err3:
benaphore_destroy(&device->lock);
err2:
free(device);
err1:
free(name);
pnp->uninit_driver(pnp->get_parent(node));
return res;
}
static status_t
block_io_uninit_device(block_io_device_info *device)
static void
block_io_uninit_device(void *_cookie)
{
pnp->uninit_driver(pnp->get_parent(device->node));
block_io_device_info *device = _cookie;
locked_pool->destroy(device->phys_vecs_pool);
benaphore_destroy(&device->lock);
free(device);
return B_OK;
}
@@ -594,70 +554,47 @@ module_dependency module_dependencies[] = {
};
pnp_devfs_driver_info block_io_module = {
struct device_module_info sBlockIOModule = {
{
{
B_BLOCK_IO_MODULE_NAME,
B_BLOCK_IO_DEVICE_MODULE_NAME,
0,
std_ops
},
NULL, // supports device
block_io_register_device,
block_io_init_device,
(status_t (*)( void * )) block_io_uninit_device,
block_io_uninit_device,
block_io_remove,
NULL, // cleanup
NULL, // get paths
},
(status_t (*)(void *, uint32, void **))block_io_open,
(status_t (*)(void *, const char *, int, void **))block_io_open,
(status_t (*)(void *))block_io_close,
(status_t (*)(void *))block_io_freecookie,
(status_t (*)(void *, uint32, void *, size_t))block_io_ioctl,
(status_t (*)(void *, off_t, void *, size_t *))block_io_read,
(status_t (*)(void *, off_t, const void *, size_t *))block_io_write,
NULL, // io
NULL,
NULL,
(status_t (*)(void *, int32, void *, size_t))block_io_ioctl,
(status_t (*)(void *, off_t, const iovec *, size_t, size_t *))block_io_readv,
(status_t (*)(void *, off_t, const iovec *, size_t, size_t *))block_io_writev
NULL, // select
NULL, // deselect
// (status_t (*)(void *, off_t, const iovec *, size_t, size_t *))block_io_readv,
// (status_t (*)(void *, off_t, const iovec *, size_t, size_t *))block_io_writev
};
static status_t
std_ops_for_driver(int32 op, ...)
{
// there is nothing to setup as this is a interface for
// drivers which are loaded by _us_
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
default:
return B_ERROR;
}
}
block_io_for_driver_interface block_io_for_driver_module = {
block_io_for_driver_interface sBlockIOForDriverModule = {
{
B_BLOCK_IO_FOR_DRIVER_MODULE_NAME,
0,
std_ops_for_driver
NULL
},
block_io_set_media_params,
};
module_info *modules[] = {
&block_io_module.info.info,
&block_io_for_driver_module.info,
&sBlockIOModule.info,
&sBlockIOForDriverModule.info,
NULL
};
@@ -34,9 +34,9 @@ typedef struct block_device_params {
// device info
typedef struct block_io_device_info {
device_node_handle node;
device_node *node;
block_device_interface *interface;
block_device_device_cookie cookie;
block_device_cookie *cookie;
benaphore lock; // used for access to following variables
uint32 block_size;
@@ -1,10 +0,0 @@
SubDir HAIKU_TOP src add-ons kernel generic fast_log ;
UsePrivateHeaders kernel ;
KernelAddon fast_log :
clients.c
device.c
long_buffers.c
;
@@ -1,585 +0,0 @@
/*
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/*
Fast logging facilities.
Client interface.
Every client opens a connection, passing a list of event
ids together with their description. All logging calls
write the encoded event into a buffer, using the event id
to save space. Once the logging data is to be read, the
buffer is decoded and written to the long buffers. The
same happens when a client closes a connection, as the
association between event ids and descriptions would be
lost.
The buffer is split into a lower and an upper half, each
of size fast_log_buffer_size. The currently active half
is determined by bit 31 of fast_log_buffer_offset_alloc:
zero means lower, one means upper half.
During write, fast_log_buffer_offset_alloc is first
incremented by the requested number of bytes atomically.
If there is enough space, the even data is copied into
the buffer and fast_log_buffer_offset_filled is
atomically incremented as well. This allows concurrent
filling by different threads without using any locking.
If the buffer is too short, logging data is discarded.
For read out, fast_log_buffer_offset_alloc
is atomically set to the beginning of the opposite buffer,
making sure that no further events are appended to the
previously active buffer. Then, we wait for
fast_log_buffer_offset having reached the value of
fast_log_buffer_alloc when it was reset, i.e. until
all active writes are completed. Now, the buffer can
be read out savely.
To detect buffer overflow, buffer halves are set to
zero before they are activated. If a write fails because
lack of space, nothing is writting to the buffer, though
fast_log_buffer_offset and fast_log_buffer_alloc are
incremented. This leads to an unwritten entry in the log,
which content remains zero. The easier way is to detect
whether fast_log_alloc is byond buffer size (which is
done as well), but because entries have different sizes,
we don't know which was the lastly written entry.
*/
#include "fast_log_int.h"
#include "dl_list.h"
#include <KernelExport.h>
#include <SupportDefs.h>
#include <stdio.h>
#include <string.h>
// one client connection
typedef struct fast_log_connection {
struct fast_log_connection *prev, *next;
// prefix in log
const char *prefix;
// list of event types
fast_log_event_type *types;
} fast_log_connection;
// one entry in logging buffer
typedef struct fast_log_entry {
// client handle.
// this must be first as it is checked against NULL
// by reader to detect overflown entries; moving it
// to a later offset would make reading of it dangerous
// as it could be located byond end of buffer
// (perhaps this could be handled as well, but it
// would make things more complicated)
fast_log_connection *handle;
// event type
int16 event;
// number of entries in "params"
int16 num_params;
// timestamp
bigtime_t time;
// parameters
uint32 params[1];
} fast_log_entry;
// list of clients
static fast_log_connection *fast_log_handles = NULL;
// to lock during access of fast_log_handles
sem_id fast_log_clients_sem;
// to lock during conversion of encoded buffer to long buffer
sem_id fast_log_convert_sem;
// logging buffer.
// it consists of 2*fast_log_buffer_size, see header
char *fast_log_buffer;
// offset in logging buffer for next write.
// bit 31 is set for upper buffer half and is rest for lower buffer half
uint32 fast_log_buffer_offset_alloc;
// offset of end of last write
uint32 fast_log_buffer_offset_filled;
// size of one half of log buffer
int fast_log_buffer_size = /*512*/ 16*1024;
// ToDo: cut down because of current allocator...
device_manager_info *pnp;
/** convert event code to text
* text_buffer - buffer used if text must is composed manually
* (must be at least 24 characters long)
*/
static const char *
fast_log_event2text(fast_log_connection *handle, int16 event, char *text_buffer)
{
fast_log_event_type *type;
for (type = handle->types; type->event != 0; ++type) {
if (type->event == event)
return type->description;
}
// longest message is 11 characters + 11 integer characters + zero byte
sprintf(text_buffer, "unknown (%d)", event);
return text_buffer;
}
/** decode one entry and write it to long buffer */
static void
fast_log_decode_entry(fast_log_entry *entry)
{
fast_log_connection *handle = entry->handle;
char buffer[100];
uint64 time;
uint32 min, sec, mill, mic;
char text_buffer[30];
int i;
time = entry->time; //entry->tsc / (sysinfo.cpu_clock_speed / 1000000);
mic = time % 1000;
time /= 1000;
mill = time % 1000;
time /= 1000;
sec = time % 60;
time /= 60;
min = time;
sprintf(buffer, "%03ld:%02ld:%03ld.%03ld ", min, sec, mill, mic);
fast_log_write_long_log(buffer);
fast_log_write_long_log(handle->prefix);
fast_log_write_long_log(": ");
fast_log_write_long_log(fast_log_event2text(handle, entry->event, text_buffer));
fast_log_write_long_log(" ");
for (i = 0; i < entry->num_params; ++i) {
if (i > 0)
fast_log_write_long_log(", ");
sprintf(buffer, "%08x", (uint)entry->params[i]);
fast_log_write_long_log(buffer);
}
fast_log_write_long_log("\n");
}
/** flush all compressed logging entries to long log */
void
fast_log_flush_buffer(void)
{
uint32 offset;
uint32 start, new_start, new_offset_alloc, size;
int i;
acquire_sem(fast_log_convert_sem);
// flip between lower and upper half of buffer
if ((fast_log_buffer_offset_alloc & (1L << 31)) == 0) {
start = 0;
new_start = fast_log_buffer_size;
new_offset_alloc = 1L << 31;
} else {
start = fast_log_buffer_size;
new_start = 0;
new_offset_alloc = 0;
}
// reset new buffer to zero to detect uninitialized, overflown entries
memset(fast_log_buffer + new_start, 0, fast_log_buffer_size);
// swap buffers
size = atomic_set((vint32*)&fast_log_buffer_offset_alloc, new_offset_alloc);
// get rid of bit 31 flag
size &= ~(1 << 31);
// decrement offset of filled data by number of bytes allocated when
// the buffer was swapped; if all writers are done, the offset is
// >= 0 now, if some writers aren't finished, it is < 0
atomic_add(&fast_log_buffer_offset_filled, -size);
// wait until all writers are finished
for (i = 1000000; i >= 0; --i) {
if ((int32)fast_log_buffer_offset_filled >= 0)
break;
spin(1);
// ToDo: spin?? If that should be a "yield", it should be snooze(1).
}
// perhaps we are in a spinlock or something nasty like that,
// so the writer is blocked by us
if (i < 0) {
fast_log_write_long_log("<TIME-OUT> during waiting for log writers; some "
"events got lost; perhaps a client disconnected with a spinlock hold\n");
}
// dprintf( "start=%d, size=%d\n", (int)start, (int)size );
// uncompress log
for (offset = 0; offset < size; ) {
fast_log_entry *entry;
// check whether there was an overflow when the buffer
// had zero bytes left
if (offset > (uint32)fast_log_buffer_size) {
fast_log_write_long_log("<TRUNCATED1>\n");
break;
}
entry = (fast_log_entry *)&fast_log_buffer[start + offset];
// check for overflow when the buffer had some bytes left;
// in this case, the entry is uninitialized and thus contains
// all zeros
if (entry->handle == NULL) {
fast_log_write_long_log( "<TRUNCATED2>\n" );
// the entry may be partially byond end of buffer, so
// we must not access any other element of the entry
break;
} else {
// normal entry, so it's time to decode it
fast_log_decode_entry(entry);
}
offset += sizeof(fast_log_entry)
+ (entry->num_params - 1) * sizeof(entry->params[0]);
}
release_sem(fast_log_convert_sem);
}
/** start logging of one client */
static fast_log_handle
fast_log_start_log(const char *prefix, fast_log_event_type types[])
{
fast_log_connection *handle;
handle = malloc(sizeof(*handle));
if (handle == NULL)
return NULL;
handle->prefix = prefix;
handle->types = types;
acquire_sem(fast_log_clients_sem);
ADD_DL_LIST_HEAD(handle, fast_log_handles, );
release_sem(fast_log_clients_sem);
return handle;
}
/** close connection of one client */
static void
fast_log_stop_log(fast_log_handle handle)
{
if (handle == NULL)
return;
fast_log_flush_buffer();
acquire_sem(fast_log_clients_sem);
REMOVE_DL_LIST(handle, fast_log_handles, );
release_sem(fast_log_clients_sem);
free(handle);
}
#define ENTRY_SIZE(num_params) (sizeof(fast_log_entry) + sizeof(uint32) * ((num_params)-1))
/** allocate space in log */
static fast_log_entry *
fast_log_alloc_entry(fast_log_handle handle, int num_params)
{
uint32 offset, real_offset, chunk_offset;
fast_log_entry *entry;
if (handle == NULL)
return NULL;
// alloc space in buffer
offset = atomic_add( &fast_log_buffer_offset_alloc, ENTRY_SIZE( num_params ));
real_offset = offset & ~(1L << 31);
chunk_offset = ((offset & (1L << 31)) == 0 ? 0 : fast_log_buffer_size);
// take care of bit 31 trick to get the address of the new entry
entry = (fast_log_entry *)&fast_log_buffer[chunk_offset + real_offset];
if (real_offset + ENTRY_SIZE( num_params ) < (uint32)fast_log_buffer_size) {
// there is enough space in buffer, so we can fill it
entry->time = system_time();
entry->handle = handle;
entry->num_params = num_params;
return entry;
} else {
// buffer overflow, return NULL to notify caller
atomic_add( &fast_log_buffer_offset_filled, ENTRY_SIZE( num_params ));
return NULL;
}
}
/** log event without parameters */
static void
fast_log_log_0(fast_log_handle handle, int event)
{
fast_log_entry *entry;
entry = fast_log_alloc_entry(handle, 0);
if (entry != NULL) {
entry->event = event;
atomic_add(&fast_log_buffer_offset_filled, ENTRY_SIZE(0));
}
}
/** log event with one parameter */
static void
fast_log_log_1(fast_log_handle handle, int event, uint32 param1)
{
fast_log_entry *entry;
entry = fast_log_alloc_entry(handle, 1);
if (entry != NULL) {
entry->event = event;
entry->params[0] = param1;
atomic_add(&fast_log_buffer_offset_filled, ENTRY_SIZE(1));
}
}
/** log event with two parameters */
static void
fast_log_log_2(fast_log_handle handle, int event, uint32 param1, uint32 param2)
{
fast_log_entry *entry;
entry = fast_log_alloc_entry(handle, 2);
if (entry != NULL) {
entry->event = event;
entry->params[0] = param1;
entry->params[1] = param2;
atomic_add(&fast_log_buffer_offset_filled, ENTRY_SIZE(2));
}
}
/** log event with three parameters */
static void
fast_log_log_3(fast_log_handle handle, int event,
uint32 param1, uint32 param2, uint32 param3)
{
fast_log_entry *entry;
entry = fast_log_alloc_entry(handle, 3);
if (entry != NULL) {
entry->event = event;
entry->params[0] = param1;
entry->params[1] = param2;
entry->params[2] = param3;
atomic_add(&fast_log_buffer_offset_filled, ENTRY_SIZE(3));
}
}
/** log event with four parameters */
static void
fast_log_log_4(fast_log_handle handle, int event, uint32 param1,
uint32 param2, uint32 param3, uint32 param4)
{
fast_log_entry *entry;
entry = fast_log_alloc_entry(handle, 4);
if (entry != NULL) {
entry->event = event;
entry->params[0] = param1;
entry->params[1] = param2;
entry->params[2] = param3;
entry->params[3] = param4;
atomic_add(&fast_log_buffer_offset_filled, ENTRY_SIZE(4));
}
}
/** log event with n parameters */
static void
fast_log_log_n(fast_log_handle handle, int event, int num_params, ...)
{
fast_log_entry *entry;
va_list vl;
entry = fast_log_alloc_entry(handle, num_params);
if (entry != NULL) {
int i;
va_start(vl, num_params);
entry->event = event;
for (i = 0; i < num_params; ++i) {
entry->params[i] = va_arg(vl, int);
}
va_end(vl);
atomic_add(&fast_log_buffer_offset_filled, ENTRY_SIZE(num_params));
}
}
/** clean up client structures */
static void
fast_log_uninit_clients()
{
free(fast_log_buffer);
delete_sem(fast_log_clients_sem);
delete_sem(fast_log_convert_sem);
}
/** init client structures.
* you must call fast_log_uninit_clients on fail
*/
static status_t
fast_log_init_clients()
{
fast_log_buffer = NULL;
fast_log_clients_sem = -1;
fast_log_convert_sem = -1;
fast_log_clients_sem = create_sem(1, "fast_log_clients_sem");
if (fast_log_clients_sem < B_OK)
return fast_log_clients_sem;
fast_log_convert_sem = create_sem(1, "fast_log_convert_sem");
if (fast_log_convert_sem < B_OK)
return fast_log_convert_sem;
fast_log_buffer = malloc(2 * fast_log_buffer_size);
if (fast_log_buffer == NULL)
return B_NO_MEMORY;
memset(fast_log_buffer, 0, 2 * fast_log_buffer_size);
fast_log_buffer_offset_filled = fast_log_buffer_offset_alloc = 0;
return B_OK;
}
/** uninitialize module */
static status_t
fast_log_uninit(void)
{
fast_log_uninit_dev();
fast_log_uninit_long_buffer();
fast_log_uninit_clients();
return B_OK;
}
/** initialize module */
static status_t
fast_log_init(void)
{
status_t res;
if ((res = fast_log_init_long_buffer()) < B_OK)
goto err3;
if ((res = fast_log_init_clients()) < B_OK)
goto err2;
if ((res = fast_log_init_dev()) < B_OK)
// yes: don't call uninit for device.c
goto err2;
return B_OK;
err2:
fast_log_uninit_clients();
err3:
fast_log_uninit_long_buffer();
return res;
}
static status_t
fast_log_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
return fast_log_init();
case B_MODULE_UNINIT:
return fast_log_uninit();
default:
return B_ERROR;
}
}
module_dependency module_dependencies[] = {
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp },
{}
};
// client interface
fast_log_info fast_log_module = {
{
FAST_LOG_MODULE_NAME,
0,
fast_log_std_ops
},
fast_log_start_log,
fast_log_stop_log,
fast_log_log_0,
fast_log_log_1,
fast_log_log_2,
fast_log_log_3,
fast_log_log_4,
fast_log_log_n
};
// embedded modules
module_info *modules[] = {
(module_info *)&fast_log_module,
(module_info *)&fast_log_devfs_module,
NULL
};
@@ -1,180 +0,0 @@
/*
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/*
Fast logging facilities.
Devfs interface.
Publishes a file where logging data can be read from
directly via read. Once read, the logging data is freed.
Obviously, you cannot seek in the file.
Concurrent reads are permitted, but you will have fun
merging read data.
*/
#include "fast_log_int.h"
#include <pnp_devfs.h>
#include <device_manager.h>
// Devfs node
device_node_handle fast_log_devfs_node;
static status_t
fast_log_devfs_open(void *device_cookie, uint32 flags, void **handle_cookie)
{
handle_cookie = NULL;
return B_OK;
}
static status_t
fast_log_devfs_close(void *cookie)
{
return B_OK;
}
static status_t
fast_log_devfs_free(void *cookie)
{
return B_OK;
}
static status_t
fast_log_devfs_control(void *cookie, uint32 op, void *data, size_t len)
{
return B_ERROR;
}
static status_t
fast_log_devfs_read(void *cookie, off_t position, void *data, size_t *num_bytes)
{
*num_bytes = fast_log_read_long(data, *num_bytes);
return B_OK;
}
static status_t
fast_log_devfs_write(void *cookie, off_t position, const void *data, size_t *num_bytes)
{
*num_bytes = 0;
return B_ERROR;
}
// #pragma mark -
/** create devfs entry */
static status_t
fast_log_create_devfs_entry(void)
{
status_t res;
device_attr attrs[] = {
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: FAST_LOG_DEVFS_MODULE_NAME }},
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: PNP_DEVFS_MODULE_NAME }},
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "fast_log" }},
{ PNP_DEVFS_FILENAME, B_STRING_TYPE, { string: FAST_LOG_DEVFS_NAME }},
{ NULL }
};
res = pnp->register_device(NULL, attrs, NULL, &fast_log_devfs_node);
if (res < 0)
fast_log_devfs_node = NULL;
return res;
}
static status_t
fast_log_devfs_init_device(device_node_handle node, void *user_cookie, void **cookie)
{
*cookie = NULL;
return B_OK;
}
static status_t
fast_log_devfs_uninit_device(void *cookie)
{
return B_OK;
}
static status_t
fast_log_devfs_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
default:
return B_ERROR;
}
}
// devfs interface
pnp_devfs_driver_info fast_log_devfs_module = {
{
{
FAST_LOG_DEVFS_MODULE_NAME,
0,
fast_log_devfs_std_ops
},
NULL,
NULL,
fast_log_devfs_init_device,
fast_log_devfs_uninit_device,
NULL,
NULL,
},
fast_log_devfs_open,
fast_log_devfs_close,
fast_log_devfs_free,
fast_log_devfs_control,
fast_log_devfs_read,
fast_log_devfs_write
};
/** cleanup devfs interface */
void
fast_log_uninit_dev(void)
{
if (fast_log_devfs_node != NULL)
pnp->unregister_device(fast_log_devfs_node);
}
/** init devfs interface */
status_t
fast_log_init_dev(void)
{
status_t res;
fast_log_devfs_node = NULL;
if ((res = fast_log_create_devfs_entry()) < 0)
return res;
return B_OK;
}
@@ -1,88 +0,0 @@
/*
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/*
Macros for double linked lists
*/
#ifndef _DL_LIST_H
#define _DL_LIST_H
#define REMOVE_DL_LIST( item, head, prefix ) \
do { \
if( item->prefix##prev ) \
item->prefix##prev->prefix##next = item->prefix##next; \
else \
head = item->prefix##next; \
\
if( item->prefix##next ) \
item->prefix##next->prefix##prev = item->prefix##prev; \
} while( 0 )
#define ADD_DL_LIST_HEAD( item, head, prefix ) \
do { \
item->prefix##next = head; \
item->prefix##prev = NULL; \
\
if( (head) ) \
(head)->prefix##prev = item; \
\
(head) = item; \
} while( 0 )
#define REMOVE_CDL_LIST( item, head, prefix ) \
do { \
item->prefix##next->prefix##prev = item->prefix##prev; \
item->prefix##prev->prefix##next = item->prefix##next; \
\
if( item == (head) ) { \
if( item->prefix##next != item ) \
(head) = item->prefix##next; \
else \
(head) = NULL; \
} \
} while( 0 )
#define ADD_CDL_LIST_TAIL( item, type, head, prefix ) \
do { \
type *old_head = head; \
\
if( old_head ) { \
type *first, *last; \
\
first = old_head; \
last = first->prefix##prev; \
\
item->prefix##next = first; \
item->prefix##prev = last; \
first->prefix##prev = item; \
last->prefix##next = item; \
} else { \
head = item; \
item->prefix##next = item->prefix##prev = item; \
} \
} while( 0 )
#define ADD_CDL_LIST_HEAD( item, type, head, prefix ) \
do { \
type *old_head = head; \
\
head = item; \
if( old_head ) { \
type *first, *last; \
\
first = old_head; \
last = first->prefix##prev; \
\
item->prefix##next = first; \
item->prefix##prev = last; \
first->prefix##prev = item; \
last->prefix##next = item; \
} else { \
item->prefix##next = item->prefix##prev = item; \
} \
} while( 0 )
#endif
@@ -1,45 +0,0 @@
/*
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/*
Fast logging facilities.
Internal header.
*/
#include <drivers/fast_log.h>
#include <malloc.h>
#include <pnp_devfs.h>
#include <device_manager.h>
// maximum number of long buffer
#define FAST_LOG_MAX_LONG_BUFFERS 256;
// size of one long buffer
#define FAST_LOG_LONG_BUFFER_SIZE (16*1024)
// name of dev interface module
#define FAST_LOG_DEVFS_MODULE_NAME "generic/fast_log/devfs/v1"
extern device_manager_info *pnp;
// long_buffers.c
void fast_log_write_long_log(const char *str);
void fast_log_flush_buffer(void);
size_t fast_log_read_long(char *buffer, size_t len);
status_t fast_log_init_long_buffer(void);
void fast_log_uninit_long_buffer(void);
// device.c
status_t fast_log_init_dev(void);
void fast_log_uninit_dev(void);
extern pnp_devfs_driver_info fast_log_devfs_module;
@@ -1,266 +0,0 @@
/*
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/*
Fast logging facilities.
Long buffer.
The internal log buffer uses encoded events and
cannot be decoded on demand as the event codes are
passed by the client and can be changed each time
the client connects. So, we store the decoded events
in long buffers which can be read from directly.
The long buffer is split up into several smaller
buffers that are allocated and freed on demand
to save space.
*/
#include "fast_log_int.h"
#include "dl_list.h"
#include <lock.h>
#include <string.h>
// one long buffer
typedef struct tagfast_log_long_buffer {
struct tagfast_log_long_buffer *next, *prev;
// content
char *data;
// offset for writing
size_t write_offset;
// offset for reading
size_t read_offset;
// size of buffer
size_t size;
} fast_log_long_buffer;
static fast_log_long_buffer
// list of long buffers
*fast_log_long_buffers,
// current buffer to write to
// (NULL if all long buffers are full)
*fast_log_cur_long_buffer;
static uint
// current number of long buffers
fast_log_num_long_buffers,
// maximum number of long buffers
fast_log_max_long_buffers;
// size of one long buffer
static size_t fast_log_long_buffer_size;
// true, if all long buffers are full
// (used to insert a proper message in logging)
static bool fast_log_long_overflow = false;
// grab this when you want to access a long buffer.
// you must make sure that no swapping occurs when holding this lock
static benaphore fast_log_long_buffer_ben;
// grab this when you read out long buffers.
// you are allowed to swap when you hold this lock;
// must be acquired before fast_log_long_buffer_ben
static benaphore fast_log_long_read_ben;
/** flush current long log buffer and allocate new one */
static status_t
fast_log_inc_long_buffer(void)
{
fast_log_long_buffer *buffer;
fast_log_cur_long_buffer = NULL;
// allocate new buffer if allowed and possible
if (fast_log_num_long_buffers >= fast_log_max_long_buffers)
return B_ERROR;
buffer = malloc(sizeof(*buffer) + fast_log_long_buffer_size);
if (buffer == NULL)
return B_NO_MEMORY;
memset(buffer, 0, sizeof(*buffer));
buffer->write_offset = 0;
buffer->read_offset = 0;
buffer->size = fast_log_long_buffer_size;
buffer->data = (char *)(buffer + 1);
ADD_CDL_LIST_TAIL(buffer, fast_log_long_buffer, fast_log_long_buffers, );
fast_log_cur_long_buffer = buffer;
return B_OK;
}
/** store string in long log, internal */
static status_t
fast_log_write_long_log_intern(const char *str)
{
size_t len;
len = strlen(str);
while (len > 0) {
fast_log_long_buffer *buffer;
size_t cur_len;
// get buffer, alloc a new one if there isn't one
if (fast_log_cur_long_buffer == NULL) {
if (fast_log_inc_long_buffer() != B_OK)
return B_ERROR;
}
buffer = fast_log_cur_long_buffer;
cur_len = min(len, buffer->size - buffer->write_offset);
memcpy(buffer->data + buffer->write_offset, str, cur_len);
buffer->write_offset += cur_len;
len -= cur_len;
str += cur_len;
if (buffer->write_offset == buffer->size) {
// next iteration will get a new one
fast_log_cur_long_buffer = NULL;
}
}
return B_OK;
}
/** store string in long log */
void
fast_log_write_long_log(const char *str)
{
benaphore_lock(&fast_log_long_buffer_ben);
// write pending "overflow" message
if (fast_log_long_overflow) {
if (fast_log_write_long_log_intern("<BUFFER OVERFLOW, increase max_long_buffers>\n") != B_OK)
goto err;
fast_log_long_overflow = false;
}
if (fast_log_write_long_log_intern(str) != B_OK)
fast_log_long_overflow = true;
err:
benaphore_unlock(&fast_log_long_buffer_ben);
}
/** free (first) long buffer */
static void
fast_log_free_long_buffer(void)
{
fast_log_long_buffer *buffer = fast_log_long_buffers;
REMOVE_CDL_LIST(buffer, fast_log_long_buffers, );
free(buffer);
}
/** read data from long buffers */
size_t
fast_log_read_long(char *data, size_t len)
{
size_t left_bytes = len;
// fill long buffer
fast_log_flush_buffer();
// make sure noone reads log concurrently
benaphore_lock(&fast_log_long_read_ben);
benaphore_lock(&fast_log_long_buffer_ben);
while (left_bytes > 0 && fast_log_long_buffers != NULL) {
size_t cur_len;
fast_log_long_buffer *buffer;
buffer = fast_log_long_buffers;
cur_len = min(left_bytes, buffer->write_offset - buffer->read_offset);
if (cur_len == 0)
break;
// "data" may be pagable, so release lock during memcpy
benaphore_unlock(&fast_log_long_buffer_ben);
memcpy(data, buffer->data + buffer->read_offset, cur_len);
benaphore_lock(&fast_log_long_buffer_ben);
buffer->read_offset += cur_len;
data += cur_len;
left_bytes -= cur_len;
// once a buffer is completely read, free it
if (buffer->read_offset == buffer->size) {
fast_log_free_long_buffer();
buffer = fast_log_long_buffers;
}
}
benaphore_unlock(&fast_log_long_buffer_ben);
benaphore_unlock(&fast_log_long_read_ben);
return len - left_bytes;
}
/** cleanup long buffers */
void
fast_log_uninit_long_buffer(void)
{
while (fast_log_long_buffers != NULL)
fast_log_free_long_buffer();
benaphore_destroy(&fast_log_long_buffer_ben);
benaphore_destroy(&fast_log_long_read_ben);
}
/** initialize long buffers.
* you must call "fast_log_uninit_long_buffer" on fail
*/
status_t
fast_log_init_long_buffer(void)
{
status_t res;
fast_log_long_buffer_ben.sem = -1;
fast_log_long_read_ben.sem = -1;
fast_log_long_buffers = fast_log_cur_long_buffer = NULL;
fast_log_num_long_buffers = 0;
fast_log_max_long_buffers = 256;
fast_log_long_buffer_size = 16*1024;
fast_log_long_overflow = false;
if ((res = benaphore_init(&fast_log_long_buffer_ben, "fast_log_long_buffer_ben")) < 0)
return res;
if ((res = benaphore_init( &fast_log_long_read_ben, "fast_log_long_read_ben")) < 0)
return res;
return res;
}
@@ -37,12 +37,19 @@ static ide_for_controller_interface *ide;
static device_manager_info *pnp;
static void
set_channel(ide_adapter_channel_info *channel, ide_channel ideChannel)
{
channel->ide_channel = ideChannel;
}
static status_t
ide_adapter_write_command_block_regs(ide_adapter_channel_info *channel,
ide_task_file *tf, ide_reg_mask mask)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
int i;
uint16 ioaddr = channel->command_block_base;
@@ -71,7 +78,7 @@ ide_adapter_read_command_block_regs(ide_adapter_channel_info *channel,
ide_task_file *tf, ide_reg_mask mask)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
int i;
uint16 ioaddr = channel->command_block_base;
@@ -94,7 +101,7 @@ static uint8
ide_adapter_get_altstatus(ide_adapter_channel_info *channel)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint16 altstatusaddr = channel->control_block_base;
if (channel->lost)
@@ -108,7 +115,7 @@ static status_t
ide_adapter_write_device_control(ide_adapter_channel_info *channel, uint8 val)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint16 device_control_addr = channel->control_block_base;
SHOW_FLOW(3, "%x", (int)val);
@@ -127,7 +134,7 @@ ide_adapter_write_pio(ide_adapter_channel_info *channel, uint16 *data,
int count, bool force_16bit)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint16 ioaddr = channel->command_block_base;
@@ -153,7 +160,7 @@ ide_adapter_read_pio(ide_adapter_channel_info *channel, uint16 *data,
int count, bool force_16bit)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint16 ioaddr = channel->command_block_base;
@@ -181,7 +188,7 @@ ide_adapter_inthand(void *arg)
{
ide_adapter_channel_info *channel = (ide_adapter_channel_info *)arg;
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint8 status;
SHOW_FLOW0(3, "");
@@ -211,7 +218,7 @@ ide_adapter_prepare_dma(ide_adapter_channel_info *channel,
const physical_entry *sgList, size_t sgListCount, bool writeToDevice)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint8 command;
uint8 status;
prd_entry *prd = channel->prdt;
@@ -255,7 +262,7 @@ static status_t
ide_adapter_start_dma(ide_adapter_channel_info *channel)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint8 command;
command = pci->read_io_8(device, channel->bus_master_base
@@ -275,7 +282,7 @@ static status_t
ide_adapter_finish_dma(ide_adapter_channel_info *channel)
{
pci_device_module_info *pci = channel->pci;
pci_device device = channel->device;
pci_device *device = channel->device;
uint8 command;
uint8 status, newStatus;
@@ -319,7 +326,7 @@ ide_adapter_finish_dma(ide_adapter_channel_info *channel)
static status_t
ide_adapter_init_channel(device_node_handle node, ide_channel ide_channel,
ide_adapter_init_channel(device_node *node,
ide_adapter_channel_info **cookie, size_t total_data_size,
int32 (*inthand)(void *arg))
{
@@ -334,6 +341,7 @@ ide_adapter_init_channel(device_node_handle node, ide_channel ide_channel,
TRACE("PCI-IDE: init channel...\n");
#if 0
if (1 /* debug */){
uint8 bus, device, function;
uint16 vendorID, deviceID;
@@ -345,6 +353,7 @@ ide_adapter_init_channel(device_node_handle node, ide_channel ide_channel,
TRACE("PCI-IDE: bus %3d, device %2d, function %2d: vendor %04x, device %04x\n",
bus, device, function, vendorID, deviceID);
}
#endif
// get device data
if (pnp->get_attr_uint16(node, IDE_ADAPTER_COMMAND_BLOCK_BASE, &command_block_base, false) != B_OK
@@ -353,8 +362,11 @@ ide_adapter_init_channel(device_node_handle node, ide_channel ide_channel,
|| pnp->get_attr_uint8(node, IDE_ADAPTER_CHANNEL_INDEX, &channel_index, false) != B_OK)
return B_ERROR;
if (pnp->init_driver(pnp->get_parent(node), NULL, NULL, (void **)&controller) != B_OK)
return B_ERROR;
{
device_node *parent = pnp->get_parent_node(node);
pnp->get_driver(parent, NULL, (void **)&controller);
pnp->put_node(parent);
}
channel = (ide_adapter_channel_info *)malloc(total_data_size);
if (channel == NULL) {
@@ -372,7 +384,6 @@ ide_adapter_init_channel(device_node_handle node, ide_channel ide_channel,
channel->control_block_base = control_block_base;
channel->bus_master_base = controller->bus_master_base + (channel_index * 8);
channel->intnum = intnum;
channel->ide_channel = ide_channel;
channel->dmaing = false;
channel->inthand = inthand;
@@ -411,7 +422,6 @@ ide_adapter_init_channel(device_node_handle node, ide_channel ide_channel,
err3:
delete_area(channel->prd_area);
err2:
pnp->uninit_driver(pnp->get_parent(node));
err:
free(channel);
@@ -419,7 +429,7 @@ err:
}
static status_t
static void
ide_adapter_uninit_channel(ide_adapter_channel_info *channel)
{
// disable IRQs
@@ -432,17 +442,13 @@ ide_adapter_uninit_channel(ide_adapter_channel_info *channel)
remove_io_interrupt_handler(channel->intnum, channel->inthand, channel);
pnp->uninit_driver( pnp->get_parent(channel->node));
delete_area(channel->prd_area);
free(channel);
return B_OK;
}
static void
ide_adapter_channel_removed(device_node_handle node, ide_adapter_channel_info *channel)
ide_adapter_channel_removed(ide_adapter_channel_info *channel)
{
SHOW_FLOW0( 3, "" );
@@ -455,18 +461,16 @@ ide_adapter_channel_removed(device_node_handle node, ide_adapter_channel_info *c
/** publish node of ide channel */
static status_t
ide_adapter_publish_channel(device_node_handle controller_node,
ide_adapter_publish_channel(device_node *controller_node,
const char *channel_module_name, uint16 command_block_base,
uint16 control_block_base, uint8 intnum, bool can_dma,
uint8 channel_index, const char *name, io_resource_handle *resources,
device_node_handle *node)
uint8 channel_index, const char *name, const io_resource *resources,
device_node **node)
{
device_attr attrs[] = {
// info about ourself and our consumer
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: channel_module_name }},
{ B_DRIVER_PRETTY_NAME, B_STRING_TYPE, { string: "IDE PCI" }},
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: name }},
{ B_DRIVER_FIXED_CHILD, B_STRING_TYPE, { string: IDE_FOR_CONTROLLER_MODULE_NAME }},
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "IDE PCI" }},
{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE, { string: IDE_FOR_CONTROLLER_MODULE_NAME }},
// private data to identify channel
{ IDE_ADAPTER_COMMAND_BLOCK_BASE, B_UINT16_TYPE, { ui16: command_block_base }},
@@ -479,21 +483,21 @@ ide_adapter_publish_channel(device_node_handle controller_node,
SHOW_FLOW0(2, "");
return pnp->register_device(controller_node, attrs, resources, node);
return pnp->register_node(controller_node, channel_module_name, attrs,
resources, node);
}
/** detect IDE channel */
static status_t
ide_adapter_detect_channel(pci_device_module_info *pci, pci_device pci_device,
device_node_handle controller_node, const char *channel_module_name,
ide_adapter_detect_channel(pci_device_module_info *pci, pci_device *pci_device,
device_node *controller_node, const char *channel_module_name,
bool controller_can_dma, uint16 command_block_base, uint16 control_block_base,
uint16 bus_master_base, uint8 intnum, uint8 channel_index, const char *name,
device_node_handle *node, bool supports_compatibility_mode)
device_node **node, bool supports_compatibility_mode)
{
uint8 api;
io_resource_handle resource_handles[3];
SHOW_FLOW0( 3, "" );
@@ -549,42 +553,38 @@ ide_adapter_detect_channel(pci_device_module_info *pci, pci_device pci_device,
}
{
// allocate channel's I/O resources
io_resource resources[3] = {
{ IO_PORT, command_block_base, 8 },
{ IO_PORT, control_block_base, 1 },
{ B_IO_PORT, command_block_base, 8 },
{ B_IO_PORT, control_block_base, 1 },
{}
};
if (pnp->acquire_io_resources(resources, resource_handles) != B_OK) {
TRACE("PCI-IDE: Couldn't acquire channel resources %#x and %#x\n",
command_block_base, control_block_base);
return B_ERROR;
}
}
return ide_adapter_publish_channel(controller_node, channel_module_name,
command_block_base, control_block_base, intnum, controller_can_dma,
channel_index, name, resource_handles, node);
channel_index, name, resources, node);
}
}
static status_t
ide_adapter_init_controller(device_node_handle node, void *user_cookie,
ide_adapter_init_controller(device_node *node,
ide_adapter_controller_info **cookie, size_t total_data_size)
{
pci_device_module_info *pci;
pci_device device;
pci_device *device;
ide_adapter_controller_info *controller;
uint16 bus_master_base;
uint16 pcicmd;
// uint16 pcicmd;
// get device data
if (pnp->get_attr_uint16(node, IDE_ADAPTER_BUS_MASTER_BASE, &bus_master_base, false) != B_OK)
return B_ERROR;
if (pnp->init_driver(pnp->get_parent(node), NULL, (driver_module_info **)&pci, (void **)&device) != B_OK)
return B_ERROR;
{
device_node *parent = pnp->get_parent_node(node);
pnp->get_driver(parent, (driver_module_info **)&pci, (void **)&device);
pnp->put_node(parent);
}
controller = (ide_adapter_controller_info *)malloc(total_data_size);
if (controller == NULL)
@@ -617,42 +617,35 @@ ide_adapter_init_controller(device_node_handle node, void *user_cookie,
}
static status_t
static void
ide_adapter_uninit_controller(ide_adapter_controller_info *controller)
{
pnp->uninit_driver(pnp->get_parent(controller->node));
free(controller);
return B_OK;
}
static void
ide_adapter_controller_removed(device_node_handle node,
ide_adapter_controller_info *controller)
ide_adapter_controller_removed(ide_adapter_controller_info *controller)
{
SHOW_FLOW0(3, "");
if (controller != NULL)
if (controller != NULL) {
// disable access instantly; unit_device takes care of unregistering ioports
atomic_or(&controller->lost, 1);
}
}
/** publish node of ide controller */
static status_t
ide_adapter_publish_controller(device_node_handle parent, uint16 bus_master_base,
io_resource_handle *resources, const char *controller_driver,
ide_adapter_publish_controller(device_node *parent, uint16 bus_master_base,
io_resource *resources, 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,
device_node_handle *node)
device_node **node)
{
device_attr attrs[] = {
// info about ourself and our consumer
{ B_DRIVER_MODULE, B_STRING_TYPE, { string: controller_driver }},
// properties of this controller for ide bus manager
// there are always max. 2 devices
// (unless this is a Compact Flash Card with a built-in IDE controller,
@@ -683,20 +676,23 @@ ide_adapter_publish_controller(device_node_handle parent, uint16 bus_master_base
SHOW_FLOW0( 2, "" );
return pnp->register_device(parent, attrs, resources, node);
return pnp->register_node(parent, controller_driver, attrs, resources, node);
}
/** detect pure IDE controller, i.e. without channels */
static status_t
ide_adapter_detect_controller(pci_device_module_info *pci, pci_device pci_device,
device_node_handle parent, uint16 bus_master_base, const char *controller_driver,
ide_adapter_detect_controller(pci_device_module_info *pci, pci_device *pci_device,
device_node *parent, uint16 bus_master_base, 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,
device_node_handle *node)
device_node **node)
{
io_resource_handle resource_handles[2];
io_resource resources[2] = {
{ B_IO_PORT, bus_master_base, 16 },
{}
};
SHOW_FLOW0( 3, "" );
@@ -705,43 +701,31 @@ ide_adapter_detect_controller(pci_device_module_info *pci, pci_device pci_device
return B_ERROR;
}
{
io_resource resources[2] = {
{ IO_PORT, bus_master_base, 16 },
{}
};
if (pnp->acquire_io_resources(resources, resource_handles) != B_OK) {
TRACE("PCI-IDE: Couldn't acquire controller resource %#x\n", bus_master_base);
return B_ERROR;
}
}
return ide_adapter_publish_controller(parent, bus_master_base, resource_handles,
return ide_adapter_publish_controller(parent, bus_master_base, resources,
controller_driver, controller_driver_type, controller_name, can_dma, can_cq,
dma_alignment, dma_boundary, max_sg_block_size, node);
}
static status_t
ide_adapter_probe_controller(device_node_handle parent, const char *controller_driver,
ide_adapter_probe_controller(device_node *parent, const char *controller_driver,
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)
{
pci_device_module_info *pci;
pci_device device;
pci_device *device;
uint16 command_block_base[2];
uint16 control_block_base[2];
uint16 bus_master_base;
device_node_handle controller_node, channels[2];
device_node *controller_node;
device_node *channels[2];
uint8 intnum;
status_t res;
SHOW_FLOW0( 3, "" );
if (pnp->init_driver(parent, NULL, (driver_module_info **)&pci, (void **)&device) != B_OK)
return B_ERROR;
pnp->get_driver(parent, (driver_module_info **)&pci, (void **)&device);
command_block_base[0] = pci->read_pci_config(device, PCI_base_registers, 4 );
control_block_base[0] = pci->read_pci_config(device, PCI_base_registers + 4, 4);
@@ -762,7 +746,7 @@ ide_adapter_probe_controller(device_node_handle parent, const char *controller_d
// don't register if controller is already registered!
// (happens during rescan; registering new channels would kick out old channels)
if (res != B_OK || controller_node == NULL)
goto err;
return res;
// ignore errors during registration of channels - could be a simple rescan collision
ide_adapter_detect_channel(pci, device, controller_node, channel_module_name,
@@ -773,13 +757,7 @@ ide_adapter_probe_controller(device_node_handle parent, const char *controller_d
can_dma, command_block_base[1], control_block_base[1], bus_master_base,
intnum, 1, "Secondary Channel", &channels[1], supports_compatibility_mode);
pnp->uninit_driver(parent);
return B_OK;
err:
pnp->uninit_driver(parent);
return res;
}
@@ -811,6 +789,8 @@ static ide_adapter_interface adapter_interface = {
std_ops
},
set_channel,
ide_adapter_write_command_block_regs,
ide_adapter_read_command_block_regs,
@@ -21,9 +21,9 @@
char *
periph_compose_device_name(device_node_handle node, const char *prefix)
periph_compose_device_name(device_node *node, const char *prefix)
{
uint8 pathID, targetID, targetLUN, isPrimary, type;
uint8 pathID, targetID, targetLUN, type;
char name[128];
uint32 channel;
@@ -55,7 +55,7 @@ periph_compose_device_name(device_node_handle node, const char *prefix)
status_t
periph_register_device(periph_device_cookie periph_device, scsi_periph_callbacks *callbacks,
scsi_device scsi_device, scsi_device_interface *scsi, device_node_handle node,
scsi_device scsi_device, scsi_device_interface *scsi, device_node *node,
bool removable, scsi_periph_device *driver)
{
scsi_periph_device_info *device;
+2 -4
View File
@@ -184,16 +184,14 @@ abort:
static status_t
inquiry(scsi_periph_device_info *device, scsi_inquiry *inquiry)
{
scsi_res_inquiry *device_inquiry = NULL;
const scsi_res_inquiry *device_inquiry = NULL;
size_t inquiry_len;
if (pnp->get_attr_raw(device->node, SCSI_DEVICE_INQUIRY_ITEM,
(void **)&device_inquiry, &inquiry_len, true) != B_OK)
(const void **)&device_inquiry, &inquiry_len, true) != B_OK)
return B_ERROR;
memcpy(inquiry, device_inquiry, min(inquiry_len, sizeof(scsi_inquiry)));
free(device_inquiry);
return B_OK;
}
@@ -21,7 +21,7 @@ typedef struct scsi_periph_device_info {
scsi_device scsi_device;
scsi_device_interface *scsi;
periph_device_cookie periph_device;
device_node_handle node;
device_node *node;
bool removal_requested;
@@ -80,9 +80,9 @@ status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb);
status_t periph_register_device(periph_device_cookie periph_device,
scsi_periph_callbacks *callbacks, scsi_device scsi_device, scsi_device_interface *scsi,
device_node_handle node, bool removable, scsi_periph_device *driver);
device_node *node, bool removable, scsi_periph_device *driver);
status_t periph_unregister_device(scsi_periph_device_info *driver);
char *periph_compose_device_name(device_node_handle device_node, const char *prefix);
char *periph_compose_device_name(device_node *device_node, const char *prefix);
// io.c
@@ -0,0 +1,34 @@
/*
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "BaseDevice.h"
BaseDevice::BaseDevice()
:
fNode(NULL),
fDeviceModule(NULL),
fDeviceData(NULL)
{
}
BaseDevice::~BaseDevice()
{
}
status_t
BaseDevice::InitDevice()
{
return B_ERROR;
}
void
BaseDevice::UninitDevice()
{
}
@@ -0,0 +1,122 @@
/*
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef BASE_DEVICE_H
#define BASE_DEVICE_H
#include <device_manager.h>
class BaseDevice {
public:
BaseDevice();
virtual ~BaseDevice();
device_node* Node() const { return fNode; }
virtual status_t InitDevice();
virtual void UninitDevice();
device_module_info* Module() const { return fDeviceModule; }
void* Data() const { return fDeviceData; }
bool HasSelect() const
{ return Module()->select != NULL; }
bool HasDeselect() const
{ return Module()->deselect != NULL; }
bool HasRead() const
{ return Module()->read != NULL; }
bool HasWrite() const
{ return Module()->write != NULL; }
bool HasIO() const
{ return Module()->io != NULL; }
virtual status_t Open(const char* path, int openMode,
void** _cookie);
status_t Read(void* cookie, off_t pos, void* buffer,
size_t* _length);
status_t Write(void* cookie, off_t pos, const void* buffer,
size_t* _length);
status_t IO(void* cookie, io_request* request);
status_t Control(void* cookie, int32 op, void* buffer,
size_t length);
virtual status_t Select(void* cookie, uint8 event, selectsync* sync);
status_t Deselect(void* cookie, uint8 event,
selectsync* sync);
status_t Close(void* cookie);
status_t Free(void* cookie);
protected:
device_node* fNode;
int32 fInitialized;
device_module_info* fDeviceModule;
void* fDeviceData;
};
inline status_t
BaseDevice::Open(const char* path, int openMode, void** _cookie)
{
return Module()->open(Data(), path, openMode, _cookie);
}
inline status_t
BaseDevice::Read(void* cookie, off_t pos, void* buffer, size_t* _length)
{
return Module()->read(cookie, pos, buffer, _length);
}
inline status_t
BaseDevice::Write(void* cookie, off_t pos, const void* buffer, size_t* _length)
{
return Module()->write(cookie, pos, buffer, _length);
}
inline status_t
BaseDevice::IO(void* cookie, io_request* request)
{
return Module()->io(cookie, request);
}
inline status_t
BaseDevice::Control(void* cookie, int32 op, void* buffer, size_t length)
{
return Module()->control(cookie, op, buffer, length);
}
inline status_t
BaseDevice::Select(void* cookie, uint8 event, selectsync* sync)
{
return Module()->select(cookie, event, sync);
}
inline status_t
BaseDevice::Deselect(void* cookie, uint8 event, selectsync* sync)
{
return Module()->deselect(cookie, event, sync);
}
inline status_t
BaseDevice::Close(void* cookie)
{
return Module()->close(cookie);
}
inline status_t
BaseDevice::Free(void* cookie)
{
return Module()->free(cookie);
}
#endif // BASE_DEVICE_H
+7 -12
View File
@@ -4,18 +4,13 @@ UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ;
UsePrivateHeaders [ FDirName kernel util ] shared ;
KernelMergeObject kernel_device_manager.o :
attributes.c
device_manager.c
driver_loader.c
id_generator.c
io_resources.c
nodes.c
notifications.c
patterns.c
probe.cpp
registration.c
root_node.c
scan.c
BaseDevice.cpp
device_manager.cpp
devfs.cpp
id_generator.cpp
io_resources.cpp
legacy_drivers.cpp
# probe.cpp
settings.cpp
:
$(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,17 @@
/*
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef DEVFS_PRIVATE_H
#define DEVFS_PRIVATE_H
#include <SupportDefs.h>
class BaseDevice;
status_t devfs_publish_device(const char* path, BaseDevice* device);
status_t devfs_get_device(dev_t device, ino_t node, BaseDevice** _device);
#endif /* DEVFS_PRIVATE_H */
File diff suppressed because it is too large Load Diff
@@ -1,223 +1,10 @@
/*
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-04, Thomas Kurschel. All rights reserved.
*
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef DEVICE_MANAGER_PRIVATE
#define DEVICE_MANAGER_PRIVATE
/*
Part of Device Manager
Internal header.
*/
#include <kdevice_manager.h>
#include <util/list.h>
#include <lock.h>
#define GENERATOR_MAX_ID 64
#define UNIVERSAL_SUBDIR "/universal"
#define GENERIC_SUBDIR "/generic"
// driver registration directories
#define PNP_DIR
#define SYSTEM_DRIVER_REGISTRATION "/boot/beos/system/add-ons/kernel/"PNP_DIR"registration/"
#define COMMON_DRIVER_REGISTRATION "/boot/home/config/add-ons/kernel/"PNP_DIR"registration/"
// info about ID generator
typedef struct id_generator {
struct list_link link;
struct id_generator *prev, *next;
int32 ref_count;
char *name;
uint32 num_ids;
uint8 alloc_map[(GENERATOR_MAX_ID + 7) / 8];
} id_generator;
#ifndef DEVICE_MANAGER_PRIVATE_H
#define DEVICE_MANAGER_PRIVATE_H
// info about a node attribute
typedef struct device_attr_info {
struct device_attr_info *prev, *next;
int32 ref_count; // reference count
device_attr attr;
} device_attr_info;
// I/O resource
typedef struct io_resource_info {
struct io_resource_info *prev, *next;
device_node_info *owner; // associated node; NULL for temporary allocation
io_resource resource; // info about actual resource
} io_resource_info;
// a structure to put nodes into lists
struct node_entry {
struct list_link link;
device_node_info *node;
};
// global lock
// whenever you do something in terms of nodes, grab it
extern benaphore gNodeLock;
// root node
extern device_node_info *gRootNode;
// true, if user addons are disabled via safemode
extern bool disable_useraddons;
// # of allocate_io_resource() calls waiting for a retry
extern int pnp_resource_wait_count;
// semaphore for allocate_io_resource() call retry
extern sem_id pnp_resource_wait_sem;
// list of driver registration directories
extern const char *pnp_registration_dirs[];
// list of I/O memory, I/O ports and ISA DMA channels
extern io_resource_info *io_mem_list, *io_port_list, *isa_dma_list;
// nesting of pnp_load_boot_links calls
int pnp_fs_emulation_nesting;
#ifdef __cplusplus
extern "C" {
#endif
// attributes.c
device_attr_info *pnp_find_attr_nolock(device_node_handle node, const char *name,
bool recursive, type_code type);
status_t pnp_get_attr_uint8(device_node_handle node, const char *name,
uint8 *value, bool recursive);
status_t pnp_get_attr_uint8_nolock(device_node_handle node, const char *name,
uint8 *value, bool recursive);
status_t pnp_get_attr_uint16(device_node_handle node, const char *name,
uint16 *value, bool recursive);
status_t pnp_get_attr_uint16_nolock(device_node_handle node, const char *name,
uint16 *value, bool recursive);
status_t pnp_get_attr_uint32(device_node_handle node, const char *name,
uint32 *value, bool recursive);
status_t pnp_get_attr_uint32_nolock(device_node_handle node, const char *name,
uint32 *value, bool recursive);
status_t pnp_get_attr_uint64(device_node_handle node, const char *name,
uint64 *value, bool recursive);
status_t pnp_get_attr_uint64_nolock(device_node_handle node, const char *name,
uint64 *value, bool recursive);
status_t pnp_get_attr_string(device_node_handle node, const char *name,
char **value, bool recursive);
status_t pnp_get_attr_string_nolock(device_node_handle node, const char *name,
const char **value, bool recursive);
status_t pnp_get_attr_raw(device_node_handle node, const char *name,
void **data, size_t *len, bool recursive);
status_t pnp_get_attr_raw_nolock(device_node_handle node, const char *name,
const void **data, size_t *len, bool recursive);
void pnp_free_node_attr(device_attr_info *attr);
status_t pnp_get_next_node_with_attrs(device_node_info **_node, const device_attr *attrs);
int pnp_compare_attrs(const device_attr *attrA, const device_attr *attrB);
status_t pnp_duplicate_node_attr(const device_attr *src, device_attr_info **dest_out);
status_t pnp_get_next_attr(device_node_handle node, device_attr_handle *attr);
status_t pnp_release_attr(device_node_handle node, device_attr_handle attr);
status_t pnp_retrieve_attr(device_attr_handle attr, const device_attr **attr_content);
status_t pnp_write_attr(device_node_handle node, const device_attr *attr);
void pnp_remove_attr_int(device_node_handle node, device_attr_info *attr);
status_t pnp_remove_attr(device_node_handle node, const char *name);
// driver_loader.c
status_t pnp_load_driver(device_node_handle node, void *user_cookie,
driver_module_info **interface, void **cookie);
status_t pnp_unload_driver(device_node_handle node);
void pnp_unblock_load(device_node_info *node);
// id_generator.c
int32 dm_create_id(const char *name);
status_t dm_free_id(const char *name, uint32 id);
extern status_t dm_init_id_generator(void);
// io_resources.c
status_t dm_acquire_io_resources(io_resource *resources, io_resource_handle *handles);
status_t dm_release_io_resources(const io_resource_handle *handles);
void dm_assign_io_resources(device_node_info *node, const io_resource_handle *handles);
void dm_release_node_resources(device_node_info *node);
// nodes.c
status_t dm_allocate_node(const device_attr *attrs, const io_resource_handle *resources,
device_node_info **new_node);
void dm_add_child_node(device_node_info *node, device_node_info *parent);
void dm_get_node_nolock(device_node_info *node);
void dm_get_node(device_node_info *node);
void dm_put_node_nolock(device_node_info *node);
void dm_dump_node(device_node_info *node, int32 level);
status_t dm_init_nodes(void);
void dm_put_node(device_node_info *node);
status_t dm_get_next_child_node(device_node_info *parent,
device_node_info **_node, const device_attr *attrs);
device_node_info *dm_get_root(void);
device_node_info *dm_get_parent(device_node_info *node);
status_t device_manager_control(const char *subsystem, uint32 function, void *buffer, size_t bufferSize);
// notifications.c
status_t dm_notify_unregistration(device_node_info *node);
void pnp_start_hook_call(device_node_info *node);
void pnp_start_hook_call_nolock(device_node_info *node);
void pnp_finish_hook_call(device_node_info *node);
void pnp_finish_hook_call_nolock(device_node_info *node);
// patterns.c
status_t pnp_expand_pattern(device_node_info *node, const char *pattern,
char *dest, char *buffer, size_t *term_array, int *num_parts);
status_t pnp_expand_pattern_attr(device_node_info *node, const char *attr_name,
char **expanded);
// probe.cpp
status_t dm_register_child_device(device_node_info *node, const char *childName, bool checkSupport);
status_t dm_register_fixed_child_devices(device_node_info *node);
status_t dm_register_dynamic_child_devices(device_node_info *node);
// registration.c
status_t dm_register_node(device_node_handle parent, const device_attr *attrs,
const io_resource_handle *resources, device_node_handle *_newNode);
status_t dm_unregister_node(device_node_handle node);
void pnp_unref_unregistered_nodes(device_node_info *node_list);
// root_node.c
void dm_init_root_node(void);
// scan.c
status_t dm_rescan(device_node_handle node);
status_t dm_register_child_devices(device_node_info *node);
#ifdef __cplusplus
}
#endif
#endif /* DEVICE_MANAGER_PRIVATE_H */
#endif // DEVICE_MANAGER_PRIVATE_H
@@ -1,16 +1,11 @@
/*
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2004, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
/*
Part of the Device Manager
ID generator.
Generators are created on demand and deleted if all their
/*! Generators are created on demand and deleted if all their
IDs are freed. They have a ref_count which is increased
whenever someone messes with the generator.
@@ -26,13 +21,17 @@
*/
#include "device_manager_private.h"
#include <KernelExport.h>
#include <util/list.h>
#include "id_generator.h"
#include <new>
#include <stdlib.h>
#include <string.h>
#include <KernelExport.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
//#define TRACE_ID_GENERATOR
#ifdef TRACE_ID_GENERATOR
@@ -41,52 +40,68 @@
# define TRACE(x) ;
#endif
#define GENERATOR_MAX_ID 64
struct list sGenerators;
static benaphore sGeneratorLock;
struct id_generator : DoublyLinkedListLinkImpl<id_generator> {
id_generator(const char* name)
:
ref_count(1),
name(strdup(name)),
num_ids(0)
{
memset(&alloc_map, 0, sizeof(alloc_map));
}
~id_generator()
{
free(name);
}
int32 ref_count;
char* name;
uint32 num_ids;
uint8 alloc_map[(GENERATOR_MAX_ID + 7) / 8];
};
typedef DoublyLinkedList<id_generator> GeneratorList;
/** Create new generator
* sGeneratorLock must be held
*/
GeneratorList sGenerators;
static mutex sLock;
static id_generator *
create_generator(const char *name)
/*! Create new generator.
sLock must be held.
*/
static id_generator*
create_generator(const char* name)
{
id_generator *generator;
TRACE(("create_generator(name: %s)\n", name));
generator = malloc(sizeof(*generator));
id_generator* generator = new(std::nothrow) id_generator(name);
if (generator == NULL)
return NULL;
memset(generator, 0, sizeof(*generator));
generator->name = strdup(name);
if (generator->name == NULL) {
free(generator);
delete generator;
return NULL;
}
generator->ref_count = 1;
list_add_link_to_head(&sGenerators, generator);
sGenerators.Add(generator);
return generator;
}
/** Allocate id */
/*! Allocate ID */
static int32
create_id_internal(id_generator *generator)
create_id_internal(id_generator* generator)
{
uint32 id;
TRACE(("create_id_internal(name: %s)\n", generator->name));
// see above: we use global instead of local lock
benaphore_lock(&sGeneratorLock);
MutexLocker _(sLock);
// simple bit search
for (id = 0; id < GENERATOR_MAX_ID; ++id) {
@@ -94,104 +109,92 @@ create_id_internal(id_generator *generator)
TRACE((" id: %lu\n", id));
generator->alloc_map[id / 8] |= 1 << (id & 7);
++generator->num_ids;
generator->num_ids++;
benaphore_unlock(&sGeneratorLock);
return id;
}
}
benaphore_unlock(&sGeneratorLock);
return B_ERROR;
}
/** Find generator by name
* sGeneratorLock must be held
*/
static id_generator *
find_generator(const char *name)
/*! Gets a generator by name, and acquires a reference to it.
sLock must be held.
*/
static id_generator*
get_generator(const char* name)
{
id_generator *generator = NULL;
TRACE(("find_generator(name: %s)\n", name));
while ((generator = list_get_next_item(&sGenerators, generator)) != NULL) {
GeneratorList::Iterator iterator = sGenerators.GetIterator();
while (iterator.HasNext()) {
id_generator* generator = iterator.Next();
if (!strcmp(generator->name, name)) {
// increase ref_count, so it won't go away
++generator->ref_count;
break;
generator->ref_count++;
return generator;
}
}
return generator;
return NULL;
}
/** Decrease ref_count, deleting generator if not used anymore */
/*! Decrease ref_count, deleting generator if not used anymore */
static void
release_generator(id_generator *generator)
{
TRACE(("release_generator(name: %s)\n", generator->name));
benaphore_lock(&sGeneratorLock);
MutexLocker _(sLock);
if (--generator->ref_count == 0) {
// no one messes with generator
if (generator->num_ids == 0) {
TRACE((" Destroy %s\n", generator->name));
// no IDs is allocated - destroy generator
list_remove_link(generator);
free(generator->name);
free(generator);
sGenerators.Remove(generator);
delete generator;
}
}
benaphore_unlock(&sGeneratorLock);
}
// #pragma mark -
// Private kernel API
// #pragma mark - Private kernel API
status_t
void
dm_init_id_generator(void)
{
list_init(&sGenerators);
return benaphore_init(&sGeneratorLock, "id generator");
new(&sGenerators) GeneratorList;
mutex_init(&sLock, "id generator");
}
// #pragma mark -
// Public module API
// #pragma mark - Public module API
/** Create automatic ID */
/*! Create automatic ID */
int32
dm_create_id(const char *name)
dm_create_id(const char* name)
{
id_generator *generator;
int32 id;
// find generator, create new if not there
benaphore_lock(&sGeneratorLock);
mutex_lock(&sLock);
generator = find_generator(name);
id_generator* generator = get_generator(name);
if (generator == NULL)
generator = create_generator(name);
benaphore_unlock(&sGeneratorLock);
mutex_unlock(&sLock);
if (generator == NULL)
return B_NO_MEMORY;
// get ID
id = create_id_internal(generator);
int32 id = create_id_internal(generator);
release_generator(generator);
@@ -200,21 +203,18 @@ dm_create_id(const char *name)
}
/** Free automatically generated ID */
/*! Free automatically generated ID */
status_t
dm_free_id(const char *name, uint32 id)
dm_free_id(const char* name, uint32 id)
{
id_generator *generator;
TRACE(("dm_free_id(name: %s, id: %ld)\n", name, id));
// find generator
benaphore_lock(&sGeneratorLock);
mutex_lock(&sLock);
generator = find_generator(name);
id_generator* generator = get_generator(name);
benaphore_unlock(&sGeneratorLock);
mutex_unlock(&sLock);
if (generator == NULL) {
TRACE((" Generator %s doesn't exist\n", name));
@@ -226,7 +226,8 @@ dm_free_id(const char *name, uint32 id)
// make sure it's really allocated
// (very important to keep <num_ids> in sync
if ((generator->alloc_map[id / 8] & (1 << (id & 7))) == 0) {
dprintf("id %ld of generator %s wasn't allocated\n", id, generator->name);
dprintf("id %ld of generator %s wasn't allocated\n", id,
generator->name);
release_generator(generator);
return B_BAD_VALUE;
@@ -236,7 +237,5 @@ dm_free_id(const char *name, uint32 id)
generator->num_ids--;
release_generator(generator);
return B_OK;
}
@@ -0,0 +1,27 @@
/*
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-04, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef ID_GENERATOR_H
#define ID_GENERATOR_H
#include <SupportDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
int32 dm_create_id(const char *name);
status_t dm_free_id(const char *name, uint32 id);
void dm_init_id_generator(void);
#ifdef __cplusplus
}
#endif
#endif /* ID_GENERATOR_H */
@@ -1,588 +0,0 @@
/*
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2004, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
/*
Part of Device Manager
I/O resource manager.
I/O resources are allocated in two flavours:
1. explicit allocation for hardware detection ("temporary allocation")
2. implicit allocation for registered devices
If hardware detection fails, the resources are freed explicitely,
if it succeeds, ownership is transfered to the device node.
Resources allocation collision is handled in the following way:
- during ownership transfer to a device node, all other device nodes
that collide in terms of resources are removed
- if two temporary allocations collide, one must wait
- if a temporary allocation collides with a device node whose driver is
loaded, the temporary allocation fails (waiting for the driver may
be hopeless as the driver may stay in memory forever)
- if a temporary allocation collides with a device node whose driver is
not loaded, loading of the driver is blocked
To avoid deadlocks between temporary allocations, they are done atomically:
either the entire allocation succeeds or fails. If it fails because of a
collision with another temporary allocation, a complete retry is done as
soon as someone released some resource.
*/
#include "device_manager_private.h"
#include "dl_list.h"
#include <KernelExport.h>
#include <stdlib.h>
#include <string.h>
//#define TRACE_IO_RESOURCES
#ifdef TRACE_IO_RESOURCES
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
// forward declarations to avoid inlining
static void unblock_temporary_allocation(void);
static void release_range(io_resource_info **list, io_resource_info *resource,
io_resource_info *up_to);
static void unregister_colliding_node_range(io_resource_info *list,
io_resource_info *resource);
/** validate I/O resource data */
static status_t
validate_io_resource(io_resource *src)
{
TRACE(("validate_io_resource()\n"));
switch (src->type) {
case IO_MEM:
if (src->base + src->length < src->base)
return B_BAD_VALUE;
break;
case IO_PORT:
if ((uint16)src->base != src->base
|| (uint16)src->length != src->length
|| (uint16)(src->base + src->length) < src->base)
return B_BAD_VALUE;
break;
case ISA_DMA_CHANNEL:
if (src->base > 8 || src->length != 1)
return B_BAD_VALUE;
break;
default:
return B_BAD_VALUE;
}
TRACE((" success!\n"));
return B_OK;
}
/** Allocate info structure for I/O resources */
static status_t
alloc_io_resource_info(io_resource *src, io_resource_info **dest_out)
{
io_resource_info *dest;
TRACE(("alloc_io_resource_info()\n"));
dest = calloc(1, sizeof(*dest));
if (dest == NULL)
return B_NO_MEMORY;
dest->owner = NULL;
dest->resource.type = src->type;
dest->resource.base = src->base;
dest->resource.length = src->length;
*dest_out = dest;
return B_OK;
}
/** Acquire I/O range; returns B_WOULD_BLOCK on collision with
* temporary allocation.
* gNodeLock must be held
*/
static status_t
acquire_range(io_resource_info **list, io_resource_info *resource)
{
io_resource_info *cur;
uint32 base = resource->resource.base;
uint32 length = resource->resource.length;
status_t res = B_OK;
TRACE(("acquire_range(base %lx, length %lx)\n", base, length));
for (cur = *list; cur != NULL; cur = cur->next) {
// we need the "base + length - 1" trick to avoid wrap around at 4 GB
if (cur->resource.base >= base
&& cur->resource.base + length - 1 <= base + length - 1) {
device_node_info *owner = cur->owner;
TRACE((" collision\n"));
if (owner == NULL) {
// collision with temporary allocation - block ourself
TRACE((" collision with temporary allocation - retry later\n"));
res = B_WOULD_BLOCK;
break;
} else {
// collision with device
if (owner->loading + owner->load_count > 0) {
// driver is already loaded - give up
// (driver may get loaded forever)
TRACE((" collision with loaded driver - giving up\n"));
res = B_BUSY;
break;
} else {
// driver is not loaded - block loading
TRACE((" collision with unloaded driver - block driver %p\n", owner));
++owner->load_block_count;
}
}
}
}
if (cur != NULL) {
// collided with someone
TRACE((" Resource collision\n"));
release_range(list, resource, cur);
return res;
}
ADD_DL_LIST_HEAD(resource, *list, );
return B_OK;
}
/** Free I/O resource info */
static void
free_io_resource_info(io_resource_info *resource)
{
TRACE(("free_io_resource_info()\n"));
free(resource);
}
/** Acquire I/O resource.
* An I/O resource info structure is allocated and added to
* appropriate resource list (i.e. mem/port/channel) plus
* all colliding resources (including ours) are marked blocked;
* returns B_WOULD_BLOCK on collision with temporary allocation;
* gNodeLock must be held.
*/
static status_t
acquire_io_resource(io_resource *src, io_resource_handle *dest_out)
{
io_resource_info *dest;
status_t res;
TRACE(("acquire_io_resource(type = %ld, base = %lx, length = %lx)\n",
src->type, src->base, src->length));
res = validate_io_resource(src);
if (res != B_OK)
return res;
res = alloc_io_resource_info(src, &dest);
if (res != B_OK)
return res;
switch (src->type) {
case IO_MEM:
res = acquire_range(&io_mem_list, dest);
break;
case IO_PORT:
res = acquire_range(&io_port_list, dest);
break;
case ISA_DMA_CHANNEL:
res = acquire_range(&isa_dma_list, dest);
break;
}
if (res != B_OK)
// collided with someone
goto err;
*dest_out = dest;
TRACE((" done\n"));
return B_OK;
err:
free_io_resource_info(dest);
TRACE((" failed: %s\n", strerror(res)));
return res;
}
/** Release I/O resource.
* gNodeLock must be held
*/
static void
release_io_resource(io_resource_info *resource)
{
TRACE(("release_io_resource()\n"));
switch (resource->resource.type) {
case IO_MEM:
release_range(&io_mem_list, resource, NULL);
break;
case IO_PORT:
release_range(&io_port_list, resource, NULL);
break;
case ISA_DMA_CHANNEL:
release_range(&isa_dma_list, resource, NULL);
break;
}
free_io_resource_info(resource);
}
/** Release I/O range, which can be I/O memory, ports and ISA DMA channels
* up_to - up to but not including colliding range to be released
* (NULL for normal release, not-NULL if used during failed allocation)
* blocked users get notified;
* gNodeLock must be held
*/
static void
release_range(io_resource_info **list, io_resource_info *resource, io_resource_info *up_to)
{
io_resource_info *cur;
uint32 base = resource->resource.base;
uint32 length = resource->resource.length;
TRACE(("release_range()\n"));
for (cur = *list; cur != NULL && cur != up_to; cur = cur->next) {
if (cur == resource)
// ignore ourselves
continue;
// we need the "base + length - 1" trick to avoid wrap around at 4 GB
if (cur->resource.base >= base && cur->resource.base + length - 1 <= base + length - 1) {
device_node_info *owner = cur->owner;
TRACE((" unblock\n"));
if (owner != NULL) {
// collision with driver - unblock it
TRACE((" collision with driver - unblock driver %p\n", owner));
pnp_unblock_load(owner);
}
}
}
if (up_to == NULL) {
// normal release - remove from list and
// notify blocked temporary allocations
REMOVE_DL_LIST(resource, *list, );
unblock_temporary_allocation();
}
}
/** Wait until someone freed some resource or
* allocated some resource permanently.
* gNodeLock must be held.
*/
static void
wait_for_resources(void)
{
TRACE(("wait_for_resources()\n"));
++pnp_resource_wait_count;
// we have to release while waiting
benaphore_unlock(&gNodeLock);
acquire_sem(pnp_resource_wait_sem);
benaphore_lock(&gNodeLock);
}
/** Try to acquire list of resources.
* returns B_WOULD_BLOCK on collision with temporary allocation.
* gNodeLock must be held.
*/
static status_t
try_acquire_io_resources(io_resource *resources, io_resource_handle *handles)
{
io_resource *resource;
io_resource_handle *handle, *handle2;
status_t res = B_OK;
for (resource = resources, handle = handles;
resource->type != 0; ++resource, ++handle) {
res = acquire_io_resource(resource, handle);
if (res != B_OK)
break;
}
if (res != B_OK)
goto err;
*handle++ = NULL;
return B_OK;
err:
// collision detected: free all previously acquired resources
for (handle2 = handle; handle2 != handle; ++handle2)
release_io_resource(*handle2);
return res;
}
/** Acquire I/O resources.
* gNodeLock must be held.
*/
static status_t
acquire_io_resources(io_resource *resources, io_resource_handle *handles)
{
// try allocation until we either got all resources or
// detected a collision with a loaded device node
while (true) {
status_t res;
// allocate all resources
res = try_acquire_io_resources( resources, handles );
if (res == B_OK)
return B_OK;
if (res == B_WOULD_BLOCK) {
// collision with temporary allocation:
// wait until some resource is freed or blocked forever
// by a loaded driver
wait_for_resources();
} else {
// collided with loaded node - no point waiting for the node
TRACE(("acquire_io_resouces(): Collision with loaded device node\n"));
return res;
}
}
}
/** Unregister devices that collide with one of our I/O resources */
static void
unregister_colliding_nodes(const io_resource_handle *resources)
{
const io_resource_handle *resource;
for (resource = resources; *resource != NULL; ++resource) {
switch ((*resource)->resource.type) {
case IO_MEM:
unregister_colliding_node_range(io_mem_list, *resource);
break;
case IO_PORT:
unregister_colliding_node_range(io_port_list, *resource);
break;
case ISA_DMA_CHANNEL:
unregister_colliding_node_range(isa_dma_list, *resource);
break;
}
}
}
/** Unregister device nodes that collide with I/O resource */
static void
unregister_colliding_node_range(io_resource_info *list, io_resource_info *resource)
{
io_resource_info *cur;
uint32 base = resource->resource.base;
uint32 length = resource->resource.length;
do {
for (cur = list; cur != NULL; cur = cur->next) {
// ignore ourself
if (cur == resource)
continue;
// we need the "base + length - 1" trick to avoid wrap around at 4 GB
if (cur->resource.base >= base
&& cur->resource.base + length - 1 <= base + length - 1) {
device_node_handle owner = cur->owner;
if (owner == NULL)
panic("Transfer of I/O resources from temporary to device node collided with other temporary allocation");
TRACE(("Deleting colliding device node %p\n", owner));
// make sure node still exists after we'll have released lock
++owner->ref_count;
// we have to release lock during unregistration
benaphore_unlock(&gNodeLock);
// unregister device node - we own its resources now
// (its resources are freed by the next remove_node_ref call)
dm_unregister_node(owner);
benaphore_lock(&gNodeLock);
dm_put_node_nolock(owner);
// restart loop as resource list may have changed meanwhile
break;
}
}
} while (cur != NULL);
}
/** Unblock other temporary allocations so they can retry.
* gNodeLock must be held.
*/
static void
unblock_temporary_allocation(void)
{
if (pnp_resource_wait_count > 0) {
TRACE(("unblock concurrent temporary allocation\n"));
release_sem_etc(pnp_resource_wait_sem, pnp_resource_wait_count, 0);
pnp_resource_wait_count = 0;
}
}
// #pragma mark -
/** Transfer temporary I/O resources to device node;
* colliding devices are unregistered.
*/
void
dm_assign_io_resources(device_node_info *node, const io_resource_handle *resources)
{
io_resource_handle *resource;
if (resources == NULL)
return;
unregister_colliding_nodes(resources);
memcpy(node->io_resources, resources,
(node->num_io_resources + 1) * sizeof(io_resource_handle));
benaphore_lock(&gNodeLock);
for (resource = node->io_resources; *resource != NULL; ++resource) {
(*resource)->owner = node;
}
// as the resources were only temporary previously, other temporary
// allocations may be waiting for us; time to wake them, so they can
// give up
unblock_temporary_allocation();
benaphore_unlock(&gNodeLock);
}
/** Release I/O resources of a device node and set list to NULL;
* users previously blocked by our resource alloction are notified;
* gNodeLock must be held.
*/
void
dm_release_node_resources(device_node_info *node)
{
io_resource_handle *resource;
if (*node->io_resources != NULL)
TRACE(("freeing I/O resources of node %p\n", node));
for (resource = node->io_resources; *resource != NULL; ++resource) {
// set owner to NULL as we don't want to resource anymore
(*resource)->owner = NULL;
release_io_resource(*resource);
}
// make sure we won't release resources twice
*node->io_resources = NULL;
}
// #pragma mark -
// Part of the module API
/** acquire I/O resources */
status_t
dm_acquire_io_resources(io_resource *resources, io_resource_handle *handles)
{
status_t status;
TRACE(("dm_acquire_io_resources()\n"));
benaphore_lock(&gNodeLock);
status = acquire_io_resources(resources, handles);
benaphore_unlock(&gNodeLock);
TRACE((" done (%s)\n", strerror(status)));
return status;
}
/** release I/O resources */
status_t
dm_release_io_resources(const io_resource_handle *handles)
{
io_resource_info *const *resource;
if (handles == NULL)
return B_OK;
benaphore_lock(&gNodeLock);
for (resource = handles; *resource != NULL; ++resource)
release_io_resource(*resource);
benaphore_unlock(&gNodeLock);
return B_OK;
}
@@ -0,0 +1,151 @@
/*
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2004, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include "io_resources.h"
#include <stdlib.h>
#include <string.h>
//#define TRACE_IO_RESOURCES
#ifdef TRACE_IO_RESOURCES
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
typedef DoublyLinkedList<io_resource_private,
DoublyLinkedListMemberGetLink<io_resource_private,
&io_resource_private::fTypeLink> > ResourceTypeList;
static ResourceTypeList sMemoryList;
static ResourceTypeList sPortList;
static ResourceTypeList sDMAChannelList;
io_resource_private::io_resource_private()
{
_Init();
}
io_resource_private::~io_resource_private()
{
Release();
}
void
io_resource_private::_Init()
{
type = 0;
base = 0;
length = 0;
}
status_t
io_resource_private::Acquire(const io_resource& resource)
{
if (!_IsValid(resource))
return B_BAD_VALUE;
type = resource.type;
base = resource.base;
if (type != B_ISA_DMA_CHANNEL)
length = resource.length;
else
length = 1;
ResourceTypeList* list = NULL;
switch (type) {
case B_IO_MEMORY:
list = &sMemoryList;
break;
case B_IO_PORT:
list = &sPortList;
break;
case B_ISA_DMA_CHANNEL:
list = &sDMAChannelList;
break;
}
ResourceTypeList::Iterator iterator = list->GetIterator();
while (iterator.HasNext()) {
io_resource* resource = iterator.Next();
// we need the "base + length - 1" trick to avoid wrap around at 4 GB
if (resource->base >= base
&& resource->base + length - 1 <= base + length - 1) {
// This range is already covered by someone else
// TODO: we might want to ignore resources that belong to
// a node that isn't used.
return B_RESOURCE_UNAVAILABLE;
}
}
list->Add(this);
return B_OK;
}
void
io_resource_private::Release()
{
if (type == 0)
return;
switch (type) {
case B_IO_MEMORY:
sMemoryList.Remove(this);
break;
case B_IO_PORT:
sPortList.Remove(this);
break;
case B_ISA_DMA_CHANNEL:
sDMAChannelList.Remove(this);
break;
}
_Init();
}
/*static*/ bool
io_resource_private::_IsValid(const io_resource& resource)
{
switch (resource.type) {
case B_IO_MEMORY:
return resource.base + resource.length > resource.base;
case B_IO_PORT:
return (uint16)resource.base == resource.base
&& (uint16)resource.length == resource.length
&& resource.base + resource.length > resource.base;
case B_ISA_DMA_CHANNEL:
return resource.base <= 8;
default:
return false;
}
}
// #pragma mark -
void
dm_init_io_resources(void)
{
new(&sMemoryList) ResourceTypeList;
new(&sPortList) ResourceTypeList;
new(&sDMAChannelList) ResourceTypeList;
}
@@ -0,0 +1,45 @@
/*
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-04, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef IO_RESOURCES_H
#define IO_RESOURCES_H
#include <device_manager.h>
#include <util/DoublyLinkedList.h>
struct io_resource_private : io_resource,
DoublyLinkedListLinkImpl<io_resource_private> {
io_resource_private();
~io_resource_private();
status_t Acquire(const io_resource& resource);
void Release();
private:
void _Init();
static bool _IsValid(const io_resource& resource);
public:
DoublyLinkedListLink<io_resource_private> fTypeLink;
};
typedef DoublyLinkedList<io_resource_private> ResourceList;
#ifdef __cplusplus
extern "C" {
#endif
void dm_init_io_resources(void);
#ifdef __cplusplus
}
#endif
#endif /* IO_RESOURCES_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
/*
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef LEGACY_DRIVERS_H
#define LEGACY_DRIVERS_H
#include <Drivers.h>
#ifdef __cplusplus
extern "C" {
#endif
status_t legacy_driver_add(const char* path);
status_t legacy_driver_publish(const char* path, device_hooks* hooks);
status_t legacy_driver_rescan(const char* driverName);
status_t legacy_driver_probe(const char* path);
status_t legacy_driver_init(void);
#ifdef __cplusplus
}
#endif
#endif // LEGACY_DRIVERS_H
File diff suppressed because it is too large Load Diff
-1
View File
@@ -6,7 +6,6 @@ UsePrivateHeaders [ FDirName kernel util ] ;
UsePrivateHeaders net shared storage ;
KernelMergeObject kernel_fs.o :
devfs.cpp
fd.cpp
fifo.cpp
IOScheduler.cpp
+1 -1
View File
@@ -275,7 +275,7 @@ main2(void *unused)
device_manager_init(&sKernelArgs);
TRACE("Add preloaded old-style drivers\n");
devfs_add_preloaded_drivers(&sKernelArgs);
legacy_driver_add_preloaded(&sKernelArgs);
int_init_post_device_manager(&sKernelArgs);
-2
View File
@@ -45,7 +45,6 @@
*/
extern module_info gDeviceManagerModule;
extern module_info gDeviceRootModule;
extern module_info gDeviceForDriversModule;
extern module_info gFrameBufferConsoleModule;
// file systems
@@ -55,7 +54,6 @@ extern module_info gDeviceFileSystem;
static module_info *sBuiltInModules[] = {
&gDeviceManagerModule,
&gDeviceRootModule,
&gDeviceForDriversModule,
&gFrameBufferConsoleModule,
&gRootFileSystem,