source: rtems/cpukit/include/rtems/flashdisk.h @ 2afb22b

5
Last change on this file since 2afb22b was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

  • Property mode set to 100644
File size: 18.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSFDisk
5 *
6 * @brief Interface to a Flash Disk Block Device
7 *
8 * This file defines the interface to a flash disk block device.
9 */
10
11/*
12 * Copyright (C) 2007 Chris Johns
13 *
14 * The license and distribution terms for this file may be
15 * found in the file LICENSE in this distribution or at
16 * http://www.rtems.org/license/LICENSE.
17 */
18
19#if !defined (_RTEMS_FLASHDISK_H_)
20#define _RTEMS_FLASHDISK_H_
21
22#include <stdint.h>
23#include <sys/ioctl.h>
24
25#include <rtems.h>
26
27/**
28 * @defgroup RTEMSFDisk Flash Disk Device
29 *
30 * @ingroup rtems_blkdev
31 *
32 * Flash disk driver for RTEMS provides support for block based
33 * file systems on flash devices. The driver is not a flash file
34 * system nor does it try to compete with flash file systems. It
35 * currently does not journal how-ever block sequence numbering
36 * could be added to allow recovery of a past positions if
37 * a power down occurred while being updated.
38 *
39 * This flash driver provides block device support for most flash
40 * devices. The driver has been tested on NOR type devices such
41 * as the AMLV160 or M28W160. Support for NAND type devices may
42 * require driver changes to allow speedy recover of the block
43 * mapping data and to also handle the current use of word programming.
44 * Currently the page descriptors are stored in the first few pages
45 * of each segment.
46 *
47 * The driver supports devices, segments and pages. You provide
48 * to the driver the device descriptions as a table of device
49 * descriptors. Each device descriptor contain a table of
50 * segment descriptions or segment descriptors. The driver uses
51 * this information to manage the devices.
52 *
53 * A device is made up of segments. These are also called
54 * sectors or blocks. It is the smallest erasable part of a device.
55 * A device can have differing size segments at different
56 * offsets in the device. The segment descriptors support repeating
57 * segments that are continuous in the device. The driver breaks the
58 * segments up into pages. The first pages of a segment contain
59 * the page descriptors. A page descriptor hold the page flags,
60 * a CRC for the page of data and the block number the page
61 * holds. The block can appear in any order in the devices. A
62 * page is active if it hold a current block of data. If the
63 * used bit is set the page is counted as used. A page moves
64 * from erased to active to used then back to erased. If a block
65 * is written that is already in a page, the block is written to
66 * a new page the old page is flagged as used.
67 *
68 * At initialization time each segment's page descriptors are
69 * read into memory and scanned to determine the active pages,
70 * the used pages and the bad pages. If a segment has any erased
71 * pages it is queue on the available queue. If the segment has
72 * no erased pages it is queue on the used queue.
73 *
74 * The available queue is sorted from the least number available
75 * to the most number of available pages. A segment that has just
76 * been erased will placed at the end of the queue. A segment that
77 * has only a few available pages will be used sooner and once
78 * there are no available pages it is queued on the used queue.
79 * The used queue hold segments that have no available pages and
80 * is sorted from the least number of active pages to the most
81 * number of active pages.
82 *
83 * The driver is required to compact segments. Compacting takes
84 * the segment with the most number of available pages from the
85 * available queue then takes segments with the least number of
86 * active pages from the used queue until it has enough pages
87 * to fill the empty segment. As the active pages are moved
88 * they flagged as used and once the segment has only used pages
89 * it is erased.
90 *
91 * A flash block driver like this never knows if a page is not
92 * being used by the file-system. A typical file system is not
93 * design with the idea of erasing a block on a disk once it is
94 * not being used. The file-system will normally use a flag
95 * or a location as a marker to say that part of the disk is
96 * no longer in use. This means a number of blocks could be
97 * held in active pages but are no in use by the file system.
98 * The file system may also read blocks that have never been
99 * written to disk. This complicates the driver and may make
100 * the wear, usage and erase patterns harsher than a flash
101 * file system. The driver may also suffer from problems if
102 * power is lost.
103 *
104 * There are some flash disk specific IO control request types.
105 * To use open the device and issue the ioctl() call.
106 *
107 * @code
108 *  int fd = open ("/dev/flashdisk0", O_WRONLY, 0);
109 *  if (fd < 0)
110 *  {
111 *    printf ("driver open failed: %s\n", strerror (errno));
112 *    exit (1);
113 *  }
114 *  if (ioctl (fd, RTEMS_FDISK_IOCTL_ERASE_DISK) < 0)
115 *  {
116 *    printf ("driver erase failed: %s\n", strerror (errno));
117 *    exit (1);
118 *  }
119 *  close (fd);
120 * @endcode
121 */
122/**@{**/
123
124/**
125 * @brief The base name of the flash disks.
126 */
127#define RTEMS_FLASHDISK_DEVICE_BASE_NAME "/dev/fdd"
128
129#define RTEMS_FDISK_IOCTL_ERASE_DISK   _IO('B', 128)
130#define RTEMS_FDISK_IOCTL_COMPACT      _IO('B', 129)
131#define RTEMS_FDISK_IOCTL_ERASE_USED   _IO('B', 130)
132#define RTEMS_FDISK_IOCTL_MONITORING   _IO('B', 131)
133#define RTEMS_FDISK_IOCTL_INFO_LEVEL   _IO('B', 132)
134#define RTEMS_FDISK_IOCTL_PRINT_STATUS _IO('B', 133)
135
136/**
137 * @brief Flash Disk Monitoring Data allows a user to obtain
138 * the current status of the disk.
139 */
140typedef struct rtems_fdisk_monitor_data
141{
142  uint32_t block_size;
143  uint32_t block_count;
144  uint32_t unavail_blocks;
145  uint32_t device_count;
146  uint32_t segment_count;
147  uint32_t page_count;
148  uint32_t blocks_used;
149  uint32_t segs_available;
150  uint32_t segs_used;
151  uint32_t segs_failed;
152  uint32_t seg_erases;
153  uint32_t pages_desc;
154  uint32_t pages_active;
155  uint32_t pages_used;
156  uint32_t pages_bad;
157  uint32_t info_level;
158} rtems_fdisk_monitor_data;
159
160/**
161 * @brief Flash Segment Descriptor holds, number of continuous segments in the
162 * device of this type, the base segment number in the device, the address
163 * offset of the base segment in the device, and the size of segment.
164 *
165 * Typically this structure is part of a table of segments in the
166 * device which is referenced in the flash disk configuration table.
167 * The reference is kept in the driver and used all the time to
168 * manage the flash device, therefore it must always exist.
169 */
170typedef struct rtems_fdisk_segment_desc
171{
172  uint16_t count;    /**< Number of segments of this type in a row. */
173  uint16_t segment;  /**< The base segment number. */
174  uint32_t offset;   /**< Address offset of base segment in device. */
175  uint32_t size;     /**< Size of the segment in bytes. */
176} rtems_fdisk_segment_desc;
177
178/**
179 * @brief Return the number of kilo-bytes.
180 */
181#define RTEMS_FDISK_KBYTES(_k) (UINT32_C(1024) * (_k))
182
183/**
184 * Forward declaration of the device descriptor.
185 */
186struct rtems_fdisk_device_desc;
187
188/**
189 * @brief Flash Low Level driver handlers.
190 *
191 * Typically this structure is part of a table of handlers in the
192 * device which is referenced in the flash disk configuration table.
193 * The reference is kept in the driver and used all the time to
194 * manage the flash device, therefore it must always exist.
195 */
196typedef struct rtems_fdisk_driver_handlers
197{
198  /**
199   * Read data from the device into the buffer. Return an errno
200   * error number if the device cannot be read. A segment descriptor
201   * can describe more than one segment in a device if the device has
202   * repeating segments. The segment number is the device segment to
203   * access and the segment descriptor must reference the segment
204   * being requested. For example the segment number must resided in
205   * the range [base, base + count).
206   *
207   * @param sd The segment descriptor.
208   * @param device The device to read data from.
209   * @param segment The segment within the device to read.
210   * @param offset The offset in the segment to read.
211   * @param buffer The buffer to read the data into.
212   * @param size The amount of data to read.
213   * @retval 0 No error.
214   * @retval EIO The read did not complete.
215   */
216  int (*read) (const rtems_fdisk_segment_desc* sd,
217               uint32_t                        device,
218               uint32_t                        segment,
219               uint32_t                        offset,
220               void*                           buffer,
221               uint32_t                        size);
222
223  /**
224   * Write data from the buffer to the device. Return an errno
225   * error number if the device cannot be written to. A segment
226   * descriptor can describe more than segment in a device if the
227   * device has repeating segments. The segment number is the device
228   * segment to access and the segment descriptor must reference
229   * the segment being requested. For example the segment number must
230   * resided in the range [base, base + count).
231   *
232   * @param sd The segment descriptor.
233   * @param device The device to write data from.
234   * @param segment The segment within the device to write to.
235   * @param offset The offset in the segment to write.
236   * @param buffer The buffer to write the data from.
237   * @param size The amount of data to write.
238   * @retval 0 No error.
239   * @retval EIO The write did not complete or verify.
240   */
241  int (*write) (const rtems_fdisk_segment_desc* sd,
242                uint32_t                        device,
243                uint32_t                        segment,
244                uint32_t                        offset,
245                const void*                     buffer,
246                uint32_t                        size);
247
248  /**
249   * Blank a segment in the device. Return an errno error number
250   * if the device cannot be read or is not blank. A segment descriptor
251   * can describe more than segment in a device if the device has
252   * repeating segments. The segment number is the device segment to
253   * access and the segment descriptor must reference the segment
254   * being requested. For example the segment number must resided in
255   * the range [base, base + count).
256   *
257   * @param sd The segment descriptor.
258   * @param device The device to read data from.
259   * @param segment The segment within the device to read.
260   * @param offset The offset in the segment to checl.
261   * @param size The amount of data to check.
262   * @retval 0 No error.
263   * @retval EIO The segment is not blank.
264   */
265  int (*blank) (const rtems_fdisk_segment_desc* sd,
266                uint32_t                        device,
267                uint32_t                        segment,
268                uint32_t                        offset,
269                uint32_t                        size);
270
271  /**
272   * Verify data in the buffer to the data in the device. Return an
273   * errno error number if the device cannot be read. A segment
274   * descriptor can describe more than segment in a device if the
275   * device has repeating segments. The segment number is the
276   * segment to access and the segment descriptor must reference
277   * the device segment being requested. For example the segment number
278   * must resided in the range [base, base + count).
279   *
280   * @param sd The segment descriptor.
281   * @param device The device to verify data in.
282   * @param segment The segment within the device to verify.
283   * @param offset The offset in the segment to verify.
284   * @param buffer The buffer to verify the data in the device with.
285   * @param size The amount of data to verify.
286   * @retval 0 No error.
287   * @retval EIO The data did not verify.
288   */
289  int (*verify) (const rtems_fdisk_segment_desc* sd,
290                 uint32_t                        device,
291                 uint32_t                        segment,
292                 uint32_t                        offset,
293                 const void*                     buffer,
294                 uint32_t                        size);
295
296  /**
297   * Erase the segment. Return an errno error number if the
298   * segment cannot be erased. A segment descriptor can describe
299   * more than segment in a device if the device has repeating
300   * segments. The segment number is the device segment to access and
301   * the segment descriptor must reference the segment being requested.
302   *
303   * @param sd The segment descriptor.
304   * @param device The device to erase the segment of.
305   * @param segment The segment within the device to erase.
306   * @retval 0 No error.
307   * @retval EIO The segment was not erased.
308   */
309  int (*erase) (const rtems_fdisk_segment_desc* sd,
310                uint32_t                        device,
311                uint32_t                        segment);
312
313  /**
314   * Erase the device. Return an errno error number if the
315   * segment cannot be erased. A segment descriptor can describe
316   * more than segment in a device if the device has repeating
317   * segments. The segment number is the segment to access and
318   * the segment descriptor must reference the segment being requested.
319   *
320   * @param sd The segment descriptor.
321   * @param device The device to erase.
322   * @retval 0 No error.
323   * @retval EIO The device was not erased.
324   */
325  int (*erase_device) (const struct rtems_fdisk_device_desc* dd,
326                       uint32_t                              device);
327
328} rtems_fdisk_driver_handlers;
329
330/**
331 * @brief Flash Device Descriptor holds the segments in a device.
332 *
333 * The placing of the segments in a device decriptor allows the low level
334 * driver to share the segment descriptors for a number of devices.
335 *
336 * Typically this structure is part of a table of segments in the
337 * device which is referenced in the flash disk configuration table.
338 * The reference is kept in the driver and used all the time to
339 * manage the flash device, therefore it must always exist.
340 */
341typedef struct rtems_fdisk_device_desc
342{
343  uint32_t                           segment_count; /**< Number of segments. */
344  const rtems_fdisk_segment_desc*    segments;      /**< Array of segments. */
345  const rtems_fdisk_driver_handlers* flash_ops;     /**< Device handlers. */
346} rtems_fdisk_device_desc;
347
348/**
349 * @brief RTEMS Flash Disk configuration table used to initialise the
350 * driver.
351 *
352 * The unavailable blocks count is the number of blocks less than the
353 * available number of blocks the file system is given. This means there
354 * will always be that number of blocks available when the file system
355 * thinks the disk is full. The compaction code needs blocks to compact
356 * with so you will never be able to have all the blocks allocated to the
357 * file system and be able to full the disk.
358 *
359 * The compacting segment count is the number of segments that are
360 * moved into a new segment. A high number will mean more segments with
361 * low active page counts and high used page counts will be moved into
362 * avaliable pages how-ever this extends the compaction time due to
363 * time it takes the erase the pages. There is no pont making this number
364 * greater than the maximum number of pages in a segment.
365 *
366 * The available compacting segment count is the level when compaction occurs
367 * when writing. If you set this to 0 then compaction will fail because
368 * there will be no segments to compact into.
369 *
370 * The info level can be 0 for off with error, and abort messages allowed.
371 * Level 1 is warning messages, level 1 is informational messages, and level 3
372 * is debugging type prints. The info level can be turned off with a compile
373 * time directive on the command line to the compiler of:
374 *
375 *     -DRTEMS_FDISK_TRACE=0
376 */
377typedef struct rtems_flashdisk_config
378{
379  uint32_t                       block_size;     /**< The block size. */
380  uint32_t                       device_count;   /**< The number of devices. */
381  const rtems_fdisk_device_desc* devices;        /**< The device descriptions. */
382  uint32_t                       flags;          /**< Set of flags to control
383                                                      driver. */
384  /**
385   * Number of blocks not available to the file system.  This number must be
386   * greater than or equal to the number of blocks in the largest segment to
387   * avoid starvation of erased blocks.
388   */
389  uint32_t                       unavail_blocks;
390
391  uint32_t                       compact_segs;   /**< Max number of segs to
392                                                      compact in one pass. */
393  /**
394   * The number of segments when compaction occurs when writing.  In case the
395   * number of segments in the available queue is less than or equal to this
396   * number the compaction process will be triggered.  The available queue
397   * contains all segments with erased blocks.
398   */
399  uint32_t                       avail_compact_segs;
400  uint32_t                       info_level;     /**< Default info level. */
401} rtems_flashdisk_config;
402
403/*
404 * Driver flags.
405 */
406
407/**
408 * Leave the erasing of used segment to the background handler.
409 */
410#define RTEMS_FDISK_BACKGROUND_ERASE (1 << 0)
411
412/**
413 * Leave the compacting of of used segment to the background handler.
414 */
415#define RTEMS_FDISK_BACKGROUND_COMPACT (1 << 1)
416
417/**
418 * Check the pages during initialisation to see which pages are
419 * valid and which are not. This could slow down initialising the
420 * disk driver.
421 */
422#define RTEMS_FDISK_CHECK_PAGES (1 << 2)
423
424/**
425 * Blank check the flash device before writing to them. This is needed if
426 * you think you have a driver or device problem.
427 */
428#define RTEMS_FDISK_BLANK_CHECK_BEFORE_WRITE (1 << 3)
429
430/**
431 * Flash disk device driver initialization. Place in a table as the
432 * initialisation entry and remainder of the entries are the
433 * RTEMS block device generic handlers.
434 *
435 * @param major Flash disk major device number.
436 * @param minor Minor device number, not applicable.
437 * @param arg Initialization argument, not applicable.
438 * @return The rtems_device_driver is actually just
439 *         rtems_status_code.
440 */
441rtems_device_driver
442rtems_fdisk_initialize (rtems_device_major_number major,
443                        rtems_device_minor_number minor,
444                        void*                     arg);
445
446/**
447 * @brief External reference to the configuration. Please supply.
448 * Support is present in confdefs.h for providing this variable.
449 */
450extern const rtems_flashdisk_config rtems_flashdisk_configuration[];
451
452/**
453 * @brief External reference to the number of configurations. Please supply.
454 * Support is present in confdefs.h for providing this variable.
455 */
456extern uint32_t rtems_flashdisk_configuration_size;
457
458/** @} */
459
460#endif
Note: See TracBrowser for help on using the repository browser.