xref: /haiku/src/add-ons/kernel/drivers/bus/pcmcia/ds.c (revision 4f9f2ee29da9e68b02891f78d4a8fafa28eb88da)
1*4f9f2ee2SJérôme Duval /*
2*4f9f2ee2SJérôme Duval  * Copyright 2005, Jérôme DUVAL. All rights reserved.
3*4f9f2ee2SJérôme Duval  * Distributed under the terms of the MIT License.
4*4f9f2ee2SJérôme Duval  */
5*4f9f2ee2SJérôme Duval 
6*4f9f2ee2SJérôme Duval #include <Drivers.h>
7*4f9f2ee2SJérôme Duval #include <OS.h>
8*4f9f2ee2SJérôme Duval #include <bus_manager.h>
9*4f9f2ee2SJérôme Duval #include <module.h>
10*4f9f2ee2SJérôme Duval #include <string.h>
11*4f9f2ee2SJérôme Duval #include <sys/ioctl.h>
12*4f9f2ee2SJérôme Duval #include <malloc.h>
13*4f9f2ee2SJérôme Duval #include <stdio.h>
14*4f9f2ee2SJérôme Duval 
15*4f9f2ee2SJérôme Duval #define __KERNEL__
16*4f9f2ee2SJérôme Duval #include <pcmcia/cs_types.h>
17*4f9f2ee2SJérôme Duval #include <pcmcia/cs.h>
18*4f9f2ee2SJérôme Duval #include <pcmcia/cistpl.h>
19*4f9f2ee2SJérôme Duval #include <pcmcia/ds.h>
20*4f9f2ee2SJérôme Duval 
21*4f9f2ee2SJérôme Duval #define copy_from_user memcpy
22*4f9f2ee2SJérôme Duval #define copy_to_user memcpy
23*4f9f2ee2SJérôme Duval #define CardServices gPcmciaCs->_CardServices
24*4f9f2ee2SJérôme Duval 
25*4f9f2ee2SJérôme Duval const char sockname[] = "bus/pcmcia/sock/%d";
26*4f9f2ee2SJérôme Duval static char ** devices;
27*4f9f2ee2SJérôme Duval uint32 devices_count = 0;
28*4f9f2ee2SJérôme Duval 
29*4f9f2ee2SJérôme Duval int32 api_version = B_CUR_DRIVER_API_VERSION;
30*4f9f2ee2SJérôme Duval 
31*4f9f2ee2SJérôme Duval cs_client_module_info *gPcmciaCs;
32*4f9f2ee2SJérôme Duval ds_module_info *gPcmciaDs;
33*4f9f2ee2SJérôme Duval 
34*4f9f2ee2SJérôme Duval static status_t
35*4f9f2ee2SJérôme Duval ds_open(const char *name, uint32 flags, void **_cookie)
36*4f9f2ee2SJérôme Duval {
37*4f9f2ee2SJérôme Duval 	int32 socket = -1;
38*4f9f2ee2SJérôme Duval 	int32 i;
39*4f9f2ee2SJérôme Duval 	*_cookie = NULL;
40*4f9f2ee2SJérôme Duval 
41*4f9f2ee2SJérôme Duval 	for (i=0; i<devices_count; i++) {
42*4f9f2ee2SJérôme Duval 		if (strcmp(name, devices[i]) == 0) {
43*4f9f2ee2SJérôme Duval 			socket = i;
44*4f9f2ee2SJérôme Duval 			break;
45*4f9f2ee2SJérôme Duval 		}
46*4f9f2ee2SJérôme Duval 	}
47*4f9f2ee2SJérôme Duval 
48*4f9f2ee2SJérôme Duval 	if (socket < 0) {
49*4f9f2ee2SJérôme Duval 		return B_BAD_VALUE;
50*4f9f2ee2SJérôme Duval 	}
51*4f9f2ee2SJérôme Duval 
52*4f9f2ee2SJérôme Duval 	if (gPcmciaDs->get_handle(socket, (client_handle_t *)_cookie) != B_OK) {
53*4f9f2ee2SJérôme Duval 		return ENODEV;
54*4f9f2ee2SJérôme Duval 	}
55*4f9f2ee2SJérôme Duval 
56*4f9f2ee2SJérôme Duval 	return B_OK;
57*4f9f2ee2SJérôme Duval }
58*4f9f2ee2SJérôme Duval 
59*4f9f2ee2SJérôme Duval 
60*4f9f2ee2SJérôme Duval static status_t
61*4f9f2ee2SJérôme Duval ds_close(void *cookie)
62*4f9f2ee2SJérôme Duval {
63*4f9f2ee2SJérôme Duval 	return B_OK;
64*4f9f2ee2SJérôme Duval }
65*4f9f2ee2SJérôme Duval 
66*4f9f2ee2SJérôme Duval 
67*4f9f2ee2SJérôme Duval static status_t
68*4f9f2ee2SJérôme Duval ds_free(void *cookie)
69*4f9f2ee2SJérôme Duval {
70*4f9f2ee2SJérôme Duval 	return B_OK;
71*4f9f2ee2SJérôme Duval }
72*4f9f2ee2SJérôme Duval 
73*4f9f2ee2SJérôme Duval 
74*4f9f2ee2SJérôme Duval static status_t
75*4f9f2ee2SJérôme Duval ds_read(void *cookie, off_t position, void *data, size_t *numBytes)
76*4f9f2ee2SJérôme Duval {
77*4f9f2ee2SJérôme Duval 	return B_ERROR;
78*4f9f2ee2SJérôme Duval }
79*4f9f2ee2SJérôme Duval 
80*4f9f2ee2SJérôme Duval 
81*4f9f2ee2SJérôme Duval static status_t
82*4f9f2ee2SJérôme Duval ds_write(void *cookie, off_t position, const void *data, size_t *numBytes)
83*4f9f2ee2SJérôme Duval {
84*4f9f2ee2SJérôme Duval 	return B_ERROR;
85*4f9f2ee2SJérôme Duval }
86*4f9f2ee2SJérôme Duval 
87*4f9f2ee2SJérôme Duval 
88*4f9f2ee2SJérôme Duval /*====================================================================*/
89*4f9f2ee2SJérôme Duval 
90*4f9f2ee2SJérôme Duval static status_t
91*4f9f2ee2SJérôme Duval ds_ioctl(void *cookie, uint32 cmd, void *arg, size_t len)
92*4f9f2ee2SJérôme Duval {
93*4f9f2ee2SJérôme Duval 	/*socket_info_t *s = (socket_info_t *) cookie;
94*4f9f2ee2SJérôme Duval     u_int size = IOCPARM_LEN(cmd);
95*4f9f2ee2SJérôme Duval     status_t ret, err;
96*4f9f2ee2SJérôme Duval     ds_ioctl_arg_t buf;
97*4f9f2ee2SJérôme Duval 
98*4f9f2ee2SJérôme Duval     if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
99*4f9f2ee2SJérôme Duval 
100*4f9f2ee2SJérôme Duval 	err = ret = 0;
101*4f9f2ee2SJérôme Duval 
102*4f9f2ee2SJérôme Duval     if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
103*4f9f2ee2SJérôme Duval 
104*4f9f2ee2SJérôme Duval     switch (cmd) {
105*4f9f2ee2SJérôme Duval     case DS_ADJUST_RESOURCE_INFO:
106*4f9f2ee2SJérôme Duval 	ret = CardServices(AdjustResourceInfo, s->handle, &buf.adjust);
107*4f9f2ee2SJérôme Duval 	break;
108*4f9f2ee2SJérôme Duval     case DS_GET_CARD_SERVICES_INFO:
109*4f9f2ee2SJérôme Duval 	ret = CardServices(GetCardServicesInfo, &buf.servinfo);
110*4f9f2ee2SJérôme Duval 	break;
111*4f9f2ee2SJérôme Duval     case DS_GET_CONFIGURATION_INFO:
112*4f9f2ee2SJérôme Duval 	ret = CardServices(GetConfigurationInfo, s->handle, &buf.config);
113*4f9f2ee2SJérôme Duval 	break;
114*4f9f2ee2SJérôme Duval     case DS_GET_FIRST_TUPLE:
115*4f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstTuple, s->handle, &buf.tuple);
116*4f9f2ee2SJérôme Duval 	break;
117*4f9f2ee2SJérôme Duval     case DS_GET_NEXT_TUPLE:
118*4f9f2ee2SJérôme Duval 	ret = CardServices(GetNextTuple, s->handle, &buf.tuple);
119*4f9f2ee2SJérôme Duval 	break;
120*4f9f2ee2SJérôme Duval     case DS_GET_TUPLE_DATA:
121*4f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
122*4f9f2ee2SJérôme Duval 	buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
123*4f9f2ee2SJérôme Duval 	ret = CardServices(GetTupleData, s->handle, &buf.tuple);
124*4f9f2ee2SJérôme Duval 	break;
125*4f9f2ee2SJérôme Duval     case DS_PARSE_TUPLE:
126*4f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
127*4f9f2ee2SJérôme Duval 	ret = CardServices(ParseTuple, s->handle, &buf.tuple,
128*4f9f2ee2SJérôme Duval 			   &buf.tuple_parse.parse);
129*4f9f2ee2SJérôme Duval 	break;
130*4f9f2ee2SJérôme Duval     case DS_RESET_CARD:
131*4f9f2ee2SJérôme Duval 	ret = CardServices(ResetCard, s->handle, NULL);
132*4f9f2ee2SJérôme Duval 	break;
133*4f9f2ee2SJérôme Duval     case DS_GET_STATUS:
134*4f9f2ee2SJérôme Duval 	ret = CardServices(GetStatus, s->handle, &buf.status);
135*4f9f2ee2SJérôme Duval 	break;
136*4f9f2ee2SJérôme Duval     case DS_VALIDATE_CIS:
137*4f9f2ee2SJérôme Duval 	ret = CardServices(ValidateCIS, s->handle, &buf.cisinfo);
138*4f9f2ee2SJérôme Duval 	break;
139*4f9f2ee2SJérôme Duval     case DS_SUSPEND_CARD:
140*4f9f2ee2SJérôme Duval 	ret = CardServices(SuspendCard, s->handle, NULL);
141*4f9f2ee2SJérôme Duval 	break;
142*4f9f2ee2SJérôme Duval     case DS_RESUME_CARD:
143*4f9f2ee2SJérôme Duval 	ret = CardServices(ResumeCard, s->handle, NULL);
144*4f9f2ee2SJérôme Duval 	break;
145*4f9f2ee2SJérôme Duval     case DS_EJECT_CARD:
146*4f9f2ee2SJérôme Duval 	ret = CardServices(EjectCard, s->handle, NULL);
147*4f9f2ee2SJérôme Duval 	break;
148*4f9f2ee2SJérôme Duval     case DS_INSERT_CARD:
149*4f9f2ee2SJérôme Duval 	ret = CardServices(InsertCard, s->handle, NULL);
150*4f9f2ee2SJérôme Duval 	break;
151*4f9f2ee2SJérôme Duval     case DS_ACCESS_CONFIGURATION_REGISTER:
152*4f9f2ee2SJérôme Duval 	if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
153*4f9f2ee2SJérôme Duval 	    return -EPERM;
154*4f9f2ee2SJérôme Duval 	ret = CardServices(AccessConfigurationRegister, s->handle,
155*4f9f2ee2SJérôme Duval 			   &buf.conf_reg);
156*4f9f2ee2SJérôme Duval 	break;
157*4f9f2ee2SJérôme Duval     case DS_GET_FIRST_REGION:
158*4f9f2ee2SJérôme Duval         ret = CardServices(GetFirstRegion, s->handle, &buf.region);
159*4f9f2ee2SJérôme Duval 	break;
160*4f9f2ee2SJérôme Duval     case DS_GET_NEXT_REGION:
161*4f9f2ee2SJérôme Duval 	ret = CardServices(GetNextRegion, s->handle, &buf.region);
162*4f9f2ee2SJérôme Duval 	break;
163*4f9f2ee2SJérôme Duval     case DS_GET_FIRST_WINDOW:
164*4f9f2ee2SJérôme Duval 	buf.win_info.handle = (window_handle_t)s->handle;
165*4f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstWindow, &buf.win_info.handle,
166*4f9f2ee2SJérôme Duval 			   &buf.win_info.window);
167*4f9f2ee2SJérôme Duval 	break;
168*4f9f2ee2SJérôme Duval     case DS_GET_NEXT_WINDOW:
169*4f9f2ee2SJérôme Duval 	ret = CardServices(GetNextWindow, &buf.win_info.handle,
170*4f9f2ee2SJérôme Duval 			   &buf.win_info.window);
171*4f9f2ee2SJérôme Duval 	break;
172*4f9f2ee2SJérôme Duval     case DS_GET_MEM_PAGE:
173*4f9f2ee2SJérôme Duval 	ret = CardServices(GetMemPage, buf.win_info.handle,
174*4f9f2ee2SJérôme Duval 			   &buf.win_info.map);
175*4f9f2ee2SJérôme Duval 	break;
176*4f9f2ee2SJérôme Duval     case DS_REPLACE_CIS:
177*4f9f2ee2SJérôme Duval 	ret = CardServices(ReplaceCIS, s->handle, &buf.cisdump);
178*4f9f2ee2SJérôme Duval 	break;
179*4f9f2ee2SJérôme Duval 	*/
180*4f9f2ee2SJérôme Duval 	client_handle_t h = (client_handle_t) cookie;
181*4f9f2ee2SJérôme Duval     u_int size = IOCPARM_LEN(cmd);
182*4f9f2ee2SJérôme Duval     status_t ret, err;
183*4f9f2ee2SJérôme Duval     ds_ioctl_arg_t buf;
184*4f9f2ee2SJérôme Duval 
185*4f9f2ee2SJérôme Duval     if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
186*4f9f2ee2SJérôme Duval 
187*4f9f2ee2SJérôme Duval 	err = ret = 0;
188*4f9f2ee2SJérôme Duval 
189*4f9f2ee2SJérôme Duval     if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
190*4f9f2ee2SJérôme Duval 
191*4f9f2ee2SJérôme Duval     switch (cmd) {
192*4f9f2ee2SJérôme Duval     case DS_ADJUST_RESOURCE_INFO:
193*4f9f2ee2SJérôme Duval 	ret = CardServices(AdjustResourceInfo, h, &buf.adjust);
194*4f9f2ee2SJérôme Duval 	break;
195*4f9f2ee2SJérôme Duval     case DS_GET_CARD_SERVICES_INFO:
196*4f9f2ee2SJérôme Duval 	ret = CardServices(GetCardServicesInfo, &buf.servinfo);
197*4f9f2ee2SJérôme Duval 	break;
198*4f9f2ee2SJérôme Duval     case DS_GET_CONFIGURATION_INFO:
199*4f9f2ee2SJérôme Duval 	ret = CardServices(GetConfigurationInfo, h, &buf.config);
200*4f9f2ee2SJérôme Duval 	break;
201*4f9f2ee2SJérôme Duval     case DS_GET_FIRST_TUPLE:
202*4f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstTuple, h, &buf.tuple);
203*4f9f2ee2SJérôme Duval 	break;
204*4f9f2ee2SJérôme Duval     case DS_GET_NEXT_TUPLE:
205*4f9f2ee2SJérôme Duval 	ret = CardServices(GetNextTuple, h, &buf.tuple);
206*4f9f2ee2SJérôme Duval 	break;
207*4f9f2ee2SJérôme Duval     case DS_GET_TUPLE_DATA:
208*4f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
209*4f9f2ee2SJérôme Duval 	buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
210*4f9f2ee2SJérôme Duval 	ret = CardServices(GetTupleData, h, &buf.tuple);
211*4f9f2ee2SJérôme Duval 	break;
212*4f9f2ee2SJérôme Duval     case DS_PARSE_TUPLE:
213*4f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
214*4f9f2ee2SJérôme Duval 	ret = CardServices(ParseTuple, h, &buf.tuple,
215*4f9f2ee2SJérôme Duval 			   &buf.tuple_parse.parse);
216*4f9f2ee2SJérôme Duval 	break;
217*4f9f2ee2SJérôme Duval     case DS_RESET_CARD:
218*4f9f2ee2SJérôme Duval 	ret = CardServices(ResetCard, h, NULL);
219*4f9f2ee2SJérôme Duval 	break;
220*4f9f2ee2SJérôme Duval     case DS_GET_STATUS:
221*4f9f2ee2SJérôme Duval 	ret = CardServices(GetStatus, h, &buf.status);
222*4f9f2ee2SJérôme Duval 	break;
223*4f9f2ee2SJérôme Duval     case DS_VALIDATE_CIS:
224*4f9f2ee2SJérôme Duval 	ret = CardServices(ValidateCIS, h, &buf.cisinfo);
225*4f9f2ee2SJérôme Duval 	break;
226*4f9f2ee2SJérôme Duval     case DS_SUSPEND_CARD:
227*4f9f2ee2SJérôme Duval 	ret = CardServices(SuspendCard, h, NULL);
228*4f9f2ee2SJérôme Duval 	break;
229*4f9f2ee2SJérôme Duval     case DS_RESUME_CARD:
230*4f9f2ee2SJérôme Duval 	ret = CardServices(ResumeCard, h, NULL);
231*4f9f2ee2SJérôme Duval 	break;
232*4f9f2ee2SJérôme Duval     case DS_EJECT_CARD:
233*4f9f2ee2SJérôme Duval 	ret = CardServices(EjectCard, h, NULL);
234*4f9f2ee2SJérôme Duval 	break;
235*4f9f2ee2SJérôme Duval     case DS_INSERT_CARD:
236*4f9f2ee2SJérôme Duval 	ret = CardServices(InsertCard, h, NULL);
237*4f9f2ee2SJérôme Duval 	break;
238*4f9f2ee2SJérôme Duval /*    case DS_ACCESS_CONFIGURATION_REGISTER:
239*4f9f2ee2SJérôme Duval 	if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
240*4f9f2ee2SJérôme Duval 	    return -EPERM;
241*4f9f2ee2SJérôme Duval 	ret = CardServices(AccessConfigurationRegister, h,
242*4f9f2ee2SJérôme Duval 			   &buf.conf_reg);
243*4f9f2ee2SJérôme Duval 	break;
244*4f9f2ee2SJérôme Duval     case DS_GET_FIRST_REGION:
245*4f9f2ee2SJérôme Duval         ret = CardServices(GetFirstRegion, h, &buf.region);
246*4f9f2ee2SJérôme Duval 	break;
247*4f9f2ee2SJérôme Duval     case DS_GET_NEXT_REGION:
248*4f9f2ee2SJérôme Duval 	ret = CardServices(GetNextRegion, h, &buf.region);
249*4f9f2ee2SJérôme Duval 	break;
250*4f9f2ee2SJérôme Duval     case DS_GET_FIRST_WINDOW:
251*4f9f2ee2SJérôme Duval 	buf.win_info.handle = (window_handle_t)h;
252*4f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstWindow, &buf.win_info.handle,
253*4f9f2ee2SJérôme Duval 			   &buf.win_info.window);
254*4f9f2ee2SJérôme Duval 	break;
255*4f9f2ee2SJérôme Duval     case DS_GET_NEXT_WINDOW:
256*4f9f2ee2SJérôme Duval 	ret = CardServices(GetNextWindow, &buf.win_info.handle,
257*4f9f2ee2SJérôme Duval 			   &buf.win_info.window);
258*4f9f2ee2SJérôme Duval 	break;
259*4f9f2ee2SJérôme Duval     case DS_GET_MEM_PAGE:
260*4f9f2ee2SJérôme Duval 	ret = CardServices(GetMemPage, buf.win_info.handle,
261*4f9f2ee2SJérôme Duval 			   &buf.win_info.map);
262*4f9f2ee2SJérôme Duval 	break;*/
263*4f9f2ee2SJérôme Duval     case DS_REPLACE_CIS:
264*4f9f2ee2SJérôme Duval 	ret = CardServices(ReplaceCIS, h, &buf.cisdump);
265*4f9f2ee2SJérôme Duval 	break;
266*4f9f2ee2SJérôme Duval 
267*4f9f2ee2SJérôme Duval /*    case DS_BIND_REQUEST:
268*4f9f2ee2SJérôme Duval 	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
269*4f9f2ee2SJérôme Duval 	err = bind_request(i, &buf.bind_info);
270*4f9f2ee2SJérôme Duval 	break;
271*4f9f2ee2SJérôme Duval     case DS_GET_DEVICE_INFO:
272*4f9f2ee2SJérôme Duval 	err = get_device_info(i, &buf.bind_info, 1);
273*4f9f2ee2SJérôme Duval 	break;
274*4f9f2ee2SJérôme Duval     case DS_GET_NEXT_DEVICE:
275*4f9f2ee2SJérôme Duval 	err = get_device_info(i, &buf.bind_info, 0);
276*4f9f2ee2SJérôme Duval 	break;
277*4f9f2ee2SJérôme Duval     case DS_UNBIND_REQUEST:
278*4f9f2ee2SJérôme Duval 	err = unbind_request(i, &buf.bind_info);
279*4f9f2ee2SJérôme Duval 	break;
280*4f9f2ee2SJérôme Duval     case DS_BIND_MTD:
281*4f9f2ee2SJérôme Duval 	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
282*4f9f2ee2SJérôme Duval 	err = bind_mtd(i, &buf.mtd_info);
283*4f9f2ee2SJérôme Duval 	break;*/
284*4f9f2ee2SJérôme Duval     default:
285*4f9f2ee2SJérôme Duval     err = -EINVAL;
286*4f9f2ee2SJérôme Duval     }
287*4f9f2ee2SJérôme Duval 
288*4f9f2ee2SJérôme Duval     if ((err == 0) && (ret != CS_SUCCESS)) {
289*4f9f2ee2SJérôme Duval 	switch (ret) {
290*4f9f2ee2SJérôme Duval 	case CS_BAD_SOCKET: case CS_NO_CARD:
291*4f9f2ee2SJérôme Duval 	    err = ENODEV; break;
292*4f9f2ee2SJérôme Duval 	case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
293*4f9f2ee2SJérôme Duval 	case CS_BAD_TUPLE:
294*4f9f2ee2SJérôme Duval 		err = EINVAL; break;
295*4f9f2ee2SJérôme Duval 	case CS_IN_USE:
296*4f9f2ee2SJérôme Duval 	    err = EBUSY; break;
297*4f9f2ee2SJérôme Duval 	case CS_OUT_OF_RESOURCE:
298*4f9f2ee2SJérôme Duval 	    err = ENOSPC; break;
299*4f9f2ee2SJérôme Duval 	case CS_NO_MORE_ITEMS:
300*4f9f2ee2SJérôme Duval 	    err = ENODATA; break;
301*4f9f2ee2SJérôme Duval 	case CS_UNSUPPORTED_FUNCTION:
302*4f9f2ee2SJérôme Duval 	    err = ENOSYS; break;
303*4f9f2ee2SJérôme Duval 	default:
304*4f9f2ee2SJérôme Duval 	    err = EIO; break;
305*4f9f2ee2SJérôme Duval 	}
306*4f9f2ee2SJérôme Duval     }
307*4f9f2ee2SJérôme Duval 
308*4f9f2ee2SJérôme Duval     if (cmd & IOC_OUT) copy_to_user((char *)arg, (char *)&buf, size);
309*4f9f2ee2SJérôme Duval 
310*4f9f2ee2SJérôme Duval     return err;
311*4f9f2ee2SJérôme Duval } /* ds_ioctl */
312*4f9f2ee2SJérôme Duval 
313*4f9f2ee2SJérôme Duval 
314*4f9f2ee2SJérôme Duval status_t
315*4f9f2ee2SJérôme Duval init_hardware()
316*4f9f2ee2SJérôme Duval {
317*4f9f2ee2SJérôme Duval 	return B_OK;
318*4f9f2ee2SJérôme Duval }
319*4f9f2ee2SJérôme Duval 
320*4f9f2ee2SJérôme Duval 
321*4f9f2ee2SJérôme Duval const char **
322*4f9f2ee2SJérôme Duval publish_devices(void)
323*4f9f2ee2SJérôme Duval {
324*4f9f2ee2SJérôme Duval 	return (const char **)devices;
325*4f9f2ee2SJérôme Duval }
326*4f9f2ee2SJérôme Duval 
327*4f9f2ee2SJérôme Duval 
328*4f9f2ee2SJérôme Duval static device_hooks hooks = {
329*4f9f2ee2SJérôme Duval 	&ds_open,
330*4f9f2ee2SJérôme Duval 	&ds_close,
331*4f9f2ee2SJérôme Duval 	&ds_free,
332*4f9f2ee2SJérôme Duval 	&ds_ioctl,
333*4f9f2ee2SJérôme Duval 	&ds_read,
334*4f9f2ee2SJérôme Duval 	&ds_write,
335*4f9f2ee2SJérôme Duval 	NULL,
336*4f9f2ee2SJérôme Duval 	NULL,
337*4f9f2ee2SJérôme Duval 	NULL,
338*4f9f2ee2SJérôme Duval 	NULL
339*4f9f2ee2SJérôme Duval };
340*4f9f2ee2SJérôme Duval 
341*4f9f2ee2SJérôme Duval device_hooks *
342*4f9f2ee2SJérôme Duval find_device(const char *name)
343*4f9f2ee2SJérôme Duval {
344*4f9f2ee2SJérôme Duval 	return &hooks;
345*4f9f2ee2SJérôme Duval }
346*4f9f2ee2SJérôme Duval 
347*4f9f2ee2SJérôme Duval 
348*4f9f2ee2SJérôme Duval status_t
349*4f9f2ee2SJérôme Duval init_driver()
350*4f9f2ee2SJérôme Duval {
351*4f9f2ee2SJérôme Duval 	status_t err;
352*4f9f2ee2SJérôme Duval 	client_handle_t handle;
353*4f9f2ee2SJérôme Duval 	uint32 i;
354*4f9f2ee2SJérôme Duval 
355*4f9f2ee2SJérôme Duval #if DEBUG
356*4f9f2ee2SJérôme Duval 	load_driver_symbols("ds");
357*4f9f2ee2SJérôme Duval #endif
358*4f9f2ee2SJérôme Duval 
359*4f9f2ee2SJérôme Duval 	if ((err = get_module(CS_CLIENT_MODULE_NAME, (module_info **)&gPcmciaCs))!=B_OK)
360*4f9f2ee2SJérôme Duval 		return err;
361*4f9f2ee2SJérôme Duval 	if ((err = get_module(DS_MODULE_NAME, (module_info **)&gPcmciaDs))!=B_OK) {
362*4f9f2ee2SJérôme Duval 		put_module(CS_CLIENT_MODULE_NAME);
363*4f9f2ee2SJérôme Duval 		return err;
364*4f9f2ee2SJérôme Duval 	}
365*4f9f2ee2SJérôme Duval 
366*4f9f2ee2SJérôme Duval 	devices_count = 0;
367*4f9f2ee2SJérôme Duval 	while (gPcmciaDs->get_handle(devices_count, &handle)==B_OK) {
368*4f9f2ee2SJérôme Duval 		devices_count++;
369*4f9f2ee2SJérôme Duval 	}
370*4f9f2ee2SJérôme Duval 
371*4f9f2ee2SJérôme Duval 	if (devices_count <= 0)
372*4f9f2ee2SJérôme Duval 		return ENODEV;
373*4f9f2ee2SJérôme Duval 
374*4f9f2ee2SJérôme Duval 	devices = malloc(sizeof(char *) * (devices_count+1));
375*4f9f2ee2SJérôme Duval 	for (i=0; i<devices_count; i++) {
376*4f9f2ee2SJérôme Duval 		devices[i] = strdup(sockname);
377*4f9f2ee2SJérôme Duval 		sprintf(devices[i], sockname, i);
378*4f9f2ee2SJérôme Duval 	}
379*4f9f2ee2SJérôme Duval 	devices[devices_count] = NULL;
380*4f9f2ee2SJérôme Duval 
381*4f9f2ee2SJérôme Duval 	return B_OK;
382*4f9f2ee2SJérôme Duval }
383*4f9f2ee2SJérôme Duval 
384*4f9f2ee2SJérôme Duval 
385*4f9f2ee2SJérôme Duval void
386*4f9f2ee2SJérôme Duval uninit_driver()
387*4f9f2ee2SJérôme Duval {
388*4f9f2ee2SJérôme Duval 	int32 i = 0;
389*4f9f2ee2SJérôme Duval 	for (i=0; i<devices_count; i++) {
390*4f9f2ee2SJérôme Duval 		free (devices[i]);
391*4f9f2ee2SJérôme Duval 	}
392*4f9f2ee2SJérôme Duval 
393*4f9f2ee2SJérôme Duval 	put_module(DS_MODULE_NAME);
394*4f9f2ee2SJérôme Duval 	put_module(CS_CLIENT_MODULE_NAME);
395*4f9f2ee2SJérôme Duval }
396