1 /*
2 * Entry point for USBD service, that handles USB HCDs
3 */
4
5 #include <ddekit/ddekit.h> /* ddekit_init */
6 #include <ddekit/thread.h> /* DDEKit threading */
7
8 #include <libdde/usb_server.h> /* DDEKit USB server */
9
10 #include <minix/devman.h> /* Initializing 'devman' */
11 #include <minix/sef.h> /* SEF handling */
12
13 #include <usbd/usbd_common.h>
14 #include <usbd/usbd_interface.h>
15 #include <usbd/usbd_schedule.h>
16
17
18 /*===========================================================================*
19 * Local declarations *
20 *===========================================================================*/
21 static int usbd_sef_handler(int, sef_init_info_t *);
22 static void usbd_signal_handler(int);
23 static int usbd_start(void);
24 static void usbd_init(void);
25 static void usbd_server_thread(void *);
26
27 /* TODO: No headers for these... */
28 extern void ddekit_minix_wait_exit(void); /* dde.c */
29 extern void ddekit_shutdown(void); /* dde.c */
30
31
32 /*===========================================================================*
33 * main *
34 *===========================================================================*/
35 int
main(int UNUSED (argc),char * UNUSED (argv[]))36 main(int UNUSED(argc), char * UNUSED(argv[]))
37 {
38 int ret_val;
39
40 USB_MSG("Starting USBD");
41 USB_MSG("Built: %s %s", __DATE__, __TIME__);
42
43 /* Basic SEF,DDE,... initialization */
44 usbd_init();
45
46 /* Assume failure unless usbd_start exits gracefully */
47 ret_val = EXIT_FAILURE;
48
49 /* USB host controllers initialization */
50 if (EXIT_SUCCESS == usbd_init_hcd()) {
51
52 /* Try initializing 'devman' */
53 if (EXIT_SUCCESS == devman_init()) {
54
55 /* Run USB driver (actually DDEKit threads)
56 * until this call returns: */
57 ret_val = usbd_start();
58
59 } else
60 USB_MSG("Initializing devman, failed");
61
62 /* Clean whatever was initialized */
63 usbd_deinit_hcd();
64
65 } else
66 USB_MSG("Initializing HCDs, failed");
67
68 return ret_val;
69 }
70
71
72 /*===========================================================================*
73 * usbd_sef_handler *
74 *===========================================================================*/
75 static int
usbd_sef_handler(int type,sef_init_info_t * UNUSED (info))76 usbd_sef_handler(int type, sef_init_info_t * UNUSED(info))
77 {
78 /* No DEBUG_DUMP, threading unavailable yet */
79
80 switch (type) {
81 case SEF_INIT_FRESH:
82 USB_MSG("Initializing");
83 return EXIT_SUCCESS;
84
85 case SEF_INIT_LU:
86 USB_MSG("Updating, not implemented");
87 return EXIT_FAILURE;
88
89 case SEF_INIT_RESTART:
90 USB_MSG("Restarting, not implemented");
91 return EXIT_FAILURE;
92
93 default:
94 USB_MSG("illegal SEF type");
95 return EXIT_FAILURE;
96 }
97 }
98
99
100 /*===========================================================================*
101 * usbd_signal_handler *
102 *===========================================================================*/
103 static void
usbd_signal_handler(int UNUSED (signo))104 usbd_signal_handler(int UNUSED(signo))
105 {
106 DEBUG_DUMP;
107
108 USB_MSG("Signal received, exiting USBD...");
109
110 /* Try graceful DDEKit exit */
111 ddekit_shutdown();
112
113 /* Unreachable, when ddekit_shutdown works correctly */
114 USB_ASSERT(0, "Calling ddekit_shutdown failed!");
115 }
116
117
118 /*===========================================================================*
119 * usbd_start *
120 *===========================================================================*/
121 static int
usbd_start(void)122 usbd_start(void)
123 {
124 ddekit_thread_t * usbd_th;
125
126 DEBUG_DUMP;
127
128 /* Driver's "main loop" is within DDEKit server thread */
129 usbd_th = ddekit_thread_create(usbd_server_thread, NULL, "ddekit_usb");
130
131 /* After spawning, allow server thread to work */
132 if (NULL != usbd_th) {
133
134 /* Allow URB scheduling */
135 if (usbd_init_scheduler()) {
136 USB_MSG("Failed to start URB scheduler");
137 } else {
138 /* This will lock current thread until DDEKit exits */
139 ddekit_minix_wait_exit();
140 }
141
142 /* Disallow URB scheduling */
143 usbd_deinit_scheduler();
144
145 /* Cleanup */
146 ddekit_thread_terminate(usbd_th);
147
148 return EXIT_SUCCESS;
149 } else
150 return EXIT_FAILURE;
151 }
152
153
154 /*===========================================================================*
155 * usbd_init *
156 *===========================================================================*/
157 static void
usbd_init(void)158 usbd_init(void)
159 {
160 /* No DEBUG_DUMP, threading unavailable yet */
161
162 /* Set one handler for all messages */
163 sef_setcb_init_fresh(usbd_sef_handler);
164 sef_setcb_init_lu(usbd_sef_handler);
165 sef_setcb_init_restart(usbd_sef_handler);
166
167 /* Initialize DDEkit (involves sef_startup()) */
168 ddekit_init();
169
170 /* After threading initialization, add signal handler */
171 sef_setcb_signal_handler(usbd_signal_handler);
172 }
173
174
175 /*===========================================================================*
176 * usbd_server_thread *
177 *===========================================================================*/
178 static void
usbd_server_thread(void * UNUSED (unused))179 usbd_server_thread(void * UNUSED(unused))
180 {
181 DEBUG_DUMP;
182
183 ddekit_usb_server_init();
184 }
185