memory: use sys_safememset() for /dev/zero
[minix.git] / drivers / hello / hello.c
blob0dd6a27e4870f70bf5a2724fb0e29239271379d7
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(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
16 flags);
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 =
27 hello_open,
28 hello_close,
29 nop_ioctl,
30 hello_prepare,
31 hello_transfer,
32 nop_cleanup,
33 nop_alarm,
34 nop_cancel,
35 nop_select,
36 NULL
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);
48 return OK;
51 static int hello_close(message *UNUSED(m))
53 printf("hello_close()\n");
54 return OK;
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);
61 return &hello_device;
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))
68 int bytes, ret;
70 printf("hello_transfer()\n");
72 if (nr_req != 1)
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;
81 if (bytes <= 0)
83 return OK;
85 switch (opcode)
87 case DEV_GATHER_S:
88 ret = sys_safecopyto(endpt, (cp_grant_id_t) iov->iov_addr, 0,
89 (vir_bytes) (HELLO_MESSAGE + ex64lo(position)),
90 bytes);
91 iov->iov_size -= bytes;
92 break;
94 default:
95 return EINVAL;
97 return ret;
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);
104 return OK;
107 static int lu_state_restore() {
108 /* Restore the state. */
109 u32_t value;
111 ds_retrieve_u32("open_counter", &value);
112 ds_delete_u32("open_counter");
113 open_counter = (int) value;
115 return OK;
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. */
138 sef_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;
146 open_counter = 0;
147 switch(type) {
148 case SEF_INIT_FRESH:
149 printf("%s", HELLO_MESSAGE);
150 break;
152 case SEF_INIT_LU:
153 /* Restore the state. */
154 lu_state_restore();
155 do_announce_driver = FALSE;
157 printf("%sHey, I'm a new version!\n", HELLO_MESSAGE);
158 break;
160 case SEF_INIT_RESTART:
161 printf("%sHey, I've just been restarted!\n", HELLO_MESSAGE);
162 break;
165 /* Announce we are up when necessary. */
166 if (do_announce_driver) {
167 chardriver_announce();
170 /* Initialization completed successfully. */
171 return OK;
174 int main(void)
177 * Perform initialization.
179 sef_local_startup();
182 * Run the main loop.
184 chardriver_task(&hello_tab, CHARDRIVER_SYNC);
185 return OK;