File indexing completed on 2025-05-11 08:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <dev/flash/jffs2_flashdev.h>
0029 #include <rtems/jffs2.h>
0030 #include <rtems/libio.h>
0031 #include <stdio.h>
0032 #include <stdlib.h>
0033 #include <string.h>
0034
0035 typedef struct {
0036 rtems_jffs2_flash_control super;
0037 FILE *handle;
0038 rtems_jffs2_mount_data *mount_data;
0039 } flash_control;
0040
0041 static flash_control *get_flash_control( rtems_jffs2_flash_control *super )
0042 {
0043 return (flash_control *) super;
0044 }
0045
0046 static int do_read(
0047 rtems_jffs2_flash_control *super,
0048 uint32_t offset,
0049 unsigned char *buffer,
0050 size_t length
0051 )
0052 {
0053 int status;
0054 flash_control *self = get_flash_control( super );
0055 int fd = fileno(self->handle);
0056
0057 status = lseek(fd, offset, SEEK_SET);
0058 if (status == -1) {
0059 return status;
0060 }
0061
0062 status = read(fd, buffer, length);
0063 if (status == -1) {
0064 return status;
0065 }
0066
0067 return 0;
0068 }
0069
0070 static int do_write(
0071 rtems_jffs2_flash_control *super,
0072 uint32_t offset,
0073 const unsigned char *buffer,
0074 size_t length
0075 )
0076 {
0077 int status;
0078 flash_control *self = get_flash_control( super );
0079 int fd = fileno(self->handle);
0080
0081 status = lseek(fd, offset, SEEK_SET);
0082 if (status == -1) {
0083 return status;
0084 }
0085
0086 status = write(fd, buffer, length);
0087 if (status == -1) {
0088 return status;
0089 }
0090
0091 return 0;
0092 }
0093
0094 static int do_erase(
0095 rtems_jffs2_flash_control *super,
0096 uint32_t offset
0097 )
0098 {
0099 int status;
0100 flash_control *self = get_flash_control( super );
0101 int fd = fileno(self->handle);
0102 rtems_flashdev_region args;
0103
0104 args.offset = offset;
0105 args.size = super->block_size;
0106
0107 status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &args);
0108 if (status == -1) {
0109 return status;
0110 }
0111
0112 return 0;
0113 }
0114
0115 static void do_destroy( rtems_jffs2_flash_control *super )
0116 {
0117 flash_control *self = get_flash_control( super );
0118 fclose(self->handle);
0119 free(self->mount_data);
0120 free(self);
0121 }
0122
0123 static int get_sector_size(int fd, uint32_t *size)
0124 {
0125 rtems_flashdev_ioctl_sector_info sec_info = {0, };
0126 int status;
0127
0128 status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_SECTORINFO_BY_OFFSET, &sec_info);
0129 if (status == 0) {
0130 *size = sec_info.sector_info.size;
0131 }
0132
0133 return status;
0134 }
0135
0136 static int get_page_size(int fd, uint32_t *size)
0137 {
0138 rtems_flashdev_ioctl_page_info page_info = {0, };
0139 int status;
0140
0141 status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_OFFSET, &page_info);
0142 if (status == 0) {
0143 *size = page_info.page_info.size;
0144 }
0145
0146 return status;
0147 }
0148
0149 static int get_jedec_id(int fd, dev_t *dev_jedec_id)
0150 {
0151 uint32_t jedec_id;
0152 int status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_JEDEC_ID, &jedec_id);
0153
0154 *dev_jedec_id = jedec_id;
0155
0156 return status;
0157 }
0158
0159 static int get_flash_type(int fd, rtems_flashdev_flash_type *flash_type)
0160 {
0161 return ioctl(fd, RTEMS_FLASHDEV_IOCTL_TYPE, flash_type);
0162 }
0163
0164 rtems_status_code jffs2_flashdev_mount(
0165 const char *flashdev_path,
0166 const char *mount_dir,
0167 rtems_flashdev_region *region,
0168 rtems_jffs2_compressor_control *compressor_control,
0169 bool read_only
0170 )
0171 {
0172 FILE *file;
0173 int fd;
0174 int status;
0175 rtems_jffs2_mount_data *mount_data;
0176 flash_control *instance;
0177 rtems_flashdev_flash_type flash_type;
0178
0179 file = fopen(flashdev_path, read_only ? "r" : "r+");
0180 if (file == NULL) {
0181 return RTEMS_NO_MEMORY;
0182 }
0183
0184 fd = fileno(file);
0185 status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_REGION_SET, region);
0186 if (status) {
0187 fclose(file);
0188 return RTEMS_NOT_IMPLEMENTED;
0189 }
0190
0191 mount_data = malloc(sizeof(*mount_data));
0192 if (mount_data == NULL) {
0193 fclose(file);
0194 return RTEMS_NO_MEMORY;
0195 }
0196 memset(mount_data, 0, sizeof(*mount_data));
0197
0198 instance = malloc(sizeof(*instance));
0199 if (instance == NULL) {
0200 free(mount_data);
0201 fclose(file);
0202 return RTEMS_NO_MEMORY;
0203 }
0204 memset(instance, 0, sizeof(*instance));
0205
0206 instance->handle = file;
0207 instance->mount_data = mount_data;
0208 mount_data->flash_control = &instance->super;
0209 mount_data->compressor_control = compressor_control;
0210
0211 instance->super.read = do_read;
0212 instance->super.write = do_write;
0213 instance->super.erase = do_erase;
0214 instance->super.destroy = do_destroy;
0215
0216
0217 status = get_jedec_id(fd, &instance->super.device_identifier);
0218 if ( status != 0 ) {
0219 return status;
0220 }
0221
0222
0223 instance->super.flash_size = region->size;
0224
0225
0226 status = get_sector_size(fd, &instance->super.block_size);
0227 if ( status != 0 ) {
0228 return status;
0229 }
0230
0231 status = get_flash_type(fd, &flash_type);
0232 if ( status != 0 ) {
0233 return status;
0234 }
0235
0236
0237
0238
0239
0240 if (flash_type == RTEMS_FLASHDEV_NAND) {
0241 status = get_page_size(fd, &instance->super.write_size);
0242 if ( status != 0 ) {
0243 return status;
0244 }
0245 }
0246
0247 status = mount(
0248 NULL,
0249 mount_dir,
0250 RTEMS_FILESYSTEM_TYPE_JFFS2,
0251 RTEMS_FILESYSTEM_READ_WRITE,
0252 mount_data
0253 );
0254 if ( status != 0 ) {
0255 return status;
0256 }
0257
0258 return 0;
0259 }