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" 7 8 /* 9 * Function prototypes for the hello driver. 10 */ 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); 15 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, int); 20 static int lu_state_restore(void); 21 22 /* Entry points to the hello driver. */ 23 static struct chardriver hello_tab = 24 { 25 .cdr_open = hello_open, 26 .cdr_close = hello_close, 27 .cdr_read = hello_read, 28 }; 29 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. 32 */ 33 static int open_counter; 34 35 static int hello_open(devminor_t UNUSED(minor), int UNUSED(access), 36 endpoint_t UNUSED(user_endpt)) 37 { 38 printf("hello_open(). Called %d time(s).\n", ++open_counter); 39 return OK; 40 } 41 42 static int hello_close(devminor_t UNUSED(minor)) 43 { 44 printf("hello_close()\n"); 45 return OK; 46 } 47 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)) 51 { 52 u64_t dev_size; 53 char *ptr; 54 int ret; 55 char *buf = HELLO_MESSAGE; 56 57 printf("hello_read()\n"); 58 59 /* This is the total size of our device. */ 60 dev_size = (u64_t) strlen(buf); 61 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 */ 66 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; 71 72 /* Return the number of bytes read. */ 73 return size; 74 } 75 76 static int sef_cb_lu_state_save(int UNUSED(state), int UNUSED(flags)) { 77 /* Save the state. */ 78 ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE); 79 80 return OK; 81 } 82 83 static int lu_state_restore() { 84 /* Restore the state. */ 85 u32_t value; 86 87 ds_retrieve_u32("open_counter", &value); 88 ds_delete_u32("open_counter"); 89 open_counter = (int) value; 90 91 return OK; 92 } 93 94 static void sef_local_startup() 95 { 96 /* 97 * Register init callbacks. Use the same function for all event types 98 */ 99 sef_setcb_init_fresh(sef_cb_init); 100 sef_setcb_init_lu(sef_cb_init); 101 sef_setcb_init_restart(sef_cb_init); 102 103 /* 104 * Register live update callbacks. 105 */ 106 sef_setcb_lu_state_save(sef_cb_lu_state_save); 107 108 /* Let SEF perform startup. */ 109 sef_startup(); 110 } 111 112 static int sef_cb_init(int type, sef_init_info_t *UNUSED(info)) 113 { 114 /* Initialize the hello driver. */ 115 int do_announce_driver = TRUE; 116 117 open_counter = 0; 118 switch(type) { 119 case SEF_INIT_FRESH: 120 printf("%s", HELLO_MESSAGE); 121 break; 122 123 case SEF_INIT_LU: 124 /* Restore the state. */ 125 lu_state_restore(); 126 do_announce_driver = FALSE; 127 128 printf("%sHey, I'm a new version!\n", HELLO_MESSAGE); 129 break; 130 131 case SEF_INIT_RESTART: 132 printf("%sHey, I've just been restarted!\n", HELLO_MESSAGE); 133 break; 134 } 135 136 /* Announce we are up when necessary. */ 137 if (do_announce_driver) { 138 chardriver_announce(); 139 } 140 141 /* Initialization completed successfully. */ 142 return OK; 143 } 144 145 int main(void) 146 { 147 /* 148 * Perform initialization. 149 */ 150 sef_local_startup(); 151 152 /* 153 * Run the main loop. 154 */ 155 chardriver_task(&hello_tab); 156 return OK; 157 } 158 159