Block device manager and block interface


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:
bitsfieldpurpose
30..22category codeto let the caller know this error comes from a block device facility
21..16sense keybroad description of the error and hint for the action to take
15..0additional error codeto provide more details about the error condition
The category code for block device errors is BLOCK_ERROR_CATEGORY. The sense key is a value defined in enum BlockSenseKeys. The most significant bit (bit 31 on 32-bit machines) must be set to make the error code negative. The error code must be sign-extended if stored in a larger integer type. The BLOCK_ERROR macro is provided to easily format error values.

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 []

Detailed Description

Overview

Block devices are facilities that provide I/O access through equally sized blocks and can contain a file system.

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, ...) 
where the function argument specifies the kind of service requested to the driver, and other parameters may follow depending on the requested function. A block device driver shall support at least the following requests:
mnemonicpurpose
REQ_GET_OPERATIONSquery the driver for a structure of operations
REQ_GET_REFERENCESget the value of the reference count of the driver
REQ_RELEASErelease an object
In addition to the request function, a driver may expose other interfaces that can be queried using the request function.

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 Documentation

#define BLOCK_ERROR ( sense,
code   )     ((int) (BLOCK_ERROR_CATEGORY | (sense) | ((code) & 0xFFFF)))

Formats a block device error value.

Parameters:
sense the sense key identifying the error type;
code a code to provide detailed error information.
Remarks:
Block device drivers should use this macro to format any error code they return.

Definition at line 54 of file block.h.

#define BLOCK_ERROR_CATEGORY   0x80800000

Error category code for block devices.

Remarks:
This macro also sets the most significant bit of the error value to make it negative.

Definition at line 46 of file block.h.

#define BLOCK_GET_SENSE ( value   )     ((value) & 0x003F0000)

Gets the sense key from a block device error value.

Definition at line 58 of file block.h.

#define BLOCK_IS_ERROR ( value   )     (((value) & 0xFFC00000) == BLOCK_ERROR_CATEGORY)

Checks if an error value belongs to the block devices category.

Definition at line 62 of file block.h.

#define BLOCK_OPERATIONS_TYPE   1

Operations type for struct BlockOperations.

Definition at line 170 of file block.h.

#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); 
where type is the type of structure of operations to obtain, and operations is the address of a pointer to receive the structure of operations. The operations pointer may be NULL if the caller is only interested in checking if the specified type is supported. If operations is not NULL, on success the reference count of the driver is incremented.

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); 
The current non-negative reference count of the object is returned.

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); 
where handle is the opaque identifier of the object to release. The reference count of the object must be decreased and the caller must not use any longer the interface used to operate on the object.

Definition at line 343 of file block.h.

Referenced by req_release().


Typedef Documentation

typedef struct BlockDevice BlockDevice

Definition at line 78 of file block.c.

Typedef shortcut for the struct BlockDeviceInfo.

Definition at line 121 of file block.h.

Typedef shortcut for the struct BlockMediumInfo.

Definition at line 140 of file block.h.

Typedef shortcut for the struct BlockOperations.

Definition at line 174 of file block.h.

typedef unsigned long ssize_t

Definition at line 83 of file block.h.


Enumeration Type Documentation

Block device information flags.

This enum provides mnemonics for the flags field of BlockDeviceInfo, that is a combination of the following bits:
0..7partition identifier (0 if not a partition)
8..11device type, useful for drive letter assignment
12device with removable media
13can check for media change (only meaningful if removable)
14device is writable
15..31reserved (zero)

Enumerator:
BLOCK_DEVICE_INFO_PARTID  Bit mask to get the partition identifier.
BLOCK_DEVICE_INFO_TYPEMASK  Bit mask to get the device type.
BLOCK_DEVICE_INFO_TGENERIC  Device type: generic block device.
BLOCK_DEVICE_INFO_TACTIVE  Device type: active or first primary partition.
BLOCK_DEVICE_INFO_TLOGICAL  Device type: logical drive or removable drive.
BLOCK_DEVICE_INFO_TPRIMARY  Device type: other primary partition.
BLOCK_DEVICE_INFO_TFLOPPY  Device type: floppy drive.
BLOCK_DEVICE_INFO_TCDDVD  Device type: CD or DVD drive.
BLOCK_DEVICE_INFO_REMOVABLE  Removable media.
BLOCK_DEVICE_INFO_MEDIACHG  Can check for media change.
BLOCK_DEVICE_INFO_WRITABLE  Writable.

Definition at line 103 of file block.h.

Flags for the read and write block device operations.

Enumerator:
BLOCK_RW_NOCACHE  Transfer data bypassing the device cache, if any.

Definition at line 161 of file block.h.

Sense key values for block device error values.

Enumerator:
BLOCK_SENSE_NONE  Reserved - device specific.
BLOCK_SENSE_RECOVERED  Recovered error.
BLOCK_SENSE_NOTREADY  Not ready.
BLOCK_SENSE_MEDIUM  Medium error.
BLOCK_SENSE_HW  Hardware error.
BLOCK_SENSE_ILLREQ  Illegal request.
BLOCK_SENSE_ATTENTION  Unit attention.
BLOCK_SENSE_DATAPROT  Data protect.
BLOCK_SENSE_BLANK  Blank check.
BLOCK_SENSE_ABORTED  Aborted command.
BLOCK_SENSE_MISCOMPARE  Miscompare.

Definition at line 67 of file block.h.


Function Documentation

const char * block_enumerate ( void **  iterator  ) 

Enumerates the registered block devices.

Parameters:
iterator opaque iterator to store the enumeration progress.
Returns:
The address of the name of the next device, or NULL if there are no more devices.
Remarks:
The pointer pointed by iterator shall be initially set to NULL so that this function knows it has to start to enumerate. Each time this function is called, it returns the name of the next registered device (in registration time order) and updates the pointer pointed by iterator to let the caller continue the enumeration.

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.

Parameters:
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.
Return values:
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.
Remarks:
The Block Device Manager uses the REQ_GET_OPERATIONS request to get the specified type of operations. If this request succeeds the reference count of the device shall be increased.

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.

void block_init ( void   ) 

Definition at line 238 of file block.c.

References address, and symbols.

int block_register ( const char *  name,
int(*)(int function,...)  request,
void *  handle 
)

Registers a device to the Block Device Manager.

Parameters:
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.
Return values:
0 success;
-EEXIST a device with the same name already exists;
-ENOMEM not enough memory to register the device.
Remarks:
The string pointed by name shall not be deallocated while the device is registered. The request function should support at least the REQ_GET_OPERATIONS, REQ_GET_REFERENCES and REQ_RELEASE requests. The handle parameter may be NULL if the block device driver does not need to distinguish between several devices.

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.

Parameters:
name name of the device to unregister.
Return values:
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.


Variable Documentation

void* { ... } address [inherited]

Definition at line 227 of file block.c.

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().

const { ... } name [inherited]

Definition at line 227 of file block.c.

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().


Generated on Sun Aug 31 13:31:31 2008 for FrankenRTOS by  doxygen 1.5.6