source: rtems/cpukit/include/rtems/media.h @ fb5f575

Last change on this file since fb5f575 was fb5f575, checked in by Joel Sherrill <joel@…>, on 03/25/22 at 16:14:25

cpukit/include/rtems: Change license to BSD-2

Updates #3053.

  • Property mode set to 100644
File size: 15.0 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSIOMedia
7 *
8 * @brief Media Manager API.
9 */
10
11/*
12 * Copyright (c) 2009, 2018 embedded brains GmbH.  All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifndef RTEMS_MEDIA_H
37#define RTEMS_MEDIA_H
38
39#include <sys/types.h>
40#include <rtems.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif /* __cplusplus */
45
46/**
47 * @defgroup RTEMSIOMedia Media Manager
48 *
49 * @ingroup LibIO
50 *
51 * @brief Removable media support.
52 *
53 * The media manager may be used to maintain the life cycle of a removable
54 * media.  Currently only disk devices are supported.  The initiator posts an
55 * event to the media manager and it will respond with appropriate default
56 * actions.  For example a disk attach will lead to inspection of the partition
57 * table and mounted file systems.  Clients can register listeners to react to
58 * events.
59 */
60/**@{**/
61
62#define RTEMS_MEDIA_MOUNT_BASE "/media"
63
64#define RTEMS_MEDIA_DELIMITER '-'
65
66/**
67 * Disk life cycle events:
68 * @dot
69 *   digraph disk_events {
70 *     "DISK ATTACH" -> "PARTITION INQUIRY";
71 *     "DISK ATTACH" -> "MOUNT";
72 *     "PARTITION INQUIRY" -> "PARTITION ATTACH";
73 *     "PARTITION INQUIRY" -> "DISK DETACH";
74 *     "PARTITION ATTACH" -> "MOUNT";
75 *     "MOUNT" -> "UNMOUNT";
76 *     "UNMOUNT" -> "PARTITION DETACH";
77 *     "UNMOUNT" -> "DISK DETACH";
78 *     "PARTITION DETACH" -> "DISK DETACH";
79 *   }
80 * @enddot
81 */
82typedef enum {
83  RTEMS_MEDIA_EVENT_DISK_ATTACH,
84  RTEMS_MEDIA_EVENT_DISK_DETACH,
85  RTEMS_MEDIA_EVENT_MOUNT,
86  RTEMS_MEDIA_EVENT_UNMOUNT,
87  RTEMS_MEDIA_EVENT_PARTITION_INQUIRY,
88  RTEMS_MEDIA_EVENT_PARTITION_ATTACH,
89  RTEMS_MEDIA_EVENT_PARTITION_DETACH,
90  RTEMS_MEDIA_EVENT_ERROR
91} rtems_media_event;
92
93/**
94 * Normal state transition:
95 * @dot
96 *   digraph state {
97 *     INQUIRY -> READY [label="all listeners\nreturned successful"];
98 *     INQUIRY -> ABORTED [label="otherwise"];
99 *     READY -> SUCCESS [label="the worker\nreturned successful"];
100 *     READY -> FAILED [label="otherwise"];
101 *   }
102 * @enddot
103 */
104typedef enum {
105  RTEMS_MEDIA_STATE_INQUIRY,
106  RTEMS_MEDIA_STATE_READY,
107  RTEMS_MEDIA_STATE_ABORTED,
108  RTEMS_MEDIA_STATE_SUCCESS,
109  RTEMS_MEDIA_STATE_FAILED,
110  RTEMS_MEDIA_ERROR_DISK_UNKNOWN,
111  RTEMS_MEDIA_ERROR_DISK_EXISTS,
112  RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_UNKNOWN,
113  RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_EXISTS,
114  RTEMS_MEDIA_ERROR_PARTITION_UNKNOWN,
115  RTEMS_MEDIA_ERROR_PARTITION_ORPHAN,
116  RTEMS_MEDIA_ERROR_PARTITION_DETACH_WITH_MOUNT,
117  RTEMS_MEDIA_ERROR_PARTITION_WITH_UNKNOWN_DISK,
118  RTEMS_MEDIA_ERROR_MOUNT_POINT_UNKNOWN,
119  RTEMS_MEDIA_ERROR_MOUNT_POINT_EXISTS,
120  RTEMS_MEDIA_ERROR_MOUNT_POINT_ORPHAN
121} rtems_media_state;
122
123/**
124 * @brief Event listener.
125 *
126 * The listener will be called with the @a listener_arg passed to
127 * rtems_media_listener_add().
128 *
129 * Source and destination values for each event and state:
130 * <table>
131 *   <tr><th>Event</th><th>State</th><th>Source</th><th>Destination</th></tr>
132 *   <tr>
133 *     <td rowspan="5">RTEMS_MEDIA_EVENT_DISK_ATTACH</td>
134 *     <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>driver name</td><td>NULL</td>
135 *   </tr>
136 *   <tr>
137 *     <td>RTEMS_MEDIA_STATE_READY</td><td>driver name</td><td>NULL</td>
138 *   </tr>
139 *   <tr>
140 *     <td>RTEMS_MEDIA_STATE_ABORTED</td><td>driver name</td><td>NULL</td>
141 *   </tr>
142 *   <tr>
143 *     <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>driver name</td><td>disk path</td>
144 *   </tr>
145 *   <tr>
146 *     <td>RTEMS_MEDIA_STATE_FAILED</td><td>driver name</td><td>NULL</td>
147 *   </tr>
148 *   <tr>
149 *     <td rowspan="5">RTEMS_MEDIA_EVENT_DISK_DETACH</td>
150 *     <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>disk path</td><td>NULL</td>
151 *   </tr>
152 *   <tr>
153 *     <td>RTEMS_MEDIA_STATE_READY</td><td>disk path</td><td>NULL</td>
154 *   </tr>
155 *   <tr>
156 *     <td>RTEMS_MEDIA_STATE_ABORTED</td><td>disk path</td><td>NULL</td>
157 *   </tr>
158 *   <tr>
159 *     <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>disk path</td><td>NULL</td>
160 *   </tr>
161 *   <tr>
162 *     <td>RTEMS_MEDIA_STATE_FAILED</td><td>disk path</td><td>NULL</td>
163 *   </tr>
164 *   <tr>
165 *     <td rowspan="5">RTEMS_MEDIA_EVENT_PARTITION_INQUIRY</td>
166 *     <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>disk path</td><td>NULL</td>
167 *   </tr>
168 *   <tr>
169 *     <td>RTEMS_MEDIA_STATE_READY</td><td>disk path</td><td>NULL</td>
170 *   </tr>
171 *   <tr>
172 *     <td>RTEMS_MEDIA_STATE_ABORTED</td><td>disk path</td><td>NULL</td>
173 *   </tr>
174 *   <tr>
175 *     <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>disk path</td><td>NULL</td>
176 *   </tr>
177 *   <tr>
178 *     <td>RTEMS_MEDIA_STATE_FAILED</td><td>disk path</td><td>NULL</td>
179 *   </tr>
180 *   <tr>
181 *     <td rowspan="5">RTEMS_MEDIA_EVENT_PARTITION_ATTACH</td>
182 *     <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>disk path</td><td>NULL</td>
183 *   </tr>
184 *   <tr>
185 *     <td>RTEMS_MEDIA_STATE_READY</td><td>disk path</td><td>NULL</td>
186 *   </tr>
187 *   <tr>
188 *     <td>RTEMS_MEDIA_STATE_ABORTED</td><td>disk path</td><td>NULL</td>
189 *   </tr>
190 *   <tr>
191 *     <td>RTEMS_MEDIA_STATE_SUCCESS</td>
192 *     <td>disk path</td><td>partition path</td>
193 *   </tr>
194 *   <tr>
195 *     <td>RTEMS_MEDIA_STATE_FAILED</td><td>disk path</td><td>NULL</td>
196 *   </tr>
197 *   <tr>
198 *     <td rowspan="5">RTEMS_MEDIA_EVENT_PARTITION_DETACH</td>
199 *     <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>partition path</td><td>NULL</td>
200 *   </tr>
201 *   <tr>
202 *     <td>RTEMS_MEDIA_STATE_READY</td><td>partition path</td><td>NULL</td>
203 *   </tr>
204 *   <tr>
205 *     <td>RTEMS_MEDIA_STATE_ABORTED</td><td>partition path</td><td>NULL</td>
206 *   </tr>
207 *   <tr>
208 *     <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>partition path</td><td>NULL</td>
209 *   </tr>
210 *   <tr>
211 *     <td>RTEMS_MEDIA_STATE_FAILED</td><td>partition path</td><td>NULL</td>
212 *   </tr>
213 *   <tr>
214 *     <td rowspan="5">RTEMS_MEDIA_EVENT_MOUNT</td>
215 *     <td>RTEMS_MEDIA_STATE_INQUIRY</td>
216 *     <td>disk or partition path</td><td>NULL</td>
217 *   </tr>
218 *   <tr>
219 *     <td>RTEMS_MEDIA_STATE_READY</td>
220 *     <td>disk or partition path</td><td>NULL</td>
221 *   </tr>
222 *   <tr>
223 *     <td>RTEMS_MEDIA_STATE_ABORTED</td>
224 *     <td>disk or partition path</td><td>NULL</td>
225 *   </tr>
226 *   <tr>
227 *     <td>RTEMS_MEDIA_STATE_SUCCESS</td>
228 *     <td>disk or partition path</td><td>mount path</td>
229 *   </tr>
230 *   <tr>
231 *     <td>RTEMS_MEDIA_STATE_FAILED</td>
232 *     <td>disk or partition path</td><td>NULL</td>
233 *   </tr>
234 *   <tr>
235 *     <td rowspan="5">RTEMS_MEDIA_EVENT_UNMOUNT</td>
236 *     <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>mount path</td><td>NULL</td>
237 *   </tr>
238 *   <tr>
239 *     <td>RTEMS_MEDIA_STATE_READY</td><td>mount path</td><td>NULL</td>
240 *   </tr>
241 *   <tr>
242 *     <td>RTEMS_MEDIA_STATE_ABORTED</td><td>mount path</td><td>NULL</td>
243 *   </tr>
244 *   <tr>
245 *     <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>mount path</td><td>NULL</td>
246 *   </tr>
247 *   <tr>
248 *     <td>RTEMS_MEDIA_STATE_FAILED</td><td>mount path</td><td>NULL</td>
249 *   </tr>
250 *   <tr>
251 *     <td rowspan="11">RTEMS_MEDIA_EVENT_ERROR</td>
252 *     <td>RTEMS_MEDIA_ERROR_DISK_UNKNOWN</td><td>disk path</td><td>NULL</td>
253 *   </tr>
254 *   <tr>
255 *     <td>RTEMS_MEDIA_ERROR_DISK_EXISTS</td><td>disk path</td><td>NULL</td>
256 *   </tr>
257 *   <tr>
258 *     <td>RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_UNKNOWN</td>
259 *     <td>disk or partition path</td><td>NULL</td>
260 *   </tr>
261 *   <tr>
262 *     <td>RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_EXISTS</td>
263 *     <td>disk or partition path</td><td>NULL</td>
264 *   </tr>
265 *   <tr>
266 *     <td>RTEMS_MEDIA_ERROR_PARTITION_UNKNOWN</td>
267 *     <td>partition path</td><td>NULL</td>
268 *   </tr>
269 *   <tr>
270 *     <td>RTEMS_MEDIA_ERROR_PARTITION_ORPHAN</td>
271 *     <td>partition path</td><td>disk path</td>
272 *   </tr>
273 *   <tr>
274 *     <td>RTEMS_MEDIA_ERROR_PARTITION_DETACH_WITH_MOUNT</td>
275 *     <td>partition path</td><td>mount path</td>
276 *   </tr>
277 *   <tr>
278 *     <td>RTEMS_MEDIA_ERROR_PARTITION_WITH_UNKNOWN_DISK</td>
279 *     <td>partition path</td><td>disk path</td>
280 *   </tr>
281 *   <tr>
282 *     <td>RTEMS_MEDIA_ERROR_MOUNT_POINT_UNKNOWN</td>
283 *     <td>mount path</td><td>NULL</td>
284 *   </tr>
285 *   <tr>
286 *     <td>RTEMS_MEDIA_ERROR_MOUNT_POINT_EXISTS</td>
287 *     <td>mount path</td><td>NULL</td>
288 *   </tr>
289 *   <tr>
290 *     <td>RTEMS_MEDIA_ERROR_MOUNT_POINT_ORPHAN</td>
291 *     <td>mount path</td><td>disk path</td>
292 *   </tr>
293 * </table>
294 *
295 * @retval RTEMS_SUCCESSFUL Successful operation.
296 * @retval RTEMS_IO_ERROR In the inquiry state this will abort the action.
297 * @retval RTEMS_INCORRECT_STATE In the failed state this will cause a retry.
298 * Make sure to have a retry counter or similar to avoid endless loops if you
299 * use this value.
300 */
301typedef rtems_status_code (*rtems_media_listener)(
302  rtems_media_event event,
303  rtems_media_state state,
304  const char *src,
305  const char *dest,
306  void *listener_arg
307);
308
309/**
310 * @brief Do the work corresponding to an event.
311 *
312 * The @a state will be
313 * - RTEMS_MEDIA_STATE_READY, or
314 * - RTEMS_MEDIA_STATE_ABORTED.
315 *
316 * It will be called with the @a src and @a worker_arg arguments passed to
317 * rtems_media_post_event().
318 *
319 * The destination shall be returned in @a dest in case of success.  It shall
320 * be allocated with malloc().
321 *
322 * @retval RTEMS_SUCCESSFUL Successful operation.
323 * @retval RTEMS_IO_ERROR Failure.
324 */
325typedef rtems_status_code (*rtems_media_worker)(
326  rtems_media_state state,
327  const char *src,
328  char **dest,
329  void *worker_arg
330);
331
332/**
333 * @name Base
334 */
335/**@{**/
336
337/**
338 * @brief Initializes the media manager.
339 *
340 * Calling this function more than once will have no effects.  There is no
341 * protection against concurrent access.
342 *
343 * @retval RTEMS_SUCCESSFUL Successful operation.
344 * @retval RTEMS_NO_MEMORY Not enough resources.
345 */
346RTEMS_INLINE_ROUTINE rtems_status_code rtems_media_initialize(void)
347{
348  return RTEMS_SUCCESSFUL;
349}
350
351/**
352 * @brief Adds the @a listener with argument @a listener_arg.
353 *
354 * @retval RTEMS_SUCCESSFUL Successful operation.
355 * @retval RTEMS_NO_MEMORY Not enough memory.
356 * @retval RTEMS_TOO_MANY Such a listener is already present.
357 */
358rtems_status_code rtems_media_listener_add(
359  rtems_media_listener listener,
360  void *listener_arg
361);
362
363/**
364 * @brief Removes the @a listener with argument @a listener_arg.
365 *
366 * @retval RTEMS_SUCCESSFUL Successful operation.
367 * @retval RTEMS_INVALID_ID No such listener is present.
368 */
369rtems_status_code rtems_media_listener_remove(
370  rtems_media_listener listener,
371  void *listener_arg
372);
373
374/**
375 * @brief Posts the @a event with source @a src.
376 *
377 * The @a worker will be called with the @a worker_arg argument.
378 *
379 * The destination will be returned in @a dest in case of success.  It will be
380 * allocated with malloc() and should be freed if not needed anymore.
381 *
382 * The work will be done by the calling thread.  You can avoid this if you use
383 * the media server via rtems_media_server_post_event().
384 *
385 * @retval RTEMS_SUCCESSFUL Successful operation.
386 * @retval RTEMS_UNSATISFIED One or more listeners aborted the action.
387 * @retval RTEMS_IO_ERROR The worker returned with an error status.
388 */
389rtems_status_code rtems_media_post_event(
390  rtems_media_event event,
391  const char *src,
392  char **dest,
393  rtems_media_worker worker,
394  void *worker_arg
395);
396
397/** @} */
398
399/**
400 * @name Server
401 */
402/**@{**/
403
404/**
405 * @brief Initializes the media manager and media server.
406 *
407 * It creates a server task with the @a priority, @a stack_size, @a modes, and
408 * @a attributes parameters.
409 *
410 * Calling this function more than once will have no effects.  There is no
411 * protection against concurrent access.
412 *
413 * @retval RTEMS_SUCCESSFUL Successful operation.
414 * @retval RTEMS_NO_MEMORY Not enough resources.
415 */
416rtems_status_code rtems_media_server_initialize(
417  rtems_task_priority priority,
418  size_t stack_size,
419  rtems_mode modes,
420  rtems_attribute attributes
421);
422
423/**
424 * @brief Sends an event message to the media server.
425 *
426 * @see See rtems_media_post_event().
427 *
428 * @retval RTEMS_SUCCESSFUL Successful operation.
429 * @retval RTEMS_NO_MEMORY Not enough resources to notify the media server.
430 * @retval RTEMS_NOT_CONFIGURED Media server is not initialized.
431 */
432rtems_status_code rtems_media_server_post_event(
433  rtems_media_event event,
434  const char *src,
435  rtems_media_worker worker,
436  void *worker_arg
437);
438
439/**
440 * @brief See rtems_media_server_post_event().
441 */
442static inline rtems_status_code rtems_media_server_disk_attach(
443  const char *driver_name,
444  rtems_media_worker worker,
445  void *worker_arg
446)
447{
448  return rtems_media_server_post_event(
449    RTEMS_MEDIA_EVENT_DISK_ATTACH,
450    driver_name,
451    worker,
452    worker_arg
453  );
454}
455
456/**
457 * @brief See rtems_media_server_post_event().
458 */
459static inline rtems_status_code rtems_media_server_disk_detach(
460  const char *disk_path
461)
462{
463  return rtems_media_server_post_event(
464    RTEMS_MEDIA_EVENT_DISK_DETACH,
465    disk_path,
466    NULL,
467    NULL
468  );
469}
470
471/** @} */
472
473/**
474 * @name Path Construction
475 */
476/**@{**/
477
478/**
479 * @brief Creates a new path as "prefix/name-major".
480 *
481 * @return New string, or @c NULL if no memory is available.
482 */
483char *rtems_media_create_path(
484  const char *prefix,
485  const char *name,
486  rtems_device_major_number major
487);
488
489/**
490 * @brief Replaces the prefix of the @a path with @a new_prefix.
491 *
492 * The prefix is everything up to the last '/'.
493 *
494 * @return New string, or @c NULL if no memory is available.
495 */
496char *rtems_media_replace_prefix(const char *new_prefix, const char *path);
497
498/**
499 * @brief Appends the @a minor number to the @a path resulting in "path-minor".
500 *
501 * @return New string, or @c NULL if no memory is available.
502 */
503char *rtems_media_append_minor(
504  const char *path,
505  rtems_device_minor_number minor
506);
507
508/** @} */
509
510/**
511 * @name Support
512 */
513/**@{**/
514
515/**
516 * @brief Returns the device identifier for the device located at
517 * @a device_path in @a device_identifier.
518 *
519 * @retval RTEMS_SUCCESSFUL Successful operation.
520 * @retval RTEMS_INVALID_ID No device at this path.
521 */
522rtems_status_code rtems_media_get_device_identifier(
523  const char *device_path,
524  dev_t *device_identifier
525);
526
527const char *rtems_media_event_description(rtems_media_event event);
528
529const char *rtems_media_state_description(rtems_media_state state);
530
531/** @} */
532
533/** @} */
534
535#ifdef __cplusplus
536}
537#endif /* __cplusplus */
538
539#endif /* RTEMS_MEDIA_H */
Note: See TracBrowser for help on using the repository browser.