44,9 → 44,8 |
#include <futex.h> |
#include <stdlib.h> |
#include <string.h> |
#include <ipc/devmap.h> |
|
#define NAME "devmap" |
#include "devmap.h" |
|
|
LIST_INITIALIZE(devices_list); |
113,8 → 112,10 |
item = item->next; |
} |
|
if (item == &devices_list) |
if (item == &devices_list) { |
printf("DEVMAP: no device named %s.\n", name); |
return NULL; |
} |
|
device = list_get_instance(item, devmap_device_t, devices); |
return device; |
202,6 → 203,7 |
* Get driver name |
*/ |
if (!ipc_data_write_receive(&callid, &name_size)) { |
printf("Unexpected request.\n"); |
free(driver); |
ipc_answer_0(callid, EREFUSED); |
ipc_answer_0(iid, EREFUSED); |
209,6 → 211,8 |
} |
|
if (name_size > DEVMAP_NAME_MAXLEN) { |
printf("Too logn name: %u: maximum is %u.\n", name_size, |
DEVMAP_NAME_MAXLEN); |
free(driver); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(iid, EREFUSED); |
219,6 → 223,7 |
* Allocate buffer for device name. |
*/ |
if (NULL == (driver->name = (char *)malloc(name_size + 1))) { |
printf("Cannot allocate space for driver name.\n"); |
free(driver); |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(iid, EREFUSED); |
229,6 → 234,7 |
* Send confirmation to sender and get data into buffer. |
*/ |
if (EOK != ipc_data_write_finalize(callid, driver->name, name_size)) { |
printf("Cannot read driver name.\n"); |
free(driver->name); |
free(driver); |
ipc_answer_0(iid, EREFUSED); |
237,6 → 243,8 |
|
driver->name[name_size] = 0; |
|
printf("Read driver name: '%s'.\n", driver->name); |
|
/* Initialize futex for list of devices owned by this driver */ |
futex_initialize(&(driver->devices_futex), 1); |
|
251,6 → 259,8 |
callid = async_get_call(&call); |
|
if (IPC_M_CONNECT_TO_ME != IPC_GET_METHOD(call)) { |
printf("DEVMAP: Unexpected method: %u.\n", |
IPC_GET_METHOD(call)); |
ipc_answer_0(callid, ENOTSUP); |
|
free(driver->name); |
278,8 → 288,10 |
futex_up(&drivers_list_futex); |
|
ipc_answer_0(iid, EOK); |
printf("Driver registered.\n"); |
|
*odriver = driver; |
return; |
} |
|
/** Unregister device driver, unregister all its devices and free driver |
289,9 → 301,12 |
{ |
devmap_device_t *device; |
|
if (NULL == driver) |
if (NULL == driver) { |
printf("Error: driver == NULL.\n"); |
return EEXISTS; |
|
} |
|
printf("Unregister driver '%s'.\n", driver->name); |
futex_down(&drivers_list_futex); |
|
ipc_hangup(driver->phone); |
307,6 → 322,7 |
while (!list_empty(&(driver->devices))) { |
device = list_get_instance(driver->devices.next, |
devmap_device_t, driver_devices); |
printf("Unregister device '%s'.\n", device->name); |
devmap_device_unregister_core(device); |
} |
|
321,6 → 337,8 |
|
free(driver); |
|
printf("Driver unregistered.\n"); |
|
return EOK; |
} |
|
336,6 → 354,7 |
devmap_device_t *device; |
|
if (NULL == driver) { |
printf("Invalid driver registration.\n"); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
342,7 → 361,8 |
|
/* Create new device entry */ |
if (NULL == |
(device = (devmap_device_t *) malloc(sizeof(devmap_device_t)))) { |
(device = (devmap_device_t *)malloc(sizeof(devmap_device_t)))) { |
printf("Cannot allocate new device.\n"); |
ipc_answer_0(iid, ENOMEM); |
return; |
} |
350,21 → 370,24 |
/* Get device name */ |
if (!ipc_data_write_receive(&callid, &size)) { |
free(device); |
printf("Cannot read device name.\n"); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
|
if (size > DEVMAP_NAME_MAXLEN) { |
printf("Too long device name: %u.\n", size); |
free(device); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
|
/* +1 for terminating \0 */ |
device->name = (char *) malloc(size + 1); |
|
/* +1 for terminating \0 */ |
device->name = (char *)malloc(size + 1); |
|
if (NULL == device->name) { |
printf("Cannot read device name.\n"); |
free(device); |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(iid, EREFUSED); |
381,7 → 404,7 |
|
/* Check that device with such name is not already registered */ |
if (NULL != devmap_device_find_name(device->name)) { |
printf(NAME ": Device '%s' already registered\n", device->name); |
printf("Device '%s' already registered.\n", device->name); |
futex_up(&devices_list_futex); |
free(device->name); |
free(device); |
405,7 → 428,10 |
futex_up(&device->driver->devices_futex); |
futex_up(&devices_list_futex); |
|
printf("Device '%s' registered.\n", device->name); |
ipc_answer_1(iid, EOK, device->handle); |
|
return; |
} |
|
/** |
435,6 → 461,8 |
dev = devmap_device_find_handle(handle); |
|
if (NULL == dev) { |
printf("DEVMAP: No registered device with handle %d.\n", |
handle); |
ipc_answer_0(callid, ENOENT); |
return; |
} |
441,6 → 469,7 |
|
ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle), |
IPC_GET_ARG3(*call), 0, IPC_FF_NONE); |
return; |
} |
|
/** Find handle for device instance identified by name. |
455,6 → 484,7 |
ipc_callid_t callid; |
ipcarg_t retval; |
|
|
/* |
* Wait for incoming message with device name (but do not |
* read the name itself until the buffer is allocated). |
498,11 → 528,16 |
* Device was not found. |
*/ |
if (NULL == dev) { |
printf("DEVMAP: device %s has not been registered.\n", name); |
ipc_answer_0(iid, ENOENT); |
return; |
} |
|
printf("DEVMAP: device %s has handler %d.\n", name, dev->handle); |
|
ipc_answer_1(iid, EOK, dev->handle); |
|
return; |
} |
|
/** Find name of device identified by id and send it to caller. |
539,12 → 574,15 |
} |
*/ |
/* TODO: send name in response */ |
|
return; |
} |
|
/** Handle connection with device driver. |
* |
*/ |
static void devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall) |
static void |
devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
555,8 → 593,10 |
|
devmap_driver_register(&driver); |
|
if (NULL == driver) |
if (NULL == driver) { |
printf("DEVMAP: driver registration failed.\n"); |
return; |
} |
|
while (cont) { |
callid = async_get_call(&call); |
563,10 → 603,13 |
|
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
printf("DEVMAP: connection hung up.\n"); |
cont = false; |
continue; /* Exit thread */ |
case DEVMAP_DRIVER_UNREGISTER: |
printf("DEVMAP: unregister driver.\n"); |
if (NULL == driver) { |
printf("DEVMAP: driver was not registered!\n"); |
ipc_answer_0(callid, ENOENT); |
} else { |
ipc_answer_0(callid, EOK); |
606,7 → 649,8 |
/** Handle connection with device client. |
* |
*/ |
static void devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall) |
static void |
devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
619,6 → 663,7 |
|
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
printf("DEVMAP: connection hung up.\n"); |
cont = false; |
continue; /* Exit thread */ |
|
641,10 → 686,14 |
/** Function for handling connections to devmap |
* |
*/ |
static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall) |
static void |
devmap_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
/* Select interface */ |
switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { |
|
printf("DEVMAP: new connection.\n"); |
|
/* Select interface */ |
switch ((ipcarg_t)(IPC_GET_ARG1(*icall))) { |
case DEVMAP_DRIVER: |
devmap_connection_driver(iid, icall); |
break; |
652,14 → 701,21 |
devmap_connection_client(iid, icall); |
break; |
case DEVMAP_CONNECT_TO_DEVICE: |
/* Connect client to selected device */ |
/* Connect client to selected device */ |
printf("DEVMAP: connect to device %d.\n", |
IPC_GET_ARG2(*icall)); |
devmap_forward(iid, icall); |
break; |
default: |
ipc_answer_0(iid, ENOENT); /* No such interface */ |
printf("DEVMAP: Unknown interface %u.\n", |
(ipcarg_t)(IPC_GET_ARG1(*icall))); |
} |
|
/* Cleanup */ |
|
printf("DEVMAP: connection closed.\n"); |
return; |
} |
|
/** |
667,16 → 723,16 |
*/ |
int main(int argc, char *argv[]) |
{ |
printf(NAME ": HelenOS Device Mapper\n"); |
|
ipcarg_t phonead; |
|
printf("DEVMAP: HelenOS device mapper.\n"); |
|
if (devmap_init() != 0) { |
printf(NAME ": Error while initializing service\n"); |
printf("Error while initializing DEVMAP service.\n"); |
return -1; |
} |
|
/* Set a handler of incomming connections */ |
|
/* Set a handler of incomming connections */ |
async_set_client_connection(devmap_connection); |
|
/* Register device mapper at naming service */ |
683,7 → 739,6 |
if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
return -1; |
|
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Never reached */ |
return 0; |
692,3 → 747,4 |
/** |
* @} |
*/ |
|