diff options
Diffstat (limited to 'drivers/pcmcia/rsrc_nonstatic.c')
| -rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 66 | 
1 files changed, 37 insertions, 29 deletions
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 4663b3fa9f9..a6eb7b59ba9 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,  		return;  	}  	for (i = base, most = 0; i < base+num; i += 8) { -		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); +		res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");  		if (!res)  			continue;  		hole = inb(i); @@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,  	bad = any = 0;  	for (i = base; i < base+num; i += 8) { -		res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); -		if (!res) +		res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); +		if (!res) { +			if (!any) +				printk(" excluding"); +			if (!bad) +				bad = any = i;  			continue; +		}  		for (j = 0; j < 8; j++)  			if (inb(i+j) != most)  				break; @@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,  	}  	if (bad) {  		if ((num > 16) && (bad == base) && (i == base+num)) { +			sub_interval(&s_data->io_db, bad, i-bad);  			printk(" nothing: probe failed.\n");  			return;  		} else { @@ -596,19 +602,17 @@ struct pcmcia_align_data {  	struct resource_map	*map;  }; -static resource_size_t -pcmcia_common_align(void *align_data, const struct resource *res, -			resource_size_t size, resource_size_t align) +static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data, +					resource_size_t start)  { -	struct pcmcia_align_data *data = align_data; -	resource_size_t start; +	resource_size_t ret;  	/*  	 * Ensure that we have the correct start address  	 */ -	start = (res->start & ~data->mask) + data->offset; -	if (start < res->start) -		start += data->mask + 1; -	return start; +	ret = (start & ~align_data->mask) + align_data->offset; +	if (ret < start) +		ret += align_data->mask + 1; +	return ret;  }  static resource_size_t @@ -619,29 +623,28 @@ pcmcia_align(void *align_data, const struct resource *res,  	struct resource_map *m;  	resource_size_t start; -	start = pcmcia_common_align(data, res, size, align); +	start = pcmcia_common_align(data, res->start);  	for (m = data->map->next; m != data->map; m = m->next) { -		unsigned long start = m->base; -		unsigned long end = m->base + m->num - 1; +		unsigned long map_start = m->base; +		unsigned long map_end = m->base + m->num - 1;  		/*  		 * If the lower resources are not available, try aligning  		 * to this entry of the resource database to see if it'll  		 * fit here.  		 */ -		if (res->start < start) { -			start = pcmcia_common_align(data, res, size, align); -		} +		if (start < map_start) +			start = pcmcia_common_align(data, map_start);  		/*  		 * If we're above the area which was passed in, there's  		 * no point proceeding.  		 */ -		if (res->start >= res->end) +		if (start >= res->end)  			break; -		if ((res->start + size - 1) <= end) +		if ((start + size - 1) <= map_end)  			break;  	} @@ -807,9 +810,18 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned  static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)  {  	struct socket_data *data = s->resource_data; -	unsigned long size = end - start + 1; +	unsigned long size;  	int ret = 0; +#if defined(CONFIG_X86) +	/* on x86, avoid anything < 0x100 for it is often used for +	 * legacy platform devices */ +	if (start < 0x100) +		start = 0x100; +#endif + +	size = end - start + 1; +  	if (end < start)  		return -EINVAL; @@ -867,10 +879,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)  			if (res == &ioport_resource)  				continue;  			dev_printk(KERN_INFO, &s->cb_dev->dev, -				   "pcmcia: parent PCI bridge I/O " -				   "window: 0x%llx - 0x%llx\n", -				   (unsigned long long)res->start, -				   (unsigned long long)res->end); +				   "pcmcia: parent PCI bridge window: %pR\n", +				   res);  			if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))  				done |= IORESOURCE_IO; @@ -880,10 +890,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)  			if (res == &iomem_resource)  				continue;  			dev_printk(KERN_INFO, &s->cb_dev->dev, -				   "pcmcia: parent PCI bridge Memory " -				   "window: 0x%llx - 0x%llx\n", -				   (unsigned long long)res->start, -				   (unsigned long long)res->end); +				   "pcmcia: parent PCI bridge window: %pR\n", +				   res);  			if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))  				done |= IORESOURCE_MEM;  		}  |