2004-06-07 03:52:08 +04:00
|
|
|
/*
|
2005-05-12 19:43:02 +04:00
|
|
|
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
|
|
|
#ifndef __BLOCK_IO_H__
|
|
|
|
#define __BLOCK_IO_H__
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
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
|
|
|
|
protocol and transparently handles transmission of partial blocks
|
|
|
|
by using a buffer (performance will suffer, though).
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <KernelExport.h>
|
|
|
|
#include <device_manager.h>
|
|
|
|
|
2005-05-12 19:43:02 +04:00
|
|
|
// cookies issued by block_io
|
|
|
|
typedef struct block_io_device_info *block_io_device;
|
|
|
|
typedef struct block_io_handle_info *block_io_handle;
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// cookies issued by device driver
|
2005-05-12 19:43:02 +04:00
|
|
|
typedef struct block_device_device_cookie *block_device_device_cookie;
|
|
|
|
typedef struct block_device_handle_cookie *block_device_handle_cookie;
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
|
|
|
|
// 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)
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_DEVICE_IS_BIOS_DRIVE "block_device/is_bios_drive"
|
2004-06-07 03:52:08 +04:00
|
|
|
// address bits that must be 0 - must be 2^i-1 for some i (uint32, optional, default: 0)
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_DEVICE_DMA_ALIGNMENT "block_device/dma_alignment"
|
2004-06-07 03:52:08 +04:00
|
|
|
// maximum number of blocks per transfer (uint32, optional, default: unlimited)
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_DEVICE_MAX_BLOCKS_ITEM "block_device/max_blocks"
|
2004-06-07 03:52:08 +04:00
|
|
|
// mask of bits that can change in one sg block (uint32, optional, default: ~0)
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_DEVICE_DMA_BOUNDARY "block_device/dma_boundary"
|
2004-06-07 03:52:08 +04:00
|
|
|
// maximum size of one block in scatter/gather list (uint32, optional, default: ~0)
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_DEVICE_MAX_SG_BLOCK_SIZE "block_device/max_sg_block_size"
|
2004-06-07 03:52:08 +04:00
|
|
|
// maximum number of scatter/gather blocks (uint32, optional, default: unlimited)
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_DEVICE_MAX_SG_BLOCKS "block_device/max_sg_blocks"
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
|
|
|
|
// interface to be provided by device driver
|
2005-05-12 19:43:02 +04:00
|
|
|
typedef struct block_device_interface {
|
|
|
|
driver_module_info info;
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// 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
|
2005-05-12 19:43:02 +04:00
|
|
|
status_t (*open)(block_device_device_cookie device, block_device_handle_cookie *handle);
|
|
|
|
status_t (*close)(block_device_handle_cookie handle);
|
|
|
|
status_t (*free)(block_device_handle_cookie handle);
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2005-05-12 19:43:02 +04:00
|
|
|
status_t (*read)(block_device_handle_cookie handle, const phys_vecs *vecs, off_t pos,
|
2004-06-07 03:52:08 +04:00
|
|
|
size_t num_blocks, uint32 block_size, size_t *bytes_transferred);
|
2005-05-12 19:43:02 +04:00
|
|
|
status_t (*write)(block_device_handle_cookie handle, const phys_vecs *vecs, off_t pos,
|
2004-06-07 03:52:08 +04:00
|
|
|
size_t num_blocks, uint32 block_size, size_t *bytes_transferred);
|
|
|
|
|
2005-05-12 19:43:02 +04:00
|
|
|
status_t (*ioctl)(block_device_handle_cookie handle, int op, void *buf, size_t len);
|
|
|
|
} block_device_interface;
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_IO_MODULE_NAME "generic/block_io/v1"
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
|
|
|
|
// Interface for Drivers
|
|
|
|
|
|
|
|
// blkman interface used for callbacks done by driver
|
2005-05-12 19:43:02 +04:00
|
|
|
typedef struct block_io_for_driver_interface {
|
|
|
|
module_info info;
|
2004-06-07 03:52:08 +04:00
|
|
|
|
|
|
|
// 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
|
2005-05-12 19:43:02 +04:00
|
|
|
void (*set_media_params)(block_io_device device, uint32 block_size, uint32 ld_block_size,
|
2004-06-07 03:52:08 +04:00
|
|
|
uint64 capacity);
|
2005-05-12 19:43:02 +04:00
|
|
|
} block_io_for_driver_interface;
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2005-05-12 19:43:02 +04:00
|
|
|
#define B_BLOCK_IO_FOR_DRIVER_MODULE_NAME "generic/block_io/driver/v1"
|
2004-06-07 03:52:08 +04:00
|
|
|
|
2005-05-12 19:43:02 +04:00
|
|
|
#endif /* __BLOCK_IO_H__ */
|