Changeset b467782b in rtems for cpukit/libblock


Ignore:
Timestamp:
Mar 26, 2012, 12:58:35 PM (8 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
228ece9, d189646
Parents:
3d60c1b
git-author:
Sebastian Huber <sebastian.huber@…> (03/26/12 12:58:35)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/12/12 08:42:43)
Message:

libblock: Add rtems_bdbuf_set_block_size()

The new function rtems_bdbuf_set_block_size() must be used to set the
block size of a disk device. It will check if the block size is valid
and set the new fields block_to_media_block_shift and bds_per_group of
the rtems_disk_device structure. This helps to avoid complex arithmetic
operations in the block device buffer get and read path.

Location:
cpukit/libblock
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libblock/include/rtems/bdbuf.h

    r3d60c1b rb467782b  
    480480 *
    481481 * @retval RTEMS_SUCCESSFUL Successful operation.
    482  * @retval RTEMS_INVALID_NUMBER Invalid block size.
     482 * @retval RTEMS_INVALID_ID Invalid block number.
    483483 */
    484484rtems_status_code
     
    513513 *
    514514 * @retval RTEMS_SUCCESSFUL Successful operation.
    515  * @retval RTEMS_INVALID_NUMBER Invalid block size.
     515 * @retval RTEMS_INVALID_ID Invalid block number.
    516516 * @retval RTEMS_IO_ERROR IO error.
    517517 */
     
    626626rtems_bdbuf_purge_dev (const rtems_disk_device *dd);
    627627
     628/**
     629 * @brief Sets the block size of a disk device.
     630 *
     631 * This will also change the block_to_media_block_shift and bds_per_group
     632 * fields of the disk device.
     633 *
     634 * Before you can use this function, the rtems_bdbuf_init() routine must be
     635 * called at least once to initialize the cache, otherwise a fatal error will
     636 * occur.
     637 *
     638 * @param dd [in, out] The disk device.
     639 * @param dd [in] The new block size.
     640 *
     641 * @retval RTEMS_SUCCESSFUL Successful operation.
     642 * @retval RTEMS_INVALID_NUMBER Invalid block size.
     643 */
     644rtems_status_code
     645rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size);
     646
    628647/** @} */
    629648
  • cpukit/libblock/include/rtems/diskdevs.h

    r3d60c1b rb467782b  
    110110   * @brief Device block size in bytes.
    111111   *
    112    * This is the minimum transfer unit. It can be any size.
     112   * This is the minimum transfer unit.  It must be positive.
     113   *
     114   * @see rtems_bdbuf_set_block_size().
    113115   */
    114116  uint32_t block_size;
     
    120122   */
    121123  uint32_t media_block_size;
     124
     125  /**
     126   * @brief Block to media block shift.
     127   *
     128   * In case this value is non-negative the media block of a block can be
     129   * calculated as media block = block << block_to_media_block_shift, otherwise
     130   * a 64-bit operation will be used.
     131   *
     132   * @see rtems_bdbuf_set_block_size().
     133   */
     134  int block_to_media_block_shift;
     135
     136  /**
     137   * @brief Buffer descriptors per group count.
     138   *
     139   * @see rtems_bdbuf_set_block_size().
     140   */
     141  size_t bds_per_group;
    122142
    123143  /**
     
    223243 * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex.
    224244 * @retval RTEMS_INVALID_ADDRESS IO control handler is @c NULL.
    225  * @retval RTEMS_INVALID_NUMBER Block size is zero.
     245 * @retval RTEMS_INVALID_NUMBER Block size is invalid.
    226246 * @retval RTEMS_NO_MEMORY Not enough memory.
    227247 * @retval RTEMS_RESOURCE_IN_USE Disk device descriptor is already in use.
  • cpukit/libblock/src/bdbuf.c

    r3d60c1b rb467782b  
    823823}
    824824
    825 /**
    826  * Change the block number for the block size to the block number for the media
    827  * block size. We have to use 64bit maths. There is no short cut here.
    828  *
    829  * @param block The logical block number in the block size terms.
    830  * @param block_size The block size.
    831  * @param media_block_size The block size of the media.
    832  * @return rtems_blkdev_bnum The media block number.
    833  */
    834825static rtems_blkdev_bnum
    835 rtems_bdbuf_media_block (rtems_blkdev_bnum block,
    836                          size_t            block_size,
    837                          size_t            media_block_size)
    838 {
    839   return (rtems_blkdev_bnum)
    840     ((((uint64_t) block) * block_size) / media_block_size);
     826rtems_bdbuf_media_block (const rtems_disk_device *dd, rtems_blkdev_bnum block)
     827{
     828  if (dd->block_to_media_block_shift >= 0)
     829    return block << dd->block_to_media_block_shift;
     830  else
     831    /*
     832     * Change the block number for the block size to the block number for the media
     833     * block size. We have to use 64bit maths. There is no short cut here.
     834     */
     835    return (rtems_blkdev_bnum)
     836      ((((uint64_t) block) * dd->block_size) / dd->media_block_size);
    841837}
    842838
     
    17441740
    17451741static rtems_status_code
    1746 rtems_bdbuf_obtain_disk (const rtems_disk_device *dd,
    1747                          rtems_blkdev_bnum   block,
    1748                          rtems_blkdev_bnum  *media_block_ptr,
    1749                          size_t             *bds_per_group_ptr)
    1750 {
    1751   if (media_block_ptr != NULL)
    1752   {
    1753     /*
    1754      * Compute the media block number. Drivers work with media block number not
    1755      * the block number a BD may have as this depends on the block size set by
    1756      * the user.
    1757      */
    1758     rtems_blkdev_bnum mb = rtems_bdbuf_media_block (block,
    1759                                                     dd->block_size,
    1760                                                     dd->media_block_size);
    1761     if (mb >= dd->size)
    1762     {
    1763       return RTEMS_INVALID_NUMBER;
    1764     }
    1765 
    1766     *media_block_ptr = mb + dd->start;
    1767   }
    1768 
    1769   if (bds_per_group_ptr != NULL)
    1770   {
    1771     size_t bds_per_group = rtems_bdbuf_bds_per_group (dd->block_size);
    1772 
    1773     if (bds_per_group == 0)
    1774     {
    1775       return RTEMS_INVALID_NUMBER;
    1776     }
    1777 
    1778     *bds_per_group_ptr = bds_per_group;
    1779   }
     1742rtems_bdbuf_get_media_block (const rtems_disk_device *dd,
     1743                             rtems_blkdev_bnum        block,
     1744                             rtems_blkdev_bnum       *media_block_ptr)
     1745{
     1746  /*
     1747   * Compute the media block number. Drivers work with media block number not
     1748   * the block number a BD may have as this depends on the block size set by
     1749   * the user.
     1750   */
     1751  rtems_blkdev_bnum mb = rtems_bdbuf_media_block (dd, block);
     1752  if (mb >= dd->size)
     1753  {
     1754    return RTEMS_INVALID_ID;
     1755  }
     1756
     1757  *media_block_ptr = mb + dd->start;
    17801758
    17811759  return RTEMS_SUCCESSFUL;
     
    17901768  rtems_bdbuf_buffer *bd = NULL;
    17911769  rtems_blkdev_bnum   media_block = 0;
    1792   size_t              bds_per_group = 0;
    1793 
    1794   sc = rtems_bdbuf_obtain_disk (dd, block, &media_block, &bds_per_group);
     1770
     1771  sc = rtems_bdbuf_get_media_block (dd, block, &media_block);
    17951772  if (sc != RTEMS_SUCCESSFUL)
    17961773    return sc;
     
    18051782            media_block, block, (unsigned) dd->dev);
    18061783
    1807   bd = rtems_bdbuf_get_buffer_for_access (dd, media_block, bds_per_group);
     1784  bd = rtems_bdbuf_get_buffer_for_access (dd, media_block, dd->bds_per_group);
    18081785
    18091786  switch (bd->state)
     
    18711848  rtems_bdbuf_buffer *bd = NULL;
    18721849  rtems_blkdev_bnum   media_block_end = dd->start + dd->size;
    1873   rtems_blkdev_bnum   media_block_count = dd->block_size / dd->media_block_size;
     1850  rtems_blkdev_bnum   media_block_count = dd->block_to_media_block_shift >= 0 ?
     1851    dd->block_size >> dd->block_to_media_block_shift
     1852      : dd->block_size / dd->media_block_size;
    18741853  uint32_t            block_size = dd->block_size;
    18751854  uint32_t            transfer_index = 1;
     
    20081987  rtems_bdbuf_buffer   *bd = NULL;
    20091988  rtems_blkdev_bnum     media_block = 0;
    2010   size_t                bds_per_group = 0;
    2011 
    2012   sc = rtems_bdbuf_obtain_disk (dd, block, &media_block, &bds_per_group);
     1989
     1990  sc = rtems_bdbuf_get_media_block (dd, block, &media_block);
    20131991  if (sc != RTEMS_SUCCESSFUL)
    20141992    return sc;
     
    20282006
    20292007  rtems_bdbuf_lock_cache ();
    2030   rtems_bdbuf_create_read_request (dd, media_block, bds_per_group, req, &bd);
     2008  rtems_bdbuf_create_read_request (dd, media_block, dd->bds_per_group, req, &bd);
    20312009
    20322010  if (req->bufnum > 0)
     
    29032881  rtems_bdbuf_unlock_cache ();
    29042882}
     2883
     2884rtems_status_code
     2885rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size)
     2886{
     2887  rtems_status_code sc = RTEMS_SUCCESSFUL;
     2888
     2889  rtems_bdbuf_lock_cache ();
     2890
     2891  if (block_size > 0)
     2892  {
     2893    size_t bds_per_group = rtems_bdbuf_bds_per_group (block_size);
     2894
     2895    if (bds_per_group != 0)
     2896    {
     2897      int block_to_media_block_shift = 0;
     2898      uint32_t media_blocks_per_block = block_size / dd->media_block_size;
     2899      uint32_t one = 1;
     2900
     2901      while ((one << block_to_media_block_shift) < media_blocks_per_block)
     2902      {
     2903        ++block_to_media_block_shift;
     2904      }
     2905
     2906      if ((dd->media_block_size << block_to_media_block_shift) != block_size)
     2907        block_to_media_block_shift = -1;
     2908
     2909      dd->block_size = block_size;
     2910      dd->block_to_media_block_shift = block_to_media_block_shift;
     2911      dd->bds_per_group = bds_per_group;
     2912    }
     2913    else
     2914    {
     2915      sc = RTEMS_INVALID_NUMBER;
     2916    }
     2917  }
     2918  else
     2919  {
     2920    sc = RTEMS_INVALID_NUMBER;
     2921  }
     2922
     2923  rtems_bdbuf_unlock_cache ();
     2924
     2925  return sc;
     2926}
  • cpukit/libblock/src/blkdev-imfs.c

    r3d60c1b rb467782b  
    269269  rtems_status_code sc = RTEMS_SUCCESSFUL;
    270270
    271   if (block_size > 0 && block_count > 0) {
     271  if (block_count > 0) {
    272272    rtems_blkdev_imfs_context *ctx = calloc(1, sizeof(*ctx));
    273273
    274274    if (ctx != NULL) {
    275275      rtems_disk_device *dd = &ctx->dd;
    276       int rv;
    277276
    278277      ctx->fd = -1;
     
    281280      dd->size = block_count;
    282281      dd->media_block_size = block_size;
    283       dd->block_size = block_size;
    284282      dd->ioctl = handler;
    285283      dd->driver_data = driver_data;
     
    289287      }
    290288
    291       rv = IMFS_make_generic_node(
    292         device,
    293         S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,
    294         &rtems_blkdev_imfs_control,
    295         ctx
    296       );
    297 
    298       if (rv != 0) {
     289      sc = rtems_bdbuf_set_block_size(dd, block_size);
     290      if (sc == RTEMS_SUCCESSFUL) {
     291        int rv = IMFS_make_generic_node(
     292          device,
     293          S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,
     294          &rtems_blkdev_imfs_control,
     295          ctx
     296        );
     297
     298        if (rv != 0) {
     299          free(ctx);
     300          sc = RTEMS_UNSATISFIED;
     301        }
     302      } else {
    299303        free(ctx);
    300         sc = RTEMS_UNSATISFIED;
    301304      }
    302305    } else {
  • cpukit/libblock/src/blkdev-ioctl.c

    r3d60c1b rb467782b  
    2424rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
    2525{
    26     size_t            *arg_size = argp;
     26    rtems_status_code  sc;
    2727    int                rc = 0;
    2828
     
    3030    {
    3131        case RTEMS_BLKIO_GETMEDIABLKSIZE:
    32             *arg_size = dd->media_block_size;
     32            *(uint32_t *) argp = dd->media_block_size;
    3333            break;
    3434
    3535        case RTEMS_BLKIO_GETBLKSIZE:
    36             *arg_size = dd->block_size;
     36            *(uint32_t *) argp = dd->block_size;
    3737            break;
    3838
    3939        case RTEMS_BLKIO_SETBLKSIZE:
    40             dd->block_size = *arg_size;
    41             break;
    42 
    43         case RTEMS_BLKIO_GETSIZE:
    44             *arg_size = dd->size;
    45             break;
    46 
    47         case RTEMS_BLKIO_SYNCDEV:
    48         {
    49             rtems_status_code sc = rtems_bdbuf_syncdev(dd);
     40            sc = rtems_bdbuf_set_block_size(dd, *(uint32_t *) argp);
    5041            if (sc != RTEMS_SUCCESSFUL) {
    5142                errno = EIO;
     
    5344            }
    5445            break;
    55         }
     46
     47        case RTEMS_BLKIO_GETSIZE:
     48            *(rtems_blkdev_bnum *) argp = dd->size;
     49            break;
     50
     51        case RTEMS_BLKIO_SYNCDEV:
     52            sc = rtems_bdbuf_syncdev(dd);
     53            if (sc != RTEMS_SUCCESSFUL) {
     54                errno = EIO;
     55                rc = -1;
     56            }
     57            break;
    5658
    5759        case RTEMS_BLKIO_GETDISKDEV:
    58         {
    59             rtems_disk_device **dd_ptr = argp;
    60             *dd_ptr = dd;
     60            *(rtems_disk_device **) argp = dd;
    6161            break;
    62         }
    6362
    6463        default:
  • cpukit/libblock/src/diskdevs.c

    r3d60c1b rb467782b  
    221221}
    222222
     223static int null_handler(
     224  rtems_disk_device *dd,
     225  uint32_t req,
     226  void *argp
     227)
     228{
     229  return -1;
     230}
     231
    223232rtems_status_code rtems_disk_create_phys(
    224233  dev_t dev,
     
    237246  }
    238247
    239   if (block_size == 0) {
    240     return RTEMS_INVALID_NUMBER;
    241   }
    242 
    243248  sc = disk_lock();
    244249  if (sc != RTEMS_SUCCESSFUL) {
     
    256261  dd->start = 0;
    257262  dd->size = block_count;
    258   dd->block_size = dd->media_block_size = block_size;
     263  dd->media_block_size = block_size;
    259264  dd->ioctl = handler;
    260265  dd->driver_data = driver_data;
     
    262267  if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) < 0) {
    263268    dd->capabilities = 0;
     269  }
     270
     271  sc = rtems_bdbuf_set_block_size(dd, block_size);
     272  if (sc != RTEMS_SUCCESSFUL) {
     273    dd->ioctl = null_handler;
     274    rtems_disk_delete(dev);
     275    disk_unlock();
     276
     277    return sc;
    264278  }
    265279
     
    320334  dd->start = begin_block;
    321335  dd->size = block_count;
    322   dd->block_size = dd->media_block_size = physical_disk->block_size;
     336  dd->block_size = physical_disk->block_size;
     337  dd->media_block_size = physical_disk->media_block_size;
     338  dd->block_to_media_block_shift = physical_disk->block_to_media_block_shift;
     339  dd->bds_per_group = physical_disk->bds_per_group;
    323340  dd->ioctl = physical_disk->ioctl;
    324341  dd->driver_data = physical_disk->driver_data;
Note: See TracChangeset for help on using the changeset viewer.