/** * @file rtems/blkdev.h * block device driver interface definitions */ /* * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Author: Victor V. Vengerov * * @(#) $Id$ */ #ifndef _RTEMS_BLKDEV_H #define _RTEMS_BLKDEV_H #include #include #ifdef __cplusplus extern "C" { #endif /* * Interface with device drivers Block device looks, initialized and behaves * like traditional RTEMS device driver. Heart of the block device driver is in * BIOREQUEST ioctl. This call puts I/O request to the block device queue, in * priority order, for asynchronous processing. When driver executes request, * req_done function invoked, so callee knows about it. Look for details below. */ /* * Block device block number datatype */ typedef uint32_t rtems_blkdev_bnum; /* Block device request type */ typedef enum rtems_blkdev_request_op { RTEMS_BLKDEV_REQ_READ, /* Read operation */ RTEMS_BLKDEV_REQ_WRITE, /* Write operation */ RTEMS_BLKDEV_CAPABILITIES /* Capabilities request */ } rtems_blkdev_request_op; /** * ATA multi-sector buffer requests only supported. This option * means the cache will only supply multiple buffers that are * inorder so the ATA multi-sector command can be used. This is a * hack to work around the current ATA driver. */ #define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT (1 << 0) /* * @typedef rtems_blkdev_request_cb * * Type for block device request done callback function. * * @param arg Argument supplied in blkdev_request * @param status RTEMS status code for this operation * @param errno errno value to be passed to the user when * status != RTEMS_SUCCESSFUL */ typedef void (* rtems_blkdev_request_cb)(void *arg, rtems_status_code status, int error); /** * @struct rtems_blkdev_sg_buffer * Block device scatter/gather buffer structure */ typedef struct rtems_blkdev_sg_buffer { uint32_t block; /* The block number */ uint32_t length; /* Buffer length */ void *buffer; /* Buffer pointer */ void *user; /* User pointer */ } rtems_blkdev_sg_buffer; /* blkdev_request (Block Device Request) structure is * used to read/write a number of blocks from/to device. */ typedef struct rtems_blkdev_request { /* Block device operation (read or write) */ rtems_blkdev_request_op req; /* Callback function */ rtems_blkdev_request_cb req_done; /* Argument to be passed to callback function*/ void *done_arg; /* Last I/O operation completion status */ rtems_status_code status; /* If status != RTEMS_SUCCESSFUL, this field contains error code */ int error; /* Start block number */ rtems_blkdev_bnum start; /* Number of blocks to be exchanged */ uint32_t count; /* Number of buffers provided */ uint32_t bufnum; /* The task requesting the IO operation. */ rtems_id io_task; /* List of scatter/gather buffers */ rtems_blkdev_sg_buffer bufs[0]; } rtems_blkdev_request; /* Block device IOCTL request codes */ #define RTEMS_BLKIO_REQUEST _IOWR('B', 1, rtems_blkdev_request) #define RTEMS_BLKIO_GETBLKSIZE _IO('B', 2) #define RTEMS_BLKIO_GETSIZE _IO('B', 3) #define RTEMS_BLKIO_SYNCDEV _IO('B', 4) /* Device driver interface conventions suppose that driver may * contain initialize/open/close/read/write/ioctl entry points. These * primitives (except initialize) can be implemented in generic fashion, * based upon supplied block device driver ioctl handler. Every block * device driver should provide initialize entry point, which is register * all block devices and appropriate ioctl handlers. */ #define RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \ rtems_blkdev_generic_open, rtems_blkdev_generic_close, \ rtems_blkdev_generic_read, rtems_blkdev_generic_write, \ rtems_blkdev_generic_ioctl /* blkdev_generic_read -- * Generic block device read primitive. Implemented using block device * buffer management primitives. */ rtems_device_driver rtems_blkdev_generic_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ); /* blkdev_generic_write -- * Generic block device driver write primitive. Implemented using block * device buffer management primitives. */ rtems_device_driver rtems_blkdev_generic_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ); /* blkdev_generic_open -- * Generic block device open primitive. */ rtems_device_driver rtems_blkdev_generic_open( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ); /* blkdev_generic_close -- * Generic block device close primitive. */ rtems_device_driver rtems_blkdev_generic_close( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ); /* blkdev_generic_ioctl -- * Generic block device ioctl primitive. */ rtems_device_driver rtems_blkdev_generic_ioctl( rtems_device_major_number major, rtems_device_minor_number minor, void * arg ); #ifdef __cplusplus } #endif #endif