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