Commit 748d7b55 authored by Adam Belay's avatar Adam Belay

Large Stack Usage Fix

Reduces the stack memory usage in the following PnP Functions:
pnp_printf
pnp_set_current_resources
pnp_manual_config_dev
pnp_activate_dev
parent 057de1bb
...@@ -32,18 +32,16 @@ int pnp_printf(pnp_info_buffer_t * buffer, char *fmt,...) ...@@ -32,18 +32,16 @@ int pnp_printf(pnp_info_buffer_t * buffer, char *fmt,...)
{ {
va_list args; va_list args;
int res; int res;
char sbuffer[512];
if (buffer->stop || buffer->error) if (buffer->stop || buffer->error)
return 0; return 0;
va_start(args, fmt); va_start(args, fmt);
res = vsprintf(sbuffer, fmt, args); res = vsnprintf(buffer->curr, buffer->len - buffer->size, fmt, args);
va_end(args); va_end(args);
if (buffer->size + res >= buffer->len) { if (buffer->size + res >= buffer->len) {
buffer->stop = 1; buffer->stop = 1;
return 0; return 0;
} }
strcpy(buffer->curr, sbuffer);
buffer->curr += res; buffer->curr += res;
buffer->size += res; buffer->size += res;
return res; return res;
...@@ -432,13 +430,13 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count ...@@ -432,13 +430,13 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
goto done; goto done;
} }
if (!strnicmp(buf,"set",3)) { if (!strnicmp(buf,"set",3)) {
struct pnp_resource_table res;
int nport = 0, nmem = 0, nirq = 0, ndma = 0; int nport = 0, nmem = 0, nirq = 0, ndma = 0;
if (dev->active) if (dev->active)
goto done; goto done;
buf += 3; buf += 3;
pnp_init_resource_table(&res); spin_lock(&pnp_lock);
dev->config_mode = PNP_CONFIG_MANUAL;
pnp_init_resource_table(&dev->res);
while (1) { while (1) {
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
...@@ -446,17 +444,17 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count ...@@ -446,17 +444,17 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
buf += 2; buf += 2;
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
res.port_resource[nport].start = simple_strtoul(buf,&buf,0); dev->res.port_resource[nport].start = simple_strtoul(buf,&buf,0);
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
if(*buf == '-') { if(*buf == '-') {
buf += 1; buf += 1;
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
res.port_resource[nport].end = simple_strtoul(buf,&buf,0); dev->res.port_resource[nport].end = simple_strtoul(buf,&buf,0);
} else } else
res.port_resource[nport].end = res.port_resource[nport].start; dev->res.port_resource[nport].end = dev->res.port_resource[nport].start;
res.port_resource[nport].flags = IORESOURCE_IO; dev->res.port_resource[nport].flags = IORESOURCE_IO;
nport++; nport++;
if (nport >= PNP_MAX_PORT) if (nport >= PNP_MAX_PORT)
break; break;
...@@ -466,17 +464,17 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count ...@@ -466,17 +464,17 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
buf += 3; buf += 3;
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
res.mem_resource[nmem].start = simple_strtoul(buf,&buf,0); dev->res.mem_resource[nmem].start = simple_strtoul(buf,&buf,0);
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
if(*buf == '-') { if(*buf == '-') {
buf += 1; buf += 1;
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
res.mem_resource[nmem].end = simple_strtoul(buf,&buf,0); dev->res.mem_resource[nmem].end = simple_strtoul(buf,&buf,0);
} else } else
res.mem_resource[nmem].end = res.mem_resource[nmem].start; dev->res.mem_resource[nmem].end = dev->res.mem_resource[nmem].start;
res.mem_resource[nmem].flags = IORESOURCE_MEM; dev->res.mem_resource[nmem].flags = IORESOURCE_MEM;
nmem++; nmem++;
if (nmem >= PNP_MAX_MEM) if (nmem >= PNP_MAX_MEM)
break; break;
...@@ -486,9 +484,9 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count ...@@ -486,9 +484,9 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
buf += 3; buf += 3;
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
res.irq_resource[nirq].start = dev->res.irq_resource[nirq].start =
res.irq_resource[nirq].end = simple_strtoul(buf,&buf,0); dev->res.irq_resource[nirq].end = simple_strtoul(buf,&buf,0);
res.irq_resource[nirq].flags = IORESOURCE_IRQ; dev->res.irq_resource[nirq].flags = IORESOURCE_IRQ;
nirq++; nirq++;
if (nirq >= PNP_MAX_IRQ) if (nirq >= PNP_MAX_IRQ)
break; break;
...@@ -498,9 +496,9 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count ...@@ -498,9 +496,9 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
buf += 3; buf += 3;
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
res.dma_resource[ndma].start = dev->res.dma_resource[ndma].start =
res.dma_resource[ndma].end = simple_strtoul(buf,&buf,0); dev->res.dma_resource[ndma].end = simple_strtoul(buf,&buf,0);
res.dma_resource[ndma].flags = IORESOURCE_DMA; dev->res.dma_resource[ndma].flags = IORESOURCE_DMA;
ndma++; ndma++;
if (ndma >= PNP_MAX_DMA) if (ndma >= PNP_MAX_DMA)
break; break;
...@@ -508,9 +506,6 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count ...@@ -508,9 +506,6 @@ pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count
} }
break; break;
} }
spin_lock(&pnp_lock);
dev->config_mode = PNP_CONFIG_MANUAL;
dev->res = res;
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
goto done; goto done;
} }
......
...@@ -543,14 +543,18 @@ int pnp_auto_config_dev(struct pnp_dev *dev) ...@@ -543,14 +543,18 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res, int mode) int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res, int mode)
{ {
int i; int i;
struct pnp_resource_table bak = dev->res; struct pnp_resource_table * bak;
if (!dev || !res) if (!dev || !res)
return -EINVAL; return -EINVAL;
if (dev->active) if (dev->active)
return -EBUSY; return -EBUSY;
bak = pnp_alloc(sizeof(struct pnp_resource_table));
if (!bak)
return -ENOMEM;
*bak = dev->res;
spin_lock(&pnp_lock); spin_lock(&pnp_lock);
dev->res = *res; dev->res = *res;
if (!(mode & PNP_CONFIG_FORCE)) { if (!(mode & PNP_CONFIG_FORCE)) {
for (i = 0; i < PNP_MAX_PORT; i++) { for (i = 0; i < PNP_MAX_PORT; i++) {
if(pnp_check_port(dev,i)) if(pnp_check_port(dev,i))
...@@ -569,15 +573,17 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res, ...@@ -569,15 +573,17 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res,
goto fail; goto fail;
} }
} }
dev->config_mode = PNP_CONFIG_MANUAL;
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
pnp_resolve_conflicts(dev); pnp_resolve_conflicts(dev);
dev->config_mode = PNP_CONFIG_MANUAL; kfree(bak);
return 0; return 0;
fail: fail:
dev->res = bak; dev->res = *bak;
spin_unlock(&pnp_lock); spin_unlock(&pnp_lock);
kfree(bak);
return -EINVAL; return -EINVAL;
} }
...@@ -625,10 +631,13 @@ int pnp_activate_dev(struct pnp_dev *dev) ...@@ -625,10 +631,13 @@ int pnp_activate_dev(struct pnp_dev *dev)
goto fail; goto fail;
} }
if (pnp_can_read(dev)) { if (pnp_can_read(dev)) {
struct pnp_resource_table res; struct pnp_resource_table * res = pnp_alloc(sizeof(struct pnp_resource_table));
dev->protocol->get(dev, &res); if (!res)
if (pnp_compare_resources(&dev->res, &res)) /* if this happens we may be in big trouble but it's best just to continue */ goto fail;
dev->protocol->get(dev, res);
if (pnp_compare_resources(&dev->res, res)) /* if this happens we may be in big trouble but it's best just to continue */
pnp_err("res: The resources requested do not match those set for the PnP device '%s'.", dev->dev.bus_id); pnp_err("res: The resources requested do not match those set for the PnP device '%s'.", dev->dev.bus_id);
kfree(res);
} else } else
dev->active = pnp_is_active(dev); dev->active = pnp_is_active(dev);
pnp_dbg("res: the device '%s' has been activated.", dev->dev.bus_id); pnp_dbg("res: the device '%s' has been activated.", dev->dev.bus_id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment