xref: /haiku/src/add-ons/kernel/drivers/bus/pcmcia/ds.c (revision 400ba068e0971623161ea2f939fd5ede8e5af25c)
14f9f2ee2SJérôme Duval /*
24f9f2ee2SJérôme Duval  * Copyright 2005, Jérôme DUVAL. All rights reserved.
34f9f2ee2SJérôme Duval  * Distributed under the terms of the MIT License.
44f9f2ee2SJérôme Duval  */
54f9f2ee2SJérôme Duval 
64f9f2ee2SJérôme Duval #include <Drivers.h>
74f9f2ee2SJérôme Duval #include <OS.h>
84f9f2ee2SJérôme Duval #include <bus_manager.h>
94f9f2ee2SJérôme Duval #include <malloc.h>
10cb57453fSJérôme Duval #include <module.h>
114f9f2ee2SJérôme Duval #include <stdio.h>
12cb57453fSJérôme Duval #include <string.h>
13cb57453fSJérôme Duval #include <sys/ioccom.h>
14cb57453fSJérôme Duval #include <sys/ioctl.h>
154f9f2ee2SJérôme Duval 
164f9f2ee2SJérôme Duval #define __KERNEL__
174f9f2ee2SJérôme Duval #include <pcmcia/cs_types.h>
184f9f2ee2SJérôme Duval #include <pcmcia/cs.h>
194f9f2ee2SJérôme Duval #include <pcmcia/cistpl.h>
204f9f2ee2SJérôme Duval #include <pcmcia/ds.h>
214f9f2ee2SJérôme Duval 
224f9f2ee2SJérôme Duval #define copy_from_user memcpy
234f9f2ee2SJérôme Duval #define copy_to_user memcpy
244f9f2ee2SJérôme Duval #define CardServices gPcmciaCs->_CardServices
254ff60cbaSJérôme Duval #define get_handle gPcmciaDs->get_handle
264f9f2ee2SJérôme Duval 
27b76d376bSJérôme Duval const char sockname[] = "bus/pcmcia/sock/%ld";
284f9f2ee2SJérôme Duval static char ** devices;
294f9f2ee2SJérôme Duval uint32 devices_count = 0;
304f9f2ee2SJérôme Duval 
314f9f2ee2SJérôme Duval int32 api_version = B_CUR_DRIVER_API_VERSION;
324f9f2ee2SJérôme Duval 
334f9f2ee2SJérôme Duval cs_client_module_info *gPcmciaCs;
344f9f2ee2SJérôme Duval ds_module_info *gPcmciaDs;
354f9f2ee2SJérôme Duval 
364f9f2ee2SJérôme Duval static status_t
ds_open(const char * name,uint32 flags,void ** _cookie)374f9f2ee2SJérôme Duval ds_open(const char *name, uint32 flags, void **_cookie)
384f9f2ee2SJérôme Duval {
394f9f2ee2SJérôme Duval 	int32 socket = -1;
404f9f2ee2SJérôme Duval 	int32 i;
414f9f2ee2SJérôme Duval 	*_cookie = NULL;
424f9f2ee2SJérôme Duval 
434f9f2ee2SJérôme Duval 	for (i=0; i<devices_count; i++) {
444f9f2ee2SJérôme Duval 		if (strcmp(name, devices[i]) == 0) {
454f9f2ee2SJérôme Duval 			socket = i;
464f9f2ee2SJérôme Duval 			break;
474f9f2ee2SJérôme Duval 		}
484f9f2ee2SJérôme Duval 	}
494f9f2ee2SJérôme Duval 
504f9f2ee2SJérôme Duval 	if (socket < 0) {
514f9f2ee2SJérôme Duval 		return B_BAD_VALUE;
524f9f2ee2SJérôme Duval 	}
534f9f2ee2SJérôme Duval 
544ff60cbaSJérôme Duval 	if (get_handle(socket, (client_handle_t *)_cookie) != B_OK) {
554f9f2ee2SJérôme Duval 		return ENODEV;
564f9f2ee2SJérôme Duval 	}
574f9f2ee2SJérôme Duval 
584f9f2ee2SJérôme Duval 	return B_OK;
594f9f2ee2SJérôme Duval }
604f9f2ee2SJérôme Duval 
614f9f2ee2SJérôme Duval 
624f9f2ee2SJérôme Duval static status_t
ds_close(void * cookie)634f9f2ee2SJérôme Duval ds_close(void *cookie)
644f9f2ee2SJérôme Duval {
654f9f2ee2SJérôme Duval 	return B_OK;
664f9f2ee2SJérôme Duval }
674f9f2ee2SJérôme Duval 
684f9f2ee2SJérôme Duval 
694f9f2ee2SJérôme Duval static status_t
ds_free(void * cookie)704f9f2ee2SJérôme Duval ds_free(void *cookie)
714f9f2ee2SJérôme Duval {
724f9f2ee2SJérôme Duval 	return B_OK;
734f9f2ee2SJérôme Duval }
744f9f2ee2SJérôme Duval 
754f9f2ee2SJérôme Duval 
764f9f2ee2SJérôme Duval static status_t
ds_read(void * cookie,off_t position,void * data,size_t * numBytes)774f9f2ee2SJérôme Duval ds_read(void *cookie, off_t position, void *data, size_t *numBytes)
784f9f2ee2SJérôme Duval {
794f9f2ee2SJérôme Duval 	return B_ERROR;
804f9f2ee2SJérôme Duval }
814f9f2ee2SJérôme Duval 
824f9f2ee2SJérôme Duval 
834f9f2ee2SJérôme Duval static status_t
ds_write(void * cookie,off_t position,const void * data,size_t * numBytes)844f9f2ee2SJérôme Duval ds_write(void *cookie, off_t position, const void *data, size_t *numBytes)
854f9f2ee2SJérôme Duval {
864f9f2ee2SJérôme Duval 	return B_ERROR;
874f9f2ee2SJérôme Duval }
884f9f2ee2SJérôme Duval 
894f9f2ee2SJérôme Duval 
904f9f2ee2SJérôme Duval /*====================================================================*/
914f9f2ee2SJérôme Duval 
924f9f2ee2SJérôme Duval static status_t
ds_ioctl(void * cookie,uint32 cmd,void * arg,size_t len)934f9f2ee2SJérôme Duval ds_ioctl(void *cookie, uint32 cmd, void *arg, size_t len)
944f9f2ee2SJérôme Duval {
954f9f2ee2SJérôme Duval 	/*socket_info_t *s = (socket_info_t *) cookie;
964f9f2ee2SJérôme Duval     u_int size = IOCPARM_LEN(cmd);
974f9f2ee2SJérôme Duval     status_t ret, err;
984f9f2ee2SJérôme Duval     ds_ioctl_arg_t buf;
994f9f2ee2SJérôme Duval 
1004f9f2ee2SJérôme Duval     if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
1014f9f2ee2SJérôme Duval 
1024f9f2ee2SJérôme Duval 	err = ret = 0;
1034f9f2ee2SJérôme Duval 
1044f9f2ee2SJérôme Duval     if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
1054f9f2ee2SJérôme Duval 
1064f9f2ee2SJérôme Duval     switch (cmd) {
1074f9f2ee2SJérôme Duval     case DS_ADJUST_RESOURCE_INFO:
1084f9f2ee2SJérôme Duval 	ret = CardServices(AdjustResourceInfo, s->handle, &buf.adjust);
1094f9f2ee2SJérôme Duval 	break;
1104f9f2ee2SJérôme Duval     case DS_GET_CARD_SERVICES_INFO:
1114f9f2ee2SJérôme Duval 	ret = CardServices(GetCardServicesInfo, &buf.servinfo);
1124f9f2ee2SJérôme Duval 	break;
1134f9f2ee2SJérôme Duval     case DS_GET_CONFIGURATION_INFO:
1144f9f2ee2SJérôme Duval 	ret = CardServices(GetConfigurationInfo, s->handle, &buf.config);
1154f9f2ee2SJérôme Duval 	break;
1164f9f2ee2SJérôme Duval     case DS_GET_FIRST_TUPLE:
1174f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstTuple, s->handle, &buf.tuple);
1184f9f2ee2SJérôme Duval 	break;
1194f9f2ee2SJérôme Duval     case DS_GET_NEXT_TUPLE:
1204f9f2ee2SJérôme Duval 	ret = CardServices(GetNextTuple, s->handle, &buf.tuple);
1214f9f2ee2SJérôme Duval 	break;
1224f9f2ee2SJérôme Duval     case DS_GET_TUPLE_DATA:
1234f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
1244f9f2ee2SJérôme Duval 	buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
1254f9f2ee2SJérôme Duval 	ret = CardServices(GetTupleData, s->handle, &buf.tuple);
1264f9f2ee2SJérôme Duval 	break;
1274f9f2ee2SJérôme Duval     case DS_PARSE_TUPLE:
1284f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
1294f9f2ee2SJérôme Duval 	ret = CardServices(ParseTuple, s->handle, &buf.tuple,
1304f9f2ee2SJérôme Duval 			   &buf.tuple_parse.parse);
1314f9f2ee2SJérôme Duval 	break;
1324f9f2ee2SJérôme Duval     case DS_RESET_CARD:
1334f9f2ee2SJérôme Duval 	ret = CardServices(ResetCard, s->handle, NULL);
1344f9f2ee2SJérôme Duval 	break;
1354f9f2ee2SJérôme Duval     case DS_GET_STATUS:
1364f9f2ee2SJérôme Duval 	ret = CardServices(GetStatus, s->handle, &buf.status);
1374f9f2ee2SJérôme Duval 	break;
1384f9f2ee2SJérôme Duval     case DS_VALIDATE_CIS:
1394f9f2ee2SJérôme Duval 	ret = CardServices(ValidateCIS, s->handle, &buf.cisinfo);
1404f9f2ee2SJérôme Duval 	break;
1414f9f2ee2SJérôme Duval     case DS_SUSPEND_CARD:
1424f9f2ee2SJérôme Duval 	ret = CardServices(SuspendCard, s->handle, NULL);
1434f9f2ee2SJérôme Duval 	break;
1444f9f2ee2SJérôme Duval     case DS_RESUME_CARD:
1454f9f2ee2SJérôme Duval 	ret = CardServices(ResumeCard, s->handle, NULL);
1464f9f2ee2SJérôme Duval 	break;
1474f9f2ee2SJérôme Duval     case DS_EJECT_CARD:
1484f9f2ee2SJérôme Duval 	ret = CardServices(EjectCard, s->handle, NULL);
1494f9f2ee2SJérôme Duval 	break;
1504f9f2ee2SJérôme Duval     case DS_INSERT_CARD:
1514f9f2ee2SJérôme Duval 	ret = CardServices(InsertCard, s->handle, NULL);
1524f9f2ee2SJérôme Duval 	break;
1534f9f2ee2SJérôme Duval     case DS_ACCESS_CONFIGURATION_REGISTER:
1544f9f2ee2SJérôme Duval 	if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
1554f9f2ee2SJérôme Duval 	    return -EPERM;
1564f9f2ee2SJérôme Duval 	ret = CardServices(AccessConfigurationRegister, s->handle,
1574f9f2ee2SJérôme Duval 			   &buf.conf_reg);
1584f9f2ee2SJérôme Duval 	break;
1594f9f2ee2SJérôme Duval     case DS_GET_FIRST_REGION:
1604f9f2ee2SJérôme Duval         ret = CardServices(GetFirstRegion, s->handle, &buf.region);
1614f9f2ee2SJérôme Duval 	break;
1624f9f2ee2SJérôme Duval     case DS_GET_NEXT_REGION:
1634f9f2ee2SJérôme Duval 	ret = CardServices(GetNextRegion, s->handle, &buf.region);
1644f9f2ee2SJérôme Duval 	break;
1654f9f2ee2SJérôme Duval     case DS_GET_FIRST_WINDOW:
1664f9f2ee2SJérôme Duval 	buf.win_info.handle = (window_handle_t)s->handle;
1674f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstWindow, &buf.win_info.handle,
1684f9f2ee2SJérôme Duval 			   &buf.win_info.window);
1694f9f2ee2SJérôme Duval 	break;
1704f9f2ee2SJérôme Duval     case DS_GET_NEXT_WINDOW:
1714f9f2ee2SJérôme Duval 	ret = CardServices(GetNextWindow, &buf.win_info.handle,
1724f9f2ee2SJérôme Duval 			   &buf.win_info.window);
1734f9f2ee2SJérôme Duval 	break;
1744f9f2ee2SJérôme Duval     case DS_GET_MEM_PAGE:
1754f9f2ee2SJérôme Duval 	ret = CardServices(GetMemPage, buf.win_info.handle,
1764f9f2ee2SJérôme Duval 			   &buf.win_info.map);
1774f9f2ee2SJérôme Duval 	break;
1784f9f2ee2SJérôme Duval     case DS_REPLACE_CIS:
1794f9f2ee2SJérôme Duval 	ret = CardServices(ReplaceCIS, s->handle, &buf.cisdump);
1804f9f2ee2SJérôme Duval 	break;
1814f9f2ee2SJérôme Duval 	*/
1824f9f2ee2SJérôme Duval 	client_handle_t h = (client_handle_t) cookie;
1834f9f2ee2SJérôme Duval     u_int size = IOCPARM_LEN(cmd);
1844f9f2ee2SJérôme Duval     status_t ret, err;
1854f9f2ee2SJérôme Duval     ds_ioctl_arg_t buf;
1864f9f2ee2SJérôme Duval 
1874f9f2ee2SJérôme Duval     if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
1884f9f2ee2SJérôme Duval 
1894f9f2ee2SJérôme Duval 	err = ret = 0;
1904f9f2ee2SJérôme Duval 
1914f9f2ee2SJérôme Duval     if (cmd & IOC_IN) copy_from_user((char *)&buf, (char *)arg, size);
1924f9f2ee2SJérôme Duval 
1934f9f2ee2SJérôme Duval     switch (cmd) {
1944f9f2ee2SJérôme Duval     case DS_ADJUST_RESOURCE_INFO:
1954f9f2ee2SJérôme Duval 	ret = CardServices(AdjustResourceInfo, h, &buf.adjust);
1964f9f2ee2SJérôme Duval 	break;
1974f9f2ee2SJérôme Duval     case DS_GET_CARD_SERVICES_INFO:
1984f9f2ee2SJérôme Duval 	ret = CardServices(GetCardServicesInfo, &buf.servinfo);
1994f9f2ee2SJérôme Duval 	break;
2004f9f2ee2SJérôme Duval     case DS_GET_CONFIGURATION_INFO:
2014f9f2ee2SJérôme Duval 	ret = CardServices(GetConfigurationInfo, h, &buf.config);
2024f9f2ee2SJérôme Duval 	break;
2034f9f2ee2SJérôme Duval     case DS_GET_FIRST_TUPLE:
2044f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstTuple, h, &buf.tuple);
2054f9f2ee2SJérôme Duval 	break;
2064f9f2ee2SJérôme Duval     case DS_GET_NEXT_TUPLE:
2074f9f2ee2SJérôme Duval 	ret = CardServices(GetNextTuple, h, &buf.tuple);
2084f9f2ee2SJérôme Duval 	break;
2094f9f2ee2SJérôme Duval     case DS_GET_TUPLE_DATA:
2104f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
2114f9f2ee2SJérôme Duval 	buf.tuple.TupleDataMax = sizeof(buf.tuple_parse.data);
2124f9f2ee2SJérôme Duval 	ret = CardServices(GetTupleData, h, &buf.tuple);
2134f9f2ee2SJérôme Duval 	break;
2144f9f2ee2SJérôme Duval     case DS_PARSE_TUPLE:
2154f9f2ee2SJérôme Duval 	buf.tuple.TupleData = buf.tuple_parse.data;
2164f9f2ee2SJérôme Duval 	ret = CardServices(ParseTuple, h, &buf.tuple,
2174f9f2ee2SJérôme Duval 			   &buf.tuple_parse.parse);
2184f9f2ee2SJérôme Duval 	break;
2194f9f2ee2SJérôme Duval     case DS_RESET_CARD:
2204f9f2ee2SJérôme Duval 	ret = CardServices(ResetCard, h, NULL);
2214f9f2ee2SJérôme Duval 	break;
2224f9f2ee2SJérôme Duval     case DS_GET_STATUS:
2234f9f2ee2SJérôme Duval 	ret = CardServices(GetStatus, h, &buf.status);
2244f9f2ee2SJérôme Duval 	break;
2254f9f2ee2SJérôme Duval     case DS_VALIDATE_CIS:
2264f9f2ee2SJérôme Duval 	ret = CardServices(ValidateCIS, h, &buf.cisinfo);
2274f9f2ee2SJérôme Duval 	break;
2284f9f2ee2SJérôme Duval     case DS_SUSPEND_CARD:
2294f9f2ee2SJérôme Duval 	ret = CardServices(SuspendCard, h, NULL);
2304f9f2ee2SJérôme Duval 	break;
2314f9f2ee2SJérôme Duval     case DS_RESUME_CARD:
2324f9f2ee2SJérôme Duval 	ret = CardServices(ResumeCard, h, NULL);
2334f9f2ee2SJérôme Duval 	break;
2344f9f2ee2SJérôme Duval     case DS_EJECT_CARD:
2354f9f2ee2SJérôme Duval 	ret = CardServices(EjectCard, h, NULL);
2364f9f2ee2SJérôme Duval 	break;
2374f9f2ee2SJérôme Duval     case DS_INSERT_CARD:
2384f9f2ee2SJérôme Duval 	ret = CardServices(InsertCard, h, NULL);
2394f9f2ee2SJérôme Duval 	break;
2404f9f2ee2SJérôme Duval /*    case DS_ACCESS_CONFIGURATION_REGISTER:
2414f9f2ee2SJérôme Duval 	if ((buf.conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN))
2424f9f2ee2SJérôme Duval 	    return -EPERM;
2434f9f2ee2SJérôme Duval 	ret = CardServices(AccessConfigurationRegister, h,
2444f9f2ee2SJérôme Duval 			   &buf.conf_reg);
2454f9f2ee2SJérôme Duval 	break;
2464f9f2ee2SJérôme Duval     case DS_GET_FIRST_REGION:
2474f9f2ee2SJérôme Duval         ret = CardServices(GetFirstRegion, h, &buf.region);
2484f9f2ee2SJérôme Duval 	break;
2494f9f2ee2SJérôme Duval     case DS_GET_NEXT_REGION:
2504f9f2ee2SJérôme Duval 	ret = CardServices(GetNextRegion, h, &buf.region);
2514f9f2ee2SJérôme Duval 	break;
2524f9f2ee2SJérôme Duval     case DS_GET_FIRST_WINDOW:
2534f9f2ee2SJérôme Duval 	buf.win_info.handle = (window_handle_t)h;
2544f9f2ee2SJérôme Duval 	ret = CardServices(GetFirstWindow, &buf.win_info.handle,
2554f9f2ee2SJérôme Duval 			   &buf.win_info.window);
2564f9f2ee2SJérôme Duval 	break;
2574f9f2ee2SJérôme Duval     case DS_GET_NEXT_WINDOW:
2584f9f2ee2SJérôme Duval 	ret = CardServices(GetNextWindow, &buf.win_info.handle,
2594f9f2ee2SJérôme Duval 			   &buf.win_info.window);
2604f9f2ee2SJérôme Duval 	break;
2614f9f2ee2SJérôme Duval     case DS_GET_MEM_PAGE:
2624f9f2ee2SJérôme Duval 	ret = CardServices(GetMemPage, buf.win_info.handle,
2634f9f2ee2SJérôme Duval 			   &buf.win_info.map);
2644f9f2ee2SJérôme Duval 	break;*/
2654f9f2ee2SJérôme Duval     case DS_REPLACE_CIS:
2664f9f2ee2SJérôme Duval 	ret = CardServices(ReplaceCIS, h, &buf.cisdump);
2674f9f2ee2SJérôme Duval 	break;
2684f9f2ee2SJérôme Duval 
2694f9f2ee2SJérôme Duval /*    case DS_BIND_REQUEST:
2704f9f2ee2SJérôme Duval 	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
2714f9f2ee2SJérôme Duval 	err = bind_request(i, &buf.bind_info);
2724f9f2ee2SJérôme Duval 	break;
2734f9f2ee2SJérôme Duval     case DS_GET_DEVICE_INFO:
2744f9f2ee2SJérôme Duval 	err = get_device_info(i, &buf.bind_info, 1);
2754f9f2ee2SJérôme Duval 	break;
2764f9f2ee2SJérôme Duval     case DS_GET_NEXT_DEVICE:
2774f9f2ee2SJérôme Duval 	err = get_device_info(i, &buf.bind_info, 0);
2784f9f2ee2SJérôme Duval 	break;
2794f9f2ee2SJérôme Duval     case DS_UNBIND_REQUEST:
2804f9f2ee2SJérôme Duval 	err = unbind_request(i, &buf.bind_info);
2814f9f2ee2SJérôme Duval 	break;
2824f9f2ee2SJérôme Duval     case DS_BIND_MTD:
2834f9f2ee2SJérôme Duval 	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
2844f9f2ee2SJérôme Duval 	err = bind_mtd(i, &buf.mtd_info);
2854f9f2ee2SJérôme Duval 	break;*/
2864f9f2ee2SJérôme Duval     default:
2874f9f2ee2SJérôme Duval     err = -EINVAL;
2884f9f2ee2SJérôme Duval     }
2894f9f2ee2SJérôme Duval 
2904f9f2ee2SJérôme Duval     if ((err == 0) && (ret != CS_SUCCESS)) {
2914f9f2ee2SJérôme Duval 	switch (ret) {
2924f9f2ee2SJérôme Duval 	case CS_BAD_SOCKET: case CS_NO_CARD:
2934f9f2ee2SJérôme Duval 	    err = ENODEV; break;
2944f9f2ee2SJérôme Duval 	case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
2954f9f2ee2SJérôme Duval 	case CS_BAD_TUPLE:
2964f9f2ee2SJérôme Duval 		err = EINVAL; break;
2974f9f2ee2SJérôme Duval 	case CS_IN_USE:
2984f9f2ee2SJérôme Duval 	    err = EBUSY; break;
2994f9f2ee2SJérôme Duval 	case CS_OUT_OF_RESOURCE:
3004f9f2ee2SJérôme Duval 	    err = ENOSPC; break;
3014f9f2ee2SJérôme Duval 	case CS_NO_MORE_ITEMS:
3024f9f2ee2SJérôme Duval 	    err = ENODATA; break;
3034f9f2ee2SJérôme Duval 	case CS_UNSUPPORTED_FUNCTION:
3044f9f2ee2SJérôme Duval 	    err = ENOSYS; break;
3054f9f2ee2SJérôme Duval 	default:
3064f9f2ee2SJérôme Duval 	    err = EIO; break;
3074f9f2ee2SJérôme Duval 	}
3084f9f2ee2SJérôme Duval     }
3094f9f2ee2SJérôme Duval 
3104f9f2ee2SJérôme Duval     if (cmd & IOC_OUT) copy_to_user((char *)arg, (char *)&buf, size);
3114f9f2ee2SJérôme Duval 
3124f9f2ee2SJérôme Duval     return err;
3134f9f2ee2SJérôme Duval } /* ds_ioctl */
3144f9f2ee2SJérôme Duval 
3154f9f2ee2SJérôme Duval 
3164f9f2ee2SJérôme Duval status_t
init_hardware()3174f9f2ee2SJérôme Duval init_hardware()
3184f9f2ee2SJérôme Duval {
3194f9f2ee2SJérôme Duval 	return B_OK;
3204f9f2ee2SJérôme Duval }
3214f9f2ee2SJérôme Duval 
3224f9f2ee2SJérôme Duval 
3234f9f2ee2SJérôme Duval const char **
publish_devices(void)3244f9f2ee2SJérôme Duval publish_devices(void)
3254f9f2ee2SJérôme Duval {
3264f9f2ee2SJérôme Duval 	return (const char **)devices;
3274f9f2ee2SJérôme Duval }
3284f9f2ee2SJérôme Duval 
3294f9f2ee2SJérôme Duval 
3304f9f2ee2SJérôme Duval static device_hooks hooks = {
3314f9f2ee2SJérôme Duval 	&ds_open,
3324f9f2ee2SJérôme Duval 	&ds_close,
3334f9f2ee2SJérôme Duval 	&ds_free,
3344f9f2ee2SJérôme Duval 	&ds_ioctl,
3354f9f2ee2SJérôme Duval 	&ds_read,
3364f9f2ee2SJérôme Duval 	&ds_write,
3374f9f2ee2SJérôme Duval 	NULL,
3384f9f2ee2SJérôme Duval 	NULL,
3394f9f2ee2SJérôme Duval 	NULL,
3404f9f2ee2SJérôme Duval 	NULL
3414f9f2ee2SJérôme Duval };
3424f9f2ee2SJérôme Duval 
3434f9f2ee2SJérôme Duval device_hooks *
find_device(const char * name)3444f9f2ee2SJérôme Duval find_device(const char *name)
3454f9f2ee2SJérôme Duval {
3464f9f2ee2SJérôme Duval 	return &hooks;
3474f9f2ee2SJérôme Duval }
3484f9f2ee2SJérôme Duval 
3494f9f2ee2SJérôme Duval 
3504f9f2ee2SJérôme Duval status_t
init_driver()3514f9f2ee2SJérôme Duval init_driver()
3524f9f2ee2SJérôme Duval {
3534f9f2ee2SJérôme Duval 	status_t err;
3544f9f2ee2SJérôme Duval 	client_handle_t handle;
3554f9f2ee2SJérôme Duval 	uint32 i;
3564f9f2ee2SJérôme Duval 
357*400ba068SAxel Dörfler #if DEBUG && !defined(__HAIKU__)
3584f9f2ee2SJérôme Duval 	load_driver_symbols("ds");
3594f9f2ee2SJérôme Duval #endif
3604f9f2ee2SJérôme Duval 
3614f9f2ee2SJérôme Duval 	if ((err = get_module(CS_CLIENT_MODULE_NAME, (module_info **)&gPcmciaCs))!=B_OK)
3624f9f2ee2SJérôme Duval 		return err;
3634f9f2ee2SJérôme Duval 	if ((err = get_module(DS_MODULE_NAME, (module_info **)&gPcmciaDs))!=B_OK) {
3644f9f2ee2SJérôme Duval 		put_module(CS_CLIENT_MODULE_NAME);
3654f9f2ee2SJérôme Duval 		return err;
3664f9f2ee2SJérôme Duval 	}
3674f9f2ee2SJérôme Duval 
3684f9f2ee2SJérôme Duval 	devices_count = 0;
3694ff60cbaSJérôme Duval 	while (get_handle(devices_count, &handle)==B_OK) {
3704f9f2ee2SJérôme Duval 		devices_count++;
3714f9f2ee2SJérôme Duval 	}
3724f9f2ee2SJérôme Duval 
373b76d376bSJérôme Duval 	if (devices_count <= 0) {
374b76d376bSJérôme Duval 		put_module(CS_CLIENT_MODULE_NAME);
375b76d376bSJérôme Duval 		put_module(DS_MODULE_NAME);
3764f9f2ee2SJérôme Duval 		return ENODEV;
377b76d376bSJérôme Duval 	}
3784f9f2ee2SJérôme Duval 
3794f9f2ee2SJérôme Duval 	devices = malloc(sizeof(char *) * (devices_count+1));
3804ff60cbaSJérôme Duval 	if (!devices) {
3814ff60cbaSJérôme Duval 		put_module(CS_CLIENT_MODULE_NAME);
3824ff60cbaSJérôme Duval 		put_module(DS_MODULE_NAME);
3834ff60cbaSJérôme Duval 		return ENOMEM;
3844ff60cbaSJérôme Duval 	}
3854f9f2ee2SJérôme Duval 	for (i=0; i<devices_count; i++) {
3864f9f2ee2SJérôme Duval 		devices[i] = strdup(sockname);
3874f9f2ee2SJérôme Duval 		sprintf(devices[i], sockname, i);
3884f9f2ee2SJérôme Duval 	}
3894f9f2ee2SJérôme Duval 	devices[devices_count] = NULL;
3904f9f2ee2SJérôme Duval 
3914f9f2ee2SJérôme Duval 	return B_OK;
3924f9f2ee2SJérôme Duval }
3934f9f2ee2SJérôme Duval 
3944f9f2ee2SJérôme Duval 
3954f9f2ee2SJérôme Duval void
uninit_driver()3964f9f2ee2SJérôme Duval uninit_driver()
3974f9f2ee2SJérôme Duval {
3984f9f2ee2SJérôme Duval 	int32 i = 0;
3994f9f2ee2SJérôme Duval 	for (i=0; i<devices_count; i++) {
4004f9f2ee2SJérôme Duval 		free (devices[i]);
4014f9f2ee2SJérôme Duval 	}
402b76d376bSJérôme Duval 	free(devices);
4034ff60cbaSJérôme Duval 	devices = NULL;
4044f9f2ee2SJérôme Duval 
4054f9f2ee2SJérôme Duval 	put_module(DS_MODULE_NAME);
4064f9f2ee2SJérôme Duval 	put_module(CS_CLIENT_MODULE_NAME);
4074f9f2ee2SJérôme Duval }
408b76d376bSJérôme Duval 
409