Data Structures | |||||||||||||
struct | BlockDevice | ||||||||||||
struct | BlockDeviceInfo | ||||||||||||
Structure of information about a block device. More... | |||||||||||||
struct | BlockMediumInfo | ||||||||||||
Structure of information about a block device medium. More... | |||||||||||||
struct | BlockOperations | ||||||||||||
Structure of operations for block devices. More... | |||||||||||||
Error reporting | |||||||||||||
Block device facilities shall return a negative error value in case of failure. The error values are formed as follows:
| |||||||||||||
enum | BlockSenseKeys { BLOCK_SENSE_NONE = 0 << 16, BLOCK_SENSE_RECOVERED = 1 << 16, BLOCK_SENSE_NOTREADY = 2 << 16, BLOCK_SENSE_MEDIUM = 3 << 16, BLOCK_SENSE_HW = 4 << 16, BLOCK_SENSE_ILLREQ = 5 << 16, BLOCK_SENSE_ATTENTION = 6 << 16, BLOCK_SENSE_DATAPROT = 7 << 16, BLOCK_SENSE_BLANK = 8 << 16, BLOCK_SENSE_ABORTED = 11 << 16, BLOCK_SENSE_MISCOMPARE = 14 << 16 } | ||||||||||||
Sense key values for block device error values. More... | |||||||||||||
#define | BLOCK_ERROR_CATEGORY 0x80800000 | ||||||||||||
Error category code for block devices. | |||||||||||||
#define | BLOCK_ERROR(sense, code) ((int) (BLOCK_ERROR_CATEGORY | (sense) | ((code) & 0xFFFF))) | ||||||||||||
Formats a block device error value. | |||||||||||||
#define | BLOCK_GET_SENSE(value) ((value) & 0x003F0000) | ||||||||||||
Gets the sense key from a block device error value. | |||||||||||||
#define | BLOCK_IS_ERROR(value) (((value) & 0xFFC00000) == BLOCK_ERROR_CATEGORY) | ||||||||||||
Checks if an error value belongs to the block devices category. | |||||||||||||
Block device operations | |||||||||||||
enum | BlockDeviceInfoFlags { BLOCK_DEVICE_INFO_PARTID = 0xFF, BLOCK_DEVICE_INFO_TYPEMASK = 15 << 8, BLOCK_DEVICE_INFO_TGENERIC = 0 << 8, BLOCK_DEVICE_INFO_TACTIVE = 1 << 8, BLOCK_DEVICE_INFO_TLOGICAL = 2 << 8, BLOCK_DEVICE_INFO_TPRIMARY = 3 << 8, BLOCK_DEVICE_INFO_TFLOPPY = 4 << 8, BLOCK_DEVICE_INFO_TCDDVD = 5 << 8, BLOCK_DEVICE_INFO_REMOVABLE = 1 << 12, BLOCK_DEVICE_INFO_MEDIACHG = 1 << 13, BLOCK_DEVICE_INFO_WRITABLE = 1 << 14 } | ||||||||||||
Block device information flags. More... | |||||||||||||
enum | BlockReadWriteFlags { BLOCK_RW_NOCACHE = 1 << 0 } | ||||||||||||
Flags for the read and write block device operations. More... | |||||||||||||
typedef struct BlockDeviceInfo | BlockDeviceInfo | ||||||||||||
Typedef shortcut for the struct BlockDeviceInfo. | |||||||||||||
typedef struct BlockMediumInfo | BlockMediumInfo | ||||||||||||
Typedef shortcut for the struct BlockMediumInfo. | |||||||||||||
typedef struct BlockOperations | BlockOperations | ||||||||||||
Typedef shortcut for the struct BlockOperations. | |||||||||||||
#define | BLOCK_OPERATIONS_TYPE 1 | ||||||||||||
Operations type for struct BlockOperations. | |||||||||||||
Block device manager functions | |||||||||||||
const char * | block_enumerate (void **iterator) | ||||||||||||
Enumerates the registered block devices. | |||||||||||||
int | block_get (const char *name, int type, void **operations, void **handle) | ||||||||||||
Gets operations for a block device. | |||||||||||||
int | block_register (const char *name, int(*request)(int function,...), void *handle) | ||||||||||||
Registers a device to the Block Device Manager. | |||||||||||||
int | block_unregister (const char *name) | ||||||||||||
Unregisters a device from the Block Device Manager. | |||||||||||||
static int | req_get_operations (int(*r)(int function,...), int type, void **operations) | ||||||||||||
Shortcut to perform a REQ_GET_OPERATIONS request. | |||||||||||||
static int | req_get_references (int(*r)(int function,...)) | ||||||||||||
Shortcut to perform a REQ_GET_REFERENCES request. | |||||||||||||
static int | req_release (int(*r)(int function,...), void *handle) | ||||||||||||
Shortcut to perform a REQ_RELEASE request. | |||||||||||||
Defines | |||||||||||||
#define | REQ_GET_OPERATIONS 0 | ||||||||||||
Request to get a structure of operations. | |||||||||||||
#define | REQ_GET_REFERENCES 1 | ||||||||||||
Request to get the reference count of an object. | |||||||||||||
#define | REQ_RELEASE 2 | ||||||||||||
Request to release an object. | |||||||||||||
Typedefs | |||||||||||||
typedef struct BlockDevice | BlockDevice | ||||||||||||
typedef unsigned long | ssize_t | ||||||||||||
Functions | |||||||||||||
void | block_init (void) | ||||||||||||
Variables | |||||||||||||
static List | list | ||||||||||||
static slabmem_t | slab | ||||||||||||
struct { | |||||||||||||
const char * name | |||||||||||||
void * address | |||||||||||||
} | symbols [] |
To use the block device functionality:
#include <block/block.h>
Each block device is registered to the Block device manager and is identified through a unique name, that is a UTF-8 string which is considered case insensitive in respect to characters in the ASCII set (that is, 'a'..'z'). This allows to use a simple implementation of strcasecmp
for name comparison, without extensive knowledge of the UTF-8 encoding and Unicode case folding, which is not trivial.
A block device driver shall expose its functionality through a variadic request function, having the following prototype:
int request(int function, ...)
mnemonic | purpose |
---|---|
REQ_GET_OPERATIONS | query the driver for a structure of operations |
REQ_GET_REFERENCES | get the value of the reference count of the driver |
REQ_RELEASE | release an object |
A driver shall maintain an internal reference counter that is used to keep track of the users of the facilities of the driver. Whenever an interface is queried, including the generic one represented by the request function, the reference count shall be increased. When a user does not need to use the functionality of the driver any longer, it shall release the interface it got and the driver shall decrease its reference count. The driver can be unloaded only if the reference count is zero.
A driver may need to manage several devices or facilities. In this case the driver shall associate to each device or facility a an opaque identifier, in form of a void pointer, that the caller shall use in the request function or other interfaces to specify what device or facility to operate on. The opaque identifier is usually the address of a structure used by the driver to store the state of the device or facility.
#define BLOCK_ERROR | ( | sense, | |||
code | ) | ((int) (BLOCK_ERROR_CATEGORY | (sense) | ((code) & 0xFFFF))) |
#define BLOCK_ERROR_CATEGORY 0x80800000 |
#define BLOCK_GET_SENSE | ( | value | ) | ((value) & 0x003F0000) |
#define BLOCK_IS_ERROR | ( | value | ) | (((value) & 0xFFC00000) == BLOCK_ERROR_CATEGORY) |
#define BLOCK_OPERATIONS_TYPE 1 |
#define REQ_GET_OPERATIONS 0 |
Request to get a structure of operations.
Call the request function as follows:
int request(REQ_GET_OPERATIONS, int type, void **operations);
Definition at line 323 of file block.h.
Referenced by block_get(), and req_get_operations().
#define REQ_GET_REFERENCES 1 |
Request to get the reference count of an object.
Call the request function as follows:
int request(REQ_GET_REFERENCES);
Definition at line 332 of file block.h.
Referenced by block_unregister(), and req_get_references().
#define REQ_RELEASE 2 |
Request to release an object.
Call the request function as follows:
int request(REQ_RELEASE, void *handle);
Definition at line 343 of file block.h.
Referenced by req_release().
typedef struct BlockDevice BlockDevice |
typedef struct BlockDeviceInfo BlockDeviceInfo |
typedef struct BlockMediumInfo BlockMediumInfo |
typedef struct BlockOperations BlockOperations |
enum BlockDeviceInfoFlags |
Block device information flags.
This enum provides mnemonics for the flags field of BlockDeviceInfo, that is a combination of the following bits:
0..7 | partition identifier (0 if not a partition) |
8..11 | device type, useful for drive letter assignment |
12 | device with removable media |
13 | can check for media change (only meaningful if removable) |
14 | device is writable |
15..31 | reserved (zero) |
enum BlockReadWriteFlags |
enum BlockSenseKeys |
Sense key values for block device error values.
const char * block_enumerate | ( | void ** | iterator | ) |
Enumerates the registered block devices.
iterator | opaque iterator to store the enumeration progress. |
When all devices have been enumerated, NULL is returned. In this case the iterator is reinitialized with a NULL pointer so that calling this function again restarts the enumeration.
Definition at line 119 of file block.c.
References list, BlockDevice::name, and BlockDevice::next.
int block_get | ( | const char * | name, | |
int | type, | |||
void ** | operations, | |||
void ** | handle | |||
) |
Gets operations for a block device.
name | name of the requested device; | |
type | the requested type of operations; | |
[out] | operations | address of a pointer to the returned operations; it may be NULL to just check if the requested type is available. |
[out] | handle | to receive the opaque identifier of the device; it may be NULL if operations is NULL, but it should not be NULL otherwise. |
0 | success, operations and handle updated if not NULL; | |
-ENOTSUP | the REQ_GET_OPERATION request or the specified type of operations is not available. The former should not happen as all devices should implement REQ_GET_OPERATIONS. |
Definition at line 147 of file block.c.
References assert, EINVAL, BlockDevice::handle, list, BlockDevice::name, BlockDevice::next, REQ_GET_OPERATIONS, BlockDevice::request, and strcasecmp.
int block_register | ( | const char * | name, | |
int(*)(int function,...) | request, | |||
void * | handle | |||
) |
Registers a device to the Block Device Manager.
name | name of the device to register; | |
request | address of the request function for the device; | |
handle | opaque identifier for the device to register, may be NULL. |
0 | success; | |
-EEXIST | a device with the same name already exists; | |
-ENOMEM | not enough memory to register the device. |
Definition at line 180 of file block.c.
References EEXIST, ENOMEM, BlockDevice::handle, list, BlockDevice::name, BlockDevice::next, BlockDevice::request, slab, and strcasecmp.
int block_unregister | ( | const char * | name | ) |
Unregisters a device from the Block Device Manager.
name | name of the device to unregister. |
0 | success; | |
-ENOENT | a device with the specified name is not registered; | |
-EBUSY | the reference count of the device is not zero (somebody is using the device). |
Definition at line 204 of file block.c.
References assert, EBUSY, ENOENT, list, BlockDevice::name, BlockDevice::next, REQ_GET_REFERENCES, BlockDevice::request, slab, and strcasecmp.
static int req_get_operations | ( | int(*)(int function,...) | r, | |
int | type, | |||
void ** | operations | |||
) | [inline, static] |
Shortcut to perform a REQ_GET_OPERATIONS request.
Definition at line 354 of file block.h.
References REQ_GET_OPERATIONS.
static int req_get_references | ( | int(*)(int function,...) | r | ) | [inline, static] |
Shortcut to perform a REQ_GET_REFERENCES request.
Definition at line 360 of file block.h.
References REQ_GET_REFERENCES.
static int req_release | ( | int(*)(int function,...) | r, | |
void * | handle | |||
) | [inline, static] |
Shortcut to perform a REQ_RELEASE request.
Definition at line 366 of file block.h.
References REQ_RELEASE.
List list [static] |
Initial value:
{ .begin = NULL, .end = NULL, .size = 0 }
Definition at line 89 of file block.c.
Referenced by block_enumerate(), block_get(), block_register(), and block_unregister().
slabmem_t slab [static] |
Initial value:
{ .pages = NULL, .obj_size = sizeof(BlockDevice), .free_objs = NULL }
Definition at line 97 of file block.c.
Referenced by block_register(), and block_unregister().
struct { ... } symbols[] [static] |
Referenced by block_init().