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