xref: /minix3/minix/drivers/usb/usbd/base/usbd.c (revision 2d64210c1dbcd340904718f2d4e9e81adeab3c7d)
1433d6423SLionel Sambuc /*
2433d6423SLionel Sambuc  * Entry point for USBD service, that handles USB HCDs
3433d6423SLionel Sambuc  */
4433d6423SLionel Sambuc 
5433d6423SLionel Sambuc #include <ddekit/ddekit.h>		/* ddekit_init */
6433d6423SLionel Sambuc #include <ddekit/thread.h>		/* DDEKit threading */
7433d6423SLionel Sambuc 
8433d6423SLionel Sambuc #include <libdde/usb_server.h>		/* DDEKit USB server */
9433d6423SLionel Sambuc 
10433d6423SLionel Sambuc #include <minix/devman.h>		/* Initializing 'devman' */
11433d6423SLionel Sambuc #include <minix/sef.h>			/* SEF handling */
12433d6423SLionel Sambuc 
13*2d64210cSWojciech Zajac #include <usbd/usbd_common.h>
14*2d64210cSWojciech Zajac #include <usbd/usbd_interface.h>
15*2d64210cSWojciech Zajac #include <usbd/usbd_schedule.h>
16433d6423SLionel Sambuc 
17433d6423SLionel Sambuc 
18433d6423SLionel Sambuc /*===========================================================================*
19433d6423SLionel Sambuc  *    Local declarations                                                     *
20433d6423SLionel Sambuc  *===========================================================================*/
21433d6423SLionel Sambuc static int usbd_sef_handler(int, sef_init_info_t *);
22433d6423SLionel Sambuc static void usbd_signal_handler(int);
23433d6423SLionel Sambuc static int usbd_start(void);
24433d6423SLionel Sambuc static void usbd_init(void);
25433d6423SLionel Sambuc static void usbd_server_thread(void *);
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc /* TODO: No headers for these... */
28433d6423SLionel Sambuc extern void ddekit_minix_wait_exit(void);	/* dde.c */
29433d6423SLionel Sambuc extern void ddekit_shutdown(void);		/* dde.c */
30433d6423SLionel Sambuc 
31433d6423SLionel Sambuc 
32433d6423SLionel Sambuc /*===========================================================================*
33433d6423SLionel Sambuc  *    main                                                                   *
34433d6423SLionel Sambuc  *===========================================================================*/
35433d6423SLionel Sambuc int
main(int UNUSED (argc),char * UNUSED (argv[]))36433d6423SLionel Sambuc main(int UNUSED(argc), char * UNUSED(argv[]))
37433d6423SLionel Sambuc {
38433d6423SLionel Sambuc 	int ret_val;
39433d6423SLionel Sambuc 
40433d6423SLionel Sambuc 	USB_MSG("Starting USBD");
41*2d64210cSWojciech Zajac 	USB_MSG("Built: %s %s", __DATE__, __TIME__);
42433d6423SLionel Sambuc 
43433d6423SLionel Sambuc 	/* Basic SEF,DDE,... initialization */
44433d6423SLionel Sambuc 	usbd_init();
45433d6423SLionel Sambuc 
46433d6423SLionel Sambuc 	/* Assume failure unless usbd_start exits gracefully */
47433d6423SLionel Sambuc 	ret_val = EXIT_FAILURE;
48433d6423SLionel Sambuc 
49433d6423SLionel Sambuc 	/* USB host controllers initialization */
50433d6423SLionel Sambuc 	if (EXIT_SUCCESS == usbd_init_hcd()) {
51433d6423SLionel Sambuc 
52433d6423SLionel Sambuc 		/* Try initializing 'devman' */
53433d6423SLionel Sambuc 		if (EXIT_SUCCESS == devman_init()) {
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc 			/* Run USB driver (actually DDEKit threads)
56433d6423SLionel Sambuc 			 * until this call returns: */
57433d6423SLionel Sambuc 			ret_val = usbd_start();
58433d6423SLionel Sambuc 
59433d6423SLionel Sambuc 		} else
60433d6423SLionel Sambuc 			USB_MSG("Initializing devman, failed");
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc 		/* Clean whatever was initialized */
63433d6423SLionel Sambuc 		usbd_deinit_hcd();
64433d6423SLionel Sambuc 
65433d6423SLionel Sambuc 	} else
66433d6423SLionel Sambuc 		USB_MSG("Initializing HCDs, failed");
67433d6423SLionel Sambuc 
68433d6423SLionel Sambuc 	return ret_val;
69433d6423SLionel Sambuc }
70433d6423SLionel Sambuc 
71433d6423SLionel Sambuc 
72433d6423SLionel Sambuc /*===========================================================================*
73433d6423SLionel Sambuc  *    usbd_sef_handler                                                       *
74433d6423SLionel Sambuc  *===========================================================================*/
75433d6423SLionel Sambuc static int
usbd_sef_handler(int type,sef_init_info_t * UNUSED (info))76433d6423SLionel Sambuc usbd_sef_handler(int type, sef_init_info_t * UNUSED(info))
77433d6423SLionel Sambuc {
78*2d64210cSWojciech Zajac 	/* No DEBUG_DUMP, threading unavailable yet */
79433d6423SLionel Sambuc 
80433d6423SLionel Sambuc 	switch (type) {
81433d6423SLionel Sambuc 		case SEF_INIT_FRESH:
82433d6423SLionel Sambuc 			USB_MSG("Initializing");
83433d6423SLionel Sambuc 			return EXIT_SUCCESS;
84433d6423SLionel Sambuc 
85433d6423SLionel Sambuc 		case SEF_INIT_LU:
86433d6423SLionel Sambuc 			USB_MSG("Updating, not implemented");
87433d6423SLionel Sambuc 			return EXIT_FAILURE;
88433d6423SLionel Sambuc 
89433d6423SLionel Sambuc 		case SEF_INIT_RESTART:
90433d6423SLionel Sambuc 			USB_MSG("Restarting, not implemented");
91433d6423SLionel Sambuc 			return EXIT_FAILURE;
92433d6423SLionel Sambuc 
93433d6423SLionel Sambuc 		default:
94433d6423SLionel Sambuc 			USB_MSG("illegal SEF type");
95433d6423SLionel Sambuc 			return EXIT_FAILURE;
96433d6423SLionel Sambuc 	}
97433d6423SLionel Sambuc }
98433d6423SLionel Sambuc 
99433d6423SLionel Sambuc 
100433d6423SLionel Sambuc /*===========================================================================*
101433d6423SLionel Sambuc  *    usbd_signal_handler                                                    *
102433d6423SLionel Sambuc  *===========================================================================*/
103433d6423SLionel Sambuc static void
usbd_signal_handler(int UNUSED (signo))104433d6423SLionel Sambuc usbd_signal_handler(int UNUSED(signo))
105433d6423SLionel Sambuc {
106433d6423SLionel Sambuc 	DEBUG_DUMP;
107433d6423SLionel Sambuc 
108433d6423SLionel Sambuc 	USB_MSG("Signal received, exiting USBD...");
109433d6423SLionel Sambuc 
110433d6423SLionel Sambuc 	/* Try graceful DDEKit exit */
111433d6423SLionel Sambuc 	ddekit_shutdown();
112433d6423SLionel Sambuc 
113433d6423SLionel Sambuc 	/* Unreachable, when ddekit_shutdown works correctly */
114433d6423SLionel Sambuc 	USB_ASSERT(0, "Calling ddekit_shutdown failed!");
115433d6423SLionel Sambuc }
116433d6423SLionel Sambuc 
117433d6423SLionel Sambuc 
118433d6423SLionel Sambuc /*===========================================================================*
119433d6423SLionel Sambuc  *    usbd_start                                                             *
120433d6423SLionel Sambuc  *===========================================================================*/
121433d6423SLionel Sambuc static int
usbd_start(void)122433d6423SLionel Sambuc usbd_start(void)
123433d6423SLionel Sambuc {
124433d6423SLionel Sambuc 	ddekit_thread_t * usbd_th;
125433d6423SLionel Sambuc 
126433d6423SLionel Sambuc 	DEBUG_DUMP;
127433d6423SLionel Sambuc 
128433d6423SLionel Sambuc 	/* Driver's "main loop" is within DDEKit server thread */
129*2d64210cSWojciech Zajac 	usbd_th = ddekit_thread_create(usbd_server_thread, NULL, "ddekit_usb");
130433d6423SLionel Sambuc 
131433d6423SLionel Sambuc 	/* After spawning, allow server thread to work */
132433d6423SLionel Sambuc 	if (NULL != usbd_th) {
133*2d64210cSWojciech Zajac 
134*2d64210cSWojciech Zajac 		/* Allow URB scheduling */
135*2d64210cSWojciech Zajac 		if (usbd_init_scheduler()) {
136*2d64210cSWojciech Zajac 			USB_MSG("Failed to start URB scheduler");
137*2d64210cSWojciech Zajac 		} else {
138433d6423SLionel Sambuc 			/* This will lock current thread until DDEKit exits */
139433d6423SLionel Sambuc 			ddekit_minix_wait_exit();
140*2d64210cSWojciech Zajac 		}
141*2d64210cSWojciech Zajac 
142*2d64210cSWojciech Zajac 		/* Disallow URB scheduling */
143*2d64210cSWojciech Zajac 		usbd_deinit_scheduler();
144433d6423SLionel Sambuc 
145433d6423SLionel Sambuc 		/* Cleanup */
146433d6423SLionel Sambuc 		ddekit_thread_terminate(usbd_th);
147433d6423SLionel Sambuc 
148433d6423SLionel Sambuc 		return EXIT_SUCCESS;
149433d6423SLionel Sambuc 	} else
150433d6423SLionel Sambuc 		return EXIT_FAILURE;
151433d6423SLionel Sambuc }
152433d6423SLionel Sambuc 
153433d6423SLionel Sambuc 
154433d6423SLionel Sambuc /*===========================================================================*
155433d6423SLionel Sambuc  *    usbd_init                                                              *
156433d6423SLionel Sambuc  *===========================================================================*/
157433d6423SLionel Sambuc static void
usbd_init(void)158433d6423SLionel Sambuc usbd_init(void)
159433d6423SLionel Sambuc {
160*2d64210cSWojciech Zajac 	/* No DEBUG_DUMP, threading unavailable yet */
161433d6423SLionel Sambuc 
162433d6423SLionel Sambuc 	/* Set one handler for all messages */
163433d6423SLionel Sambuc 	sef_setcb_init_fresh(usbd_sef_handler);
164433d6423SLionel Sambuc 	sef_setcb_init_lu(usbd_sef_handler);
165433d6423SLionel Sambuc 	sef_setcb_init_restart(usbd_sef_handler);
166433d6423SLionel Sambuc 
167433d6423SLionel Sambuc 	/* Initialize DDEkit (involves sef_startup()) */
168433d6423SLionel Sambuc 	ddekit_init();
169*2d64210cSWojciech Zajac 
170*2d64210cSWojciech Zajac 	/* After threading initialization, add signal handler */
171*2d64210cSWojciech Zajac 	sef_setcb_signal_handler(usbd_signal_handler);
172433d6423SLionel Sambuc }
173433d6423SLionel Sambuc 
174433d6423SLionel Sambuc 
175433d6423SLionel Sambuc /*===========================================================================*
176433d6423SLionel Sambuc  *    usbd_server_thread                                                     *
177433d6423SLionel Sambuc  *===========================================================================*/
178433d6423SLionel Sambuc static void
usbd_server_thread(void * UNUSED (unused))179433d6423SLionel Sambuc usbd_server_thread(void * UNUSED(unused))
180433d6423SLionel Sambuc {
181433d6423SLionel Sambuc 	DEBUG_DUMP;
182433d6423SLionel Sambuc 
183433d6423SLionel Sambuc 	ddekit_usb_server_init();
184433d6423SLionel Sambuc }
185