patch-2.3.27 linux/drivers/pcmcia/rsrc_mgr.c
Next file: linux/drivers/pcmcia/rsrc_mgr.h
Previous file: linux/drivers/pcmcia/ricoh.h
Back to the patch index
Back to the overall index
- Lines: 150
- Date:
Thu Nov 11 16:03:37 1999
- Orig file:
v2.3.26/linux/drivers/pcmcia/rsrc_mgr.c
- Orig date:
Wed Oct 27 16:34:12 1999
diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/rsrc_mgr.c linux/drivers/pcmcia/rsrc_mgr.c
@@ -2,7 +2,7 @@
Resource management routines
- rsrc_mgr.c 1.73 1999/10/19 00:54:04
+ rsrc_mgr.c 1.76 1999/11/08 20:47:02
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
@@ -15,7 +15,7 @@
rights and limitations under the License.
The initial developer of the original code is David A. Hinds
- <dhinds@hyper.stanford.edu>. Portions created by David A. Hinds
+ <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds
are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
Alternatively, the contents of this file may be used under the
@@ -100,6 +100,14 @@
/*======================================================================
+ Linux resource management extensions
+
+======================================================================*/
+
+#define check_io_region(b,n) (0)
+
+/*======================================================================
+
These manage the internal databases of available resources.
======================================================================*/
@@ -180,7 +188,7 @@
b = kmalloc(256, GFP_KERNEL);
memset(b, 0, 256);
for (i = base, most = 0; i < base+num; i += 8) {
- if (check_region(i, 8))
+ if (check_region(i, 8) || check_io_region(i, 8))
continue;
hole = inb(i);
for (j = 1; j < 8; j++)
@@ -193,7 +201,7 @@
bad = any = 0;
for (i = base; i < base+num; i += 8) {
- if (check_region(i, 8))
+ if (check_region(i, 8) || check_io_region(i, 8))
continue;
for (j = 0; j < 8; j++)
if (inb(i+j) != most) break;
@@ -344,67 +352,59 @@
These find ranges of I/O ports or memory addresses that are not
currently allocated by other devices.
+
+ The 'align' field should reflect the number of bits of address
+ that need to be preserved from the initial value of *base. It
+ should be a power of two, greater than or equal to 'num'. A value
+ of 0 means that all bits of *base are significant. *base should
+ also be strictly less than 'align'.
======================================================================*/
-int find_io_region(ioaddr_t *base, ioaddr_t num, char *name)
+int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
+ char *name)
{
- ioaddr_t align;
+ ioaddr_t try;
resource_map_t *m;
- if (*base != 0) {
- for (m = io_db.next; m != &io_db; m = m->next) {
- if ((*base >= m->base) && (*base+num <= m->base+m->num)) {
- if (check_region(*base, num)) {
- return -1;
- } else {
- request_region(*base, num, name);
- return 0;
- }
- }
- }
- return -1;
- }
-
- for (align = 1; align < num; align *= 2) ;
for (m = io_db.next; m != &io_db; m = m->next) {
- for (*base = (m->base + align - 1) & (~(align-1));
- *base+align <= m->base + m->num;
- *base += align)
- if (check_region(*base, num) == 0) {
- request_region(*base, num, name);
+ try = (m->base & ~(align-1)) + *base;
+ for (try = (try >= m->base) ? try : try+align;
+ (try >= m->base) && (try+num <= m->base+m->num);
+ try += align) {
+ if ((check_region(try, num) == 0) &&
+ (check_io_region(try, num) == 0)) {
+ *base = try;
+ request_region(try, num, name);
return 0;
}
+ if (!align) break;
+ }
}
return -1;
} /* find_io_region */
-int find_mem_region(u_long *base, u_long num, char *name,
- u_long align, int force_low)
+int find_mem_region(u_long *base, u_long num, u_long align,
+ int force_low, char *name)
{
+ u_long try;
resource_map_t *m;
- if (*base != 0) {
- for (m = mem_db.next; m != &mem_db; m = m->next) {
- if ((*base >= m->base) && (*base+num <= m->base+m->num))
- if (check_mem_region(*base, num) == 0) {
- request_mem_region(*base, num, name);
- return 0;
- }
- }
- return -1;
- }
-
while (1) {
for (m = mem_db.next; m != &mem_db; m = m->next) {
/* first pass >1MB, second pass <1MB */
if ((force_low != 0) ^ (m->base < 0x100000)) continue;
- for (*base = (m->base + align - 1) & (~(align-1));
- *base+num <= m->base+m->num; *base += align)
- if (check_mem_region(*base, num) == 0) {
- request_mem_region(*base, num, name);
+ try = (m->base & ~(align-1)) + *base;
+ for (try = (try >= m->base) ? try : try+align;
+ (try >= m->base) && (try+num <= m->base+m->num);
+ try += align) {
+ if (check_mem_region(try, num) == 0) {
+ request_mem_region(try, num, name);
+ *base = try;
return 0;
}
+ if (!align) break;
+ }
}
if (force_low) break;
force_low++;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)