forked from Imagelibrary/rtems
libblock API update
This commit is contained in:
@@ -1005,7 +1005,7 @@ static int sd_card_disk_block_read( sd_card_driver_entry *e, rtems_blkdev_reques
|
||||
RTEMS_CHECK_SC_RV( sc, "Stop");
|
||||
|
||||
/* Done */
|
||||
r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
|
||||
r->req_done( r->done_arg, RTEMS_SUCCESSFUL);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1020,7 +1020,7 @@ sd_card_disk_block_read_cleanup:
|
||||
sd_card_stop( e);
|
||||
|
||||
/* Done */
|
||||
r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
|
||||
r->req_done( r->done_arg, RTEMS_IO_ERROR);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -1094,7 +1094,7 @@ static int sd_card_disk_block_write( sd_card_driver_entry *e, rtems_blkdev_reque
|
||||
RTEMS_CHECK_SC_RV( sc, "Stop");
|
||||
|
||||
/* Done */
|
||||
r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
|
||||
r->req_done( r->done_arg, RTEMS_SUCCESSFUL);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1113,7 +1113,7 @@ sd_card_disk_block_write_cleanup:
|
||||
sd_card_stop( e);
|
||||
|
||||
/* Done */
|
||||
r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
|
||||
r->req_done( r->done_arg, RTEMS_IO_ERROR);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -546,7 +546,7 @@ ata_process_request(rtems_device_minor_number ctrl_minor)
|
||||
*/
|
||||
static inline void
|
||||
ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
|
||||
rtems_status_code status, int error)
|
||||
rtems_status_code status)
|
||||
{
|
||||
assert(areq);
|
||||
|
||||
@@ -554,7 +554,7 @@ ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
|
||||
ata_printf("ata_request_done: entry\n");
|
||||
#endif
|
||||
|
||||
ATA_EXEC_CALLBACK(areq, status, error);
|
||||
ATA_EXEC_CALLBACK(areq, status);
|
||||
rtems_chain_extract(&areq->link);
|
||||
|
||||
if (!rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
|
||||
@@ -586,14 +586,14 @@ ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
|
||||
static inline void
|
||||
ata_non_data_request_done(ata_req_t *areq,
|
||||
rtems_device_minor_number ctrl_minor,
|
||||
rtems_status_code status, int error)
|
||||
rtems_status_code status, int info)
|
||||
{
|
||||
#if ATA_DEBUG
|
||||
ata_printf("ata_non_data_request_done: entry\n");
|
||||
#endif
|
||||
|
||||
areq->status = status;
|
||||
areq->error = error;
|
||||
areq->info = info;
|
||||
rtems_semaphore_release(areq->sema);
|
||||
}
|
||||
|
||||
@@ -784,7 +784,7 @@ ata_pio_in_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
|
||||
|
||||
if (areq->cnt == 0)
|
||||
{
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
|
||||
}
|
||||
else if (IDE_Controller_Table[ctrl_minor].int_driven == false)
|
||||
{
|
||||
@@ -822,7 +822,7 @@ ata_pio_out_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
|
||||
|
||||
if (areq->cnt == 0)
|
||||
{
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -909,8 +909,7 @@ ata_queue_task(rtems_task_argument arg)
|
||||
* status and start processing of the next request in the
|
||||
* controller queue
|
||||
*/
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL,
|
||||
msg.error);
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
|
||||
break;
|
||||
|
||||
case ATA_MSG_ERROR_EVT:
|
||||
@@ -919,8 +918,7 @@ ata_queue_task(rtems_task_argument arg)
|
||||
* status and start processing of the next request in the
|
||||
* controller queue
|
||||
*/
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED,
|
||||
msg.error);
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
|
||||
break;
|
||||
|
||||
case ATA_MSG_GEN_EVT:
|
||||
@@ -948,8 +946,7 @@ ata_queue_task(rtems_task_argument arg)
|
||||
RTEMS_UNSATISFIED,
|
||||
RTEMS_IO_ERROR);
|
||||
else
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED,
|
||||
RTEMS_IO_ERROR);
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -977,9 +974,7 @@ ata_queue_task(rtems_task_argument arg)
|
||||
#if ATA_DEBUG
|
||||
ata_printf("ata_queue_task: non-supported command type\n");
|
||||
#endif
|
||||
ata_request_done(areq, ctrl_minor,
|
||||
RTEMS_UNSATISFIED,
|
||||
RTEMS_NOT_IMPLEMENTED);
|
||||
ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1315,19 +1310,19 @@ rtems_ata_initialize(rtems_device_major_number major,
|
||||
if (breq.req.status == RTEMS_SUCCESSFUL)
|
||||
{
|
||||
/* disassemble returned diagnostic codes */
|
||||
if (breq.req.error == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
|
||||
if (areq.info == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
|
||||
{
|
||||
printk("ATA: ctrl:%d: primary, secondary\n", ctrl_minor);
|
||||
ATA_DEV_INFO(ctrl_minor,0).present = true;
|
||||
ATA_DEV_INFO(ctrl_minor,1).present = true;
|
||||
}
|
||||
else if (breq.req.error == ATA_DEV0_PASSED_DEV1_FAILED)
|
||||
else if (areq.info == ATA_DEV0_PASSED_DEV1_FAILED)
|
||||
{
|
||||
printk("ATA: ctrl:%d: primary\n", ctrl_minor);
|
||||
ATA_DEV_INFO(ctrl_minor,0).present = true;
|
||||
ATA_DEV_INFO(ctrl_minor,1).present = false;
|
||||
}
|
||||
else if (breq.req.error < ATA_DEV1_PASSED_DEV0_FAILED)
|
||||
else if (areq.info < ATA_DEV1_PASSED_DEV0_FAILED)
|
||||
{
|
||||
printk("ATA: ctrl:%d: secondary\n", ctrl_minor);
|
||||
ATA_DEV_INFO(ctrl_minor,0).present = false;
|
||||
@@ -1521,7 +1516,6 @@ ata_process_request_on_init_phase(rtems_device_minor_number ctrl_minor,
|
||||
if ( 10000 == retries ) {
|
||||
/* probably no drive connected */
|
||||
areq->breq->status = RTEMS_UNSATISFIED;
|
||||
areq->breq->error = RTEMS_IO_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1545,8 +1539,7 @@ ata_process_request_on_init_phase(rtems_device_minor_number ctrl_minor,
|
||||
|
||||
if (val & IDE_REGISTER_STATUS_ERR)
|
||||
{
|
||||
areq->breq->status = RTEMS_UNSATISFIED;
|
||||
areq->breq->error = RTEMS_IO_ERROR;
|
||||
areq->breq->status = RTEMS_IO_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1579,15 +1572,14 @@ ata_process_request_on_init_phase(rtems_device_minor_number ctrl_minor,
|
||||
|
||||
case ATA_COMMAND_TYPE_NON_DATA:
|
||||
areq->breq->status = RTEMS_SUCCESSFUL;
|
||||
areq->breq->error = val1;
|
||||
areq->info = val1;
|
||||
break;
|
||||
|
||||
default:
|
||||
#if ATA_DEBUG
|
||||
ata_printf("ata_queue_task: non-supported command type\n");
|
||||
#endif
|
||||
areq->breq->status = RTEMS_UNSATISFIED;
|
||||
areq->breq->error = RTEMS_NOT_IMPLEMENTED;
|
||||
areq->breq->status = RTEMS_IO_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,14 +210,14 @@ typedef struct ata_req_s {
|
||||
* processing of the ata request is required
|
||||
*/
|
||||
rtems_status_code status; /* status of ata request processing */
|
||||
int error; /* device error code */
|
||||
int info; /* device info code */
|
||||
} ata_req_t;
|
||||
|
||||
/* call callback provided by block device request if it is defined */
|
||||
#define ATA_EXEC_CALLBACK(areq, status, error) \
|
||||
#define ATA_EXEC_CALLBACK(areq, status) \
|
||||
do {\
|
||||
if (((areq)->breq != NULL) && ((areq)->breq->req_done != NULL)) \
|
||||
(areq)->breq->req_done((areq)->breq->done_arg, status, error); \
|
||||
(areq)->breq->req_done((areq)->breq->done_arg, status); \
|
||||
} while (0)
|
||||
|
||||
/* ATA RTEMS driver events types */
|
||||
|
||||
@@ -25,6 +25,7 @@ if HAS_NETWORKING
|
||||
SRCS += ../libchip/libnetchip.a
|
||||
endif
|
||||
SRCS += ../libchip/libi2cio.a
|
||||
SRCS += ../libchip/libdisplay.a
|
||||
|
||||
if HAS_MP
|
||||
SRCS += ../libchip/shmdr.rel
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
2010-01-18 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||
|
||||
* libblock/include/rtems/bdbuf.h: Documentation. Renamed
|
||||
RTEMS_BDBUF_STATE_EMPTY in RTEMS_BDBUF_STATE_FREE. Renamed
|
||||
RTEMS_BDBUF_STATE_FRESH in RTEMS_BDBUF_STATE_EMPTY. Renamed
|
||||
RTEMS_BDBUF_STATE_ACCESS in RTEMS_BDBUF_STATE_ACCESS_CACHED. New
|
||||
state RTEMS_BDBUF_STATE_ACCESS_EMPTY. Removed error field from
|
||||
rtems_bdbuf_buffer.
|
||||
* libblock/include/rtems/blkdev.h: Documentation. Removed error
|
||||
field from block device IO control.
|
||||
* libblock/src/bdbuf.c: Update for block device API change. New block
|
||||
device driver error policies. A transfer error or a write to a
|
||||
deleted disk will invalidate the block data now. See test
|
||||
"libtests/block09". A get and release sequence will no longer trigger
|
||||
a disk write.
|
||||
* libblock/src/flashdisk.c, libblock/src/nvdisk.c,
|
||||
libblock/src/ramdisk-driver.c: Update for block device API change.
|
||||
|
||||
2010-01-18 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
Coverity Id 27
|
||||
|
||||
@@ -80,11 +80,12 @@ extern "C" {
|
||||
* @dot
|
||||
* digraph state {
|
||||
* size="16,8";
|
||||
* e [label="EMPTY",style="filled",fillcolor="aquamarine"];
|
||||
* f [label="FRESH",style="filled",fillcolor="seagreen"];
|
||||
* f [label="FREE",style="filled",fillcolor="aquamarine"];
|
||||
* e [label="EMPTY",style="filled",fillcolor="seagreen"];
|
||||
* c [label="CACHED",style="filled",fillcolor="chartreuse"];
|
||||
* a [label="ACCESS",style="filled",fillcolor="royalblue"];
|
||||
* ac [label="ACCESS CACHED",style="filled",fillcolor="royalblue"];
|
||||
* am [label="ACCESS MODIFIED",style="filled",fillcolor="royalblue"];
|
||||
* ae [label="ACCESS EMPTY",style="filled",fillcolor="royalblue"];
|
||||
* t [label="TRANSFER",style="filled",fillcolor="red"];
|
||||
* s [label="SYNC",style="filled",fillcolor="red"];
|
||||
* m [label="MODIFIED",style="filled",fillcolor="gold"];
|
||||
@@ -93,22 +94,28 @@ extern "C" {
|
||||
* legend_transfer [label="Transfer Wake-Up",fontcolor="red",shape="none"];
|
||||
* legend_access [label="Access Wake-Up",fontcolor="royalblue",shape="none"];
|
||||
*
|
||||
* i -> e [label="Init"];
|
||||
* e -> f [label="Buffer Recycle"];
|
||||
* f -> a [label="Get"];
|
||||
* f -> t [label="Read\nRead Ahead"];
|
||||
* c -> e [label="Reallocate\nBlock Size Changed"];
|
||||
* c -> a [label="Get\nRead"];
|
||||
* c -> f [label="Buffer Recycle"];
|
||||
* t -> c [label="Write Transfer Done\nRead Transfer Done\nRead Ahead Transfer Done",color="red",fontcolor="red"];
|
||||
* i -> f [label="Init"];
|
||||
* f -> e [label="Buffer Recycle"];
|
||||
* e -> ae [label="Get"];
|
||||
* e -> t [label="Read\nRead Ahead"];
|
||||
* c -> f [label="Reallocate\nBlock Size Changed"];
|
||||
* c -> ac [label="Get\nRead"];
|
||||
* c -> e [label="Buffer Recycle"];
|
||||
* t -> c [label="Transfer Done",color="red",fontcolor="red"];
|
||||
* t -> e [label="Transfer Error With Waiter",color="red",fontcolor="red"];
|
||||
* t -> f [label="Transfer Error Without Waiter",color="red",fontcolor="red"];
|
||||
* m -> t [label="Swapout"];
|
||||
* m -> s [label="Block Size Changed"];
|
||||
* m -> am [label="Get\nRead"];
|
||||
* a -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
|
||||
* a -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
|
||||
* a -> c [label="Release",color="royalblue",fontcolor="royalblue"];
|
||||
* ac -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
|
||||
* ac -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
|
||||
* ac -> c [label="Release",color="royalblue",fontcolor="royalblue"];
|
||||
* am -> m [label="Release\nRelease Modified",color="royalblue",fontcolor="royalblue"];
|
||||
* am -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
|
||||
* ae -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
|
||||
* ae -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
|
||||
* ae -> e [label="Release With Waiter",color="royalblue",fontcolor="royalblue"];
|
||||
* ae -> f [label="Release Without Waiter",color="royalblue",fontcolor="royalblue"];
|
||||
* s -> t [label="Swapout"];
|
||||
* }
|
||||
* @enddot
|
||||
@@ -164,69 +171,95 @@ extern "C" {
|
||||
*
|
||||
* The state has several implications. Depending on the state a buffer can be
|
||||
* in the AVL tree, in a list, in use by an entity and a group user or not.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th>State</th><th>Valid Data</th><th>AVL Tree</th>
|
||||
* <th>LRU List</th><th>Modified List</th><th>Synchronization List</th>
|
||||
* <th>Group User</th><th>External User</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>FREE</td><td></td><td></td>
|
||||
* <td>X</td><td></td><td></td><td></td><td></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>EMPTY</td><td></td><td>X</td>
|
||||
* <td>X</td><td></td><td></td><td></td><td></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>CACHED</td><td>X</td><td>X</td>
|
||||
* <td>X</td><td></td><td></td><td></td><td></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>ACCESS_CACHED</td><td>X</td><td>X</td>
|
||||
* <td></td><td></td><td></td><td>X</td><td>X</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>ACCESS_MODIFIED</td><td>X</td><td>X</td>
|
||||
* <td></td><td></td><td></td><td>X</td><td>X</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>ACCESS_EMPTY</td><td></td><td>X</td>
|
||||
* <td></td><td></td><td></td><td>X</td><td>X</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>MODIFIED</td><td>X</td><td>X</td>
|
||||
* <td></td><td>X</td><td></td><td>X</td><td></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>SYNC</td><td>X</td><td>X</td>
|
||||
* <td></td><td></td><td>X</td><td>X</td><td></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>TRANSFER</td><td>X</td><td>X</td>
|
||||
* <td></td><td></td><td></td><td>X</td><td>X</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* @brief Empty.
|
||||
*
|
||||
* Not in the AVL tree. Not in a list. Not in use. Not a user of its
|
||||
* group.
|
||||
* @brief Free.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_EMPTY = 0,
|
||||
RTEMS_BDBUF_STATE_FREE = 0,
|
||||
|
||||
/**
|
||||
* @brief Fresh.
|
||||
*
|
||||
* In the AVL tree. Not in a list. In use by a get or read request. A user
|
||||
* of its group.
|
||||
* @brief Empty.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_FRESH,
|
||||
RTEMS_BDBUF_STATE_EMPTY,
|
||||
|
||||
/**
|
||||
* @brief Cached.
|
||||
*
|
||||
* In the AVL tree. In the LRU list. Not in use. Not a user of its group.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_CACHED,
|
||||
|
||||
/**
|
||||
* @brief Accessed by upper layer.
|
||||
*
|
||||
* In the AVL tree. Not in a list. In use by an upper layer. A user of its
|
||||
* group.
|
||||
* @brief Accessed by upper layer with cached data.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_ACCESS,
|
||||
RTEMS_BDBUF_STATE_ACCESS_CACHED,
|
||||
|
||||
/**
|
||||
* @brief Accessed and modified by upper layer.
|
||||
*
|
||||
* In the AVL tree. Not in a list. In use by an upper layer. A user of its
|
||||
* group.
|
||||
* @brief Accessed by upper layer with modified data.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_ACCESS_MODIFIED,
|
||||
|
||||
/**
|
||||
* @brief Accessed by upper layer with invalid data.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_ACCESS_EMPTY,
|
||||
|
||||
/**
|
||||
* @brief Modified by upper layer.
|
||||
*
|
||||
* In the AVL tree. In the modified list. In use by swapout mechanic. A
|
||||
* user of its group.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_MODIFIED,
|
||||
|
||||
/**
|
||||
* @brief Scheduled for synchronization.
|
||||
*
|
||||
* In the AVL tree. In the sync list. In use by swapout mechanic. A user
|
||||
* of its group.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_SYNC,
|
||||
|
||||
/**
|
||||
* @brief In transfer by block device driver.
|
||||
*
|
||||
* In the AVL tree. Not in a list. In use by the block device driver. A
|
||||
* user of its group.
|
||||
*/
|
||||
RTEMS_BDBUF_STATE_TRANSFER
|
||||
} rtems_bdbuf_buf_state;
|
||||
@@ -260,8 +293,6 @@ typedef struct rtems_bdbuf_buffer
|
||||
rtems_blkdev_bnum block; /**< block number on the device */
|
||||
|
||||
unsigned char* buffer; /**< Pointer to the buffer memory area */
|
||||
int error; /**< If not 0 indicate an error value (errno)
|
||||
* which can be used by user later */
|
||||
|
||||
volatile rtems_bdbuf_buf_state state; /**< State of the buffer. */
|
||||
|
||||
|
||||
@@ -59,16 +59,17 @@ typedef enum rtems_blkdev_request_op {
|
||||
#define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT (1 << 0)
|
||||
|
||||
/**
|
||||
* Type for block device request done callback function.
|
||||
* @brief Block device request done callback function type.
|
||||
*
|
||||
* @param arg Argument supplied in @ref rtems_blkdev_request.
|
||||
* @param status Status code for this operation.
|
||||
* @param errno The @c errno value to be passed to the user when status is not
|
||||
* equal to @c RTEMS_SUCCESSFUL.
|
||||
* The first parameter @a arg must be the argument provided by the block device
|
||||
* request structure @ref rtems_blkdev_request.
|
||||
*
|
||||
* The second parameter @a status should contain the status of the operation:
|
||||
* - @c RTEMS_SUCCESSFUL Operation was successful.
|
||||
* - @c RTEMS_IO_ERROR Some sort of input or output error.
|
||||
* - @c RTEMS_UNSATISFIED Media no more present.
|
||||
*/
|
||||
typedef void (* rtems_blkdev_request_cb)(void *arg,
|
||||
rtems_status_code status,
|
||||
int error);
|
||||
typedef void (*rtems_blkdev_request_cb)(void *arg, rtems_status_code status);
|
||||
|
||||
/**
|
||||
* Block device scatter or gather buffer structure.
|
||||
@@ -127,12 +128,6 @@ typedef struct rtems_blkdev_request {
|
||||
*/
|
||||
rtems_status_code status;
|
||||
|
||||
/**
|
||||
* If @c status is not equal to @c RTEMS_SUCCESSFUL, this field contains the
|
||||
* error number.
|
||||
*/
|
||||
int error;
|
||||
|
||||
/**
|
||||
* Number of blocks for this request.
|
||||
*/
|
||||
|
||||
@@ -123,7 +123,9 @@ typedef struct rtems_bdbuf_cache
|
||||
rtems_chain_control modified; /**< Modified buffers list */
|
||||
rtems_chain_control sync; /**< Buffers to sync list */
|
||||
|
||||
rtems_bdbuf_waiters access_waiters; /**< Wait for a buffer in ACCESS
|
||||
rtems_bdbuf_waiters access_waiters; /**< Wait for a buffer in
|
||||
* ACCESS_CACHED, ACCESS_MODIFIED or
|
||||
* ACCESS_EMPTY
|
||||
* state. */
|
||||
rtems_bdbuf_waiters transfer_waiters; /**< Wait for a buffer in TRANSFER
|
||||
* state. */
|
||||
@@ -142,7 +144,6 @@ typedef struct rtems_bdbuf_cache
|
||||
#define RTEMS_BLKDEV_FATAL_ERROR(n) \
|
||||
(((uint32_t)'B' << 24) | ((uint32_t)(n) & (uint32_t)0x00FFFFFF))
|
||||
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_3 RTEMS_BLKDEV_FATAL_ERROR(1)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_4 RTEMS_BLKDEV_FATAL_ERROR(2)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_5 RTEMS_BLKDEV_FATAL_ERROR(3)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_6 RTEMS_BLKDEV_FATAL_ERROR(4)
|
||||
@@ -150,7 +151,7 @@ typedef struct rtems_bdbuf_cache
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_8 RTEMS_BLKDEV_FATAL_ERROR(6)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_9 RTEMS_BLKDEV_FATAL_ERROR(7)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_10 RTEMS_BLKDEV_FATAL_ERROR(8)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_CACHE_RM RTEMS_BLKDEV_FATAL_ERROR(9)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_TREE_RM RTEMS_BLKDEV_FATAL_ERROR(9)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_SWAPOUT RTEMS_BLKDEV_FATAL_ERROR(10)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_SYNC_LOCK RTEMS_BLKDEV_FATAL_ERROR(11)
|
||||
#define RTEMS_BLKDEV_FATAL_BDBUF_SYNC_UNLOCK RTEMS_BLKDEV_FATAL_ERROR(12)
|
||||
@@ -1058,11 +1059,11 @@ rtems_bdbuf_add_to_modified_list_after_access (rtems_bdbuf_buffer *bd)
|
||||
* only a specific period of time even if still changing and get onto disk
|
||||
* and letting the file system try and recover this position if it can.
|
||||
*/
|
||||
if (bd->state == RTEMS_BDBUF_STATE_ACCESS)
|
||||
if (bd->state == RTEMS_BDBUF_STATE_ACCESS_CACHED
|
||||
|| bd->state == RTEMS_BDBUF_STATE_ACCESS_EMPTY)
|
||||
bd->hold_timer = bdbuf_config.swap_block_hold;
|
||||
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_MODIFIED);
|
||||
|
||||
rtems_chain_append (&bdbuf_cache.modified, &bd->link);
|
||||
|
||||
if (bd->waiters)
|
||||
@@ -1075,9 +1076,7 @@ static void
|
||||
rtems_bdbuf_add_to_lru_list_after_access (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
|
||||
|
||||
rtems_chain_append (&bdbuf_cache.lru, &bd->link);
|
||||
|
||||
rtems_bdbuf_group_release (bd);
|
||||
|
||||
if (bd->waiters)
|
||||
@@ -1122,15 +1121,21 @@ rtems_bdbuf_bds_per_group (size_t size)
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bdbuf_remove_from_cache_and_lru_list (rtems_bdbuf_buffer *bd)
|
||||
rtems_bdbuf_remove_from_tree (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
|
||||
rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_TREE_RM);
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bdbuf_remove_from_tree_and_lru_list (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_FREE:
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_CACHED:
|
||||
if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
|
||||
rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_3);
|
||||
rtems_bdbuf_remove_from_tree (bd);
|
||||
break;
|
||||
default:
|
||||
rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_10);
|
||||
@@ -1139,11 +1144,37 @@ rtems_bdbuf_remove_from_cache_and_lru_list (rtems_bdbuf_buffer *bd)
|
||||
rtems_chain_extract (&bd->link);
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bdbuf_make_free_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_FREE);
|
||||
rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bdbuf_make_empty_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
|
||||
rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
|
||||
rtems_chain_append (&bdbuf_cache.lru, &bd->link);
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bdbuf_release_empty_buffer (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
rtems_bdbuf_group_release (bd);
|
||||
|
||||
if (bd->waiters)
|
||||
{
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
|
||||
rtems_chain_append (&bdbuf_cache.lru, &bd->link);
|
||||
rtems_bdbuf_wake (&bdbuf_cache.access_waiters);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_bdbuf_remove_from_tree (bd);
|
||||
rtems_bdbuf_make_free_and_add_to_lru_list (bd);
|
||||
rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1172,7 +1203,7 @@ rtems_bdbuf_group_realloc (rtems_bdbuf_group* group, size_t new_bds_per_group)
|
||||
for (b = 0, bd = group->bdbuf;
|
||||
b < group->bds_per_group;
|
||||
b++, bd += bufs_per_bd)
|
||||
rtems_bdbuf_remove_from_cache_and_lru_list (bd);
|
||||
rtems_bdbuf_remove_from_tree_and_lru_list (bd);
|
||||
|
||||
group->bds_per_group = new_bds_per_group;
|
||||
bufs_per_bd = bdbuf_cache.max_bds_per_group / new_bds_per_group;
|
||||
@@ -1180,7 +1211,7 @@ rtems_bdbuf_group_realloc (rtems_bdbuf_group* group, size_t new_bds_per_group)
|
||||
for (b = 1, bd = group->bdbuf + bufs_per_bd;
|
||||
b < group->bds_per_group;
|
||||
b++, bd += bufs_per_bd)
|
||||
rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
|
||||
rtems_bdbuf_make_free_and_add_to_lru_list (bd);
|
||||
|
||||
if (b > 1)
|
||||
rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
|
||||
@@ -1193,17 +1224,16 @@ rtems_bdbuf_recycle_buffer (rtems_bdbuf_buffer *bd,
|
||||
dev_t dev,
|
||||
rtems_blkdev_bnum block)
|
||||
{
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_FRESH);
|
||||
|
||||
bd->dev = dev;
|
||||
bd->block = block;
|
||||
bd->avl.left = NULL;
|
||||
bd->avl.right = NULL;
|
||||
bd->error = 0;
|
||||
bd->waiters = 0;
|
||||
|
||||
if (rtems_bdbuf_avl_insert (&bdbuf_cache.tree, bd) != 0)
|
||||
rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_RECYCLE);
|
||||
|
||||
rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
|
||||
}
|
||||
|
||||
static rtems_bdbuf_buffer *
|
||||
@@ -1231,7 +1261,7 @@ rtems_bdbuf_get_buffer_from_lru_list (dev_t dev,
|
||||
{
|
||||
if (bd->group->bds_per_group == bds_per_group)
|
||||
{
|
||||
rtems_bdbuf_remove_from_cache_and_lru_list (bd);
|
||||
rtems_bdbuf_remove_from_tree_and_lru_list (bd);
|
||||
|
||||
recycle_bd = bd;
|
||||
}
|
||||
@@ -1489,16 +1519,16 @@ rtems_bdbuf_wait_for_access (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_FRESH:
|
||||
return;
|
||||
case RTEMS_BDBUF_STATE_MODIFIED:
|
||||
rtems_bdbuf_group_release (bd);
|
||||
/* Fall through */
|
||||
case RTEMS_BDBUF_STATE_CACHED:
|
||||
case RTEMS_BDBUF_STATE_EMPTY:
|
||||
rtems_chain_extract (&bd->link);
|
||||
return;
|
||||
case RTEMS_BDBUF_STATE_ACCESS_CACHED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS:
|
||||
rtems_bdbuf_wait (bd, &bdbuf_cache.access_waiters);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_TRANSFER:
|
||||
@@ -1533,12 +1563,13 @@ rtems_bdbuf_wait_for_recycle (rtems_bdbuf_buffer *bd)
|
||||
{
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_FREE:
|
||||
return true;
|
||||
case RTEMS_BDBUF_STATE_MODIFIED:
|
||||
rtems_bdbuf_request_sync_for_modified_buffer (bd);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_CACHED:
|
||||
case RTEMS_BDBUF_STATE_EMPTY:
|
||||
if (bd->waiters == 0)
|
||||
return true;
|
||||
else
|
||||
@@ -1552,8 +1583,9 @@ rtems_bdbuf_wait_for_recycle (rtems_bdbuf_buffer *bd)
|
||||
rtems_bdbuf_anonymous_wait (&bdbuf_cache.buffer_waiters);
|
||||
return false;
|
||||
}
|
||||
case RTEMS_BDBUF_STATE_ACCESS_CACHED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS:
|
||||
rtems_bdbuf_wait (bd, &bdbuf_cache.access_waiters);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_TRANSFER:
|
||||
@@ -1564,8 +1596,6 @@ rtems_bdbuf_wait_for_recycle (rtems_bdbuf_buffer *bd)
|
||||
rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_8);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1576,8 +1606,10 @@ rtems_bdbuf_wait_for_sync_done (rtems_bdbuf_buffer *bd)
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_CACHED:
|
||||
case RTEMS_BDBUF_STATE_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_MODIFIED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_CACHED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
|
||||
return;
|
||||
case RTEMS_BDBUF_STATE_SYNC:
|
||||
@@ -1642,8 +1674,8 @@ rtems_bdbuf_get_buffer_for_access (dev_t dev,
|
||||
{
|
||||
if (rtems_bdbuf_wait_for_recycle (bd))
|
||||
{
|
||||
rtems_bdbuf_remove_from_cache_and_lru_list (bd);
|
||||
rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
|
||||
rtems_bdbuf_remove_from_tree_and_lru_list (bd);
|
||||
rtems_bdbuf_make_free_and_add_to_lru_list (bd);
|
||||
rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
|
||||
}
|
||||
bd = NULL;
|
||||
@@ -1760,8 +1792,10 @@ rtems_bdbuf_get (dev_t dev,
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_CACHED:
|
||||
case RTEMS_BDBUF_STATE_FRESH:
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS);
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_CACHED);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_EMPTY:
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_EMPTY);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_MODIFIED:
|
||||
/*
|
||||
@@ -1801,24 +1835,23 @@ rtems_bdbuf_get (dev_t dev,
|
||||
* structure (in this case - pointer to the appropriate
|
||||
* block device request structure).
|
||||
* @param status I/O completion status
|
||||
* @param error errno error code if status != RTEMS_SUCCESSFUL
|
||||
*/
|
||||
static void
|
||||
rtems_bdbuf_read_done (void* arg, rtems_status_code status, int error)
|
||||
rtems_bdbuf_transfer_done (void* arg, rtems_status_code status)
|
||||
{
|
||||
rtems_blkdev_request* req = (rtems_blkdev_request*) arg;
|
||||
|
||||
req->error = error;
|
||||
req->status = status;
|
||||
|
||||
rtems_event_send (req->io_task, RTEMS_BDBUF_TRANSFER_SYNC);
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bdbuf_create_read_request (rtems_blkdev_request *req,
|
||||
rtems_disk_device *dd,
|
||||
rtems_bdbuf_create_read_request (const rtems_disk_device *dd,
|
||||
rtems_blkdev_bnum media_block,
|
||||
size_t bds_per_group)
|
||||
size_t bds_per_group,
|
||||
rtems_blkdev_request *req,
|
||||
rtems_bdbuf_buffer **bd_ptr)
|
||||
{
|
||||
rtems_bdbuf_buffer *bd = NULL;
|
||||
rtems_blkdev_bnum media_block_end = dd->start + dd->size;
|
||||
@@ -1831,10 +1864,17 @@ rtems_bdbuf_create_read_request (rtems_blkdev_request *req,
|
||||
if (media_block_end - media_block < transfer_count)
|
||||
transfer_count = media_block_end - media_block;
|
||||
|
||||
req->req = RTEMS_BLKDEV_REQ_READ;
|
||||
req->req_done = rtems_bdbuf_transfer_done;
|
||||
req->done_arg = req;
|
||||
req->io_task = rtems_task_self ();
|
||||
req->status = RTEMS_RESOURCE_IN_USE;
|
||||
req->bufnum = 0;
|
||||
|
||||
bd = rtems_bdbuf_get_buffer_for_access (dev, media_block, bds_per_group);
|
||||
|
||||
*bd_ptr = bd;
|
||||
|
||||
req->bufs [0].user = bd;
|
||||
req->bufs [0].block = media_block;
|
||||
req->bufs [0].length = block_size;
|
||||
@@ -1848,7 +1888,7 @@ rtems_bdbuf_create_read_request (rtems_blkdev_request *req,
|
||||
case RTEMS_BDBUF_STATE_CACHED:
|
||||
case RTEMS_BDBUF_STATE_MODIFIED:
|
||||
return;
|
||||
case RTEMS_BDBUF_STATE_FRESH:
|
||||
case RTEMS_BDBUF_STATE_EMPTY:
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_TRANSFER);
|
||||
break;
|
||||
default:
|
||||
@@ -1882,86 +1922,61 @@ rtems_bdbuf_create_read_request (rtems_blkdev_request *req,
|
||||
req->bufnum = transfer_index;
|
||||
}
|
||||
|
||||
static rtems_bdbuf_buffer *
|
||||
rtems_bdbuf_execute_read_request (rtems_blkdev_request *req,
|
||||
rtems_disk_device *dd)
|
||||
static rtems_status_code
|
||||
rtems_bdbuf_execute_transfer_request (const rtems_disk_device *dd,
|
||||
rtems_blkdev_request *req,
|
||||
bool cache_locked)
|
||||
{
|
||||
if (req->bufnum)
|
||||
{
|
||||
/*
|
||||
* Unlock the cache. We have the buffer for the block and it will be in the
|
||||
* access or transfer state. We may also have a number of read ahead blocks
|
||||
* if we need to transfer data. At this point any other threads can gain
|
||||
* access to the cache and if they are after any of the buffers we have
|
||||
* they will block and be woken when the buffer is returned to the cache.
|
||||
*
|
||||
* If a transfer is needed the I/O operation will occur with pre-emption
|
||||
* enabled and the cache unlocked. This is a change to the previous version
|
||||
* of the bdbuf code.
|
||||
*/
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
int result = 0;
|
||||
int error = 0;
|
||||
uint32_t transfer_index = 0;
|
||||
bool wake_transfer = false;
|
||||
bool wake_buffer = false;
|
||||
|
||||
if (cache_locked)
|
||||
rtems_bdbuf_unlock_cache ();
|
||||
|
||||
req->req = RTEMS_BLKDEV_REQ_READ;
|
||||
req->req_done = rtems_bdbuf_read_done;
|
||||
req->done_arg = req;
|
||||
req->io_task = rtems_task_self ();
|
||||
req->status = RTEMS_RESOURCE_IN_USE;
|
||||
req->error = 0;
|
||||
|
||||
result = dd->ioctl (dd->phys_dev, RTEMS_BLKIO_REQUEST, req);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
rtems_bdbuf_wait_for_event (RTEMS_BDBUF_TRANSFER_SYNC);
|
||||
error = req->error;
|
||||
sc = req->status;
|
||||
}
|
||||
else
|
||||
error = errno;
|
||||
sc = RTEMS_IO_ERROR;
|
||||
|
||||
rtems_bdbuf_lock_cache ();
|
||||
|
||||
for (transfer_index = 0; transfer_index < req->bufnum; ++transfer_index)
|
||||
{
|
||||
rtems_bdbuf_buffer *bd = req->bufs [transfer_index].user;
|
||||
bool waiters = bd->waiters;
|
||||
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
|
||||
bool waiters = bd->waiters > 0;
|
||||
|
||||
if (waiters)
|
||||
wake_transfer = true;
|
||||
|
||||
bd->error = error;
|
||||
|
||||
if (rtems_bdbuf_tracer)
|
||||
rtems_bdbuf_show_users ("read-ahead", bd);
|
||||
|
||||
if (transfer_index > 0)
|
||||
{
|
||||
/*
|
||||
* This is a read ahead buffer.
|
||||
*/
|
||||
else
|
||||
wake_buffer = true;
|
||||
|
||||
rtems_bdbuf_group_release (bd);
|
||||
|
||||
if (!waiters)
|
||||
wake_buffer = true;
|
||||
|
||||
if (error == 0 || waiters)
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
{
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
|
||||
rtems_chain_append (&bdbuf_cache.lru, &bd->link);
|
||||
}
|
||||
else if (waiters)
|
||||
{
|
||||
rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
|
||||
rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
|
||||
if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
|
||||
rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_CACHE_RM);
|
||||
}
|
||||
rtems_bdbuf_remove_from_tree (bd);
|
||||
rtems_bdbuf_make_free_and_add_to_lru_list (bd);
|
||||
}
|
||||
|
||||
if (rtems_bdbuf_tracer)
|
||||
rtems_bdbuf_show_users ("transfer", bd);
|
||||
}
|
||||
|
||||
if (wake_transfer)
|
||||
@@ -1969,9 +1984,14 @@ rtems_bdbuf_execute_read_request (rtems_blkdev_request *req,
|
||||
|
||||
if (wake_buffer)
|
||||
rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
|
||||
}
|
||||
|
||||
return req->bufs [0].user;
|
||||
if (!cache_locked)
|
||||
rtems_bdbuf_unlock_cache ();
|
||||
|
||||
if (sc == RTEMS_SUCCESSFUL || sc == RTEMS_UNSATISFIED)
|
||||
return sc;
|
||||
else
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
rtems_status_code
|
||||
@@ -1981,8 +2001,8 @@ rtems_bdbuf_read (dev_t dev,
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
rtems_disk_device *dd = NULL;
|
||||
rtems_bdbuf_buffer *bd = NULL;
|
||||
rtems_blkdev_request *req = NULL;
|
||||
rtems_bdbuf_buffer *bd = NULL;
|
||||
rtems_blkdev_bnum media_block = 0;
|
||||
size_t bds_per_group = 0;
|
||||
|
||||
@@ -2004,14 +2024,24 @@ rtems_bdbuf_read (dev_t dev,
|
||||
media_block + dd->start, block, (unsigned) dev);
|
||||
|
||||
rtems_bdbuf_lock_cache ();
|
||||
rtems_bdbuf_create_read_request (req, dd, media_block, bds_per_group);
|
||||
rtems_bdbuf_create_read_request (dd, media_block, bds_per_group, req, &bd);
|
||||
|
||||
bd = rtems_bdbuf_execute_read_request (req, dd);
|
||||
if (req->bufnum > 0)
|
||||
{
|
||||
sc = rtems_bdbuf_execute_transfer_request (dd, req, true);
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
{
|
||||
rtems_chain_extract (&bd->link);
|
||||
rtems_bdbuf_group_obtain (bd);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc == RTEMS_SUCCESSFUL)
|
||||
{
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_CACHED:
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS);
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_CACHED);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_MODIFIED:
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_MODIFIED);
|
||||
@@ -2027,12 +2057,15 @@ rtems_bdbuf_read (dev_t dev,
|
||||
rtems_bdbuf_show_usage ();
|
||||
}
|
||||
|
||||
*bd_ptr = bd;
|
||||
}
|
||||
else
|
||||
*bd_ptr = NULL;
|
||||
|
||||
rtems_bdbuf_unlock_cache ();
|
||||
rtems_bdbuf_release_disk (dd);
|
||||
|
||||
*bd_ptr = bd;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
return sc;
|
||||
}
|
||||
|
||||
static rtems_status_code
|
||||
@@ -2063,9 +2096,12 @@ rtems_bdbuf_release (rtems_bdbuf_buffer *bd)
|
||||
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_ACCESS:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_CACHED:
|
||||
rtems_bdbuf_add_to_lru_list_after_access (bd);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
|
||||
rtems_bdbuf_release_empty_buffer (bd);
|
||||
break;
|
||||
case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
|
||||
rtems_bdbuf_add_to_modified_list_after_access (bd);
|
||||
break;
|
||||
@@ -2093,7 +2129,8 @@ rtems_bdbuf_release_modified (rtems_bdbuf_buffer *bd)
|
||||
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_ACCESS:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_CACHED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
|
||||
rtems_bdbuf_add_to_modified_list_after_access (bd);
|
||||
break;
|
||||
@@ -2121,7 +2158,8 @@ rtems_bdbuf_sync (rtems_bdbuf_buffer *bd)
|
||||
|
||||
switch (bd->state)
|
||||
{
|
||||
case RTEMS_BDBUF_STATE_ACCESS:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_CACHED:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
|
||||
case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
|
||||
rtems_bdbuf_add_to_sync_list_after_access (bd);
|
||||
break;
|
||||
@@ -2140,8 +2178,17 @@ rtems_bdbuf_sync (rtems_bdbuf_buffer *bd)
|
||||
* If no one intercepts the sync, we created a cached buffer which may be
|
||||
* recycled.
|
||||
*/
|
||||
if (bd->state == RTEMS_BDBUF_STATE_CACHED && bd->waiters == 0)
|
||||
if (bd->waiters == 0
|
||||
&& (bd->state == RTEMS_BDBUF_STATE_CACHED
|
||||
|| bd->state == RTEMS_BDBUF_STATE_EMPTY))
|
||||
{
|
||||
if (bd->state == RTEMS_BDBUF_STATE_EMPTY)
|
||||
{
|
||||
rtems_bdbuf_remove_from_tree (bd);
|
||||
rtems_bdbuf_make_free_and_add_to_lru_list (bd);
|
||||
}
|
||||
rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
|
||||
}
|
||||
|
||||
rtems_bdbuf_unlock_cache ();
|
||||
|
||||
@@ -2190,25 +2237,10 @@ rtems_bdbuf_syncdev (dev_t dev)
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call back handler called by the low level driver when the transfer has
|
||||
* completed. This function may be invoked from interrupt handlers.
|
||||
*
|
||||
* @param arg Arbitrary argument specified in block device request
|
||||
* structure (in this case - pointer to the appropriate
|
||||
* block device request structure).
|
||||
* @param status I/O completion status
|
||||
* @param error errno error code if status != RTEMS_SUCCESSFUL
|
||||
*/
|
||||
static void
|
||||
rtems_bdbuf_write_done(void *arg, rtems_status_code status, int error)
|
||||
static int
|
||||
rtems_bdbuf_null_disk_ioctl (rtems_disk_device *dd, uint32_t req, void *arg)
|
||||
{
|
||||
rtems_blkdev_request* req = (rtems_blkdev_request*) arg;
|
||||
|
||||
req->error = error;
|
||||
req->status = status;
|
||||
|
||||
rtems_event_send (req->io_task, RTEMS_BDBUF_TRANSFER_SYNC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2221,7 +2253,10 @@ rtems_bdbuf_write_done(void *arg, rtems_status_code status, int error)
|
||||
static void
|
||||
rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
|
||||
{
|
||||
rtems_disk_device* dd;
|
||||
static rtems_disk_device null_disk = {
|
||||
.capabilities = 0,
|
||||
.ioctl = rtems_bdbuf_null_disk_ioctl
|
||||
};
|
||||
|
||||
if (rtems_bdbuf_tracer)
|
||||
printf ("bdbuf:swapout transfer: %08x\n", (unsigned) transfer->dev);
|
||||
@@ -2230,13 +2265,6 @@ rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
|
||||
* If there are buffers to transfer to the media transfer them.
|
||||
*/
|
||||
if (!rtems_chain_is_empty (&transfer->bds))
|
||||
{
|
||||
/*
|
||||
* Obtain the disk device. The cache's mutex has been released to avoid a
|
||||
* dead lock.
|
||||
*/
|
||||
dd = rtems_disk_obtain (transfer->dev);
|
||||
if (dd)
|
||||
{
|
||||
/*
|
||||
* The last block number used when the driver only supports
|
||||
@@ -2248,7 +2276,18 @@ rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
|
||||
* Number of buffers per bd. This is used to detect the next
|
||||
* block.
|
||||
*/
|
||||
uint32_t bufs_per_bd = dd->block_size / bdbuf_config.buffer_min;
|
||||
uint32_t bufs_per_bd = 0;
|
||||
|
||||
/*
|
||||
* Obtain the disk device. The cache's mutex has been released to avoid a
|
||||
* dead lock.
|
||||
*/
|
||||
rtems_disk_device *dd = rtems_disk_obtain (transfer->dev);
|
||||
|
||||
if (dd == NULL)
|
||||
dd = &null_disk;
|
||||
|
||||
bufs_per_bd = dd->block_size / bdbuf_config.buffer_min;
|
||||
|
||||
/*
|
||||
* Take as many buffers as configured and pass to the driver. Note, the
|
||||
@@ -2260,7 +2299,6 @@ rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
|
||||
* trouble waiting to happen.
|
||||
*/
|
||||
transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
|
||||
transfer->write_req->error = 0;
|
||||
transfer->write_req->bufnum = 0;
|
||||
|
||||
while (!rtems_chain_is_empty (&transfer->bds))
|
||||
@@ -2313,86 +2351,16 @@ rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
|
||||
|
||||
if (write)
|
||||
{
|
||||
int result;
|
||||
uint32_t b;
|
||||
|
||||
if (rtems_bdbuf_tracer)
|
||||
printf ("bdbuf:swapout write: writing bufnum:%" PRIu32 "\n",
|
||||
transfer->write_req->bufnum);
|
||||
|
||||
/*
|
||||
* Perform the transfer. No cache locks, no preemption, only the disk
|
||||
* device is being held.
|
||||
*/
|
||||
result = dd->ioctl (dd->phys_dev, RTEMS_BLKIO_REQUEST,
|
||||
transfer->write_req);
|
||||
if (result < 0)
|
||||
{
|
||||
rtems_bdbuf_lock_cache ();
|
||||
|
||||
for (b = 0; b < transfer->write_req->bufnum; b++)
|
||||
{
|
||||
bd = transfer->write_req->bufs[b].user;
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_MODIFIED);
|
||||
bd->error = errno;
|
||||
|
||||
/*
|
||||
* Place back on the cache's modified queue and try again.
|
||||
*
|
||||
* @warning Not sure this is the best option but I do not know
|
||||
* what else can be done.
|
||||
*/
|
||||
rtems_chain_append (&bdbuf_cache.modified, &bd->link);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_bdbuf_wait_for_event (RTEMS_BDBUF_TRANSFER_SYNC);
|
||||
|
||||
rtems_bdbuf_lock_cache ();
|
||||
|
||||
for (b = 0; b < transfer->write_req->bufnum; b++)
|
||||
{
|
||||
bd = transfer->write_req->bufs[b].user;
|
||||
rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
|
||||
bd->error = 0;
|
||||
|
||||
rtems_bdbuf_group_release (bd);
|
||||
|
||||
if (rtems_bdbuf_tracer)
|
||||
rtems_bdbuf_show_users ("write", bd);
|
||||
|
||||
rtems_chain_append (&bdbuf_cache.lru, &bd->link);
|
||||
|
||||
if (bd->waiters)
|
||||
rtems_bdbuf_wake (&bdbuf_cache.transfer_waiters);
|
||||
else
|
||||
rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
|
||||
}
|
||||
}
|
||||
|
||||
if (rtems_bdbuf_tracer)
|
||||
rtems_bdbuf_show_usage ();
|
||||
|
||||
rtems_bdbuf_unlock_cache ();
|
||||
rtems_bdbuf_execute_transfer_request (dd, transfer->write_req, false);
|
||||
|
||||
transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
|
||||
transfer->write_req->error = 0;
|
||||
transfer->write_req->bufnum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (dd != &null_disk)
|
||||
rtems_disk_release (dd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* We have buffers but no device. Put the BDs back onto the
|
||||
* ready queue and exit.
|
||||
*/
|
||||
/* @todo fixme */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2644,7 +2612,7 @@ rtems_bdbuf_swapout_writereq_alloc (void)
|
||||
rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_SO_NOMEM);
|
||||
|
||||
write_req->req = RTEMS_BLKDEV_REQ_WRITE;
|
||||
write_req->req_done = rtems_bdbuf_write_done;
|
||||
write_req->req_done = rtems_bdbuf_transfer_done;
|
||||
write_req->done_arg = write_req;
|
||||
write_req->io_task = rtems_task_self ();
|
||||
|
||||
|
||||
@@ -2071,8 +2071,7 @@ rtems_fdisk_read (rtems_flashdisk* fd, rtems_blkdev_request* req)
|
||||
}
|
||||
}
|
||||
|
||||
req->req_done (req->done_arg,
|
||||
ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
|
||||
req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2107,8 +2106,7 @@ rtems_fdisk_write (rtems_flashdisk* fd, rtems_blkdev_request* req)
|
||||
}
|
||||
}
|
||||
|
||||
req->req_done (req->done_arg,
|
||||
ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
|
||||
req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -595,8 +595,7 @@ rtems_nvdisk_read (rtems_nvdisk* nvd, rtems_blkdev_request* req)
|
||||
}
|
||||
}
|
||||
|
||||
req->req_done (req->done_arg,
|
||||
ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
|
||||
req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -635,8 +634,7 @@ rtems_nvdisk_write (rtems_nvdisk* nvd, rtems_blkdev_request* req)
|
||||
}
|
||||
}
|
||||
|
||||
req->req_done (req->done_arg,
|
||||
ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
|
||||
req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ ramdisk_read(struct ramdisk *rd, rtems_blkdev_request *req)
|
||||
#endif
|
||||
memcpy(sg->buffer, from + (sg->block * rd->block_size), sg->length);
|
||||
}
|
||||
req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
|
||||
req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ ramdisk_write(struct ramdisk *rd, rtems_blkdev_request *req)
|
||||
#endif
|
||||
memcpy(to + (sg->block * rd->block_size), sg->buffer, sg->length);
|
||||
}
|
||||
req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
|
||||
req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user