1433d6423SLionel Sambuc #include <minix/drivers.h>
2433d6423SLionel Sambuc #include <minix/chardriver.h>
3433d6423SLionel Sambuc #include <stdio.h>
4433d6423SLionel Sambuc #include <stdlib.h>
5433d6423SLionel Sambuc #include <minix/ds.h>
6433d6423SLionel Sambuc #include "hello.h"
7433d6423SLionel Sambuc
8433d6423SLionel Sambuc /*
9433d6423SLionel Sambuc * Function prototypes for the hello driver.
10433d6423SLionel Sambuc */
11433d6423SLionel Sambuc static int hello_open(devminor_t minor, int access, endpoint_t user_endpt);
12433d6423SLionel Sambuc static int hello_close(devminor_t minor);
13433d6423SLionel Sambuc static ssize_t hello_read(devminor_t minor, u64_t position, endpoint_t endpt,
14433d6423SLionel Sambuc cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
15433d6423SLionel Sambuc
16433d6423SLionel Sambuc /* SEF functions and variables. */
17433d6423SLionel Sambuc static void sef_local_startup(void);
18433d6423SLionel Sambuc static int sef_cb_init(int type, sef_init_info_t *info);
19*e1f889d2SCristiano Giuffrida static int sef_cb_lu_state_save(int, int);
20433d6423SLionel Sambuc static int lu_state_restore(void);
21433d6423SLionel Sambuc
22433d6423SLionel Sambuc /* Entry points to the hello driver. */
23433d6423SLionel Sambuc static struct chardriver hello_tab =
24433d6423SLionel Sambuc {
25433d6423SLionel Sambuc .cdr_open = hello_open,
26433d6423SLionel Sambuc .cdr_close = hello_close,
27433d6423SLionel Sambuc .cdr_read = hello_read,
28433d6423SLionel Sambuc };
29433d6423SLionel Sambuc
30433d6423SLionel Sambuc /** State variable to count the number of times the device has been opened.
31433d6423SLionel Sambuc * Note that this is not the regular type of open counter: it never decreases.
32433d6423SLionel Sambuc */
33433d6423SLionel Sambuc static int open_counter;
34433d6423SLionel Sambuc
hello_open(devminor_t UNUSED (minor),int UNUSED (access),endpoint_t UNUSED (user_endpt))35433d6423SLionel Sambuc static int hello_open(devminor_t UNUSED(minor), int UNUSED(access),
36433d6423SLionel Sambuc endpoint_t UNUSED(user_endpt))
37433d6423SLionel Sambuc {
38433d6423SLionel Sambuc printf("hello_open(). Called %d time(s).\n", ++open_counter);
39433d6423SLionel Sambuc return OK;
40433d6423SLionel Sambuc }
41433d6423SLionel Sambuc
hello_close(devminor_t UNUSED (minor))42433d6423SLionel Sambuc static int hello_close(devminor_t UNUSED(minor))
43433d6423SLionel Sambuc {
44433d6423SLionel Sambuc printf("hello_close()\n");
45433d6423SLionel Sambuc return OK;
46433d6423SLionel Sambuc }
47433d6423SLionel Sambuc
hello_read(devminor_t UNUSED (minor),u64_t position,endpoint_t endpt,cp_grant_id_t grant,size_t size,int UNUSED (flags),cdev_id_t UNUSED (id))48433d6423SLionel Sambuc static ssize_t hello_read(devminor_t UNUSED(minor), u64_t position,
49433d6423SLionel Sambuc endpoint_t endpt, cp_grant_id_t grant, size_t size, int UNUSED(flags),
50433d6423SLionel Sambuc cdev_id_t UNUSED(id))
51433d6423SLionel Sambuc {
52433d6423SLionel Sambuc u64_t dev_size;
53433d6423SLionel Sambuc char *ptr;
54433d6423SLionel Sambuc int ret;
55433d6423SLionel Sambuc char *buf = HELLO_MESSAGE;
56433d6423SLionel Sambuc
57433d6423SLionel Sambuc printf("hello_read()\n");
58433d6423SLionel Sambuc
59433d6423SLionel Sambuc /* This is the total size of our device. */
60433d6423SLionel Sambuc dev_size = (u64_t) strlen(buf);
61433d6423SLionel Sambuc
62433d6423SLionel Sambuc /* Check for EOF, and possibly limit the read size. */
63433d6423SLionel Sambuc if (position >= dev_size) return 0; /* EOF */
64433d6423SLionel Sambuc if (position + size > dev_size)
65433d6423SLionel Sambuc size = (size_t)(dev_size - position); /* limit size */
66433d6423SLionel Sambuc
67433d6423SLionel Sambuc /* Copy the requested part to the caller. */
68433d6423SLionel Sambuc ptr = buf + (size_t)position;
69433d6423SLionel Sambuc if ((ret = sys_safecopyto(endpt, grant, 0, (vir_bytes) ptr, size)) != OK)
70433d6423SLionel Sambuc return ret;
71433d6423SLionel Sambuc
72433d6423SLionel Sambuc /* Return the number of bytes read. */
73433d6423SLionel Sambuc return size;
74433d6423SLionel Sambuc }
75433d6423SLionel Sambuc
sef_cb_lu_state_save(int UNUSED (state),int UNUSED (flags))76*e1f889d2SCristiano Giuffrida static int sef_cb_lu_state_save(int UNUSED(state), int UNUSED(flags)) {
77433d6423SLionel Sambuc /* Save the state. */
78433d6423SLionel Sambuc ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE);
79433d6423SLionel Sambuc
80433d6423SLionel Sambuc return OK;
81433d6423SLionel Sambuc }
82433d6423SLionel Sambuc
lu_state_restore()83433d6423SLionel Sambuc static int lu_state_restore() {
84433d6423SLionel Sambuc /* Restore the state. */
85433d6423SLionel Sambuc u32_t value;
86433d6423SLionel Sambuc
87433d6423SLionel Sambuc ds_retrieve_u32("open_counter", &value);
88433d6423SLionel Sambuc ds_delete_u32("open_counter");
89433d6423SLionel Sambuc open_counter = (int) value;
90433d6423SLionel Sambuc
91433d6423SLionel Sambuc return OK;
92433d6423SLionel Sambuc }
93433d6423SLionel Sambuc
sef_local_startup()94433d6423SLionel Sambuc static void sef_local_startup()
95433d6423SLionel Sambuc {
96433d6423SLionel Sambuc /*
97433d6423SLionel Sambuc * Register init callbacks. Use the same function for all event types
98433d6423SLionel Sambuc */
99433d6423SLionel Sambuc sef_setcb_init_fresh(sef_cb_init);
100433d6423SLionel Sambuc sef_setcb_init_lu(sef_cb_init);
101433d6423SLionel Sambuc sef_setcb_init_restart(sef_cb_init);
102433d6423SLionel Sambuc
103433d6423SLionel Sambuc /*
104433d6423SLionel Sambuc * Register live update callbacks.
105433d6423SLionel Sambuc */
106433d6423SLionel Sambuc sef_setcb_lu_state_save(sef_cb_lu_state_save);
107433d6423SLionel Sambuc
108433d6423SLionel Sambuc /* Let SEF perform startup. */
109433d6423SLionel Sambuc sef_startup();
110433d6423SLionel Sambuc }
111433d6423SLionel Sambuc
sef_cb_init(int type,sef_init_info_t * UNUSED (info))112433d6423SLionel Sambuc static int sef_cb_init(int type, sef_init_info_t *UNUSED(info))
113433d6423SLionel Sambuc {
114433d6423SLionel Sambuc /* Initialize the hello driver. */
115433d6423SLionel Sambuc int do_announce_driver = TRUE;
116433d6423SLionel Sambuc
117433d6423SLionel Sambuc open_counter = 0;
118433d6423SLionel Sambuc switch(type) {
119433d6423SLionel Sambuc case SEF_INIT_FRESH:
120433d6423SLionel Sambuc printf("%s", HELLO_MESSAGE);
121433d6423SLionel Sambuc break;
122433d6423SLionel Sambuc
123433d6423SLionel Sambuc case SEF_INIT_LU:
124433d6423SLionel Sambuc /* Restore the state. */
125433d6423SLionel Sambuc lu_state_restore();
126433d6423SLionel Sambuc do_announce_driver = FALSE;
127433d6423SLionel Sambuc
128433d6423SLionel Sambuc printf("%sHey, I'm a new version!\n", HELLO_MESSAGE);
129433d6423SLionel Sambuc break;
130433d6423SLionel Sambuc
131433d6423SLionel Sambuc case SEF_INIT_RESTART:
132433d6423SLionel Sambuc printf("%sHey, I've just been restarted!\n", HELLO_MESSAGE);
133433d6423SLionel Sambuc break;
134433d6423SLionel Sambuc }
135433d6423SLionel Sambuc
136433d6423SLionel Sambuc /* Announce we are up when necessary. */
137433d6423SLionel Sambuc if (do_announce_driver) {
138433d6423SLionel Sambuc chardriver_announce();
139433d6423SLionel Sambuc }
140433d6423SLionel Sambuc
141433d6423SLionel Sambuc /* Initialization completed successfully. */
142433d6423SLionel Sambuc return OK;
143433d6423SLionel Sambuc }
144433d6423SLionel Sambuc
main(void)145433d6423SLionel Sambuc int main(void)
146433d6423SLionel Sambuc {
147433d6423SLionel Sambuc /*
148433d6423SLionel Sambuc * Perform initialization.
149433d6423SLionel Sambuc */
150433d6423SLionel Sambuc sef_local_startup();
151433d6423SLionel Sambuc
152433d6423SLionel Sambuc /*
153433d6423SLionel Sambuc * Run the main loop.
154433d6423SLionel Sambuc */
155433d6423SLionel Sambuc chardriver_task(&hello_tab);
156433d6423SLionel Sambuc return OK;
157433d6423SLionel Sambuc }
158433d6423SLionel Sambuc
159