summaryrefslogtreecommitdiffstats
path: root/cpukit/libblock/include/rtems/blkdev.h
blob: 03b639c73c692f5faca007765e53a64b939f39c4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/**
 * @file rtems/blkdev.h
 * block device driver interface definitions
 */
 
/*
 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
 * Author: Victor V. Vengerov <vvv@oktet.ru>
 *
 * @(#) $Id$
 */

#ifndef _RTEMS_BLKDEV_H
#define _RTEMS_BLKDEV_H

#include <rtems.h>
#include <sys/ioctl.h>

#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