Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision 3e6a98c595287c43d200d28d97f57755342be117)
+++ uspace/drv/bus/isa/isa.c	(revision 03362fbdd97fb8df65b78ada498e07140aaa9080)
@@ -85,4 +85,5 @@
 	fibril_mutex_t mutex;
 	ddf_fun_t *fnode;
+	hw_resource_t resources[ISA_MAX_HW_RES];
 	hw_resource_list_t hw_resources;
 	link_t bus_link;
@@ -103,15 +104,16 @@
 static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
 {
-	isa_fun_t *fun = isa_fun(fnode);
-	assert(fun != NULL);
-
-	return &fun->hw_resources;
-}
-
-static bool isa_enable_fun_interrupt(ddf_fun_t *fnode)
+	isa_fun_t *isa = isa_fun(fnode);
+	assert(isa);
+
+	return &isa->hw_resources;
+}
+
+static bool isa_fun_enable_interrupt(ddf_fun_t *fnode)
 {
 	/* This is an old ugly way, copied from pci driver */
 	assert(fnode);
-	isa_fun_t *fun = isa_fun(fnode);
+	isa_fun_t *isa = isa_fun(fnode);
+	assert(isa);
 
 	sysarg_t apic;
@@ -129,5 +131,5 @@
 		return false;
 
-	const hw_resource_list_t *res = &fun->hw_resources;
+	const hw_resource_list_t *res = &isa->hw_resources;
 	assert(res);
 	for (size_t i = 0; i < res->count; ++i) {
@@ -151,22 +153,46 @@
 }
 
-static int isa_dma_channel_fun_setup(ddf_fun_t *fnode,
+static int isa_fun_setup_dma(ddf_fun_t *fnode,
     unsigned int channel, uint32_t pa, uint16_t size, uint8_t mode)
 {
 	assert(fnode);
-	isa_fun_t *fun = isa_fun(fnode);
-	const hw_resource_list_t *res = &fun->hw_resources;
+	isa_fun_t *isa = isa_fun(fnode);
+	assert(isa);
+	const hw_resource_list_t *res = &isa->hw_resources;
 	assert(res);
-	
-	const unsigned int ch = channel;
+
 	for (size_t i = 0; i < res->count; ++i) {
+		/* Check for assigned channel */
 		if (((res->resources[i].type == DMA_CHANNEL_16) &&
-		    (res->resources[i].res.dma_channel.dma16 == ch)) ||
+		    (res->resources[i].res.dma_channel.dma16 == channel)) ||
 		    ((res->resources[i].type == DMA_CHANNEL_8) &&
-		    (res->resources[i].res.dma_channel.dma8 == ch))) {
-			return dma_setup_channel(channel, pa, size, mode);
-		}
-	}
-	
+		    (res->resources[i].res.dma_channel.dma8 == channel))) {
+			return dma_channel_setup(channel, pa, size, mode);
+		}
+	}
+
+	return EINVAL;
+}
+
+static int isa_fun_remain_dma(ddf_fun_t *fnode,
+    unsigned channel, size_t *size)
+{
+	assert(size);
+	assert(fnode);
+	isa_fun_t *isa = isa_fun(fnode);
+	assert(isa);
+	const hw_resource_list_t *res = &isa->hw_resources;
+	assert(res);
+
+	for (size_t i = 0; i < res->count; ++i) {
+		/* Check for assigned channel */
+		if (((res->resources[i].type == DMA_CHANNEL_16) &&
+		    (res->resources[i].res.dma_channel.dma16 == channel)) ||
+		    ((res->resources[i].type == DMA_CHANNEL_8) &&
+		    (res->resources[i].res.dma_channel.dma8 == channel))) {
+			return dma_channel_remain(channel, size);
+		}
+	}
+
 	return EINVAL;
 }
@@ -174,9 +200,12 @@
 static hw_res_ops_t isa_fun_hw_res_ops = {
 	.get_resource_list = isa_get_fun_resources,
-	.enable_interrupt = isa_enable_fun_interrupt,
-	.dma_channel_setup = isa_dma_channel_fun_setup,
+	.enable_interrupt = isa_fun_enable_interrupt,
+	.dma_channel_setup = isa_fun_setup_dma,
+	.dma_channel_remain = isa_fun_remain_dma,
 };
 
-static ddf_dev_ops_t isa_fun_ops;
+static ddf_dev_ops_t isa_fun_ops= {
+	.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops,
+};
 
 static int isa_dev_add(ddf_dev_t *dev);
@@ -212,4 +241,6 @@
 
 	fibril_mutex_initialize(&fun->mutex);
+	fun->hw_resources.resources = fun->resources;
+
 	fun->fnode = fnode;
 	return fun;
@@ -270,7 +301,7 @@
 {
 	char *line = str;
+	*next = NULL;
 
 	if (str == NULL) {
-		*next = NULL;
 		return NULL;
 	}
@@ -282,6 +313,4 @@
 	if (*str != '\0') {
 		*next = str + 1;
-	} else {
-		*next = NULL;
 	}
 
@@ -310,18 +339,8 @@
 	/* Get the name part of the rest of the line. */
 	strtok(line, ":");
-
-	/* Allocate output buffer. */
-	size_t size = str_size(line) + 1;
-	char *name = malloc(size);
-
-	if (name != NULL) {
-		/* Copy the result to the output buffer. */
-		str_cpy(name, size, line);
-	}
-
-	return name;
-}
-
-static inline char *skip_spaces(char *line)
+	return line;
+}
+
+static inline const char *skip_spaces(const char *line)
 {
 	/* Skip leading spaces. */
@@ -332,5 +351,5 @@
 }
 
-static void isa_fun_set_irq(isa_fun_t *fun, int irq)
+static void isa_fun_add_irq(isa_fun_t *fun, int irq)
 {
 	size_t count = fun->hw_resources.count;
@@ -348,5 +367,5 @@
 }
 
-static void isa_fun_set_dma(isa_fun_t *fun, int dma)
+static void isa_fun_add_dma(isa_fun_t *fun, int dma)
 {
 	size_t count = fun->hw_resources.count;
@@ -381,5 +400,5 @@
 }
 
-static void isa_fun_set_io_range(isa_fun_t *fun, size_t addr, size_t len)
+static void isa_fun_add_io_range(isa_fun_t *fun, size_t addr, size_t len)
 {
 	size_t count = fun->hw_resources.count;
@@ -400,5 +419,5 @@
 }
 
-static void fun_parse_irq(isa_fun_t *fun, char *val)
+static void fun_parse_irq(isa_fun_t *fun, const char *val)
 {
 	int irq = 0;
@@ -409,20 +428,19 @@
 
 	if (val != end)
-		isa_fun_set_irq(fun, irq);
-}
-
-static void fun_parse_dma(isa_fun_t *fun, char *val)
-{
-	unsigned int dma = 0;
+		isa_fun_add_irq(fun, irq);
+}
+
+static void fun_parse_dma(isa_fun_t *fun, const char *val)
+{
 	char *end = NULL;
 	
 	val = skip_spaces(val);
-	dma = (unsigned int) strtol(val, &end, 10);
+	const int dma = strtol(val, &end, 10);
 	
 	if (val != end)
-		isa_fun_set_dma(fun, dma);
-}
-
-static void fun_parse_io_range(isa_fun_t *fun, char *val)
+		isa_fun_add_dma(fun, dma);
+}
+
+static void fun_parse_io_range(isa_fun_t *fun, const char *val)
 {
 	size_t addr, len;
@@ -441,10 +459,10 @@
 		return;
 
-	isa_fun_set_io_range(fun, addr, len);
-}
-
-static void get_match_id(char **id, char *val)
-{
-	char *end = val;
+	isa_fun_add_io_range(fun, addr, len);
+}
+
+static void get_match_id(char **id, const char *val)
+{
+	const char *end = val;
 
 	while (!isspace(*end))
@@ -456,14 +474,12 @@
 }
 
-static void fun_parse_match_id(isa_fun_t *fun, char *val)
+static void fun_parse_match_id(isa_fun_t *fun, const char *val)
 {
 	char *id = NULL;
-	int score = 0;
 	char *end = NULL;
-	int rc;
 
 	val = skip_spaces(val);
 
-	score = (int)strtol(val, &end, 10);
+	int score = (int)strtol(val, &end, 10);
 	if (val == end) {
 		ddf_msg(LVL_ERROR, "Cannot read match score for function "
@@ -483,5 +499,5 @@
 	    "function %s", id, score, ddf_fun_get_name(fun->fnode));
 
-	rc = ddf_fun_add_match_id(fun->fnode, id, score);
+	int rc = ddf_fun_add_match_id(fun->fnode, id, score);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed adding match ID: %s",
@@ -492,6 +508,6 @@
 }
 
-static bool prop_parse(isa_fun_t *fun, char *line, const char *prop,
-    void (*read_fn)(isa_fun_t *, char *))
+static bool prop_parse(isa_fun_t *fun, const char *line, const char *prop,
+    void (*read_fn)(isa_fun_t *, const char *))
 {
 	size_t proplen = str_size(prop);
@@ -508,5 +524,5 @@
 }
 
-static void fun_prop_parse(isa_fun_t *fun, char *line)
+static void fun_prop_parse(isa_fun_t *fun, const char *line)
 {
 	/* Skip leading spaces. */
@@ -523,23 +539,10 @@
 }
 
-static void fun_hw_res_alloc(isa_fun_t *fun)
-{
-	fun->hw_resources.resources =
-	    (hw_resource_t *) malloc(sizeof(hw_resource_t) * ISA_MAX_HW_RES);
-}
-
-static void fun_hw_res_free(isa_fun_t *fun)
-{
-	free(fun->hw_resources.resources);
-	fun->hw_resources.resources = NULL;
-}
-
 static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa)
 {
 	char *line;
-	char *fun_name = NULL;
 
 	/* Skip empty lines. */
-	while (true) {
+	do {
 		line = str_get_line(fun_conf, &fun_conf);
 
@@ -549,21 +552,15 @@
 		}
 
-		if (!line_empty(line))
-			break;
-	}
+	} while (line_empty(line));
 
 	/* Get device name. */
-	fun_name = get_device_name(line);
+	const char *fun_name = get_device_name(line);
 	if (fun_name == NULL)
 		return NULL;
 
 	isa_fun_t *fun = isa_fun_create(isa, fun_name);
-	free(fun_name);
 	if (fun == NULL) {
 		return NULL;
 	}
-
-	/* Allocate buffer for the list of hardware resources of the device. */
-	fun_hw_res_alloc(fun);
 
 	/* Get properties of the device (match ids, irq and io range). */
@@ -596,30 +593,19 @@
 }
 
-static void fun_conf_parse(char *conf, isa_bus_t *isa)
-{
+static void isa_functions_add(isa_bus_t *isa)
+{
+	char *conf = fun_conf_read(CHILD_FUN_CONF_PATH);
 	while (conf != NULL && *conf != '\0') {
 		conf = isa_fun_read_info(conf, isa);
 	}
-}
-
-static void isa_functions_add(isa_bus_t *isa)
-{
-	char *fun_conf;
-
-	fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH);
-	if (fun_conf != NULL) {
-		fun_conf_parse(fun_conf, isa);
-		free(fun_conf);
-	}
+	free(conf);
 }
 
 static int isa_dev_add(ddf_dev_t *dev)
 {
-	isa_bus_t *isa;
-
 	ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
 	    (int) ddf_dev_get_handle(dev));
 
-	isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
+	isa_bus_t *isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
 	if (isa == NULL)
 		return ENOMEM;
@@ -658,5 +644,4 @@
 {
 	isa_bus_t *isa = isa_bus(dev);
-	int rc;
 
 	fibril_mutex_lock(&isa->mutex);
@@ -666,5 +651,5 @@
 		    isa_fun_t, bus_link);
 
-		rc = ddf_fun_offline(fun->fnode);
+		int rc = ddf_fun_offline(fun->fnode);
 		if (rc != EOK) {
 			fibril_mutex_unlock(&isa->mutex);
@@ -682,5 +667,4 @@
 		list_remove(&fun->bus_link);
 
-		fun_hw_res_free(fun);
 		ddf_fun_destroy(fun->fnode);
 	}
@@ -709,15 +693,8 @@
 }
 
-
-static void isa_init()
-{
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS ISA bus driver\n");
 	ddf_log_init(NAME);
-	isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
-}
-
-int main(int argc, char *argv[])
-{
-	printf(NAME ": HelenOS ISA bus driver\n");
-	isa_init();
 	return ddf_driver_main(&isa_driver);
 }
