1 #include <minix/drivers.h>
2 #include <minix/chardriver.h>
9 * Function prototypes for the hello driver.
11 static int hello_open(devminor_t minor
, int access
, endpoint_t user_endpt
);
12 static int hello_close(devminor_t minor
);
13 static ssize_t
hello_read(devminor_t minor
, u64_t position
, endpoint_t endpt
,
14 cp_grant_id_t grant
, size_t size
, int flags
, cdev_id_t id
);
16 /* SEF functions and variables. */
17 static void sef_local_startup(void);
18 static int sef_cb_init(int type
, sef_init_info_t
*info
);
19 static int sef_cb_lu_state_save(int);
20 static int lu_state_restore(void);
22 /* Entry points to the hello driver. */
23 static struct chardriver hello_tab
=
25 .cdr_open
= hello_open
,
26 .cdr_close
= hello_close
,
27 .cdr_read
= hello_read
,
30 /** State variable to count the number of times the device has been opened.
31 * Note that this is not the regular type of open counter: it never decreases.
33 static int open_counter
;
35 static int hello_open(devminor_t
UNUSED(minor
), int UNUSED(access
),
36 endpoint_t
UNUSED(user_endpt
))
38 printf("hello_open(). Called %d time(s).\n", ++open_counter
);
42 static int hello_close(devminor_t
UNUSED(minor
))
44 printf("hello_close()\n");
48 static ssize_t
hello_read(devminor_t
UNUSED(minor
), u64_t position
,
49 endpoint_t endpt
, cp_grant_id_t grant
, size_t size
, int UNUSED(flags
),
55 char *buf
= HELLO_MESSAGE
;
57 printf("hello_read()\n");
59 /* This is the total size of our device. */
60 dev_size
= (u64_t
) strlen(buf
);
62 /* Check for EOF, and possibly limit the read size. */
63 if (position
>= dev_size
) return 0; /* EOF */
64 if (position
+ size
> dev_size
)
65 size
= (size_t)(dev_size
- position
); /* limit size */
67 /* Copy the requested part to the caller. */
68 ptr
= buf
+ (size_t)position
;
69 if ((ret
= sys_safecopyto(endpt
, grant
, 0, (vir_bytes
) ptr
, size
)) != OK
)
72 /* Return the number of bytes read. */
76 static int sef_cb_lu_state_save(int UNUSED(state
)) {
78 ds_publish_u32("open_counter", open_counter
, DSF_OVERWRITE
);
83 static int lu_state_restore() {
84 /* Restore the state. */
87 ds_retrieve_u32("open_counter", &value
);
88 ds_delete_u32("open_counter");
89 open_counter
= (int) value
;
94 static void sef_local_startup()
97 * Register init callbacks. Use the same function for all event types
99 sef_setcb_init_fresh(sef_cb_init
);
100 sef_setcb_init_lu(sef_cb_init
);
101 sef_setcb_init_restart(sef_cb_init
);
104 * Register live update callbacks.
106 /* - Agree to update immediately when LU is requested in a valid state. */
107 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
108 /* - Support live update starting from any standard state. */
109 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard
);
110 /* - Register a custom routine to save the state. */
111 sef_setcb_lu_state_save(sef_cb_lu_state_save
);
113 /* Let SEF perform startup. */
117 static int sef_cb_init(int type
, sef_init_info_t
*UNUSED(info
))
119 /* Initialize the hello driver. */
120 int do_announce_driver
= TRUE
;
125 printf("%s", HELLO_MESSAGE
);
129 /* Restore the state. */
131 do_announce_driver
= FALSE
;
133 printf("%sHey, I'm a new version!\n", HELLO_MESSAGE
);
136 case SEF_INIT_RESTART
:
137 printf("%sHey, I've just been restarted!\n", HELLO_MESSAGE
);
141 /* Announce we are up when necessary. */
142 if (do_announce_driver
) {
143 chardriver_announce();
146 /* Initialization completed successfully. */
153 * Perform initialization.
160 chardriver_task(&hello_tab
);