Changeset 5c587596 in rtems


Ignore:
Timestamp:
Jan 19, 2010, 9:10:03 AM (10 years ago)
Author:
Thomas Doerfler <Thomas.Doerfler@…>
Branches:
4.10, 4.11, master
Children:
1ba96ef9
Parents:
64734fc
Message:

libblock API update

Files:
11 edited

Legend:

Unmodified
Added
Removed
  • c/src/libchip/i2c/spi-sd-card.c

    r64734fc r5c587596  
    10061006
    10071007        /* Done */
    1008         r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
     1008        r->req_done( r->done_arg, RTEMS_SUCCESSFUL);
    10091009
    10101010        return 0;
     
    10211021
    10221022        /* Done */
    1023         r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
     1023        r->req_done( r->done_arg, RTEMS_IO_ERROR);
    10241024
    10251025        return rv;
     
    10951095
    10961096        /* Done */
    1097         r->req_done( r->done_arg, RTEMS_SUCCESSFUL, 0);
     1097        r->req_done( r->done_arg, RTEMS_SUCCESSFUL);
    10981098
    10991099        return 0;
     
    11141114
    11151115        /* Done */
    1116         r->req_done( r->done_arg, RTEMS_IO_ERROR, 0);
     1116        r->req_done( r->done_arg, RTEMS_IO_ERROR);
    11171117
    11181118        return rv;
  • c/src/libchip/ide/ata.c

    r64734fc r5c587596  
    547547static inline void
    548548ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
    549                  rtems_status_code status, int error)
     549                 rtems_status_code status)
    550550{
    551551    assert(areq);
     
    555555#endif
    556556
    557     ATA_EXEC_CALLBACK(areq, status, error);
     557    ATA_EXEC_CALLBACK(areq, status);
    558558    rtems_chain_extract(&areq->link);
    559559
     
    587587ata_non_data_request_done(ata_req_t *areq,
    588588                          rtems_device_minor_number ctrl_minor,
    589                           rtems_status_code status, int error)
     589                          rtems_status_code status, int info)
    590590{
    591591#if ATA_DEBUG
     
    594594
    595595    areq->status = status;
    596     areq->error = error;
     596    areq->info = info;
    597597    rtems_semaphore_release(areq->sema);
    598598}
     
    785785    if (areq->cnt == 0)
    786786    {
    787         ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
     787        ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
    788788    }
    789789    else if (IDE_Controller_Table[ctrl_minor].int_driven == false)
     
    823823    if (areq->cnt == 0)
    824824    {
    825         ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL, RTEMS_SUCCESSFUL);
     825        ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
    826826    }
    827827    else
     
    910910                 * controller queue
    911911                 */
    912                 ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL,
    913                                  msg.error);
     912                ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
    914913                break;
    915914
     
    920919                 * controller queue
    921920                 */
    922                 ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED,
    923                                  msg.error);
     921                ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
    924922                break;
    925923
     
    949947                                                      RTEMS_IO_ERROR);
    950948                        else
    951                             ata_request_done(areq, ctrl_minor, RTEMS_UNSATISFIED,
    952                                              RTEMS_IO_ERROR);
     949                            ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
    953950                        break;
    954951                    }
     
    978975                        ata_printf("ata_queue_task: non-supported command type\n");
    979976#endif
    980                         ata_request_done(areq, ctrl_minor,
    981                                          RTEMS_UNSATISFIED,
    982                                          RTEMS_NOT_IMPLEMENTED);
     977                        ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
    983978                        break;
    984979                }
     
    13161311        {
    13171312          /* disassemble returned diagnostic codes */
    1318           if (breq.req.error == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
     1313          if (areq.info == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
    13191314          {
    13201315            printk("ATA: ctrl:%d: primary, secondary\n", ctrl_minor);
     
    13221317            ATA_DEV_INFO(ctrl_minor,1).present = true;
    13231318          }
    1324           else if (breq.req.error == ATA_DEV0_PASSED_DEV1_FAILED)
     1319          else if (areq.info == ATA_DEV0_PASSED_DEV1_FAILED)
    13251320          {
    13261321            printk("ATA: ctrl:%d: primary\n", ctrl_minor);
     
    13281323            ATA_DEV_INFO(ctrl_minor,1).present = false;
    13291324          }
    1330           else if (breq.req.error < ATA_DEV1_PASSED_DEV0_FAILED)
     1325          else if (areq.info < ATA_DEV1_PASSED_DEV0_FAILED)
    13311326          {
    13321327            printk("ATA: ctrl:%d: secondary\n", ctrl_minor);
     
    15221517              /* probably no drive connected */
    15231518              areq->breq->status = RTEMS_UNSATISFIED;
    1524               areq->breq->error = RTEMS_IO_ERROR;
    15251519              return;
    15261520            }
     
    15461540    if (val & IDE_REGISTER_STATUS_ERR)
    15471541    {
    1548         areq->breq->status = RTEMS_UNSATISFIED;
    1549         areq->breq->error = RTEMS_IO_ERROR;
     1542        areq->breq->status = RTEMS_IO_ERROR;
    15501543        return;
    15511544    }
     
    15801573        case ATA_COMMAND_TYPE_NON_DATA:
    15811574            areq->breq->status = RTEMS_SUCCESSFUL;
    1582             areq->breq->error = val1;
     1575            areq->info = val1;
    15831576            break;
    15841577
     
    15871580            ata_printf("ata_queue_task: non-supported command type\n");
    15881581#endif
    1589             areq->breq->status = RTEMS_UNSATISFIED;
    1590             areq->breq->error = RTEMS_NOT_IMPLEMENTED;
     1582            areq->breq->status = RTEMS_IO_ERROR;
    15911583            break;
    15921584    }
  • c/src/libchip/ide/ata_internal.h

    r64734fc r5c587596  
    211211                               */
    212212    rtems_status_code status; /* status of ata request processing */
    213     int               error;  /* device error code */
     213    int               info;  /* device info code */
    214214} ata_req_t;
    215215
    216216/* call callback provided by block device request if it is defined */
    217 #define ATA_EXEC_CALLBACK(areq, status, error) \
     217#define ATA_EXEC_CALLBACK(areq, status) \
    218218    do {\
    219219        if (((areq)->breq != NULL) && ((areq)->breq->req_done != NULL)) \
    220             (areq)->breq->req_done((areq)->breq->done_arg, status, error); \
     220            (areq)->breq->req_done((areq)->breq->done_arg, status); \
    221221    } while (0)
    222222
  • c/src/wrapup/Makefile.am

    r64734fc r5c587596  
    2626endif
    2727SRCS += ../libchip/libi2cio.a
     28SRCS += ../libchip/libdisplay.a
    2829
    2930if HAS_MP
  • cpukit/ChangeLog

    r64734fc r5c587596  
     12010-01-18      Sebastian Huber <sebastian.huber@embedded-brains.de>
     2
     3        * libblock/include/rtems/bdbuf.h: Documentation.  Renamed
     4        RTEMS_BDBUF_STATE_EMPTY in RTEMS_BDBUF_STATE_FREE.  Renamed
     5        RTEMS_BDBUF_STATE_FRESH in RTEMS_BDBUF_STATE_EMPTY.  Renamed
     6        RTEMS_BDBUF_STATE_ACCESS in RTEMS_BDBUF_STATE_ACCESS_CACHED.  New
     7        state RTEMS_BDBUF_STATE_ACCESS_EMPTY.  Removed error field from
     8        rtems_bdbuf_buffer.
     9        * libblock/include/rtems/blkdev.h:  Documentation.  Removed error
     10        field from block device IO control.
     11        * libblock/src/bdbuf.c: Update for block device API change.  New block
     12        device driver error policies.  A transfer error or a write to a
     13        deleted disk will invalidate the block data now.  See test
     14        "libtests/block09".  A get and release sequence will no longer trigger
     15        a disk write.
     16        * libblock/src/flashdisk.c, libblock/src/nvdisk.c,
     17        libblock/src/ramdisk-driver.c: Update for block device API change.
     18
    1192010-01-18      Joel Sherrill <joel.sherrill@oarcorp.com>
    220
  • cpukit/libblock/include/rtems/bdbuf.h

    r64734fc r5c587596  
    8181 * digraph state {
    8282 *   size="16,8";
    83  *   e [label="EMPTY",style="filled",fillcolor="aquamarine"];
    84  *   f [label="FRESH",style="filled",fillcolor="seagreen"];
     83 *   f [label="FREE",style="filled",fillcolor="aquamarine"];
     84 *   e [label="EMPTY",style="filled",fillcolor="seagreen"];
    8585 *   c [label="CACHED",style="filled",fillcolor="chartreuse"];
    86  *   a [label="ACCESS",style="filled",fillcolor="royalblue"];
     86 *   ac [label="ACCESS CACHED",style="filled",fillcolor="royalblue"];
    8787 *   am [label="ACCESS MODIFIED",style="filled",fillcolor="royalblue"];
     88 *   ae [label="ACCESS EMPTY",style="filled",fillcolor="royalblue"];
    8889 *   t [label="TRANSFER",style="filled",fillcolor="red"];
    8990 *   s [label="SYNC",style="filled",fillcolor="red"];
     
    9495 *   legend_access [label="Access Wake-Up",fontcolor="royalblue",shape="none"];
    9596 *
    96  *   i -> e [label="Init"];
    97  *   e -> f [label="Buffer Recycle"];
    98  *   f -> a [label="Get"];
    99  *   f -> t [label="Read\nRead Ahead"];
    100  *   c -> e [label="Reallocate\nBlock Size Changed"];
    101  *   c -> a [label="Get\nRead"];
    102  *   c -> f [label="Buffer Recycle"];
    103  *   t -> c [label="Write Transfer Done\nRead Transfer Done\nRead Ahead Transfer Done",color="red",fontcolor="red"];
     97 *   i -> f [label="Init"];
     98 *   f -> e [label="Buffer Recycle"];
     99 *   e -> ae [label="Get"];
     100 *   e -> t [label="Read\nRead Ahead"];
     101 *   c -> f [label="Reallocate\nBlock Size Changed"];
     102 *   c -> ac [label="Get\nRead"];
     103 *   c -> e [label="Buffer Recycle"];
     104 *   t -> c [label="Transfer Done",color="red",fontcolor="red"];
     105 *   t -> e [label="Transfer Error With Waiter",color="red",fontcolor="red"];
     106 *   t -> f [label="Transfer Error Without Waiter",color="red",fontcolor="red"];
    104107 *   m -> t [label="Swapout"];
    105108 *   m -> s [label="Block Size Changed"];
    106109 *   m -> am [label="Get\nRead"];
    107  *   a -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
    108  *   a -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
    109  *   a -> c [label="Release",color="royalblue",fontcolor="royalblue"];
     110 *   ac -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
     111 *   ac -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
     112 *   ac -> c [label="Release",color="royalblue",fontcolor="royalblue"];
    110113 *   am -> m [label="Release\nRelease Modified",color="royalblue",fontcolor="royalblue"];
    111114 *   am -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
     115 *   ae -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
     116 *   ae -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
     117 *   ae -> e [label="Release With Waiter",color="royalblue",fontcolor="royalblue"];
     118 *   ae -> f [label="Release Without Waiter",color="royalblue",fontcolor="royalblue"];
    112119 *   s -> t [label="Swapout"];
    113120 * }
     
    165172 * The state has several implications.  Depending on the state a buffer can be
    166173 * in the AVL tree, in a list, in use by an entity and a group user or not.
     174 *
     175 * <table>
     176 *   <tr>
     177 *     <th>State</th><th>Valid Data</th><th>AVL Tree</th>
     178 *     <th>LRU List</th><th>Modified List</th><th>Synchronization List</th>
     179 *     <th>Group User</th><th>External User</th>
     180 *   </tr>
     181 *   <tr>
     182 *     <td>FREE</td><td></td><td></td>
     183 *     <td>X</td><td></td><td></td><td></td><td></td>
     184 *   </tr>
     185 *   <tr>
     186 *     <td>EMPTY</td><td></td><td>X</td>
     187 *     <td>X</td><td></td><td></td><td></td><td></td>
     188 *   </tr>
     189 *   <tr>
     190 *     <td>CACHED</td><td>X</td><td>X</td>
     191 *     <td>X</td><td></td><td></td><td></td><td></td>
     192 *   </tr>
     193 *   <tr>
     194 *     <td>ACCESS_CACHED</td><td>X</td><td>X</td>
     195 *     <td></td><td></td><td></td><td>X</td><td>X</td>
     196 *   </tr>
     197 *   <tr>
     198 *     <td>ACCESS_MODIFIED</td><td>X</td><td>X</td>
     199 *     <td></td><td></td><td></td><td>X</td><td>X</td>
     200 *   </tr>
     201 *   <tr>
     202 *     <td>ACCESS_EMPTY</td><td></td><td>X</td>
     203 *     <td></td><td></td><td></td><td>X</td><td>X</td>
     204 *   </tr>
     205 *   <tr>
     206 *     <td>MODIFIED</td><td>X</td><td>X</td>
     207 *     <td></td><td>X</td><td></td><td>X</td><td></td>
     208 *   </tr>
     209 *   <tr>
     210 *     <td>SYNC</td><td>X</td><td>X</td>
     211 *     <td></td><td></td><td>X</td><td>X</td><td></td>
     212 *   </tr>
     213 *   <tr>
     214 *     <td>TRANSFER</td><td>X</td><td>X</td>
     215 *     <td></td><td></td><td></td><td>X</td><td>X</td>
     216 *   </tr>
     217 * </table>
    167218 */
    168219typedef enum
    169220{
    170221  /**
     222   * @brief Free.
     223   */
     224  RTEMS_BDBUF_STATE_FREE = 0,
     225
     226  /**
    171227   * @brief Empty.
    172    *
    173    * Not in the AVL tree.  Not in a list.  Not in use.  Not a user of its
    174    * group.
    175    */
    176   RTEMS_BDBUF_STATE_EMPTY = 0,
    177 
    178   /**
    179    * @brief Fresh.
    180    *
    181    * In the AVL tree.  Not in a list.  In use by a get or read request.  A user
    182    * of its group.
    183    */
    184   RTEMS_BDBUF_STATE_FRESH,
     228   */
     229  RTEMS_BDBUF_STATE_EMPTY,
    185230
    186231  /**
    187232   * @brief Cached.
    188    *
    189    * In the AVL tree.  In the LRU list.  Not in use.  Not a user of its group.
    190233   */
    191234  RTEMS_BDBUF_STATE_CACHED,
    192235
    193236  /**
    194    * @brief Accessed by upper layer.
    195    *
    196    * In the AVL tree.  Not in a list.  In use by an upper layer.  A user of its
    197    * group.
    198    */
    199   RTEMS_BDBUF_STATE_ACCESS,
    200 
    201   /**
    202    * @brief Accessed and modified by upper layer.
    203    *
    204    * In the AVL tree.  Not in a list.  In use by an upper layer.  A user of its
    205    * group.
     237   * @brief Accessed by upper layer with cached data.
     238   */
     239  RTEMS_BDBUF_STATE_ACCESS_CACHED,
     240
     241  /**
     242   * @brief Accessed by upper layer with modified data.
    206243   */
    207244  RTEMS_BDBUF_STATE_ACCESS_MODIFIED,
    208245
    209246  /**
     247   * @brief Accessed by upper layer with invalid data.
     248   */
     249  RTEMS_BDBUF_STATE_ACCESS_EMPTY,
     250
     251  /**
    210252   * @brief Modified by upper layer.
    211    *
    212    * In the AVL tree.  In the modified list.  In use by swapout mechanic.  A
    213    * user of its group.
    214253   */
    215254  RTEMS_BDBUF_STATE_MODIFIED,
     
    217256  /**
    218257   * @brief Scheduled for synchronization.
    219    *
    220    * In the AVL tree.  In the sync list.  In use by swapout mechanic.  A user
    221    * of its group.
    222258   */
    223259  RTEMS_BDBUF_STATE_SYNC,
     
    225261  /**
    226262   * @brief In transfer by block device driver.
    227    *
    228    * In the AVL tree.  Not in a list.  In use by the block device driver.  A
    229    * user of its group.
    230263   */
    231264  RTEMS_BDBUF_STATE_TRANSFER
     
    261294
    262295  unsigned char*    buffer;     /**< Pointer to the buffer memory area */
    263   int               error;      /**< If not 0 indicate an error value (errno)
    264                                  * which can be used by user later */
    265296
    266297  volatile rtems_bdbuf_buf_state state;  /**< State of the buffer. */
  • cpukit/libblock/include/rtems/blkdev.h

    r64734fc r5c587596  
    6060
    6161/**
    62  * Type for block device request done callback function.
    63  *
    64  * @param arg Argument supplied in @ref rtems_blkdev_request.
    65  * @param status Status code for this operation.
    66  * @param errno The @c errno value to be passed to the user when status is not
    67  * equal to @c RTEMS_SUCCESSFUL.
    68  */
    69 typedef void (* rtems_blkdev_request_cb)(void *arg,
    70                                          rtems_status_code status,
    71                                          int error);
     62 * @brief Block device request done callback function type.
     63 *
     64 * The first parameter @a arg must be the argument provided by the block device
     65 * request structure @ref rtems_blkdev_request.
     66 *
     67 * The second parameter @a status should contain the status of the operation:
     68 *  - @c RTEMS_SUCCESSFUL Operation was successful.
     69 *  - @c RTEMS_IO_ERROR Some sort of input or output error.
     70 *  - @c RTEMS_UNSATISFIED Media no more present.
     71 */
     72typedef void (*rtems_blkdev_request_cb)(void *arg, rtems_status_code status);
    7273
    7374/**
     
    127128   */
    128129  rtems_status_code status;
    129 
    130   /**
    131    * If @c status is not equal to @c RTEMS_SUCCESSFUL, this field contains the
    132    * error number.
    133    */
    134   int error;
    135130
    136131  /**
  • cpukit/libblock/src/bdbuf.c

    r64734fc r5c587596  
    124124  rtems_chain_control sync;              /**< Buffers to sync list */
    125125
    126   rtems_bdbuf_waiters access_waiters;    /**< Wait for a buffer in ACCESS
     126  rtems_bdbuf_waiters access_waiters;    /**< Wait for a buffer in
     127                                          * ACCESS_CACHED, ACCESS_MODIFIED or
     128                                          * ACCESS_EMPTY
    127129                                          * state. */
    128130  rtems_bdbuf_waiters transfer_waiters;  /**< Wait for a buffer in TRANSFER
     
    143145  (((uint32_t)'B' << 24) | ((uint32_t)(n) & (uint32_t)0x00FFFFFF))
    144146
    145 #define RTEMS_BLKDEV_FATAL_BDBUF_STATE_3       RTEMS_BLKDEV_FATAL_ERROR(1)
    146147#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_4       RTEMS_BLKDEV_FATAL_ERROR(2)
    147148#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_5       RTEMS_BLKDEV_FATAL_ERROR(3)
     
    151152#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_9       RTEMS_BLKDEV_FATAL_ERROR(7)
    152153#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_10      RTEMS_BLKDEV_FATAL_ERROR(8)
    153 #define RTEMS_BLKDEV_FATAL_BDBUF_CACHE_RM      RTEMS_BLKDEV_FATAL_ERROR(9)
     154#define RTEMS_BLKDEV_FATAL_BDBUF_TREE_RM       RTEMS_BLKDEV_FATAL_ERROR(9)
    154155#define RTEMS_BLKDEV_FATAL_BDBUF_SWAPOUT       RTEMS_BLKDEV_FATAL_ERROR(10)
    155156#define RTEMS_BLKDEV_FATAL_BDBUF_SYNC_LOCK     RTEMS_BLKDEV_FATAL_ERROR(11)
     
    10551056   * buffer never getting to 0 and never being forced onto disk. This raises a
    10561057   * difficult question. Is a snapshot of a block that is changing better than
    1057    * nothing being written ? We have tended to think we should hold changes for
     1058   * nothing being written? We have tended to think we should hold changes for
    10581059   * only a specific period of time even if still changing and get onto disk
    10591060   * and letting the file system try and recover this position if it can.
    10601061   */
    1061   if (bd->state == RTEMS_BDBUF_STATE_ACCESS)
     1062  if (bd->state == RTEMS_BDBUF_STATE_ACCESS_CACHED
     1063        || bd->state == RTEMS_BDBUF_STATE_ACCESS_EMPTY)
    10621064    bd->hold_timer = bdbuf_config.swap_block_hold;
    10631065
    10641066  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_MODIFIED);
    1065 
    10661067  rtems_chain_append (&bdbuf_cache.modified, &bd->link);
    10671068
     
    10761077{
    10771078  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
    1078 
    10791079  rtems_chain_append (&bdbuf_cache.lru, &bd->link);
    1080 
    10811080  rtems_bdbuf_group_release (bd);
    10821081
     
    11231122
    11241123static void
    1125 rtems_bdbuf_remove_from_cache_and_lru_list (rtems_bdbuf_buffer *bd)
     1124rtems_bdbuf_remove_from_tree (rtems_bdbuf_buffer *bd)
     1125{
     1126  if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
     1127    rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_TREE_RM);
     1128}
     1129
     1130static void
     1131rtems_bdbuf_remove_from_tree_and_lru_list (rtems_bdbuf_buffer *bd)
    11261132{
    11271133  switch (bd->state)
    11281134  {
    1129     case RTEMS_BDBUF_STATE_EMPTY:
     1135    case RTEMS_BDBUF_STATE_FREE:
    11301136      break;
    11311137    case RTEMS_BDBUF_STATE_CACHED:
    1132       if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
    1133         rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_3);
     1138      rtems_bdbuf_remove_from_tree (bd);
    11341139      break;
    11351140    default:
     
    11411146
    11421147static void
     1148rtems_bdbuf_make_free_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
     1149{
     1150  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_FREE);
     1151  rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
     1152}
     1153
     1154static void
    11431155rtems_bdbuf_make_empty_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
    11441156{
    11451157  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
    1146   rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
     1158  rtems_chain_append (&bdbuf_cache.lru, &bd->link);
     1159}
     1160
     1161static void
     1162rtems_bdbuf_release_empty_buffer (rtems_bdbuf_buffer *bd)
     1163{
     1164  rtems_bdbuf_group_release (bd);
     1165
     1166  if (bd->waiters)
     1167  {
     1168    rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
     1169    rtems_chain_append (&bdbuf_cache.lru, &bd->link);
     1170    rtems_bdbuf_wake (&bdbuf_cache.access_waiters);
     1171  }
     1172  else
     1173  {
     1174    rtems_bdbuf_remove_from_tree (bd);
     1175    rtems_bdbuf_make_free_and_add_to_lru_list (bd);
     1176    rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
     1177  }
    11471178}
    11481179
     
    11731204       b < group->bds_per_group;
    11741205       b++, bd += bufs_per_bd)
    1175     rtems_bdbuf_remove_from_cache_and_lru_list (bd);
     1206    rtems_bdbuf_remove_from_tree_and_lru_list (bd);
    11761207
    11771208  group->bds_per_group = new_bds_per_group;
     
    11811212       b < group->bds_per_group;
    11821213       b++, bd += bufs_per_bd)
    1183     rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
     1214    rtems_bdbuf_make_free_and_add_to_lru_list (bd);
    11841215
    11851216  if (b > 1)
     
    11941225                            rtems_blkdev_bnum   block)
    11951226{
    1196   rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_FRESH);
    1197 
    11981227  bd->dev       = dev;
    11991228  bd->block     = block;
    12001229  bd->avl.left  = NULL;
    12011230  bd->avl.right = NULL;
    1202   bd->error     = 0;
    12031231  bd->waiters   = 0;
    12041232
    12051233  if (rtems_bdbuf_avl_insert (&bdbuf_cache.tree, bd) != 0)
    12061234    rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_RECYCLE);
     1235
     1236  rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
    12071237}
    12081238
     
    12321262      if (bd->group->bds_per_group == bds_per_group)
    12331263      {
    1234         rtems_bdbuf_remove_from_cache_and_lru_list (bd);
     1264        rtems_bdbuf_remove_from_tree_and_lru_list (bd);
    12351265
    12361266        recycle_bd = bd;
     
    14901520    switch (bd->state)
    14911521    {
    1492       case RTEMS_BDBUF_STATE_FRESH:
    1493         return;
    14941522      case RTEMS_BDBUF_STATE_MODIFIED:
    14951523        rtems_bdbuf_group_release (bd);
    14961524        /* Fall through */
    14971525      case RTEMS_BDBUF_STATE_CACHED:
     1526      case RTEMS_BDBUF_STATE_EMPTY:
    14981527        rtems_chain_extract (&bd->link);
    14991528        return;
     1529      case RTEMS_BDBUF_STATE_ACCESS_CACHED:
     1530      case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    15001531      case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
    1501       case RTEMS_BDBUF_STATE_ACCESS:
    15021532        rtems_bdbuf_wait (bd, &bdbuf_cache.access_waiters);
    15031533        break;
     
    15341564    switch (bd->state)
    15351565    {
    1536       case RTEMS_BDBUF_STATE_EMPTY:
     1566      case RTEMS_BDBUF_STATE_FREE:
    15371567        return true;
    15381568      case RTEMS_BDBUF_STATE_MODIFIED:
     
    15401570        break;
    15411571      case RTEMS_BDBUF_STATE_CACHED:
     1572      case RTEMS_BDBUF_STATE_EMPTY:
    15421573        if (bd->waiters == 0)
    15431574          return true;
     
    15531584          return false;
    15541585        }
     1586      case RTEMS_BDBUF_STATE_ACCESS_CACHED:
     1587      case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    15551588      case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
    1556       case RTEMS_BDBUF_STATE_ACCESS:
    15571589        rtems_bdbuf_wait (bd, &bdbuf_cache.access_waiters);
    15581590        break;
     
    15651597    }
    15661598  }
    1567 
    1568   return true;
    15691599}
    15701600
     
    15771607    {
    15781608      case RTEMS_BDBUF_STATE_CACHED:
     1609      case RTEMS_BDBUF_STATE_EMPTY:
    15791610      case RTEMS_BDBUF_STATE_MODIFIED:
    1580       case RTEMS_BDBUF_STATE_ACCESS:
     1611      case RTEMS_BDBUF_STATE_ACCESS_CACHED:
     1612      case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    15811613      case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
    15821614        return;
     
    16431675        if (rtems_bdbuf_wait_for_recycle (bd))
    16441676        {
    1645           rtems_bdbuf_remove_from_cache_and_lru_list (bd);
    1646           rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
     1677          rtems_bdbuf_remove_from_tree_and_lru_list (bd);
     1678          rtems_bdbuf_make_free_and_add_to_lru_list (bd);
    16471679          rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
    16481680        }
     
    17611793  {
    17621794    case RTEMS_BDBUF_STATE_CACHED:
    1763     case RTEMS_BDBUF_STATE_FRESH:
    1764       rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS);
     1795      rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_CACHED);
     1796      break;
     1797    case RTEMS_BDBUF_STATE_EMPTY:
     1798      rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_EMPTY);
    17651799      break;
    17661800    case RTEMS_BDBUF_STATE_MODIFIED:
     
    18021836 *            block device request structure).
    18031837 * @param status I/O completion status
    1804  * @param error errno error code if status != RTEMS_SUCCESSFUL
    1805  */
    1806 static void
    1807 rtems_bdbuf_read_done (void* arg, rtems_status_code status, int error)
     1838 */
     1839static void
     1840rtems_bdbuf_transfer_done (void* arg, rtems_status_code status)
    18081841{
    18091842  rtems_blkdev_request* req = (rtems_blkdev_request*) arg;
    18101843
    1811   req->error = error;
    18121844  req->status = status;
    18131845
     
    18161848
    18171849static void
    1818 rtems_bdbuf_create_read_request (rtems_blkdev_request *req,
    1819                                  rtems_disk_device    *dd,
    1820                                  rtems_blkdev_bnum     media_block,
    1821                                  size_t                bds_per_group)
     1850rtems_bdbuf_create_read_request (const rtems_disk_device *dd,
     1851                                 rtems_blkdev_bnum        media_block,
     1852                                 size_t                   bds_per_group,
     1853                                 rtems_blkdev_request    *req,
     1854                                 rtems_bdbuf_buffer     **bd_ptr)
    18221855{
    18231856  rtems_bdbuf_buffer *bd = NULL;
     
    18321865    transfer_count = media_block_end - media_block;
    18331866
     1867  req->req = RTEMS_BLKDEV_REQ_READ;
     1868  req->req_done = rtems_bdbuf_transfer_done;
     1869  req->done_arg = req;
     1870  req->io_task = rtems_task_self ();
     1871  req->status = RTEMS_RESOURCE_IN_USE;
    18341872  req->bufnum = 0;
    18351873
    18361874  bd = rtems_bdbuf_get_buffer_for_access (dev, media_block, bds_per_group);
     1875
     1876  *bd_ptr = bd;
    18371877
    18381878  req->bufs [0].user   = bd;
     
    18491889    case RTEMS_BDBUF_STATE_MODIFIED:
    18501890      return;
    1851     case RTEMS_BDBUF_STATE_FRESH:
     1891    case RTEMS_BDBUF_STATE_EMPTY:
    18521892      rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_TRANSFER);
    18531893      break;
     
    18831923}
    18841924
    1885 static rtems_bdbuf_buffer *
    1886 rtems_bdbuf_execute_read_request (rtems_blkdev_request *req,
    1887                                   rtems_disk_device    *dd)
    1888 {
    1889   if (req->bufnum)
    1890   {
    1891     /*
    1892      * Unlock the cache. We have the buffer for the block and it will be in the
    1893      * access or transfer state. We may also have a number of read ahead blocks
    1894      * if we need to transfer data. At this point any other threads can gain
    1895      * access to the cache and if they are after any of the buffers we have
    1896      * they will block and be woken when the buffer is returned to the cache.
    1897      *
    1898      * If a transfer is needed the I/O operation will occur with pre-emption
    1899      * enabled and the cache unlocked. This is a change to the previous version
    1900      * of the bdbuf code.
    1901      */
    1902     int      result = 0;
    1903     int      error = 0;
    1904     uint32_t transfer_index = 0;
    1905     bool     wake_transfer = false;
    1906     bool     wake_buffer = false;
    1907 
     1925static rtems_status_code
     1926rtems_bdbuf_execute_transfer_request (const rtems_disk_device *dd,
     1927                                      rtems_blkdev_request    *req,
     1928                                      bool                     cache_locked)
     1929{
     1930  rtems_status_code sc = RTEMS_SUCCESSFUL;
     1931  int result = 0;
     1932  uint32_t transfer_index = 0;
     1933  bool wake_transfer = false;
     1934  bool wake_buffer = false;
     1935
     1936  if (cache_locked)
    19081937    rtems_bdbuf_unlock_cache ();
    19091938
    1910     req->req = RTEMS_BLKDEV_REQ_READ;
    1911     req->req_done = rtems_bdbuf_read_done;
    1912     req->done_arg = req;
    1913     req->io_task = rtems_task_self ();
    1914     req->status = RTEMS_RESOURCE_IN_USE;
    1915     req->error = 0;
    1916 
    1917     result = dd->ioctl (dd->phys_dev, RTEMS_BLKIO_REQUEST, req);
    1918 
    1919     if (result == 0)
    1920     {
    1921       rtems_bdbuf_wait_for_event (RTEMS_BDBUF_TRANSFER_SYNC);
    1922       error = req->error;
    1923     }
     1939  result = dd->ioctl (dd->phys_dev, RTEMS_BLKIO_REQUEST, req);
     1940
     1941  if (result == 0)
     1942  {
     1943    rtems_bdbuf_wait_for_event (RTEMS_BDBUF_TRANSFER_SYNC);
     1944    sc = req->status;
     1945  }
     1946  else
     1947    sc = RTEMS_IO_ERROR;
     1948
     1949  rtems_bdbuf_lock_cache ();
     1950
     1951  for (transfer_index = 0; transfer_index < req->bufnum; ++transfer_index)
     1952  {
     1953    rtems_bdbuf_buffer *bd = req->bufs [transfer_index].user;
     1954    bool waiters = bd->waiters > 0;
     1955
     1956    if (waiters)
     1957      wake_transfer = true;
    19241958    else
    1925       error = errno;
    1926 
    1927     rtems_bdbuf_lock_cache ();
    1928 
    1929     for (transfer_index = 0; transfer_index < req->bufnum; ++transfer_index)
    1930     {
    1931       rtems_bdbuf_buffer *bd = req->bufs [transfer_index].user;
    1932       bool waiters = bd->waiters;
    1933 
     1959      wake_buffer = true;
     1960
     1961    rtems_bdbuf_group_release (bd);
     1962
     1963    if (sc == RTEMS_SUCCESSFUL)
     1964    {
    19341965      rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
    1935 
    1936       if (waiters)
    1937         wake_transfer = true;
    1938 
    1939       bd->error = error;
    1940 
    1941       if (rtems_bdbuf_tracer)
    1942         rtems_bdbuf_show_users ("read-ahead", bd);
    1943 
    1944       if (transfer_index > 0)
    1945       {
    1946         /*
    1947          * This is a read ahead buffer.
    1948          */
    1949 
    1950         rtems_bdbuf_group_release (bd);
    1951 
    1952         if (!waiters)
    1953           wake_buffer = true;
    1954 
    1955         if (error == 0 || waiters)
    1956           rtems_chain_append (&bdbuf_cache.lru, &bd->link);
    1957         else
    1958         {
    1959           rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
    1960           rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
    1961           if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
    1962             rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_CACHE_RM);
    1963         }
    1964       }
    1965     }
    1966 
    1967     if (wake_transfer)
    1968       rtems_bdbuf_wake (&bdbuf_cache.transfer_waiters);
    1969 
    1970     if (wake_buffer)
    1971       rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
    1972   }
    1973 
    1974   return req->bufs [0].user;
     1966      rtems_chain_append (&bdbuf_cache.lru, &bd->link);
     1967    }
     1968    else if (waiters)
     1969    {
     1970      rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
     1971    }
     1972    else
     1973    {
     1974      rtems_bdbuf_remove_from_tree (bd);
     1975      rtems_bdbuf_make_free_and_add_to_lru_list (bd);
     1976    }
     1977
     1978    if (rtems_bdbuf_tracer)
     1979      rtems_bdbuf_show_users ("transfer", bd);
     1980  }
     1981
     1982  if (wake_transfer)
     1983    rtems_bdbuf_wake (&bdbuf_cache.transfer_waiters);
     1984
     1985  if (wake_buffer)
     1986    rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
     1987
     1988  if (!cache_locked)
     1989    rtems_bdbuf_unlock_cache ();
     1990
     1991  if (sc == RTEMS_SUCCESSFUL || sc == RTEMS_UNSATISFIED)
     1992    return sc;
     1993  else
     1994    return RTEMS_IO_ERROR;
    19751995}
    19761996
     
    19822002  rtems_status_code     sc = RTEMS_SUCCESSFUL;
    19832003  rtems_disk_device    *dd = NULL;
     2004  rtems_blkdev_request *req = NULL;
    19842005  rtems_bdbuf_buffer   *bd = NULL;
    1985   rtems_blkdev_request *req = NULL;
    19862006  rtems_blkdev_bnum     media_block = 0;
    19872007  size_t                bds_per_group = 0;
     
    20052025
    20062026  rtems_bdbuf_lock_cache ();
    2007   rtems_bdbuf_create_read_request (req, dd, media_block, bds_per_group);
    2008 
    2009   bd = rtems_bdbuf_execute_read_request (req, dd);
    2010 
    2011   switch (bd->state)
    2012   {
    2013     case RTEMS_BDBUF_STATE_CACHED:
    2014       rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS);
    2015       break;
    2016     case RTEMS_BDBUF_STATE_MODIFIED:
    2017       rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_MODIFIED);
    2018       break;
    2019     default:
    2020       rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_4);
    2021       break;
    2022   }
    2023 
    2024   if (rtems_bdbuf_tracer)
    2025   {
    2026     rtems_bdbuf_show_users ("read", bd);
    2027     rtems_bdbuf_show_usage ();
    2028   }
     2027  rtems_bdbuf_create_read_request (dd, media_block, bds_per_group, req, &bd);
     2028
     2029  if (req->bufnum > 0)
     2030  {
     2031    sc = rtems_bdbuf_execute_transfer_request (dd, req, true);
     2032    if (sc == RTEMS_SUCCESSFUL)
     2033    {
     2034      rtems_chain_extract (&bd->link);
     2035      rtems_bdbuf_group_obtain (bd);
     2036    }
     2037  }
     2038
     2039  if (sc == RTEMS_SUCCESSFUL)
     2040  {
     2041    switch (bd->state)
     2042    {
     2043      case RTEMS_BDBUF_STATE_CACHED:
     2044        rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_CACHED);
     2045        break;
     2046      case RTEMS_BDBUF_STATE_MODIFIED:
     2047        rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_MODIFIED);
     2048        break;
     2049      default:
     2050        rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_4);
     2051        break;
     2052    }
     2053
     2054    if (rtems_bdbuf_tracer)
     2055    {
     2056      rtems_bdbuf_show_users ("read", bd);
     2057      rtems_bdbuf_show_usage ();
     2058    }
     2059
     2060    *bd_ptr = bd;
     2061  }
     2062  else
     2063    *bd_ptr = NULL;
    20292064
    20302065  rtems_bdbuf_unlock_cache ();
    20312066  rtems_bdbuf_release_disk (dd);
    20322067
    2033   *bd_ptr = bd;
    2034 
    2035   return RTEMS_SUCCESSFUL;
     2068  return sc;
    20362069}
    20372070
     
    20642097  switch (bd->state)
    20652098  {
    2066     case RTEMS_BDBUF_STATE_ACCESS:
     2099    case RTEMS_BDBUF_STATE_ACCESS_CACHED:
    20672100      rtems_bdbuf_add_to_lru_list_after_access (bd);
     2101      break;
     2102    case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
     2103      rtems_bdbuf_release_empty_buffer (bd);
    20682104      break;
    20692105    case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
     
    20942130  switch (bd->state)
    20952131  {
    2096     case RTEMS_BDBUF_STATE_ACCESS:
     2132    case RTEMS_BDBUF_STATE_ACCESS_CACHED:
     2133    case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    20972134    case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
    20982135      rtems_bdbuf_add_to_modified_list_after_access (bd);
     
    21222159  switch (bd->state)
    21232160  {
    2124     case RTEMS_BDBUF_STATE_ACCESS:
     2161    case RTEMS_BDBUF_STATE_ACCESS_CACHED:
     2162    case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    21252163    case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
    21262164      rtems_bdbuf_add_to_sync_list_after_access (bd);
     
    21412179   * recycled.
    21422180   */
    2143   if (bd->state == RTEMS_BDBUF_STATE_CACHED && bd->waiters == 0)
     2181  if (bd->waiters == 0
     2182        && (bd->state == RTEMS_BDBUF_STATE_CACHED
     2183          || bd->state == RTEMS_BDBUF_STATE_EMPTY))
     2184  {
     2185    if (bd->state == RTEMS_BDBUF_STATE_EMPTY)
     2186    {
     2187      rtems_bdbuf_remove_from_tree (bd);
     2188      rtems_bdbuf_make_free_and_add_to_lru_list (bd);
     2189    }
    21442190    rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
     2191  }
    21452192
    21462193  rtems_bdbuf_unlock_cache ();
     
    21912238}
    21922239
    2193 /**
    2194  * Call back handler called by the low level driver when the transfer has
    2195  * completed. This function may be invoked from interrupt handlers.
    2196  *
    2197  * @param arg Arbitrary argument specified in block device request
    2198  *            structure (in this case - pointer to the appropriate
    2199  *            block device request structure).
    2200  * @param status I/O completion status
    2201  * @param error errno error code if status != RTEMS_SUCCESSFUL
    2202  */
    2203 static void
    2204 rtems_bdbuf_write_done(void *arg, rtems_status_code status, int error)
    2205 {
    2206   rtems_blkdev_request* req = (rtems_blkdev_request*) arg;
    2207 
    2208   req->error = error;
    2209   req->status = status;
    2210 
    2211   rtems_event_send (req->io_task, RTEMS_BDBUF_TRANSFER_SYNC);
     2240static int
     2241rtems_bdbuf_null_disk_ioctl (rtems_disk_device *dd, uint32_t req, void *arg)
     2242{
     2243  return -1;
    22122244}
    22132245
     
    22222254rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
    22232255{
    2224   rtems_disk_device* dd;
     2256  static rtems_disk_device null_disk = {
     2257    .capabilities = 0,
     2258    .ioctl = rtems_bdbuf_null_disk_ioctl
     2259  };
    22252260
    22262261  if (rtems_bdbuf_tracer)
     
    22322267  if (!rtems_chain_is_empty (&transfer->bds))
    22332268  {
     2269    /*
     2270     * The last block number used when the driver only supports
     2271     * continuous blocks in a single request.
     2272     */
     2273    uint32_t last_block = 0;
     2274
     2275    /*
     2276     * Number of buffers per bd. This is used to detect the next
     2277     * block.
     2278     */
     2279    uint32_t bufs_per_bd = 0;
     2280
    22342281    /*
    22352282     * Obtain the disk device. The cache's mutex has been released to avoid a
    22362283     * dead lock.
    22372284     */
    2238     dd = rtems_disk_obtain (transfer->dev);
    2239     if (dd)
    2240     {
     2285    rtems_disk_device *dd = rtems_disk_obtain (transfer->dev);
     2286
     2287    if (dd == NULL)
     2288      dd = &null_disk;
     2289
     2290    bufs_per_bd = dd->block_size / bdbuf_config.buffer_min;
     2291
     2292    /*
     2293     * Take as many buffers as configured and pass to the driver. Note, the
     2294     * API to the drivers has an array of buffers and if a chain was passed
     2295     * we could have just passed the list. If the driver API is updated it
     2296     * should be possible to make this change with little effect in this
     2297     * code. The array that is passed is broken in design and should be
     2298     * removed. Merging members of a struct into the first member is
     2299     * trouble waiting to happen.
     2300     */
     2301    transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
     2302    transfer->write_req->bufnum = 0;
     2303
     2304    while (!rtems_chain_is_empty (&transfer->bds))
     2305    {
     2306      rtems_bdbuf_buffer* bd =
     2307        (rtems_bdbuf_buffer*) rtems_chain_get (&transfer->bds);
     2308
     2309      bool write = false;
     2310
    22412311      /*
    2242        * The last block number used when the driver only supports
    2243        * continuous blocks in a single request.
     2312       * If the device only accepts sequential buffers and this is not the
     2313       * first buffer (the first is always sequential, and the buffer is not
     2314       * sequential then put the buffer back on the transfer chain and write
     2315       * the committed buffers.
    22442316       */
    2245       uint32_t last_block = 0;
     2317
     2318      if (rtems_bdbuf_tracer)
     2319        printf ("bdbuf:swapout write: bd:%" PRIu32 ", bufnum:%" PRIu32 " mode:%s\n",
     2320                bd->block, transfer->write_req->bufnum,
     2321                dd->phys_dev->capabilities &
     2322                RTEMS_BLKDEV_CAP_MULTISECTOR_CONT ? "MULIT" : "SCAT");
     2323
     2324      if ((dd->phys_dev->capabilities & RTEMS_BLKDEV_CAP_MULTISECTOR_CONT) &&
     2325          transfer->write_req->bufnum &&
     2326          (bd->block != (last_block + bufs_per_bd)))
     2327      {
     2328        rtems_chain_prepend (&transfer->bds, &bd->link);
     2329        write = true;
     2330      }
     2331      else
     2332      {
     2333        rtems_blkdev_sg_buffer* buf;
     2334        buf = &transfer->write_req->bufs[transfer->write_req->bufnum];
     2335        transfer->write_req->bufnum++;
     2336        buf->user   = bd;
     2337        buf->block  = bd->block;
     2338        buf->length = dd->block_size;
     2339        buf->buffer = bd->buffer;
     2340        last_block  = bd->block;
     2341      }
    22462342
    22472343      /*
    2248        * Number of buffers per bd. This is used to detect the next
    2249        * block.
     2344       * Perform the transfer if there are no more buffers, or the transfer
     2345       * size has reached the configured max. value.
    22502346       */
    2251       uint32_t bufs_per_bd = dd->block_size / bdbuf_config.buffer_min;
    2252 
    2253       /*
    2254        * Take as many buffers as configured and pass to the driver. Note, the
    2255        * API to the drivers has an array of buffers and if a chain was passed
    2256        * we could have just passed the list. If the driver API is updated it
    2257        * should be possible to make this change with little effect in this
    2258        * code. The array that is passed is broken in design and should be
    2259        * removed. Merging members of a struct into the first member is
    2260        * trouble waiting to happen.
    2261        */
    2262       transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
    2263       transfer->write_req->error = 0;
    2264       transfer->write_req->bufnum = 0;
    2265 
    2266       while (!rtems_chain_is_empty (&transfer->bds))
     2347
     2348      if (rtems_chain_is_empty (&transfer->bds) ||
     2349          (transfer->write_req->bufnum >= bdbuf_config.max_write_blocks))
     2350        write = true;
     2351
     2352      if (write)
    22672353      {
    2268         rtems_bdbuf_buffer* bd =
    2269           (rtems_bdbuf_buffer*) rtems_chain_get (&transfer->bds);
    2270 
    2271         bool write = false;
    2272 
    2273         /*
    2274          * If the device only accepts sequential buffers and this is not the
    2275          * first buffer (the first is always sequential, and the buffer is not
    2276          * sequential then put the buffer back on the transfer chain and write
    2277          * the committed buffers.
    2278          */
    2279 
    2280         if (rtems_bdbuf_tracer)
    2281           printf ("bdbuf:swapout write: bd:%" PRIu32 ", bufnum:%" PRIu32 " mode:%s\n",
    2282                   bd->block, transfer->write_req->bufnum,
    2283                   dd->phys_dev->capabilities &
    2284                   RTEMS_BLKDEV_CAP_MULTISECTOR_CONT ? "MULIT" : "SCAT");
    2285 
    2286         if ((dd->phys_dev->capabilities & RTEMS_BLKDEV_CAP_MULTISECTOR_CONT) &&
    2287             transfer->write_req->bufnum &&
    2288             (bd->block != (last_block + bufs_per_bd)))
    2289         {
    2290           rtems_chain_prepend (&transfer->bds, &bd->link);
    2291           write = true;
    2292         }
    2293         else
    2294         {
    2295           rtems_blkdev_sg_buffer* buf;
    2296           buf = &transfer->write_req->bufs[transfer->write_req->bufnum];
    2297           transfer->write_req->bufnum++;
    2298           buf->user   = bd;
    2299           buf->block  = bd->block;
    2300           buf->length = dd->block_size;
    2301           buf->buffer = bd->buffer;
    2302           last_block  = bd->block;
    2303         }
    2304 
    2305         /*
    2306          * Perform the transfer if there are no more buffers, or the transfer
    2307          * size has reached the configured max. value.
    2308          */
    2309 
    2310         if (rtems_chain_is_empty (&transfer->bds) ||
    2311             (transfer->write_req->bufnum >= bdbuf_config.max_write_blocks))
    2312           write = true;
    2313 
    2314         if (write)
    2315         {
    2316           int result;
    2317           uint32_t b;
    2318 
    2319           if (rtems_bdbuf_tracer)
    2320             printf ("bdbuf:swapout write: writing bufnum:%" PRIu32 "\n",
    2321                     transfer->write_req->bufnum);
    2322 
    2323           /*
    2324            * Perform the transfer. No cache locks, no preemption, only the disk
    2325            * device is being held.
    2326            */
    2327           result = dd->ioctl (dd->phys_dev, RTEMS_BLKIO_REQUEST,
    2328                               transfer->write_req);
    2329           if (result < 0)
    2330           {
    2331             rtems_bdbuf_lock_cache ();
    2332 
    2333             for (b = 0; b < transfer->write_req->bufnum; b++)
    2334             {
    2335               bd = transfer->write_req->bufs[b].user;
    2336               rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_MODIFIED);
    2337               bd->error = errno;
    2338 
    2339               /*
    2340                * Place back on the cache's modified queue and try again.
    2341                *
    2342                * @warning Not sure this is the best option but I do not know
    2343                *          what else can be done.
    2344                */
    2345               rtems_chain_append (&bdbuf_cache.modified, &bd->link);
    2346             }
    2347           }
    2348           else
    2349           {
    2350             rtems_bdbuf_wait_for_event (RTEMS_BDBUF_TRANSFER_SYNC);
    2351 
    2352             rtems_bdbuf_lock_cache ();
    2353 
    2354             for (b = 0; b < transfer->write_req->bufnum; b++)
    2355             {
    2356               bd = transfer->write_req->bufs[b].user;
    2357               rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
    2358               bd->error = 0;
    2359 
    2360               rtems_bdbuf_group_release (bd);
    2361 
    2362               if (rtems_bdbuf_tracer)
    2363                 rtems_bdbuf_show_users ("write", bd);
    2364 
    2365               rtems_chain_append (&bdbuf_cache.lru, &bd->link);
    2366 
    2367               if (bd->waiters)
    2368                 rtems_bdbuf_wake (&bdbuf_cache.transfer_waiters);
    2369               else
    2370                 rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
    2371             }
    2372           }
    2373 
    2374           if (rtems_bdbuf_tracer)
    2375             rtems_bdbuf_show_usage ();
    2376 
    2377           rtems_bdbuf_unlock_cache ();
    2378 
    2379           transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
    2380           transfer->write_req->error = 0;
    2381           transfer->write_req->bufnum = 0;
    2382         }
     2354        rtems_bdbuf_execute_transfer_request (dd, transfer->write_req, false);
     2355
     2356        transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
     2357        transfer->write_req->bufnum = 0;
    23832358      }
    2384 
     2359    }
     2360
     2361    if (dd != &null_disk)
    23852362      rtems_disk_release (dd);
    2386     }
    2387     else
    2388     {
    2389       /*
    2390        * We have buffers but no device. Put the BDs back onto the
    2391        * ready queue and exit.
    2392        */
    2393       /* @todo fixme */
    2394     }
    23952363  }
    23962364}
     
    26452613
    26462614  write_req->req = RTEMS_BLKDEV_REQ_WRITE;
    2647   write_req->req_done = rtems_bdbuf_write_done;
     2615  write_req->req_done = rtems_bdbuf_transfer_done;
    26482616  write_req->done_arg = write_req;
    26492617  write_req->io_task = rtems_task_self ();
  • cpukit/libblock/src/flashdisk.c

    r64734fc r5c587596  
    20722072  }
    20732073
    2074   req->req_done (req->done_arg,
    2075                  ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
     2074  req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
    20762075
    20772076  return ret;
     
    21082107  }
    21092108
    2110   req->req_done (req->done_arg,
    2111                  ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
     2109  req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
    21122110
    21132111  return 0;
  • cpukit/libblock/src/nvdisk.c

    r64734fc r5c587596  
    596596  }
    597597
    598   req->req_done (req->done_arg,
    599                  ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
     598  req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
    600599
    601600  return ret;
     
    636635  }
    637636
    638   req->req_done (req->done_arg,
    639                  ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR, ret);
     637  req->req_done (req->done_arg, ret ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR);
    640638
    641639  return 0;
  • cpukit/libblock/src/ramdisk-driver.c

    r64734fc r5c587596  
    6666        memcpy(sg->buffer, from + (sg->block * rd->block_size), sg->length);
    6767    }
    68     req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
     68    req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
    6969    return 0;
    7070}
     
    9090        memcpy(to + (sg->block * rd->block_size), sg->buffer, sg->length);
    9191    }
    92     req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
     92    req->req_done(req->done_arg, RTEMS_SUCCESSFUL);
    9393    return 0;
    9494}
Note: See TracChangeset for help on using the changeset viewer.