From 70e2d4ac43aa54d8c567ec12e6b24155d3171dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 14 Aug 2008 15:08:16 +0000 Subject: [PATCH] * Replaced the B_BLOCK_DEVICE_* defines with B_DMA_* defines that better match our dma_restrictions structure (but we're using blocks instead of bytes, since unlike the block size, the restrictions attributes are constant). * We might want to use blocks for the dma_restrictions structure as well in the future... * Fixed another bug in the device_node variant of DMAResource::Init(): the max segment size was specified in blocks as well. * Removed the "hardcode" block_io module and header. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26973 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/block_io.h | 102 --- headers/os/drivers/device_manager.h | 8 + headers/private/drivers/scsi_periph.h | 3 +- src/add-ons/kernel/bus_managers/Jamfile | 1 + .../kernel/bus_managers/ata/channels.c | 6 +- .../kernel/bus_managers/ide/channels.c | 4 +- src/add-ons/kernel/bus_managers/scsi/busses.c | 17 +- .../kernel/bus_managers/scsi/devices.c | 7 +- .../kernel/busses/ide/ide_isa/ide_isa.c | 3 +- .../busses/ide/legacy_sata/legacy_sata.c | 1 - .../busses/ide/promise_tx2/promise_tx2.c | 27 +- .../silicon_image_3112/silicon_image_3112.c | 11 +- src/add-ons/kernel/busses/scsi/ahci/ahci.c | 16 +- .../drivers/disk/scsi/scsi_cd/scsi_cd.cpp | 55 +- .../drivers/disk/scsi/scsi_cd/scsi_cd.h | 1 - .../drivers/disk/scsi/scsi_disk/scsi_disk.cpp | 4 +- .../drivers/disk/scsi/scsi_disk/scsi_disk.h | 1 - src/add-ons/kernel/generic/Jamfile | 1 - src/add-ons/kernel/generic/block_io/Jamfile | 17 - .../kernel/generic/block_io/bios_drive.h | 26 - .../kernel/generic/block_io/block_io.c | 596 -------------- .../generic/block_io/block_io_private.h | 90 --- src/add-ons/kernel/generic/block_io/io.c | 740 ------------------ .../kernel/generic/block_io/virtual_memory.c | 119 --- .../kernel/generic/block_io/virtual_memory.h | 19 - src/add-ons/kernel/generic/block_io/wrapper.h | 90 --- .../kernel/generic/ide_adapter/ide_adapter.c | 15 +- .../generic/scsi_periph/scsi_periph_int.h | 1 - .../kernel/device_manager/dma_resources.cpp | 14 +- 29 files changed, 91 insertions(+), 1904 deletions(-) delete mode 100644 headers/os/drivers/block_io.h delete mode 100644 src/add-ons/kernel/generic/block_io/Jamfile delete mode 100644 src/add-ons/kernel/generic/block_io/bios_drive.h delete mode 100644 src/add-ons/kernel/generic/block_io/block_io.c delete mode 100644 src/add-ons/kernel/generic/block_io/block_io_private.h delete mode 100644 src/add-ons/kernel/generic/block_io/io.c delete mode 100644 src/add-ons/kernel/generic/block_io/virtual_memory.c delete mode 100644 src/add-ons/kernel/generic/block_io/virtual_memory.h delete mode 100644 src/add-ons/kernel/generic/block_io/wrapper.h diff --git a/headers/os/drivers/block_io.h b/headers/os/drivers/block_io.h deleted file mode 100644 index b2850f5895..0000000000 --- a/headers/os/drivers/block_io.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef __BLOCK_IO_H__ -#define __BLOCK_IO_H__ - -/*! - 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 - protocol and transparently handles transmission of partial blocks - by using a buffer (performance will suffer, though). -*/ - - -#include -#include - -// cookies issued by block_io -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_handle_cookie block_device_handle_cookie; - - -// two reason why to use array of size 1: -// 1. zero-sized arrays aren't standard C -// 2. it's handy if you need a temporary global variable with num=1 -typedef struct phys_vecs { - size_t num; - size_t total_len; - physical_entry vec[1]; -} phys_vecs; - -#define PHYS_VECS(name, size) \ - uint8 name[sizeof(phys_vecs) + (size - 1)*sizeof(phys_vec)]; \ - phys_vecs *name = (phys_vecs *)name - - -// Block Device Node - -// attributes: - -// if true, this device may be a BIOS drive (uint8, optional, default: false) -#define B_BLOCK_DEVICE_IS_BIOS_DRIVE "block_device/is_bios_drive" -// address bits that must be 0 - must be 2^i-1 for some i (uint32, optional, default: 0) -#define B_BLOCK_DEVICE_DMA_ALIGNMENT "block_device/dma_alignment" -// maximum number of blocks per transfer (uint32, optional, default: unlimited) -#define B_BLOCK_DEVICE_MAX_BLOCKS_ITEM "block_device/max_blocks" -// mask of bits that can change in one sg block (uint32, optional, default: ~0) -#define B_BLOCK_DEVICE_DMA_BOUNDARY "block_device/dma_boundary" -// maximum size of one block in scatter/gather list (uint32, optional, default: ~0) -#define B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE "block_device/max_sg_block_size" -// 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 { - 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_cookie *cookie, block_device_handle_cookie **handle); - status_t (*close)(block_device_handle_cookie *handle); - status_t (*free)(block_device_handle_cookie *handle); - - status_t (*read)(block_device_handle_cookie *handle, const phys_vecs *vecs, off_t pos, - size_t num_blocks, uint32 block_size, size_t *bytes_transferred); - status_t (*write)(block_device_handle_cookie *handle, const phys_vecs *vecs, off_t pos, - size_t num_blocks, uint32 block_size, size_t *bytes_transferred); - - status_t (*ioctl)(block_device_handle_cookie *handle, int op, void *buf, size_t len); -} block_device_interface; - -#define B_BLOCK_IO_DEVICE_MODULE_NAME "generic/block_io/device_v1" - - -// Interface for Drivers - -// interface used for callbacks done by driver -typedef struct block_io_for_driver_interface { - module_info info; - - // block_size - block size in bytes - // ld_block_size - log2( block_size) (set to zero if block_size is not power of two) - // capacity - capacity in blocks - void (*set_media_params)(block_io_device device, uint32 block_size, uint32 ld_block_size, - uint64 capacity); -} block_io_for_driver_interface; - -#define B_BLOCK_IO_FOR_DRIVER_MODULE_NAME "generic/block_io/driver/v1" - -#endif /* __BLOCK_IO_H__ */ diff --git a/headers/os/drivers/device_manager.h b/headers/os/drivers/device_manager.h index 2b11af2c73..a411d4708f 100644 --- a/headers/os/drivers/device_manager.h +++ b/headers/os/drivers/device_manager.h @@ -150,6 +150,14 @@ struct driver_module_info { #define B_FIND_MULTIPLE_CHILDREN 0x02 #define B_KEEP_DRIVER_LOADED 0x04 +/* DMA attributes */ +#define B_DMA_LOW_ADDRESS "dma/low_address" +#define B_DMA_HIGH_ADDRESS "dma/high_address" +#define B_DMA_ALIGNMENT "dma/alignment" +#define B_DMA_BOUNDARY "dma/boundary" +#define B_DMA_MAX_TRANSFER_BLOCKS "dma/max_transfer_blocks" +#define B_DMA_MAX_SEGMENT_BLOCKS "dma/max_segment_blocks" +#define B_DMA_MAX_SEGMENT_COUNT "dma/max_segment_count" /* interface of device */ diff --git a/headers/private/drivers/scsi_periph.h b/headers/private/drivers/scsi_periph.h index 23dd56a812..f8a2027e00 100644 --- a/headers/private/drivers/scsi_periph.h +++ b/headers/private/drivers/scsi_periph.h @@ -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. @@ -18,7 +18,6 @@ #include -#include #include #include diff --git a/src/add-ons/kernel/bus_managers/Jamfile b/src/add-ons/kernel/bus_managers/Jamfile index 63503dd6e6..739e1cfee1 100644 --- a/src/add-ons/kernel/bus_managers/Jamfile +++ b/src/add-ons/kernel/bus_managers/Jamfile @@ -4,6 +4,7 @@ SubInclude HAIKU_TOP src add-ons kernel bus_managers acpi ; SubInclude HAIKU_TOP src add-ons kernel bus_managers agp_gart ; SubInclude HAIKU_TOP src add-ons kernel bus_managers config_manager ; SubInclude HAIKU_TOP src add-ons kernel bus_managers firewire ; +#SubInclude HAIKU_TOP src add-ons kernel bus_managers ata ; SubInclude HAIKU_TOP src add-ons kernel bus_managers ide ; SubInclude HAIKU_TOP src add-ons kernel bus_managers isa ; SubInclude HAIKU_TOP src add-ons kernel bus_managers pci ; diff --git a/src/add-ons/kernel/bus_managers/ata/channels.c b/src/add-ons/kernel/bus_managers/ata/channels.c index a09784da4f..1c5437a2fb 100644 --- a/src/add-ons/kernel/bus_managers/ata/channels.c +++ b/src/add-ons/kernel/bus_managers/ata/channels.c @@ -16,8 +16,6 @@ #include #include -#include - #define TRACE dprintf @@ -30,7 +28,7 @@ ide_channel_added(device_node *parent) TRACE("ide_channel_added, parent is %p\n", parent); - if (pnp->get_attr_string(parent, IDE_CONTROLLER_CONTROLLER_NAME_ITEM, + if (pnp->get_attr_string(parent, IDE_CONTROLLER_CONTROLLER_NAME_ITEM, &controller_name, true) != B_OK) { dprintf("ide: ignored controller - controller name missing\n"); goto err; @@ -61,7 +59,7 @@ ide_channel_added(device_node *parent) // which should be sufficient) // Note: to fix specific drive bugs, use ide_sim_get_restrictions() // in ide_sim.c! - { B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: 255 }}, + { B_DMA_MAX_TRANSFER_BLOCKS, 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 }}, diff --git a/src/add-ons/kernel/bus_managers/ide/channels.c b/src/add-ons/kernel/bus_managers/ide/channels.c index 746a003963..45686041ca 100644 --- a/src/add-ons/kernel/bus_managers/ide/channels.c +++ b/src/add-ons/kernel/bus_managers/ide/channels.c @@ -18,8 +18,6 @@ #include #include -#include - /** called when an IDE channel was registered by a controller driver */ @@ -62,7 +60,7 @@ ide_channel_added(device_node *parent) // which should be sufficient) // Note: to fix specific drive bugs, use ide_sim_get_restrictions() // in ide_sim.c! - { B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: 255 }}, + { B_DMA_MAX_TRANSFER_BLOCKS, 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 }}, diff --git a/src/add-ons/kernel/bus_managers/scsi/busses.c b/src/add-ons/kernel/bus_managers/scsi/busses.c index 41c29ba45a..59cfd28f18 100644 --- a/src/add-ons/kernel/bus_managers/scsi/busses.c +++ b/src/add-ons/kernel/bus_managers/scsi/busses.c @@ -18,7 +18,6 @@ #include #include -#include // bus service should hurry up a bit - good controllers don't take much time @@ -198,19 +197,23 @@ scsi_init_bus(device_node *node, void **cookie) return B_NO_MEMORY; // extract controller/protocoll restrictions from node - if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_DMA_ALIGNMENT, &bus->dma_params.alignment, true) != B_OK) + if (pnp->get_attr_uint32(node, B_DMA_ALIGNMENT, &bus->dma_params.alignment, + true) != B_OK) bus->dma_params.alignment = 0; - if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, &bus->dma_params.max_blocks, true) != B_OK) + if (pnp->get_attr_uint32(node, B_DMA_MAX_TRANSFER_BLOCKS, + &bus->dma_params.max_blocks, true) != B_OK) bus->dma_params.max_blocks = 0xffffffff; - if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_DMA_BOUNDARY, &bus->dma_params.dma_boundary, true) != B_OK) + if (pnp->get_attr_uint32(node, B_DMA_BOUNDARY, + &bus->dma_params.dma_boundary, true) != B_OK) bus->dma_params.dma_boundary = ~0; - if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, &bus->dma_params.max_sg_block_size, true) != B_OK) + if (pnp->get_attr_uint32(node, B_DMA_MAX_SEGMENT_BLOCKS, + &bus->dma_params.max_sg_block_size, true) != B_OK) bus->dma_params.max_sg_block_size = 0xffffffff; - if (pnp->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_SG_BLOCKS, &bus->dma_params.max_sg_blocks, true) != B_OK) + if (pnp->get_attr_uint32(node, B_DMA_MAX_SEGMENT_COUNT, + &bus->dma_params.max_sg_blocks, true) != B_OK) bus->dma_params.max_sg_blocks = ~0; // do some sanity check: - // (see blkman.c) bus->dma_params.max_sg_block_size &= ~bus->dma_params.alignment; if (bus->dma_params.alignment > B_PAGE_SIZE) { diff --git a/src/add-ons/kernel/bus_managers/scsi/devices.c b/src/add-ons/kernel/bus_managers/scsi/devices.c index 65e9cd2f22..57bb541a75 100644 --- a/src/add-ons/kernel/bus_managers/scsi/devices.c +++ b/src/add-ons/kernel/bus_managers/scsi/devices.c @@ -15,8 +15,6 @@ #include "scsi_internal.h" -#include - #include #include #include @@ -103,7 +101,8 @@ scsi_register_device(scsi_bus_info *bus, uchar target_id, // find maximum transfer blocks // set default value to max (need something like ULONG_MAX here) orig_max_blocks = ~0; - pnp->get_attr_uint32(bus->node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, &orig_max_blocks, true); + pnp->get_attr_uint32(bus->node, B_DMA_MAX_TRANSFER_BLOCKS, &orig_max_blocks, + true); max_blocks = min(max_blocks, orig_max_blocks); @@ -130,7 +129,7 @@ scsi_register_device(scsi_bus_info *bus, uchar target_id, { 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 }}, + { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { ui32: max_blocks }}, // atapi emulation { SCSI_DEVICE_IS_ATAPI_ITEM, B_UINT8_TYPE, { ui8: is_atapi }}, diff --git a/src/add-ons/kernel/busses/ide/ide_isa/ide_isa.c b/src/add-ons/kernel/busses/ide/ide_isa/ide_isa.c index a476ea4dcd..5887a13063 100644 --- a/src/add-ons/kernel/busses/ide/ide_isa/ide_isa.c +++ b/src/add-ons/kernel/busses/ide/ide_isa/ide_isa.c @@ -20,7 +20,6 @@ #include #include #include -#include //#define TRACE_IDE_ISA @@ -78,7 +77,7 @@ publish_channel(device_node *parent, uint16 command_block_base, // DMA properties; the 16 bit alignment is not necessary as // the ide bus manager handles that very efficiently, but why // not use the block device manager for doing that? - { B_BLOCK_DEVICE_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 1 }}, + { B_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 1 }}, // private data to identify device { IDE_ISA_COMMAND_BLOCK_BASE, B_UINT16_TYPE, { ui16: command_block_base }}, diff --git a/src/add-ons/kernel/busses/ide/legacy_sata/legacy_sata.c b/src/add-ons/kernel/busses/ide/legacy_sata/legacy_sata.c index 9df55b8e15..15d37b5650 100644 --- a/src/add-ons/kernel/busses/ide/legacy_sata/legacy_sata.c +++ b/src/add-ons/kernel/busses/ide/legacy_sata/legacy_sata.c @@ -9,7 +9,6 @@ #include #include #include -#include #define DRIVER_PRETTY_NAME "Legacy SATA" diff --git a/src/add-ons/kernel/busses/ide/promise_tx2/promise_tx2.c b/src/add-ons/kernel/busses/ide/promise_tx2/promise_tx2.c index 57ae2bf3e6..6bc100e3d8 100644 --- a/src/add-ons/kernel/busses/ide/promise_tx2/promise_tx2.c +++ b/src/add-ons/kernel/busses/ide/promise_tx2/promise_tx2.c @@ -12,7 +12,6 @@ #include #include -#include #define debug_level_flow 0 #define debug_level_error 3 @@ -95,7 +94,7 @@ inthand(void *arg) if (channel->dmaing) { // in DMA mode, there is a safe test // in PIO mode, this doesn't work - *(uint8 *)&bm_status = pci->read_io_8( device, + *(uint8 *)&bm_status = pci->read_io_8( device, channel->bus_master_base + ide_bm_status_reg ); if (!bm_status.interrupt) @@ -179,7 +178,7 @@ controller_removed(device_node_handle node, ide_adapter_controller_info *control // publish node of ide controller static status_t -publish_controller(device_node_handle parent, uint16 bus_master_base, uint8 intnum, +publish_controller(device_node_handle parent, uint16 bus_master_base, uint8 intnum, io_resource_handle *resources, device_node_handle *node) { device_attr attrs[] = { @@ -199,13 +198,13 @@ publish_controller(device_node_handle parent, uint16 bus_master_base, uint8 intn // DMA properties // some say it must be dword-aligned, others that it can be byte-aligned; // stay on the safe side - { B_BLOCK_DEVICE_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 3 }}, + { B_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 3 }}, // one S/G block must not cross 64K boundary - { B_BLOCK_DEVICE_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: 0xffff }}, + { B_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: 0xffff }}, // size of S/G block is 16 bits with zero being 64K - { B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, B_UINT32_TYPE, { ui32: 0x10000 }}, - // see definition of MAX_SG_COUNT - { B_BLOCK_DEVICE_MAX_SG_BLOCKS, B_UINT32_TYPE, { ui32: IDE_ADAPTER_MAX_SG_COUNT }}, + { B_DMA_MAX_SEGMENT_BLOCKS, B_UINT32_TYPE, { ui32: 0x10000 }}, + { B_DMA_MAX_SEGMENT_COUNT, B_UINT32_TYPE, + { ui32: IDE_ADAPTER_MAX_SG_COUNT }}, // private data to find controller { IDE_ADAPTER_BUS_MASTER_BASE, B_UINT16_TYPE, { ui16: bus_master_base }}, @@ -249,7 +248,7 @@ detect_controller(pci_device_module_info *pci, pci_device pci_device, return publish_controller(parent, bus_master_base, intnum, resource_handles, node); } - + static status_t probe_controller(device_node_handle parent) { @@ -284,14 +283,14 @@ probe_controller(device_node_handle parent) if (res != B_OK || controller_node == NULL) goto err; - ide_adapter->detect_channel(pci, device, controller_node, + ide_adapter->detect_channel(pci, device, controller_node, PROMISE_TX2_CHANNEL_MODULE_NAME, true, command_block_base[0], control_block_base[0], bus_master_base, intnum, 0, "Primary Channel", &channels[0], false); - ide_adapter->detect_channel(pci, device, controller_node, - PROMISE_TX2_CHANNEL_MODULE_NAME, true, - command_block_base[1], control_block_base[1], bus_master_base, intnum, + ide_adapter->detect_channel(pci, device, controller_node, + PROMISE_TX2_CHANNEL_MODULE_NAME, true, + command_block_base[1], control_block_base[1], bus_master_base, intnum, 1, "Secondary Channel", &channels[1], false); pnp->uninit_driver(parent); @@ -299,7 +298,7 @@ probe_controller(device_node_handle parent) return B_OK; err: - pnp->uninit_driver(parent); + pnp->uninit_driver(parent); return res; } diff --git a/src/add-ons/kernel/busses/ide/silicon_image_3112/silicon_image_3112.c b/src/add-ons/kernel/busses/ide/silicon_image_3112/silicon_image_3112.c index 2a22f26a9b..bebacc349e 100644 --- a/src/add-ons/kernel/busses/ide/silicon_image_3112/silicon_image_3112.c +++ b/src/add-ons/kernel/busses/ide/silicon_image_3112/silicon_image_3112.c @@ -11,7 +11,6 @@ #include #include -#include #define TRACE(x...) dprintf("si-3112: " x) //#define FLOW(x...) dprintf("si-3112: " x) @@ -225,13 +224,13 @@ controller_probe(device_node *parent) // DMA properties // data must be word-aligned; // warning: some controllers are more picky! - { B_BLOCK_DEVICE_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 1}}, + { B_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 1}}, // one S/G block must not cross 64K boundary - { B_BLOCK_DEVICE_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: 0xffff }}, + { B_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: 0xffff }}, // max size of S/G block is 16 bits with zero being 64K - { B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, B_UINT32_TYPE, { ui32: 0x10000 }}, - // see definition of MAX_SG_COUNT - { B_BLOCK_DEVICE_MAX_SG_BLOCKS, B_UINT32_TYPE, { ui32: IDE_ADAPTER_MAX_SG_COUNT }}, + { B_DMA_MAX_SEGMENT_BLOCKS, B_UINT32_TYPE, { ui32: 0x10000 }}, + { B_DMA_MAX_SEGMENT_COUNT, B_UINT32_TYPE, + { ui32: IDE_ADAPTER_MAX_SG_COUNT }}, // private data to find controller { "silicon_image_3112/asic_index", B_UINT32_TYPE, { ui32: asicIndex }}, diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci.c b/src/add-ons/kernel/busses/scsi/ahci/ahci.c index 9de6880d54..b4c43265ef 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci.c +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci.c @@ -8,8 +8,6 @@ #include #include -#include - #define TRACE(a...) dprintf("\33[35mahci:\33[0m " a) #define FLOW(a...) dprintf("ahci: " a) @@ -148,7 +146,7 @@ register_sim(device_node *parent) { SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE, { string: AHCI_DEVICE_MODULE_NAME }}, - { B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, { ui32: 255 }}, + { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { ui32: 255 }}, { AHCI_ID_ITEM, B_UINT32_TYPE, { ui32: id }}, // { PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, // { string: AHCI_ID_GENERATOR }}, @@ -237,16 +235,12 @@ ahci_register_device(device_node *parent) // DMA properties // data must be word-aligned; - { B_BLOCK_DEVICE_DMA_ALIGNMENT, B_UINT32_TYPE, - { ui32: 1 }}, + { B_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: 1 }}, // one S/G block must not cross 64K boundary - { B_BLOCK_DEVICE_DMA_BOUNDARY, B_UINT32_TYPE, - { ui32: 0xffff }}, + { B_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: 0xffff }}, // max size of S/G block is 16 bits with zero being 64K - { B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, B_UINT32_TYPE, - { ui32: 0x10000 }}, - // see definition of MAX_SG_COUNT - { B_BLOCK_DEVICE_MAX_SG_BLOCKS, B_UINT32_TYPE, + { B_DMA_MAX_SEGMENT_BLOCKS, B_UINT32_TYPE, { ui32: 0x10000 }}, + { B_DMA_MAX_SEGMENT_COUNT, B_UINT32_TYPE, { ui32: 32 /* whatever... */ }}, { NULL } }; diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp index cd7f0f96cf..f9070604e1 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp @@ -674,7 +674,7 @@ cd_write(void* cookie, off_t pos, const void* buffer, size_t* _length) static status_t -cd_io(void *cookie, io_request *request) +cd_io(void* cookie, io_request* request) { cd_handle* handle = (cd_handle*)cookie; @@ -797,7 +797,7 @@ cd_ioctl(void* cookie, uint32 op, void* buffer, size_t length) static void -cd_set_capacity(cd_driver_info *info, uint64 capacity, uint32 blockSize) +cd_set_capacity(cd_driver_info* info, uint64 capacity, uint32 blockSize) { TRACE("cd_set_capacity(info = %p, capacity = %Ld, blockSize = %ld)\n", info, capacity, blockSize); @@ -838,7 +838,7 @@ cd_set_capacity(cd_driver_info *info, uint64 capacity, uint32 blockSize) static void -cd_media_changed(cd_driver_info *info, scsi_ccb *request) +cd_media_changed(cd_driver_info* info, scsi_ccb* request) { // do a capacity check // TBD: is this a good idea (e.g. if this is an empty CD)? @@ -856,9 +856,9 @@ scsi_periph_callbacks callbacks = { static float -cd_supports_device(device_node *parent) +cd_supports_device(device_node* parent) { - const char *bus; + const char* bus; uint8 deviceType; // make sure parent is really the SCSI bus manager @@ -883,20 +883,20 @@ cd_supports_device(device_node *parent) server by the block_io module */ static status_t -cd_register_device(device_node *node) +cd_register_device(device_node* node) { - const scsi_res_inquiry *deviceInquiry = NULL; + const scsi_res_inquiry* deviceInquiry = NULL; size_t inquiryLength; uint32 maxBlocks; // get inquiry data if (sDeviceManager->get_attr_raw(node, SCSI_DEVICE_INQUIRY_ITEM, - (const void **)&deviceInquiry, &inquiryLength, true) != B_OK + (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 (sDeviceManager->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, + if (sDeviceManager->get_attr_uint32(node, B_DMA_MAX_TRANSFER_BLOCKS, &maxBlocks, true) != B_OK) maxBlocks = INT_MAX; @@ -907,10 +907,8 @@ cd_register_device(device_node *node) // ready to register device_attr attrs[] = { - // tell block_io whether the device is removable {"removable", B_UINT8_TYPE, {ui8: deviceInquiry->removable_medium}}, - // impose own max block restriction - {B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, {ui32: maxBlocks}}, + {B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, {ui32: maxBlocks}}, { NULL } }; @@ -920,24 +918,21 @@ cd_register_device(device_node *node) static status_t -cd_init_driver(device_node *node, void **cookie) +cd_init_driver(device_node* node, void** _cookie) { - cd_driver_info *info; - status_t status; - uint8 removable; - TRACE("cd_init_driver"); - status = sDeviceManager->get_attr_uint8(node, "removable", + uint8 removable; + status_t status = sDeviceManager->get_attr_uint8(node, "removable", &removable, false); if (status != B_OK) return status; - info = (cd_driver_info *)malloc(sizeof(*info)); + cd_driver_info* info = (cd_driver_info*)malloc(sizeof(cd_driver_info)); if (info == NULL) return B_NO_MEMORY; - memset(info, 0, sizeof(*info)); + memset(info, 0, sizeof(cd_driver_info)); info->dma_resource = new(std::nothrow) DMAResource; if (info->dma_resource == NULL) { @@ -956,8 +951,8 @@ cd_init_driver(device_node *node, void **cookie) &info->device_type, true); device_node *parent = sDeviceManager->get_parent_node(node); - sDeviceManager->get_driver(parent, (driver_module_info **)&info->scsi, - (void **)&info->scsi_device); + sDeviceManager->get_driver(parent, (driver_module_info**)&info->scsi, + (void**)&info->scsi_device); sDeviceManager->put_node(parent); status = sSCSIPeripheral->register_device((periph_device_cookie)info, @@ -968,15 +963,15 @@ cd_init_driver(device_node *node, void **cookie) return status; } - *cookie = info; + *_cookie = info; return B_OK; } static void -cd_uninit_driver(void *_cookie) +cd_uninit_driver(void* _cookie) { - cd_driver_info *info = (cd_driver_info *)_cookie; + cd_driver_info* info = (cd_driver_info*)_cookie; sSCSIPeripheral->unregister_device(info->scsi_periph_device); free(info); @@ -984,17 +979,15 @@ cd_uninit_driver(void *_cookie) static status_t -cd_register_child_devices(void *_cookie) +cd_register_child_devices(void* _cookie) { - cd_driver_info *info = (cd_driver_info *)_cookie; - status_t status; - char *name; + cd_driver_info* info = (cd_driver_info*)_cookie; - name = sSCSIPeripheral->compose_device_name(info->node, "disk/scsi"); + char* name = sSCSIPeripheral->compose_device_name(info->node, "disk/scsi"); if (name == NULL) return B_ERROR; - status = sDeviceManager->publish_device(info->node, name, + status_t status = sDeviceManager->publish_device(info->node, name, SCSI_CD_DEVICE_MODULE_NAME); free(name); diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.h b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.h index 75158a67d3..a8e19af81f 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.h +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.h @@ -7,7 +7,6 @@ #define _SCSI_CD_H -#include #include #include #include diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp index 4d8ee0c4a5..69855c68d9 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp @@ -441,7 +441,7 @@ das_register_device(device_node *node) return B_ERROR; // get block limit of underlying hardware to lower it (if necessary) - if (sDeviceManager->get_attr_uint32(node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, + if (sDeviceManager->get_attr_uint32(node, B_DMA_MAX_TRANSFER_BLOCKS, &maxBlocks, true) != B_OK) maxBlocks = INT_MAX; @@ -455,7 +455,7 @@ das_register_device(device_node *node) // tell block_io whether the device is removable {"removable", B_UINT8_TYPE, {ui8: deviceInquiry->removable_medium}}, // impose own max block restriction - {B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, B_UINT32_TYPE, {ui32: maxBlocks}}, + {B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, {ui32: maxBlocks}}, { NULL } }; diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h index 6be48694fc..20af9fd5c2 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.h @@ -7,7 +7,6 @@ #define _SCSI_DISK_H -#include #include #include #include diff --git a/src/add-ons/kernel/generic/Jamfile b/src/add-ons/kernel/generic/Jamfile index 617d177eaf..261d8e7998 100644 --- a/src/add-ons/kernel/generic/Jamfile +++ b/src/add-ons/kernel/generic/Jamfile @@ -1,7 +1,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 ide_adapter ; SubInclude HAIKU_TOP src add-ons kernel generic locked_pool ; diff --git a/src/add-ons/kernel/generic/block_io/Jamfile b/src/add-ons/kernel/generic/block_io/Jamfile deleted file mode 100644 index 232c833d48..0000000000 --- a/src/add-ons/kernel/generic/block_io/Jamfile +++ /dev/null @@ -1,17 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel generic block_io ; - -UsePrivateHeaders kernel ; -UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; -UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; - -# disable debug output, if debugging is disabled -if $(DEBUG) = 0 { - SubDirCcFlags [ FDefines DEBUG_MAX_LEVEL_FLOW=0 DEBUG_MAX_LEVEL_INFO=0 ] ; -} - -KernelAddon block_io : - block_io.c - io.c - virtual_memory.c - ; - diff --git a/src/add-ons/kernel/generic/block_io/bios_drive.h b/src/add-ons/kernel/generic/block_io/bios_drive.h deleted file mode 100644 index f68f9bba6d..0000000000 --- a/src/add-ons/kernel/generic/block_io/bios_drive.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __BIOS_INFO_H__ -#define __BIOS_INFO_H__ - -// length: 0x84 -typedef struct tagbios_drive { - char name[32]; // 0 - uint8 bios_id; // 20 - uint8 padding[3]; - uint32 cylinder_count; // 24 - uint32 head_count; // 28 - uint32 sectors_per_track; // 2c - - uint32 num_chksums; // 30 - - struct { - uint64 offset; // 34+ - uint32 len; // 3c+ - uint32 chksum; // 40+ - } chksums[5]; // 34 -} bios_drive; - -extern bios_drive *bios_drive_info; - -extern uint32 boot_calculate_hash( void *buffer, size_t len ); - -#endif diff --git a/src/add-ons/kernel/generic/block_io/block_io.c b/src/add-ons/kernel/generic/block_io/block_io.c deleted file mode 100644 index 275a59b456..0000000000 --- a/src/add-ons/kernel/generic/block_io/block_io.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "block_io_private.h" - -#include - - -//#define TRACE_BLOCK_IO -#ifdef TRACE_BLOCK_IO -# define TRACE(x) dprintf x -#else -# define TRACE(x) ; -#endif - - -uint block_io_buffer_size; -sem_id block_io_buffer_lock; -struct iovec block_io_buffer_vec[1]; -void *block_io_buffer_phys; -char *block_io_buffer; -phys_vecs block_io_buffer_phys_vec; -area_id block_io_buffer_area; - -locked_pool_interface *locked_pool; -device_manager_info *pnp; - - -static status_t -block_io_open(block_io_device_info *device, const char *path, int openMode, - block_io_handle_info **res_handle) -{ - block_io_handle_info *handle; - status_t res; - - TRACE(("block_io_open()\n")); - - handle = (block_io_handle_info *)malloc(sizeof(*handle)); - - if (handle == NULL) - return B_NO_MEMORY; - - handle->device = device; - - res = device->interface->open(device->cookie, &handle->cookie); - if (res < B_OK) - goto err; - - *res_handle = handle; - - TRACE((" opened.\n")); - - return B_OK; - -err: - free(handle); - return res; -} - - -static status_t -block_io_close(block_io_handle_info *handle) -{ - block_io_device_info *device = handle->device; - - TRACE(("block_io_close()\n")); - - device->interface->close(handle->cookie); - return B_OK; -} - - -static status_t -block_io_freecookie(block_io_handle_info *handle) -{ - block_io_device_info *device = handle->device; - - TRACE(("block_io_freecookie()\n")); - - device->interface->free(handle->cookie); - free(handle); - - TRACE(("done.\n")); - - return B_OK; -} - -// TODO: this assumes private R5 kernel functions to be present -#if 0 -/** Verify a checksum that is part of BIOS drive identification. - * returns B_OK on success - */ - -static status_t -verify_checksum(block_io_handle_info *handle, uint64 offset, uint32 len, uint32 chksum) -{ - void *buffer; - uint32 readlen; - status_t res; - -// SHOW_FLOW( 0, "offset=%lld, len=%ld", offset, len ); - - buffer = malloc(len); - if (buffer == NULL) - return B_NO_MEMORY; - - readlen = len; - - res = block_io_read(handle, offset, buffer, &readlen); - if (res < B_OK || readlen < len) - goto err; - -// SHOW_FLOW0( 0, "check hash sum" ); - - if (boot_calculate_hash(buffer, len) != chksum) - goto err; - -// SHOW_FLOW0( 0, "success" ); - - free(buffer); - return B_OK; - -err: - free(buffer); - return B_ERROR; -} - - -/** store BIOS drive id in node's attribute */ - -static status_t -store_bios_drive_in_node(block_io_device_info *device) -{ - device_attr attribute = { - B_BLOCK_DEVICE_BIOS_ID, B_UINT8_TYPE, { ui8: - device->bios_drive != NULL ? device->bios_drive->bios_id : 0 } - }; - - return pnp->write_attr(device->node, &attribute); -} - - -/** find BIOS info of drive, if not happened yet. - * this must be called whenever someone wants to access BIOS infos about the drive; - * there are two reasons to not call this during probe(): - * - perhaps nobody is interested in BIOS info - * - we need a working block_io device to handle lower level driver - * restrictions, so this method can only be safely called once the - * node has been loaded - */ - -static void -find_bios_drive_info(block_io_handle_info *handle) -{ - block_io_device_info *device = handle->device; - bios_drive *drive = NULL; //, *colliding_drive; - char name[32]; - uint8 bios_id; - -// SHOW_FLOW( 0, "%p", device ); - - // return immediately if BIOS info has already been found - if (device->bios_drive != NULL) - return; - - // check whether BIOS info was found during one of the previous - // loads - if (pnp->get_attr_uint8(device->node, B_BLOCK_DEVICE_BIOS_ID, &bios_id, false) == B_OK) { - TRACE(("use previous BIOS ID 0x%x\n", bios_id)); - - // yes, so find the associated data structure - if (bios_id != 0) { - for (drive = bios_drive_info; drive->bios_id != 0; ++drive) { - if (drive->bios_id == bios_id) - break; - } - } else - drive = NULL; - - device->bios_drive = drive; - return; - } - - sprintf(name, "PnP %p", device->node); - - // do it the hard way: find a BIOS drive with the same checksums - for (drive = bios_drive_info; drive->bios_id != 0; ++drive) { - uint32 i; - - // ignore identified BIOS drives - if (drive->name[0] != 0) - continue; - - TRACE(("verifying drive 0x%x", drive->bios_id)); - - for (i = 0; i < drive->num_chksums; ++i) { - if (verify_checksum( handle, drive->chksums[i].offset, - drive->chksums[i].len, drive->chksums[i].chksum) != B_OK) - break; - } - - if (i == drive->num_chksums) - break; - } - - if (drive->bios_id == 0) { - TRACE(("this is no BIOS drive\n")); - // no BIOS drive found - goto no_bios_drive; - } - - TRACE(("this is BIOS drive 0x%x\n", drive->bios_id)); - - // the R5 boot loader assumes that two drives can be distinguished by - // - their checksums - // - their physical layout - // unfortunately, the "physical layout" is something virtual defined by the - // BIOS itself, so nobody can verify that; - // as a result, we may have two drives with same checksums and different - // geometry - having no opportunity to check the geometry, we cannot - // distinguish between them. - // The simple solution is to modify the boot loader to not take geometry - // into account, but without sources, the boot loader cannot be fixed. - for (colliding_drive = bios_drive_info; colliding_drive->bios_id != 0; ++colliding_drive) { - uint32 i; - - if (drive == colliding_drive) - continue; - - if (drive->num_chksums != colliding_drive->num_chksums) - continue; - - for (i = 0; i < colliding_drive->num_chksums; ++i) { - if (colliding_drive->chksums[i].offset != drive->chksums[i].offset - || colliding_drive->chksums[i].len != drive->chksums[i].len - || colliding_drive->chksums[i].chksum != drive->chksums[i].chksum) - break; - } - - if (i < colliding_drive->num_chksums) - continue; - - dprintf("Cannot distinguish between BIOS drives %x and %x without geometry\n", - drive->bios_id, colliding_drive->bios_id); - - // this is nasty - we cannot reliable assign BIOS drive number. - // if the user has luck, he "only" cannot install a boot manager; - // but if the boot drive is affected, he cannot even boot. - goto no_bios_drive; - } - - TRACE(("store driver \"%s\" in system data\n", name)); - - // store name so noone else will test this BIOS drive - strcpy(drive->name, name); - device->bios_drive = drive; - - // remember that to avoid testing next time - store_bios_drive_in_node(device); - return; - -no_bios_drive: - device->bios_drive = NULL; - - // remember that to avoid testing next time - store_bios_drive_in_node(device); - return; -} -#endif - - -static status_t -block_io_ioctl(block_io_handle_info *handle, uint32 op, void *buffer, size_t length) -{ - block_io_device_info *device = handle->device; - -#if 0 - if (device->is_bios_drive) { - switch (op) { - case B_GET_BIOS_DRIVE_ID: - find_bios_drive_info(handle); - - if (device->bios_drive == NULL) - return B_ERROR; - - *(char *)buffer = device->bios_drive->bios_id; - return B_OK; - - case B_GET_BIOS_GEOMETRY: - { - device_geometry *geometry = (device_geometry *)buffer; - status_t status; - - find_bios_drive_info(handle); - if (device->bios_drive == NULL) - return B_ERROR; - - TRACE(("GET_BIOS_GEOMETRY\n")); - - // get real geometry from low level driver - status = device->interface->ioctl(handle->cookie, B_GET_GEOMETRY, - geometry, sizeof(*geometry)); - if (status != B_OK) - return status; - - // replace entries with bios info retrieved by boot loader - geometry->cylinder_count = device->bios_drive->cylinder_count; - geometry->head_count = device->bios_drive->head_count; - geometry->sectors_per_track = device->bios_drive->sectors_per_track; - return B_OK; - } - } - } -#endif - - return device->interface->ioctl(handle->cookie, op, buffer, length); -} - - -static void -block_io_remove(void *cookie) -{ -#if 0 - uint8 bios_id; - //bios_drive *drive; - - // if this drive has a BIOS ID, remove it from BIOS drive list - if (pnp->get_attr_uint8(node, B_BLOCK_DEVICE_BIOS_ID, &bios_id, false) != B_OK - || bios_id == 0 ) - return; - -// ToDo: this assumes private R5 kernel functions to be present - for (drive = bios_drive_info; drive->bios_id != 0; ++drive) { - if (drive->bios_id == bios_id) - break; - } - - if (drive->bios_id != 0) { - TRACE(("Marking BIOS device 0x%x as being unknown\n", bios_id)); - drive->name[0] = 0; - } -#endif -} - - -static status_t -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; -// 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(data->node, B_BLOCK_DEVICE_DMA_ALIGNMENT, ¶ms.alignment, true) != B_OK) - params.alignment = 0; - if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, ¶ms.max_blocks, true) != B_OK) - params.max_blocks = 0xffffffff; - if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_DMA_BOUNDARY, ¶ms.dma_boundary, true) != B_OK) - params.dma_boundary = ~0; - if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, ¶ms.max_sg_block_size, true) != B_OK) - params.max_sg_block_size = 0xffffffff; - if (pnp->get_attr_uint32(data->node, B_BLOCK_DEVICE_MAX_SG_BLOCKS, ¶ms.max_sg_blocks, true) != B_OK) - params.max_sg_blocks = ~0; - - // do some sanity check: - // (see scsi/bus_mgr.c) - params.max_sg_block_size &= ~params.alignment; - - if (params.alignment > B_PAGE_SIZE) { - dprintf("Alignment (0x%lx) must be less then B_PAGE_SIZE\n", params.alignment); - return B_ERROR; - } - - if (params.max_sg_block_size < 512) { - dprintf("Max s/g block size (0x%lx) is too small\n", params.max_sg_block_size); - return B_ERROR; - } - - if (params.dma_boundary < B_PAGE_SIZE - 1) { - dprintf("DMA boundary (0x%lx) must be at least B_PAGE_SIZE\n", params.dma_boundary); - return B_ERROR; - } - - if (params.max_blocks < 1 || params.max_sg_blocks < 1) { - dprintf("Max blocks (%ld) and max s/g blocks (%ld) must be at least 1", - params.max_blocks, params.max_sg_blocks); - return B_ERROR; - } - - // allow "only" up to 512 sg entries - // (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(data->node, B_BLOCK_DEVICE_IS_BIOS_DRIVE, &is_bios_drive, true) != B_OK) - is_bios_drive = false; - - device = (block_io_device_info *)malloc(sizeof(*device)); - if (device == NULL) { - res = B_NO_MEMORY; - goto err1; - } - - memset(device, 0, sizeof(*device)); - - device->node = data->node; - - mutex_init(&device->lock, "block_device_mutex"); - -#if 0 - // construct a identifiable name for S/G pool - tmp_name = malloc(name + strlen(" sg_lists") + 1); - if (tmp_name == NULL) { - res = B_NO_MEMORY; - goto err3; - } - - 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, "block io sg lists", - B_CONTIGUOUS, NULL, NULL, NULL); - -// free(tmp_name); - - if (device->phys_vecs_pool == NULL) { - res = B_NO_MEMORY; - goto err3; - } - - device->params = params; - device->is_bios_drive = is_bios_drive != 0; - - pnp->get_driver(device->node, (driver_module_info **)&device->interface, - (void **)&device->cookie); - - device->interface->set_device(device->cookie, device); - - TRACE(("done\n")); - - *cookie = device; - return B_OK; - -err3: - mutex_destroy(&device->lock); - free(device); -err1: - return res; -} - - -static void -block_io_uninit_device(void *_cookie) -{ - block_io_device_info *device = _cookie; - - locked_pool->destroy(device->phys_vecs_pool); - mutex_destroy(&device->lock); - free(device); -} - - -static status_t -block_io_init_buffer(void) -{ - physical_entry physicalTable[2]; - status_t res; - - TRACE(("block_io_init_buffer()\n")); - - block_io_buffer_size = 32*1024; - - block_io_buffer_lock = create_sem(1, "block_io_buffer_mutex"); - if (block_io_buffer_lock < 0) { - res = block_io_buffer_lock; - goto err1; - } - - res = block_io_buffer_area = create_area("block_io_buffer", - (void **)&block_io_buffer, B_ANY_KERNEL_ADDRESS, - block_io_buffer_size, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); - if (res < 0) - goto err2; - - res = get_memory_map(block_io_buffer, block_io_buffer_size, physicalTable, 2); - if (res < 0) - goto err3; - - block_io_buffer_vec[0].iov_base = block_io_buffer; - block_io_buffer_vec[0].iov_len = block_io_buffer_size; - - block_io_buffer_phys_vec.num = 1; - block_io_buffer_phys_vec.total_len = block_io_buffer_size; - block_io_buffer_phys_vec.vec[0] = physicalTable[0]; - - return B_OK; - -err3: - delete_area(block_io_buffer_area); -err2: - delete_sem(block_io_buffer_lock); -err1: - return res; -} - - -static status_t -block_io_uninit_buffer(void) -{ - delete_area(block_io_buffer_area); - delete_sem(block_io_buffer_lock); - - return B_OK; -} - - -static status_t -std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - return block_io_init_buffer(); - case B_MODULE_UNINIT: - block_io_uninit_buffer(); - return B_OK; - - default: - return B_ERROR; - } -} - - -module_dependency module_dependencies[] = { - { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp }, - { LOCKED_POOL_MODULE_NAME, (module_info **)&locked_pool }, - {} -}; - - -struct device_module_info sBlockIOModule = { - { - B_BLOCK_IO_DEVICE_MODULE_NAME, - 0, - - std_ops - }, - - block_io_init_device, - block_io_uninit_device, - block_io_remove, - - (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 *, off_t, void *, size_t *))block_io_read, - (status_t (*)(void *, off_t, const void *, size_t *))block_io_write, - NULL, // io - - (status_t (*)(void *, uint32, void *, size_t))block_io_ioctl, - - 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 -}; - - -block_io_for_driver_interface sBlockIOForDriverModule = { - { - B_BLOCK_IO_FOR_DRIVER_MODULE_NAME, - 0, - NULL - }, - - block_io_set_media_params, -}; - -module_info *modules[] = { - &sBlockIOModule.info, - &sBlockIOForDriverModule.info, - NULL -}; diff --git a/src/add-ons/kernel/generic/block_io/block_io_private.h b/src/add-ons/kernel/generic/block_io/block_io_private.h deleted file mode 100644 index 9d28db86d7..0000000000 --- a/src/add-ons/kernel/generic/block_io/block_io_private.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -/* - Part of Open block device manager - - Internal header. -*/ - -#include -#include -#include - -#include -#include - -#include "bios_drive.h" -#include "wrapper.h" - - -// controller restrictions (see block_io.h) -typedef struct block_device_params { - uint32 alignment; - uint32 max_blocks; - uint32 dma_boundary; - uint32 max_sg_block_size; - uint32 max_sg_blocks; -} block_device_params; - - -// device info -typedef struct block_io_device_info { - device_node *node; - block_device_interface *interface; - block_device_cookie *cookie; - - mutex lock; // used for access to following variables - uint32 block_size; - uint32 ld_block_size; - uint64 capacity; - - block_device_params params; - bool is_bios_drive; // could be a BIOS drive - locked_pool_cookie phys_vecs_pool; // pool of temporary phys_vecs - bios_drive *bios_drive; // info about corresponding BIOS drive -} block_io_device_info; - - -// file handle info -typedef struct block_io_handle_info { - block_io_device_info *device; - block_device_handle_cookie *cookie; -} block_io_handle_info; - - -// attribute containing BIOS drive ID (or 0, if it's no BIOS drive) (uint8) -#define B_BLOCK_DEVICE_BIOS_ID "blkdev/bios_id" - -// transmission buffer data: -// size in bytes -extern uint block_io_buffer_size; -// to use the buffer, you must own this semaphore -extern sem_id block_io_buffer_lock; -// iovec -extern struct iovec block_io_buffer_vec[1]; -// physical address -extern void *block_io_buffer_phys; -// virtual address -extern char *block_io_buffer; -// phys_vec of it (always linear) -extern phys_vecs block_io_buffer_phys_vec; -// area containing buffer -extern area_id block_io_buffer_area; - -extern locked_pool_interface *locked_pool; -extern device_manager_info *pnp; - - -// io.c - -status_t block_io_readv(block_io_handle_info *handle, off_t pos, struct iovec *vec, - size_t vec_count, size_t *len); -status_t block_io_read(block_io_handle_info *handle, off_t pos, void *buf, size_t *len); -ssize_t block_io_writev(block_io_handle_info *handle, off_t pos, struct iovec *vec, - size_t vec_count, ssize_t *len); -ssize_t block_io_write(block_io_handle_info *handle, off_t pos, void *buf, size_t *len); -void block_io_set_media_params(block_io_device_info *device, - uint32 block_size, uint32 ld_block_size, uint64 capacity); diff --git a/src/add-ons/kernel/generic/block_io/io.c b/src/add-ons/kernel/generic/block_io/io.c deleted file mode 100644 index b53e77efeb..0000000000 --- a/src/add-ons/kernel/generic/block_io/io.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -/* - Part of Open block device manager - - Actual I/O. - - This is hardcode. Think twice before changing something - in here. - - Things could become a lot easier with the following restrictions: - - stricter data alignment that is sufficient for all controllers - (e.g. page-aligned should certainly be) - - no partial block access - - locked data - - always sufficient iovecs for entire transfer - - The last thing is a design problem of the devfs. The first two - make sure that we need no buffer anymore, which would make much - code unnecessary. The locked data would save much code too - having - a sg list as input would make it even more sweeter. - - Obviously these restrictions cannot be enforced for user programs, - but at least for transfers from/to disk cache, we could define - extra functions with these properties. -*/ - - -#include "block_io_private.h" -#include "virtual_memory.h" - - -/** get sg list of iovecs, taking dma boundaries and maximum size of - * single s/g entry into account - * must not point byond first iovec - */ - -static int -block_io_map_iovecs(iovec *vec, size_t vec_count, size_t vec_offset, size_t len, - phys_vecs *map, size_t max_phys_entries, size_t dma_boundary, - size_t max_sg_block_size) -{ - status_t res; - size_t total_len; - size_t cur_idx; - - SHOW_FLOW0( 3, "" ); - - if ((res = get_iovec_memory_map(vec, vec_count, vec_offset, len, - map->vec, max_phys_entries, &map->num, &map->total_len)) < B_OK) - return res; - - if (dma_boundary == ~0UL && max_sg_block_size >= map->total_len) - return B_OK; - - SHOW_FLOW(3, "Checking violation of dma boundary 0x%x and entry size 0x%x", - (int)dma_boundary, (int)max_sg_block_size); - - total_len = 0; - - for (cur_idx = 0; cur_idx < map->num; ++cur_idx) { - addr_t max_len; - - // calculate space upto next dma boundary crossing - max_len = (dma_boundary + 1) - ((addr_t)map->vec[cur_idx].address & dma_boundary); - - // restrict size per sg item - max_len = min(max_len, max_sg_block_size); - - SHOW_FLOW(4, "addr=%p, size=%x, max_len=%x, idx=%d, num=%d", - map->vec[cur_idx].address, (int)map->vec[cur_idx].size, - (int)max_len, (int)cur_idx, (int)map->num); - - if (max_len < map->vec[cur_idx].size) { - // split sg block - map->num = min(map->num + 1, max_phys_entries); - memmove(&map->vec[cur_idx + 1], &map->vec[cur_idx], - (map->num - 1 - cur_idx) * sizeof(physical_entry)); - - map->vec[cur_idx].size = max_len; - map->vec[cur_idx + 1].address = (void *)((addr_t)map->vec[cur_idx + 1].address + max_len); - map->vec[cur_idx + 1].size -= max_len; - } - - total_len += map->vec[cur_idx].size; - } - - // we really have to update total_len - due to block splitting, - // some other blocks may got discarded if s/g list became too long - map->total_len = total_len; - return B_OK; -} - - -/** check whether dma alignment restrictions are met - * returns true on success - * remark: if the user specifies too many iovecs and the unused iovecs - * are mis-aligned, it's bad luck as we ignore this case and still - * report an alignment problem - */ - -static bool -block_io_check_alignment(struct iovec *vecs, uint num_vecs, - size_t vec_offset, uint alignment) -{ - if (alignment == 0) - // no alignment - good boy - return true; - - for (; num_vecs > 0; ++vecs, --num_vecs) { - // check both begin and end of iovec - if ((((addr_t)vecs->iov_base + vec_offset) & alignment) != 0) { - SHOW_FLOW(1, "s/g entry not aligned (%p)", vecs->iov_base); - return false; - } - - if ((((addr_t)vecs->iov_base + vecs->iov_len) & alignment) != 0) { - SHOW_FLOW(1, "end of s/g entry not aligned (%p)", - (void *)((addr_t)vecs->iov_base + vecs->iov_len)); - return false; - } - - vec_offset = 0; - } - - return true; -} - - -/** try to lock iovecs - * returns number of locked bytes - * (only entire iovecs are attempted to be locked) - * remark: if there are too few iovecs, you simply get fewer locked bytes - */ - -static size_t -block_io_lock_iovecs(struct iovec *vecs, uint num_vecs, - size_t vec_offset, size_t len, int flags) -{ - size_t orig_len = len; - - SHOW_FLOW(3, "len = %lu", len); - - for (; len > 0 && num_vecs > 0; ++vecs, --num_vecs) { - size_t lock_len; - status_t res; - - lock_len = min(vecs->iov_len - vec_offset, len); - - SHOW_FLOW(3, "pos = %p, len = %lu", vecs->iov_base, vecs->iov_len); - - res = lock_memory((void *)((addr_t)vecs->iov_base + vec_offset), lock_len, flags); - if (res != B_OK) { - SHOW_FLOW(3, "cannot lock: %s", strerror(res)); - break; - } - - len -= lock_len; - vec_offset = 0; - } - - SHOW_FLOW( 3, "remaining len=%lu", len); - - return orig_len - len; -} - - -/** unlock iovecs */ - -static void -block_io_unlock_iovecs(struct iovec *vecs, uint num_vecs, - size_t vec_offset, size_t len, int flags) -{ - SHOW_FLOW(3, "len = %lu", len); - - for (; len > 0; ++vecs, --num_vecs) { - size_t lock_len; - - lock_len = min(vecs->iov_len - vec_offset, len); - - if (unlock_memory((void *)((addr_t)vecs->iov_base + vec_offset), lock_len, - flags) != B_OK) - panic( "Cannot unlock previously locked memory!" ); - - len -= lock_len; - vec_offset = 0; - } -} - - -/** copy data from/to transfer buffer; - * remark: if iovecs are missing, copying is aborted - */ - -static void -block_io_copy_buffer(char *buffer, struct iovec *vecs, uint num_vecs, - size_t vec_offset, size_t len, bool to_buffer) -{ - for (; len > 0 && num_vecs > 0; ++vecs, --num_vecs) { - size_t bytes; - - bytes = min(len, vecs->iov_len - vec_offset); - - if (to_buffer) - memcpy(buffer, (void *)((addr_t)vecs->iov_base + vec_offset), bytes); - else - memcpy((void *)((addr_t)vecs->iov_base + vec_offset), buffer, bytes); - - buffer += bytes; - vec_offset = 0; - } -} - - -/** determine number of bytes described by iovecs */ - -static size_t -block_io_iovec_len(struct iovec *vecs, uint num_vecs, size_t vec_offset) -{ - size_t len = 0; - - for (; num_vecs > 0; ++vecs, --num_vecs) { - len += vecs->iov_len - vec_offset; - vec_offset = 0; - } - - return len; -} - - -/** main beast to execute i/o transfer - * as and is usual const, we really want to inline - * it - this makes this function much smaller in a given instance - * - data must be locked before transferring it - * - should be locked, though it's probably not really necessary - */ - -static inline status_t -block_io_readwrite(block_io_handle_info *handle, off_t pos, struct iovec *vec, - int vec_count, size_t *total_len, bool need_locking, bool write) -{ - block_io_device_info *device = handle->device; - uint32 block_size, ld_block_size; - uint64 capacity; - bool need_buffer; - status_t res = B_OK; - - size_t len = *total_len; - size_t orig_len = len; - size_t vec_offset; - - phys_vecs *phys_vecs; - - SHOW_FLOW(3, "pos = %Ld, len = %lu, need_locking = %d, write = %d, vec_count = %d", - pos, len, need_locking, write, vec_count); - - // general properties may get modified, so make a copy first - /*device->interface->get_media_params( handle->handle_cookie, - &block_size, &ld_block_size, &capacity );*/ - ACQUIRE_BEN(&device->lock); - block_size = device->block_size; - ld_block_size = device->ld_block_size; - capacity = device->capacity; - RELEASE_BEN(&device->lock); - - if (capacity == 0) { - res = B_DEV_NO_MEDIA; - goto err; - } - - if (block_size == 0) { - res = B_DEV_CONFIGURATION_ERROR; - goto err; - } - - phys_vecs = locked_pool->alloc(device->phys_vecs_pool); - - SHOW_FLOW0(3, "got phys_vecs"); - - // offset in active iovec (can span even byond first iovec) - vec_offset = 0; - - while (len > 0) { - //off_t block_pos; - uint64 block_pos; - uint32 block_ofs; - size_t cur_len; - - size_t cur_blocks; - struct iovec *cur_vecs; - size_t cur_vec_count; - size_t cur_vec_offset; - - size_t bytes_transferred; - - SHOW_FLOW(3, "current len = %lu", len); - - // skip handled iovecs - while (vec_count > 0 && vec_offset >= vec->iov_len) { - vec_offset -= vec->iov_len; - ++vec; - --vec_count; - } - - // having too few iovecs is handled in the following way: - // 1. if no other problem occurs, lock_iovecs restrict transfer - // up to the last block fully described by iovecs - // 2. if only a partial block is described, we fallback to - // buffered transfer because lock_iovecs cannot give you - // a whole block - // 3. whenever buffered transfer is used, an explicit test for - // iovec shortage is done and transmission is restricted up to - // and including the last block that has an iovec; copying from/to - // buffer stops when no iovec is left (copy_buffer) and thus - // restricts transfer appropriately - // 4. whenever all iovecs are consumed, we arrive at this piece of - // code and abort - if (vec_count == 0) { - SHOW_FLOW0(3, "vec too short"); - res = B_BAD_VALUE; - goto err2; - } - - // get block index / start offset in block - if (ld_block_size) { - block_pos = pos >> ld_block_size; - block_ofs = pos - (block_pos << ld_block_size); - } else { - block_pos = pos / block_size; - block_ofs = pos - block_pos * block_size; - } - - // read requests beyond end of volume must be ignored without notice - if (block_pos >= capacity) { - SHOW_FLOW0(1, "transfer starts beyond end of device"); - goto err2; - } - - SHOW_FLOW(3, "block_pos = %Ld, block_ofs = %lu", block_pos, block_ofs); - - // check whether a buffered transfer is required: - // 1. partial block transfer: - // 1a. transfer starts within block - // 1b. transfer finishes within block - // 2. dma alignment problem - - // 1a and 2 is handled immediately, case 1b is delayed: we transmit - // whole blocks until the last (partial) block is reached and handle - // it seperately; therefore we only check for len < block_size, e.g. - // for a last partial block (we could do better, but you get what - // you deserve) - need_buffer = block_ofs != 0 - || len < block_size - || !block_io_check_alignment(vec, vec_count, vec_offset, device->params.alignment); - -retry: - if (need_buffer) { - size_t tmp_len; - - // argh! - need buffered transfer - SHOW_FLOW(1, "buffer required: len=%ld, block_ofs=%ld", - len, block_ofs); - - acquire_sem(block_io_buffer_lock); - - // nobody helps us if there are too few iovecs, so test - // for that explicitely - // (case that tmp_len = 0 is already checked above; if not, - // we would get trouble when we try to round up to next - // block size, which would lead to zero, making trouble - // during lock) - tmp_len = block_io_iovec_len(vec, vec_count, vec_offset); - tmp_len = min(tmp_len, len); - - SHOW_FLOW(3, "tmp_len: %lu", tmp_len); - - if (write && (block_ofs != 0 || tmp_len < block_size)) { - // partial block write - need to read block first - // we always handle one block only to keep things simple - cur_blocks = 1; - - SHOW_FLOW0(3, "partial write at beginning: reading content of first block"); - - // temporarily restrict the buffer's S/G list size to how much - // we actually want to read - block_io_buffer_phys_vec.total_len = block_size; - block_io_buffer_phys_vec.vec[0].size = block_size; - - res = device->interface->read(handle->cookie, - &block_io_buffer_phys_vec, block_pos, - cur_blocks, block_size, &bytes_transferred); - - block_io_buffer_phys_vec.total_len = block_io_buffer_size; - block_io_buffer_phys_vec.vec[0].size = block_io_buffer_size; - } else { - // alignment problem or partial block read - find out how many - // blocks are spanned by this transfer - cur_blocks = (tmp_len + block_ofs + block_size - 1) / block_size; - - SHOW_FLOW(3, "cur_blocks: %ld", cur_blocks); - - // restrict block count to buffer size - if (cur_blocks * block_size > block_io_buffer_size) - cur_blocks = block_io_buffer_size / block_size; - } - - // copy data into buffer before write - // (calculate number of bytes to copy carefully!) - if (write) { - SHOW_FLOW(3, "copy data to buffer (%ld bytes)", - cur_blocks * block_size - block_ofs); - block_io_copy_buffer(block_io_buffer + block_ofs, - vec, vec_count, vec_offset, cur_blocks * block_size - block_ofs, - true); - } - - cur_vecs = block_io_buffer_vec; - cur_vec_count = 1; - cur_vec_offset = 0; - } else { - // no buffer needed - if (ld_block_size) - cur_blocks = len >> ld_block_size; - else - cur_blocks = len / block_size; - - cur_vecs = vec; - cur_vec_count = vec_count; - cur_vec_offset = vec_offset; - } - - SHOW_FLOW(3, "cur_blocks = %lu, cur_vec_offset = %lu, cur_vec_count = %lu", - cur_blocks, cur_vec_offset, cur_vec_count); - - // restrict transfer size to device limits and media capacity - cur_blocks = min(cur_blocks, device->params.max_blocks); - - if (block_pos + cur_blocks > capacity) - cur_blocks = capacity - block_pos; - - SHOW_FLOW(3, "after applying size restriction: cur_blocks = %lu", cur_blocks); - - cur_len = cur_blocks * block_size; - - if (need_locking) { - // lock data - // side-node: we also lock the transfer buffer to simplify code - - // if n bytes are to be transferred, we try to lock - // n bytes, then n/2, n/4 etc. until we succeed - // this is needed because locking fails for entire iovecs only - for (; cur_len > 0; cur_blocks >>= 1, cur_len = cur_blocks * block_size) { - size_t locked_len; - - SHOW_FLOW(3, "trying to lock %lu bytes", cur_len); - - locked_len = block_io_lock_iovecs(cur_vecs, cur_vec_count, - cur_vec_offset, cur_len, B_DMA_IO | (write ? 0 : B_READ_DEVICE)); - - if (locked_len == cur_len) - break; - - // couldn't lock all we want - SHOW_FLOW0(3, "couldn't lock all bytes"); - - if (locked_len > block_size) { - // locked at least one block - we are happy - SHOW_FLOW0(3, "transmission length restricted to locked bytes"); - cur_blocks = locked_len / block_size; - cur_len = cur_blocks * block_size; - break; - } - - // got less then one block locked - unlock and retry - SHOW_FLOW0(3, "too few bytes locked - trying again with fewer bytes"); - - block_io_unlock_iovecs(cur_vecs, cur_vec_count, cur_vec_offset, locked_len, - B_DMA_IO | (write ? 0 : B_READ_DEVICE)); - } - - if (cur_len == 0) { - // didn't manage to lock at least one block - // -> fallback to buffered transfer - SHOW_FLOW0(3, "locking failed"); - - if (need_buffer) { - // error locking transfer buffer? - // that's impossible - it is locked already! - panic("Cannot lock scratch buffer\n"); - res = B_ERROR; - goto err3; - } - - need_buffer = true; - goto retry; - } - } - - // data is locked and all restrictions are obeyed now; - // time to setup sg list - SHOW_FLOW0(3, "Creating SG list"); - - res = block_io_map_iovecs(cur_vecs, cur_vec_count, cur_vec_offset, cur_len, - phys_vecs, device->params.max_sg_blocks, device->params.dma_boundary, - device->params.max_sg_block_size); - - if (res < 0) { - SHOW_FLOW(3, "failed - %s", strerror(res)); - goto cannot_map; - } - - if (phys_vecs->total_len < cur_len) { - // we hit some sg limit - restrict transfer appropriately - cur_blocks = phys_vecs->total_len / block_size; - - SHOW_FLOW(3, "transmission to complex - restricted to %d blocks", (int)cur_blocks); - - if (cur_blocks == 0) { - // oh no - not even one block is left; use transfer buffer instead - SHOW_FLOW0(3, "SG too small to handle even one block"); - - if (need_locking) { - block_io_unlock_iovecs(cur_vecs, cur_vec_count, cur_vec_offset, - cur_len, B_DMA_IO | (write ? 0 : B_READ_DEVICE)); - } - - if (need_buffer) { - // we are already using the transfer buffer - // this case is impossible as transfer buffer is linear! - panic("Scratch buffer turned out to be too fragmented !?\n"); - } - - SHOW_FLOW0(3, "Falling back to buffered transfer"); - - need_buffer = true; - goto retry; - } - - // reflect rounded len in sg list - phys_vecs->total_len = cur_blocks * block_size; - } - - // at least - let the bytes flow - SHOW_FLOW(2, "Transmitting %d bytes @%Ld", - (int)phys_vecs->total_len, block_pos); - - if (write) { - res = device->interface->write(handle->cookie, - phys_vecs, block_pos, cur_blocks, block_size, &bytes_transferred); - } else { - res = device->interface->read(handle->cookie, - phys_vecs, block_pos, cur_blocks, block_size, &bytes_transferred); - } - - SHOW_FLOW(3, "Transfer of %d bytes completed (%s)", - (int)bytes_transferred, strerror(res)); - -cannot_map: - // unlock data - if (need_locking) { - block_io_unlock_iovecs(cur_vecs, cur_vec_count, cur_vec_offset, - cur_len, B_DMA_IO | (write ? 0 : B_READ_DEVICE)); - } - - if (res < 0) - goto err3; - - if (need_buffer) { - // adjust transfer size by gap skipped at beginning of blocks - bytes_transferred -= block_ofs; - - // if we had to round up to block size, adjust transfer as well - if (bytes_transferred > len) - bytes_transferred = len; - - // if transfer buffer is used for read, copy result from it - if (!write) { - SHOW_FLOW(3, "copying data back from buffer (%ld bytes)", - bytes_transferred); - block_io_copy_buffer(block_io_buffer + block_ofs, - vec, vec_count, vec_offset, bytes_transferred, false); - } - - release_sem(block_io_buffer_lock); - } - - len -= bytes_transferred; - vec_offset += bytes_transferred; - pos += bytes_transferred; - } - - locked_pool->free(device->phys_vecs_pool, phys_vecs); - - SHOW_FLOW0(3, "done"); - - return B_OK; - -err3: - if (need_buffer) - release_sem(block_io_buffer_lock); -err2: - locked_pool->free(device->phys_vecs_pool, phys_vecs); -err: - SHOW_FLOW(3, "done with error %s", strerror(res)); - - // we haven't transferred all data - tell caller about - *total_len = orig_len - len; - return res; -} - - -static status_t -block_io_readv_int(block_io_handle_info *handle, off_t pos, struct iovec *vec, - size_t vec_count, size_t *len, bool need_locking) -{ - return block_io_readwrite(handle, pos, vec, vec_count, len, need_locking, false); -} - - -static status_t -block_io_writev_int(block_io_handle_info *handle, off_t pos, struct iovec *vec, - size_t vec_count, size_t *len, bool need_locking) -{ - return block_io_readwrite(handle, pos, vec, vec_count, len, need_locking, true); -} - - -/** generic read(v)/write(v) routine; - * iovecs are locked during transfer - * inlining it leads to overall code reduction as is const - */ - -static inline status_t -block_io_readwritev(block_io_handle_info *handle, off_t pos, struct iovec *vec, - size_t vec_count, size_t *len, bool write) - -{ - status_t res; - struct iovec *cur_vec; - size_t left; - size_t total_len; - - if ((res = lock_memory(vec, vec_count * sizeof(vec[0]), 0)) < 0) - return res; - - // there is an error in the BeBook: *len does _not_ contain correct - // total length on call - you have to calculate that yourself - total_len = 0; - - for (cur_vec = vec, left = vec_count; left > 0; ++cur_vec, --left) { - total_len += cur_vec->iov_len; - } - - *len = total_len; - - if (write) - res = block_io_writev_int(handle, pos, vec, vec_count, len, true); - else - res = block_io_readv_int(handle, pos, vec, vec_count, len, true); - - unlock_memory(vec, vec_count * sizeof(vec[0]), 0); - - return res; -} - - -status_t -block_io_readv(block_io_handle_info *handle, off_t pos, struct iovec *vec, - size_t vec_count, size_t *len) -{ -/* SHOW_FLOW( 4, "len=%d", (int)*len ); - - for( cur_vec = vec, left = vec_count; left > 0; ++cur_vec, --left ) { - SHOW_FLOW( 4, "pos=%x, size=%d", - (int)cur_vec->iov_base, (int)cur_vec->iov_len ); - }*/ - - return block_io_readwritev(handle, pos, vec, vec_count, len, false); -} - - -status_t -block_io_read(block_io_handle_info *handle, off_t pos, void *buf, size_t *len) -{ - iovec vec[1]; - - vec[0].iov_base = buf; - vec[0].iov_len = *len; - - SHOW_FLOW0( 3, "" ); - - // This assumes that the thread stack is not paged, - // else you want to use block_io_readv - // But this is not a problem, since kernel stacks - // are always paged in (since they can be used by - // an interrupt at any time) - return block_io_readv_int(handle, pos, vec, 1, len, true); -} - - -ssize_t -block_io_writev(block_io_handle_info *handle, off_t pos, struct iovec *vec, - size_t vec_count, ssize_t *len) -{ - return block_io_readwritev(handle, pos, vec, vec_count, len, true); -} - - -ssize_t -block_io_write(block_io_handle_info *handle, off_t pos, void *buf, size_t *len) -{ - iovec vec[1]; - - vec[0].iov_base = buf; - vec[0].iov_len = *len; - - // see block_io_read - return block_io_writev_int(handle, pos, vec, 1, len, true); -} - - -void -block_io_set_media_params(block_io_device_info *device, uint32 block_size, - uint32 ld_block_size, uint64 capacity) -{ - SHOW_FLOW(3, "block_size = %lu, ld_block_size = %lu, capacity = %Lu\n", block_size, - ld_block_size, capacity); - - ACQUIRE_BEN(&device->lock); - - device->block_size = block_size; - device->ld_block_size = ld_block_size; - device->capacity = capacity; - - RELEASE_BEN(&device->lock); -} - diff --git a/src/add-ons/kernel/generic/block_io/virtual_memory.c b/src/add-ons/kernel/generic/block_io/virtual_memory.c deleted file mode 100644 index 2f769ac9db..0000000000 --- a/src/add-ons/kernel/generic/block_io/virtual_memory.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -/* - VM helper functions. - - Important assumption: get_memory_map must combine adjacent - physical pages, so contignous memory always leads to a S/G - list of length one. -*/ - -#include "virtual_memory.h" -#include "wrapper.h" - -#include - - -/** get sg list of iovec - * TBD: this should be moved to somewhere in kernel - */ - -status_t -get_iovec_memory_map(iovec *vec, size_t vec_count, size_t vec_offset, size_t len, - physical_entry *map, size_t max_entries, size_t *num_entries, size_t *mapped_len) -{ - size_t cur_idx; - size_t left_len; - - SHOW_FLOW(3, "vec_count=%lu, vec_offset=%lu, len=%lu, max_entries=%lu", - vec_count, vec_offset, len, max_entries); - - // skip iovec blocks if needed - while (vec_count > 0 && vec_offset > vec->iov_len) { - vec_offset -= vec->iov_len; - --vec_count; - ++vec; - } - - for (left_len = len, cur_idx = 0; left_len > 0 && vec_count > 0 && cur_idx < max_entries;) { - char *range_start; - size_t range_len; - status_t res; - size_t cur_num_entries, cur_mapped_len; - uint32 tmp_idx; - - SHOW_FLOW( 3, "left_len=%d, vec_count=%d, cur_idx=%d", - (int)left_len, (int)vec_count, (int)cur_idx ); - - // map one iovec - range_start = (char *)vec->iov_base + vec_offset; - range_len = min( vec->iov_len - vec_offset, left_len ); - - SHOW_FLOW( 3, "range_start=%x, range_len=%x", - (int)range_start, (int)range_len ); - - vec_offset = 0; - - if ((res = get_memory_map(range_start, range_len, &map[cur_idx], - max_entries - cur_idx)) != B_OK) { - // according to docu, no error is ever reported - argh! - SHOW_ERROR(1, "invalid io_vec passed (%s)", strerror(res)); - return res; - } - - // stupid: get_memory_map does neither tell how many sg blocks - // are used nor whether there were enough sg blocks at all; - // -> determine that manually - cur_mapped_len = 0; - cur_num_entries = 0; - - for (tmp_idx = cur_idx; tmp_idx < max_entries; ++tmp_idx) { - if (map[tmp_idx].size == 0) - break; - - cur_mapped_len += map[tmp_idx].size; - ++cur_num_entries; - } - - if (cur_mapped_len == 0) { - panic("get_memory_map() returned empty list; left_len=%d, idx=%d/%d", - (int)left_len, (int)cur_idx, (int)max_entries); - SHOW_ERROR(2, "get_memory_map() returned empty list; left_len=%d, idx=%d/%d", - (int)left_len, (int)cur_idx, (int)max_entries); - return B_ERROR; - } - - SHOW_FLOW( 3, "cur_num_entries=%d, cur_mapped_len=%x", - (int)cur_num_entries, (int)cur_mapped_len ); - - // try to combine with previous sg block - if (cur_num_entries > 0 && cur_idx > 0 - && map[cur_idx].address == (char *)map[cur_idx - 1].address + map[cur_idx - 1].size) { - SHOW_FLOW0( 3, "combine with previous chunk" ); - map[cur_idx - 1].size += map[cur_idx].size; - memcpy(&map[cur_idx], &map[cur_idx + 1], (cur_num_entries - 1) * sizeof(map[0])); - --cur_num_entries; - } - - cur_idx += cur_num_entries; - left_len -= cur_mapped_len; - - // advance iovec if current one is described completely - if (cur_mapped_len == range_len) { - ++vec; - --vec_count; - } - } - - *num_entries = cur_idx; - *mapped_len = len - left_len; - - SHOW_FLOW( 3, "num_entries=%d, mapped_len=%x", - (int)*num_entries, (int)*mapped_len ); - - return B_OK; -} - diff --git a/src/add-ons/kernel/generic/block_io/virtual_memory.h b/src/add-ons/kernel/generic/block_io/virtual_memory.h deleted file mode 100644 index 8115e12d4b..0000000000 --- a/src/add-ons/kernel/generic/block_io/virtual_memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2002/03, Thomas Kurschel. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _VIRTUAL_MEMORY_H -#define _VIRTUAL_MEMORY_H - - -#include -#include - - -// get memory map of iovec -extern status_t get_iovec_memory_map(iovec *vec, size_t vecCount, - size_t vecOffset, size_t length, physical_entry *map, - size_t maxMapEntries, size_t *_numEntries, - size_t *_mappedLength); - -#endif /* _VIRTUAL_MEMORY_H */ diff --git a/src/add-ons/kernel/generic/block_io/wrapper.h b/src/add-ons/kernel/generic/block_io/wrapper.h deleted file mode 100644 index 3baee034b8..0000000000 --- a/src/add-ons/kernel/generic/block_io/wrapper.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef _WRAPPER_H -#define _WRAPPER_H - -#include -#include - - -// benaphores - -#define INIT_BEN(x, prefix) (mutex_init_etc(x, prefix, MUTEX_FLAG_CLONE_NAME), \ - B_OK) -#define DELETE_BEN(x) mutex_destroy(x) -#define ACQUIRE_BEN(x) mutex_lock(x) -#define RELEASE_BEN(x) mutex_unlock(x) - -// debug output - -#ifdef DEBUG_WAIT_ON_MSG -# define DEBUG_WAIT snooze( DEBUG_WAIT_ON_MSG ); -#else -# define DEBUG_WAIT -#endif - -#ifdef DEBUG_WAIT_ON_ERROR -# define DEBUG_WAIT_ERROR snooze( DEBUG_WAIT_ON_ERROR ); -#else -# define DEBUG_WAIT_ERROR -#endif - -#ifndef DEBUG_MAX_LEVEL_FLOW -# define DEBUG_MAX_LEVEL_FLOW 4 -#endif - -#ifndef DEBUG_MAX_LEVEL_INFO -# define DEBUG_MAX_LEVEL_INFO 4 -#endif - -#ifndef DEBUG_MAX_LEVEL_ERROR -# define DEBUG_MAX_LEVEL_ERROR 4 -#endif - -#ifndef DEBUG_MSG_PREFIX -# define DEBUG_MSG_PREFIX "" -#endif - -#ifndef debug_level_flow -# define debug_level_flow 0 -#endif - -#ifndef debug_level_info -# define debug_level_info 1 -#endif - -#ifndef debug_level_error -# define debug_level_error 2 -#endif - -#define FUNC_NAME DEBUG_MSG_PREFIX, __FUNCTION__ - -#define SHOW_FLOW(seriousness, format, param...) \ - do { if( seriousness <= debug_level_flow && seriousness <= DEBUG_MAX_LEVEL_FLOW ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME, param ); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_FLOW0(seriousness, format) \ - do { if( seriousness <= debug_level_flow && seriousness <= DEBUG_MAX_LEVEL_FLOW ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_INFO(seriousness, format, param...) \ - do { if( seriousness <= debug_level_info && seriousness <= DEBUG_MAX_LEVEL_INFO ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME, param ); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_INFO0(seriousness, format) \ - do { if( seriousness <= debug_level_info && seriousness <= DEBUG_MAX_LEVEL_INFO ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME); DEBUG_WAIT \ - }} while( 0 ) - -#define SHOW_ERROR(seriousness, format, param...) \ - do { if( seriousness <= debug_level_error && seriousness <= DEBUG_MAX_LEVEL_ERROR ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME, param ); DEBUG_WAIT_ERROR \ - }} while( 0 ) - -#define SHOW_ERROR0(seriousness, format) \ - do { if( seriousness <= debug_level_error && seriousness <= DEBUG_MAX_LEVEL_ERROR ) { \ - dprintf( "%s%s: "format"\n", FUNC_NAME); DEBUG_WAIT_ERROR \ - }} while( 0 ) - -#endif /* _BENAPHORE_H */ diff --git a/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c b/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c index 8163e13edb..c039e4cbfd 100644 --- a/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c +++ b/src/add-ons/kernel/generic/ide_adapter/ide_adapter.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #define debug_level_flow 0 @@ -656,18 +655,20 @@ ide_adapter_publish_controller(device_node *parent, uint16 bus_master_base, // command queuing always works (unless controller is buggy) { IDE_CONTROLLER_CAN_CQ_ITEM, B_UINT8_TYPE, { ui8: can_cq }}, // choose any name here - { IDE_CONTROLLER_CONTROLLER_NAME_ITEM, B_STRING_TYPE, { string: controller_name }}, + { IDE_CONTROLLER_CONTROLLER_NAME_ITEM, B_STRING_TYPE, + { string: controller_name }}, // DMA properties // data must be word-aligned; // warning: some controllers are more picky! - { B_BLOCK_DEVICE_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: dma_alignment /*1*/}}, + { B_DMA_ALIGNMENT, B_UINT32_TYPE, { ui32: dma_alignment /*1*/}}, // one S/G block must not cross 64K boundary - { B_BLOCK_DEVICE_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: dma_boundary/*0xffff*/ }}, + { B_DMA_BOUNDARY, B_UINT32_TYPE, { ui32: dma_boundary/*0xffff*/ }}, // max size of S/G block is 16 bits with zero being 64K - { B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, B_UINT32_TYPE, { ui32: max_sg_block_size/*0x10000*/ }}, - // see definition of MAX_SG_COUNT - { B_BLOCK_DEVICE_MAX_SG_BLOCKS, B_UINT32_TYPE, { ui32: IDE_ADAPTER_MAX_SG_COUNT }}, + { B_DMA_MAX_SEGMENT_BLOCKS, B_UINT32_TYPE, + { ui32: max_sg_block_size/*0x10000*/ }}, + { B_DMA_MAX_SEGMENT_COUNT, B_UINT32_TYPE, + { ui32: IDE_ADAPTER_MAX_SG_COUNT }}, // private data to find controller { IDE_ADAPTER_BUS_MASTER_BASE, B_UINT16_TYPE, { ui16: bus_master_base }}, diff --git a/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h b/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h index 0057c3cef5..1f56933041 100644 --- a/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h +++ b/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h @@ -10,7 +10,6 @@ #include #include -#include #include #include "io_requests.h" diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp index 28d59070cf..f1d396d3bd 100644 --- a/src/system/kernel/device_manager/dma_resources.cpp +++ b/src/system/kernel/device_manager/dma_resources.cpp @@ -6,7 +6,7 @@ #include "dma_resources.h" -#include +#include #include #include @@ -124,23 +124,23 @@ DMAResource::Init(device_node* node, size_t blockSize, uint32 bufferCount) uint32 value; if (gDeviceManagerModule.get_attr_uint32(node, - B_BLOCK_DEVICE_DMA_ALIGNMENT, &value, true) == B_OK) + B_DMA_ALIGNMENT, &value, true) == B_OK) restrictions.alignment = value + 1; if (gDeviceManagerModule.get_attr_uint32(node, - B_BLOCK_DEVICE_DMA_BOUNDARY, &value, true) == B_OK) + B_DMA_BOUNDARY, &value, true) == B_OK) restrictions.boundary = value + 1; if (gDeviceManagerModule.get_attr_uint32(node, - B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE, &value, true) == B_OK) - restrictions.max_segment_size = value; + B_DMA_MAX_SEGMENT_BLOCKS, &value, true) == B_OK) + restrictions.max_segment_size = value * blockSize; if (gDeviceManagerModule.get_attr_uint32(node, - B_BLOCK_DEVICE_MAX_BLOCKS_ITEM, &value, true) == B_OK) + B_DMA_MAX_TRANSFER_BLOCKS, &value, true) == B_OK) restrictions.max_transfer_size = value * blockSize; if (gDeviceManagerModule.get_attr_uint32(node, - B_BLOCK_DEVICE_MAX_SG_BLOCKS, &value, true) == B_OK) + B_DMA_MAX_SEGMENT_COUNT, &value, true) == B_OK) restrictions.max_segment_count = value; return Init(restrictions, blockSize, bufferCount);