1 #include <minix/drivers.h>
2 #include <minix/chardriver.h>
9 * Function prototypes for the hello driver.
11 static int hello_open(message
*m
);
12 static int hello_close(message
*m
);
13 static struct device
* hello_prepare(dev_t device
);
14 static int hello_transfer(endpoint_t endpt
, int opcode
, u64_t position
,
15 iovec_t
*iov
, unsigned int nr_req
, endpoint_t user_endpt
, unsigned int
18 /* SEF functions and variables. */
19 static void sef_local_startup(void);
20 static int sef_cb_init(int type
, sef_init_info_t
*info
);
21 static int sef_cb_lu_state_save(int);
22 static int lu_state_restore(void);
24 /* Entry points to the hello driver. */
25 static struct chardriver hello_tab
=
39 /** Represents the /dev/hello device. */
40 static struct device hello_device
;
42 /** State variable to count the number of times the device has been opened. */
43 static int open_counter
;
45 static int hello_open(message
*UNUSED(m
))
47 printf("hello_open(). Called %d time(s).\n", ++open_counter
);
51 static int hello_close(message
*UNUSED(m
))
53 printf("hello_close()\n");
57 static struct device
* hello_prepare(dev_t
UNUSED(dev
))
59 hello_device
.dv_base
= make64(0, 0);
60 hello_device
.dv_size
= make64(strlen(HELLO_MESSAGE
), 0);
64 static int hello_transfer(endpoint_t endpt
, int opcode
, u64_t position
,
65 iovec_t
*iov
, unsigned nr_req
, endpoint_t
UNUSED(user_endpt
),
66 unsigned int UNUSED(flags
))
70 printf("hello_transfer()\n");
74 /* This should never trigger for character drivers at the moment. */
75 printf("HELLO: vectored transfer request, using first element only\n");
78 bytes
= strlen(HELLO_MESSAGE
) - ex64lo(position
) < iov
->iov_size
?
79 strlen(HELLO_MESSAGE
) - ex64lo(position
) : iov
->iov_size
;
88 ret
= sys_safecopyto(endpt
, (cp_grant_id_t
) iov
->iov_addr
, 0,
89 (vir_bytes
) (HELLO_MESSAGE
+ ex64lo(position
)),
91 iov
->iov_size
-= bytes
;
100 static int sef_cb_lu_state_save(int UNUSED(state
)) {
101 /* Save the state. */
102 ds_publish_u32("open_counter", open_counter
, DSF_OVERWRITE
);
107 static int lu_state_restore() {
108 /* Restore the state. */
111 ds_retrieve_u32("open_counter", &value
);
112 ds_delete_u32("open_counter");
113 open_counter
= (int) value
;
118 static void sef_local_startup()
121 * Register init callbacks. Use the same function for all event types
123 sef_setcb_init_fresh(sef_cb_init
);
124 sef_setcb_init_lu(sef_cb_init
);
125 sef_setcb_init_restart(sef_cb_init
);
128 * Register live update callbacks.
130 /* - Agree to update immediately when LU is requested in a valid state. */
131 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready
);
132 /* - Support live update starting from any standard state. */
133 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard
);
134 /* - Register a custom routine to save the state. */
135 sef_setcb_lu_state_save(sef_cb_lu_state_save
);
137 /* Let SEF perform startup. */
141 static int sef_cb_init(int type
, sef_init_info_t
*UNUSED(info
))
143 /* Initialize the hello driver. */
144 int do_announce_driver
= TRUE
;
149 printf("%s", HELLO_MESSAGE
);
153 /* Restore the state. */
155 do_announce_driver
= FALSE
;
157 printf("%sHey, I'm a new version!\n", HELLO_MESSAGE
);
160 case SEF_INIT_RESTART
:
161 printf("%sHey, I've just been restarted!\n", HELLO_MESSAGE
);
165 /* Announce we are up when necessary. */
166 if (do_announce_driver
) {
167 chardriver_announce();
170 /* Initialization completed successfully. */
177 * Perform initialization.
184 chardriver_task(&hello_tab
, CHARDRIVER_SYNC
);