Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:14

0001 /**
0002  * @file
0003  *
0004  * @ingroup rtems_blkdev
0005  *
0006  * @brief Block Device Management
0007  */
0008 
0009 /*
0010  * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
0011  * Author: Victor V. Vengerov <vvv@oktet.ru>
0012  */
0013 
0014 #ifdef HAVE_CONFIG_H
0015 #include "config.h"
0016 #endif
0017 
0018 #include <errno.h>
0019 #include <string.h>
0020 
0021 #include <rtems.h>
0022 #include <rtems/libio.h>
0023 #include <sys/ioctl.h>
0024 
0025 #include "rtems/diskdevs.h"
0026 #include "rtems/bdbuf.h"
0027 
0028 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0029 
0030 /* rtems_blkdev_generic_read --
0031  *     Generic block device read primitive. Implemented using block device
0032  *     buffer management primitives.
0033  */
0034 rtems_device_driver
0035 rtems_blkdev_generic_read(
0036     rtems_device_major_number major RTEMS_UNUSED,
0037     rtems_device_minor_number minor RTEMS_UNUSED,
0038     void                    * arg)
0039 {
0040     rtems_status_code rc = RTEMS_SUCCESSFUL;
0041     rtems_libio_rw_args_t *args = arg;
0042     rtems_libio_t *iop = args->iop;
0043     rtems_disk_device *dd = iop->data1;
0044     uint32_t block_size = dd->block_size;
0045     char *buf = args->buffer;
0046     uint32_t count = args->count;
0047     rtems_blkdev_bnum block = (rtems_blkdev_bnum) (args->offset / block_size);
0048     uint32_t blkofs = (uint32_t) (args->offset % block_size);
0049 
0050     args->bytes_moved = 0;
0051 
0052     while (count > 0)
0053     {
0054         rtems_bdbuf_buffer *diskbuf;
0055         uint32_t            copy;
0056 
0057         rc = rtems_bdbuf_read(dd, block, &diskbuf);
0058         if (rc != RTEMS_SUCCESSFUL)
0059             break;
0060         copy = block_size - blkofs;
0061         if (copy > count)
0062             copy = count;
0063         memcpy(buf, (char *)diskbuf->buffer + blkofs, copy);
0064         rc = rtems_bdbuf_release(diskbuf);
0065         args->bytes_moved += copy;
0066         if (rc != RTEMS_SUCCESSFUL)
0067             break;
0068         count -= copy;
0069         buf += copy;
0070         blkofs = 0;
0071         block++;
0072     }
0073 
0074     return rc;
0075 }
0076 
0077 /* rtems_blkdev_generic_write --
0078  *     Generic block device write primitive. Implemented using block device
0079  *     buffer management primitives.
0080  */
0081 rtems_device_driver
0082 rtems_blkdev_generic_write(
0083     rtems_device_major_number major RTEMS_UNUSED,
0084     rtems_device_minor_number minor RTEMS_UNUSED,
0085     void                    * arg)
0086 {
0087     rtems_status_code rc = RTEMS_SUCCESSFUL;
0088     rtems_libio_rw_args_t *args = arg;
0089     rtems_libio_t *iop = args->iop;
0090     rtems_disk_device *dd = iop->data1;
0091     uint32_t block_size = dd->block_size;
0092     char *buf = args->buffer;
0093     uint32_t count = args->count;
0094     rtems_blkdev_bnum block = (rtems_blkdev_bnum) (args->offset / block_size);
0095     uint32_t blkofs = (uint32_t) (args->offset % block_size);
0096 
0097     args->bytes_moved = 0;
0098 
0099     while (count > 0)
0100     {
0101         rtems_bdbuf_buffer *diskbuf;
0102         uint32_t            copy;
0103 
0104         if ((blkofs == 0) && (count >= block_size))
0105             rc = rtems_bdbuf_get(dd, block, &diskbuf);
0106         else
0107             rc = rtems_bdbuf_read(dd, block, &diskbuf);
0108         if (rc != RTEMS_SUCCESSFUL)
0109             break;
0110 
0111         copy = block_size - blkofs;
0112         if (copy > count)
0113             copy = count;
0114         memcpy((char *)diskbuf->buffer + blkofs, buf, copy);
0115         args->bytes_moved += copy;
0116 
0117         rc = rtems_bdbuf_release_modified(diskbuf);
0118         if (rc != RTEMS_SUCCESSFUL)
0119             break;
0120 
0121         count -= copy;
0122         buf += copy;
0123         blkofs = 0;
0124         block++;
0125     }
0126 
0127     return rc;
0128 }
0129 
0130 /* blkdev_generic_open --
0131  *     Generic block device open primitive.
0132  */
0133 rtems_device_driver
0134 rtems_blkdev_generic_open(
0135     rtems_device_major_number major,
0136     rtems_device_minor_number minor,
0137     void                    * arg)
0138 {
0139   rtems_libio_open_close_args_t *oc = arg;
0140   rtems_libio_t *iop = oc->iop;
0141   dev_t dev = rtems_filesystem_make_dev_t(major, minor);
0142   rtems_disk_device *dd = rtems_disk_obtain(dev);
0143 
0144   iop->data1 = dd;
0145 
0146   if (dd != NULL)
0147     return RTEMS_SUCCESSFUL;
0148   else
0149     return RTEMS_UNSATISFIED;
0150 }
0151 
0152 
0153 /* blkdev_generic_close --
0154  *     Generic block device close primitive.
0155  */
0156 rtems_device_driver
0157 rtems_blkdev_generic_close(
0158     rtems_device_major_number major RTEMS_UNUSED,
0159     rtems_device_minor_number minor RTEMS_UNUSED,
0160     void                    * arg)
0161 {
0162   rtems_libio_open_close_args_t *oc = arg;
0163   rtems_libio_t *iop = oc->iop;
0164   rtems_disk_device *dd = iop->data1;
0165 
0166   rtems_disk_release(dd);
0167 
0168   return RTEMS_SUCCESSFUL;
0169 }
0170 
0171 /* blkdev_generic_ioctl --
0172  *     Generic block device ioctl primitive.
0173  */
0174 rtems_device_driver
0175 rtems_blkdev_generic_ioctl(
0176     rtems_device_major_number major RTEMS_UNUSED,
0177     rtems_device_minor_number minor RTEMS_UNUSED,
0178     void                    * arg)
0179 {
0180     rtems_libio_ioctl_args_t *args = arg;
0181     rtems_libio_t *iop = args->iop;
0182     rtems_disk_device *dd = iop->data1;
0183 
0184     if (args->command != RTEMS_BLKIO_REQUEST)
0185     {
0186         args->ioctl_return = dd->ioctl(dd,
0187                                                   args->command,
0188                                                   args->buffer);
0189     }
0190     else
0191     {
0192         /*
0193          * It is not allowed to directly access the driver circumventing the
0194          * cache.
0195          */
0196         args->ioctl_return = -1;
0197     }
0198 
0199     return RTEMS_SUCCESSFUL;
0200 }