custom message type for VM_INFO
[minix3.git] / drivers / hello / hello.c
blob791e20e0ba7a8b8e4bbdd52d6150b29eb62d6e71
1 #include <minix/drivers.h>
2 #include <minix/chardriver.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <minix/ds.h>
6 #include "hello.h"
8 /*
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);
39 return OK;
42 static int hello_close(devminor_t UNUSED(minor))
44 printf("hello_close()\n");
45 return OK;
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),
50 cdev_id_t UNUSED(id))
52 u64_t dev_size;
53 char *ptr;
54 int ret;
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)
70 return ret;
72 /* Return the number of bytes read. */
73 return size;
76 static int sef_cb_lu_state_save(int UNUSED(state)) {
77 /* Save the state. */
78 ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE);
80 return OK;
83 static int lu_state_restore() {
84 /* Restore the state. */
85 u32_t value;
87 ds_retrieve_u32("open_counter", &value);
88 ds_delete_u32("open_counter");
89 open_counter = (int) value;
91 return OK;
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. */
114 sef_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;
122 open_counter = 0;
123 switch(type) {
124 case SEF_INIT_FRESH:
125 printf("%s", HELLO_MESSAGE);
126 break;
128 case SEF_INIT_LU:
129 /* Restore the state. */
130 lu_state_restore();
131 do_announce_driver = FALSE;
133 printf("%sHey, I'm a new version!\n", HELLO_MESSAGE);
134 break;
136 case SEF_INIT_RESTART:
137 printf("%sHey, I've just been restarted!\n", HELLO_MESSAGE);
138 break;
141 /* Announce we are up when necessary. */
142 if (do_announce_driver) {
143 chardriver_announce();
146 /* Initialization completed successfully. */
147 return OK;
150 int main(void)
153 * Perform initialization.
155 sef_local_startup();
158 * Run the main loop.
160 chardriver_task(&hello_tab);
161 return OK;