xref: /minix3/minix/servers/devman/bind.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #include "devman.h"
2*433d6423SLionel Sambuc #include "proto.h"
3*433d6423SLionel Sambuc 
4*433d6423SLionel Sambuc /*****************************************************************************
5*433d6423SLionel Sambuc  *    do_bind_device                                                         *
6*433d6423SLionel Sambuc  ****************************************************************************/
do_bind_device(message * m)7*433d6423SLionel Sambuc int do_bind_device(message *m)
8*433d6423SLionel Sambuc {
9*433d6423SLionel Sambuc 	struct devman_device *dev;
10*433d6423SLionel Sambuc 	int res;
11*433d6423SLionel Sambuc 	endpoint_t src = m->m_source;
12*433d6423SLionel Sambuc 
13*433d6423SLionel Sambuc 	/* check if msg comes from RS */
14*433d6423SLionel Sambuc 	if (src != RS_PROC_NR) {
15*433d6423SLionel Sambuc 		m->DEVMAN_RESULT = EPERM;
16*433d6423SLionel Sambuc 		printf("[W] could bind message from somebody else than RS\n");
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc 		return 0;
19*433d6423SLionel Sambuc 	} else {
20*433d6423SLionel Sambuc 		/* get the device */
21*433d6423SLionel Sambuc 		dev = devman_find_device(m->DEVMAN_DEVICE_ID);
22*433d6423SLionel Sambuc 		/* bind device at device provider*/
23*433d6423SLionel Sambuc 		if (dev != NULL) {
24*433d6423SLionel Sambuc 			m->m_type = DEVMAN_BIND;
25*433d6423SLionel Sambuc 			/* ...device ID and endpoint is still set */
26*433d6423SLionel Sambuc 
27*433d6423SLionel Sambuc #ifdef DEBUG
28*433d6423SLionel Sambuc 			printf("devman: bind call to %d for dev %d\n",
29*433d6423SLionel Sambuc 			    dev->owner, m->DEVMAN_DEVICE_ID);
30*433d6423SLionel Sambuc #endif
31*433d6423SLionel Sambuc 
32*433d6423SLionel Sambuc 			res = ipc_sendrec(dev->owner, m);
33*433d6423SLionel Sambuc 			if (res != OK) {
34*433d6423SLionel Sambuc 				printf("[W] devman.do_bind_device(): could not send "
35*433d6423SLionel Sambuc 				       "message to device owner (%d)\n", res);
36*433d6423SLionel Sambuc 				m->DEVMAN_RESULT= res;
37*433d6423SLionel Sambuc 			} else if (m->DEVMAN_RESULT != OK) {
38*433d6423SLionel Sambuc 				printf("[W] devman.do_bind_device(): driver could"
39*433d6423SLionel Sambuc 				       " not bind device (%ld)\n", m->DEVMAN_RESULT);
40*433d6423SLionel Sambuc 			} else {
41*433d6423SLionel Sambuc 				dev->state = DEVMAN_DEVICE_BOUND;
42*433d6423SLionel Sambuc 				devman_get_device(dev);
43*433d6423SLionel Sambuc 			}
44*433d6423SLionel Sambuc 		} else {
45*433d6423SLionel Sambuc 			m->DEVMAN_RESULT = ENODEV;
46*433d6423SLionel Sambuc 		}
47*433d6423SLionel Sambuc 		m->m_type = DEVMAN_REPLY;
48*433d6423SLionel Sambuc 		ipc_send(RS_PROC_NR, m);
49*433d6423SLionel Sambuc 	}
50*433d6423SLionel Sambuc 	return 0;
51*433d6423SLionel Sambuc }
52*433d6423SLionel Sambuc 
53*433d6423SLionel Sambuc /*****************************************************************************
54*433d6423SLionel Sambuc  *    do_unbind_device                                                       *
55*433d6423SLionel Sambuc  ****************************************************************************/
do_unbind_device(message * m)56*433d6423SLionel Sambuc int do_unbind_device(message *m)
57*433d6423SLionel Sambuc {
58*433d6423SLionel Sambuc 	struct devman_device *dev;
59*433d6423SLionel Sambuc 	int res;
60*433d6423SLionel Sambuc 	endpoint_t src = m->m_source;
61*433d6423SLionel Sambuc 
62*433d6423SLionel Sambuc 	/* check if msg comes from RS */
63*433d6423SLionel Sambuc 	if (src != RS_PROC_NR) {
64*433d6423SLionel Sambuc 		m->DEVMAN_RESULT = EPERM;
65*433d6423SLionel Sambuc 		printf("[W] devman.do_unbind_device(): unbind message from somebody"
66*433d6423SLionel Sambuc 		       "else than RS (%d)\n", src);
67*433d6423SLionel Sambuc 		return 0;
68*433d6423SLionel Sambuc 	} else {
69*433d6423SLionel Sambuc 		/* get the device */
70*433d6423SLionel Sambuc 		dev = devman_find_device(m->DEVMAN_DEVICE_ID);
71*433d6423SLionel Sambuc 		/* bind device at device provider*/
72*433d6423SLionel Sambuc 		if (dev != NULL) {
73*433d6423SLionel Sambuc 
74*433d6423SLionel Sambuc 			m->m_type = DEVMAN_UNBIND;
75*433d6423SLionel Sambuc 			/* ...device ID and endpoint is still set */
76*433d6423SLionel Sambuc #ifdef DEBUG
77*433d6423SLionel Sambuc 			printf("devman: unbind call to %d for dev %d\n",
78*433d6423SLionel Sambuc 			    dev->owner, m->DEVMAN_DEVICE_ID);
79*433d6423SLionel Sambuc #endif
80*433d6423SLionel Sambuc 			res = ipc_sendrec(dev->owner, m);
81*433d6423SLionel Sambuc 			if (res != OK) {
82*433d6423SLionel Sambuc 				printf("[W] devman.do_unbind_device(): could not send "
83*433d6423SLionel Sambuc 				       "message to device owner (%d)\n", res);
84*433d6423SLionel Sambuc 				m->DEVMAN_RESULT= res;
85*433d6423SLionel Sambuc 			} else if (m->DEVMAN_RESULT != OK && m->DEVMAN_RESULT != 19) {
86*433d6423SLionel Sambuc 				/* device drive deleted device already? */
87*433d6423SLionel Sambuc 				printf("[W] devman.do_unbind_device(): driver could"
88*433d6423SLionel Sambuc 				       " not unbind device (%ld)\n", m->DEVMAN_RESULT);
89*433d6423SLionel Sambuc 			} else {
90*433d6423SLionel Sambuc 				if (dev->state != DEVMAN_DEVICE_ZOMBIE) {
91*433d6423SLionel Sambuc 					dev->state = DEVMAN_DEVICE_UNBOUND;
92*433d6423SLionel Sambuc 				}
93*433d6423SLionel Sambuc 				devman_put_device(dev);
94*433d6423SLionel Sambuc 				m->DEVMAN_RESULT = OK;
95*433d6423SLionel Sambuc 			}
96*433d6423SLionel Sambuc 		} else {
97*433d6423SLionel Sambuc 			/* this might be the case, but perhaps its better to keep
98*433d6423SLionel Sambuc 			   the device in the db as long a driver is bound to it*/
99*433d6423SLionel Sambuc 			m->DEVMAN_RESULT = ENODEV;
100*433d6423SLionel Sambuc 		}
101*433d6423SLionel Sambuc 		m->m_type = DEVMAN_REPLY;
102*433d6423SLionel Sambuc 		ipc_send(RS_PROC_NR, m);
103*433d6423SLionel Sambuc 	}
104*433d6423SLionel Sambuc 	return 0;
105*433d6423SLionel Sambuc }
106