linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Paul Mackerras <paulus@samba.org>
To: torvalds@transmeta.com
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH]
Date: Wed, 7 Aug 2002 09:04:00 +1000 (EST)	[thread overview]
Message-ID: <15696.21984.645493.409103@argo.ozlabs.ibm.com> (raw)

Linus,

This patch is a forward-port from 2.4.  It changes the pcmcia resource
allocation code so that it allocates IO and memory resources from the
correct resource parent.  The details were discussed on lkml last year
in the 2.4 context.  I need this on powerbooks because they have
multiple PCI host bridges.  Please apply this to your tree.

Paul.

diff -urN linux-2.5/drivers/pcmcia/cistpl.c pmac-2.5/drivers/pcmcia/cistpl.c
--- linux-2.5/drivers/pcmcia/cistpl.c	Tue Feb  5 18:55:14 2002
+++ pmac-2.5/drivers/pcmcia/cistpl.c	Sun Jul 21 14:01:56 2002
@@ -264,11 +264,11 @@
 	(s->cis_mem.sys_start == 0)) {
 	int low = !(s->cap.features & SS_CAP_PAGE_REGS);
 	vs = s;
-	validate_mem(cis_readable, checksum_match, low);
+	validate_mem(cis_readable, checksum_match, low, s);
 	s->cis_mem.sys_start = 0;
 	vs = NULL;
 	if (find_mem_region(&s->cis_mem.sys_start, s->cap.map_size,
-			    s->cap.map_size, low, "card services")) {
+			    s->cap.map_size, low, "card services", s)) {
 	    printk(KERN_NOTICE "cs: unable to map card memory!\n");
 	    return CS_OUT_OF_RESOURCE;
 	}
diff -urN linux-2.5/drivers/pcmcia/cs.c pmac-2.5/drivers/pcmcia/cs.c
--- linux-2.5/drivers/pcmcia/cs.c	Tue Feb  5 18:55:14 2002
+++ pmac-2.5/drivers/pcmcia/cs.c	Sat Jul 20 20:41:46 2002
@@ -809,7 +809,7 @@
 	    return 1;
     for (i = 0; i < MAX_IO_WIN; i++) {
 	if (s->io[i].NumPorts == 0) {
-	    if (find_io_region(base, num, align, name) == 0) {
+	    if (find_io_region(base, num, align, name, s) == 0) {
 		s->io[i].Attributes = attr;
 		s->io[i].BasePort = *base;
 		s->io[i].NumPorts = s->io[i].InUse = num;
@@ -821,7 +821,7 @@
 	/* Try to extend top of window */
 	try = s->io[i].BasePort + s->io[i].NumPorts;
 	if ((*base == 0) || (*base == try))
-	    if (find_io_region(&try, num, 0, name) == 0) {
+	    if (find_io_region(&try, num, 0, name, s) == 0) {
 		*base = try;
 		s->io[i].NumPorts += num;
 		s->io[i].InUse += num;
@@ -830,7 +830,7 @@
 	/* Try to extend bottom of window */
 	try = s->io[i].BasePort - num;
 	if ((*base == 0) || (*base == try))
-	    if (find_io_region(&try, num, 0, name) == 0) {
+	    if (find_io_region(&try, num, 0, name, s) == 0) {
 		s->io[i].BasePort = *base = try;
 		s->io[i].NumPorts += num;
 		s->io[i].InUse += num;
@@ -1974,7 +1974,7 @@
 	find_mem_region(&win->base, win->size, align,
 			(req->Attributes & WIN_MAP_BELOW_1MB) ||
 			!(s->cap.features & SS_CAP_PAGE_REGS),
-			(*handle)->dev_info))
+			(*handle)->dev_info, s))
 	return CS_IN_USE;
     (*handle)->state |= CLIENT_WIN_REQ(w);
 
diff -urN linux-2.5/drivers/pcmcia/cs_internal.h pmac-2.5/drivers/pcmcia/cs_internal.h
--- linux-2.5/drivers/pcmcia/cs_internal.h	Wed Feb  6 04:40:18 2002
+++ pmac-2.5/drivers/pcmcia/cs_internal.h	Sat Jul 20 20:38:06 2002
@@ -238,11 +238,11 @@
 
 /* In rsrc_mgr */
 void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
-		  int force_low);
+		  int force_low, socket_info_t *s);
 int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
-		   char *name);
+		   char *name, socket_info_t *s);
 int find_mem_region(u_long *base, u_long num, u_long align,
-		    int force_low, char *name);
+		    int force_low, char *name, socket_info_t *s);
 int try_irq(u_int Attributes, int irq, int specific);
 void undo_irq(u_int Attributes, int irq);
 int adjust_resource_info(client_handle_t handle, adjust_t *adj);
diff -urN linux-2.5/drivers/pcmcia/rsrc_mgr.c pmac-2.5/drivers/pcmcia/rsrc_mgr.c
--- linux-2.5/drivers/pcmcia/rsrc_mgr.c	Tue Feb  5 18:55:14 2002
+++ pmac-2.5/drivers/pcmcia/rsrc_mgr.c	Sun Jul 21 14:02:02 2002
@@ -44,6 +44,7 @@
 #include <linux/ioport.h>
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
+#include <linux/pci.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
@@ -103,8 +104,82 @@
 
 ======================================================================*/
 
-#define check_io_resource(b,n)	check_resource(&ioport_resource, (b), (n))
-#define check_mem_resource(b,n)	check_resource(&iomem_resource, (b), (n))
+static struct resource *resource_parent(unsigned long b, unsigned long n,
+					int flags, struct pci_dev *dev)
+{
+#ifdef CONFIG_PCI
+	struct resource res, *pr;
+
+	if (dev != NULL) {
+		res.start = b;
+		res.end = b + n - 1;
+		res.flags = flags;
+		pr = pci_find_parent_resource(dev, &res);
+		if (pr)
+			return pr;
+	}
+#endif /* CONFIG_PCI */
+	if (flags & IORESOURCE_MEM)
+		return &iomem_resource;
+	return &ioport_resource;
+}
+
+static inline int check_io_resource(unsigned long b, unsigned long n,
+				    struct pci_dev *dev)
+{
+	return check_resource(resource_parent(b, n, IORESOURCE_IO, dev), b, n);
+}
+
+static inline int check_mem_resource(unsigned long b, unsigned long n,
+				     struct pci_dev *dev)
+{
+	return check_resource(resource_parent(b, n, IORESOURCE_MEM, dev), b, n);
+}
+
+static struct resource *make_resource(unsigned long b, unsigned long n,
+				      int flags, char *name)
+{
+	struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+
+	if (res) {
+		memset(res, 0, sizeof(*res));
+		res->name = name;
+		res->start = b;
+		res->end = b + n - 1;
+		res->flags = flags | IORESOURCE_BUSY;
+	}
+	return res;
+}
+
+static int request_io_resource(unsigned long b, unsigned long n,
+			       char *name, struct pci_dev *dev)
+{
+	struct resource *res = make_resource(b, n, IORESOURCE_IO, name);
+	struct resource *pr = resource_parent(b, n, IORESOURCE_IO, dev);
+	int err = -ENOMEM;
+
+	if (res) {
+		err = request_resource(pr, res);
+		if (err)
+			kfree(res);
+	}
+	return err;
+}
+
+static int request_mem_resource(unsigned long b, unsigned long n,
+				char *name, struct pci_dev *dev)
+{
+	struct resource *res = make_resource(b, n, IORESOURCE_MEM, name);
+	struct resource *pr = resource_parent(b, n, IORESOURCE_MEM, dev);
+	int err = -ENOMEM;
+
+	if (res) {
+		err = request_resource(pr, res);
+		if (err)
+			kfree(res);
+	}
+	return err;
+}
 
 /*======================================================================
 
@@ -194,7 +269,7 @@
     }   
     memset(b, 0, 256);
     for (i = base, most = 0; i < base+num; i += 8) {
-	if (check_io_resource(i, 8))
+	if (check_io_resource(i, 8, NULL))
 	    continue;
 	hole = inb(i);
 	for (j = 1; j < 8; j++)
@@ -207,7 +282,7 @@
 
     bad = any = 0;
     for (i = base; i < base+num; i += 8) {
-	if (check_io_resource(i, 8))
+	if (check_io_resource(i, 8, NULL))
 	    continue;
 	for (j = 0; j < 8; j++)
 	    if (inb(i+j) != most) break;
@@ -247,7 +322,8 @@
 ======================================================================*/
 
 static int do_mem_probe(u_long base, u_long num,
-			int (*is_valid)(u_long), int (*do_cksum)(u_long))
+			int (*is_valid)(u_long), int (*do_cksum)(u_long),
+			socket_info_t *s)
 {
     u_long i, j, bad, fail, step;
 
@@ -258,13 +334,14 @@
     for (i = j = base; i < base+num; i = j + step) {
 	if (!fail) {	
 	    for (j = i; j < base+num; j += step)
-		if ((check_mem_resource(j, step) == 0) && is_valid(j))
+		if ((check_mem_resource(j, step, s->cap.cb_dev) == 0) &&
+		    is_valid(j))
 		    break;
 	    fail = ((i == base) && (j == base+num));
 	}
 	if (fail) {
 	    for (j = i; j < base+num; j += 2*step)
-		if ((check_mem_resource(j, 2*step) == 0) &&
+		if ((check_mem_resource(j, 2*step, s->cap.cb_dev) == 0) &&
 		    do_cksum(j) && do_cksum(j+step))
 		    break;
 	}
@@ -283,12 +360,12 @@
 
 static u_long inv_probe(int (*is_valid)(u_long),
 			int (*do_cksum)(u_long),
-			resource_map_t *m)
+			resource_map_t *m, socket_info_t *s)
 {
     u_long ok;
     if (m == &mem_db)
 	return 0;
-    ok = inv_probe(is_valid, do_cksum, m->next);
+    ok = inv_probe(is_valid, do_cksum, m->next, s);
     if (ok) {
 	if (m->base >= 0x100000)
 	    sub_interval(&mem_db, m->base, m->num);
@@ -296,11 +373,11 @@
     }
     if (m->base < 0x100000)
 	return 0;
-    return do_mem_probe(m->base, m->num, is_valid, do_cksum);
+    return do_mem_probe(m->base, m->num, is_valid, do_cksum, s);
 }
 
 void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
-		  int force_low)
+		  int force_low, socket_info_t *s)
 {
     resource_map_t *m, *n;
     static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
@@ -310,7 +387,7 @@
     if (!probe_mem) return;
     /* We do up to four passes through the list */
     if (!force_low) {
-	if (hi++ || (inv_probe(is_valid, do_cksum, mem_db.next) > 0))
+	if (hi++ || (inv_probe(is_valid, do_cksum, mem_db.next, s) > 0))
 	    return;
 	printk(KERN_NOTICE "cs: warning: no high memory space "
 	       "available!\n");
@@ -321,7 +398,7 @@
 	/* Only probe < 1 MB */
 	if (m->base >= 0x100000) continue;
 	if ((m->base | m->num) & 0xffff) {
-	    ok += do_mem_probe(m->base, m->num, is_valid, do_cksum);
+	    ok += do_mem_probe(m->base, m->num, is_valid, do_cksum, s);
 	    continue;
 	}
 	/* Special probe for 64K-aligned block */
@@ -331,7 +408,7 @@
 		if (ok >= mem_limit)
 		    sub_interval(&mem_db, b, 0x10000);
 		else
-		    ok += do_mem_probe(b, 0x10000, is_valid, do_cksum);
+		    ok += do_mem_probe(b, 0x10000, is_valid, do_cksum, s);
 	    }
 	}
     }
@@ -340,7 +417,7 @@
 #else /* CONFIG_ISA */
 
 void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
-		  int force_low)
+		  int force_low, socket_info_t *s)
 {
     resource_map_t *m;
     static int done = 0;
@@ -348,7 +425,7 @@
     if (!probe_mem || done++)
 	return;
     for (m = mem_db.next; m != &mem_db; m = m->next)
-	if (do_mem_probe(m->base, m->num, is_valid, do_cksum))
+	if (do_mem_probe(m->base, m->num, is_valid, do_cksum, s))
 	    return;
 }
 
@@ -368,7 +445,7 @@
 ======================================================================*/
 
 int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
-		   char *name)
+		   char *name, socket_info_t *s)
 {
     ioaddr_t try;
     resource_map_t *m;
@@ -378,9 +455,8 @@
 	for (try = (try >= m->base) ? try : try+align;
 	     (try >= m->base) && (try+num <= m->base+m->num);
 	     try += align) {
-	    if (check_io_resource(try, num) == 0) {
+	    if (request_io_resource(try, num, name, s->cap.cb_dev) == 0) {
 		*base = try;
-		request_region(try, num, name);
 		return 0;
 	    }
 	    if (!align) break;
@@ -390,7 +466,7 @@
 }
 
 int find_mem_region(u_long *base, u_long num, u_long align,
-		    int force_low, char *name)
+		    int force_low, char *name, socket_info_t *s)
 {
     u_long try;
     resource_map_t *m;
@@ -403,8 +479,7 @@
 	    for (try = (try >= m->base) ? try : try+align;
 		 (try >= m->base) && (try+num <= m->base+m->num);
 		 try += align) {
-		if (check_mem_resource(try, num) == 0) {
-		    request_mem_region(try, num, name);
+		if (request_mem_resource(try, num, name, s->cap.cb_dev) == 0) {
 		    *base = try;
 		    return 0;
 		}

             reply	other threads:[~2002-08-06 23:03 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-08-06 23:04 Paul Mackerras [this message]
  -- strict thread matches above, loose matches on Subject: below --
2022-02-02 21:26 [PATCH] Sergey Shtylyov
2017-07-09 23:58 [PATCH] armetallica
2017-07-09 23:54 ` [PATCH] Kershner, David A
2017-07-09 23:35 [PATCH] armetallica
2017-07-20 15:06 ` [PATCH] Mauro Carvalho Chehab
2013-12-24 15:45 [PATCH] Evan Hosseini
2014-01-09 18:27 ` [PATCH] Greg KH
2012-03-04 20:34 [PATCH] Stefan Richter
2012-03-04 20:36 ` [PATCH] Stefan Richter
2011-08-11 21:29 [PATCH] Rafael J. Wysocki
2010-09-19  2:25 [PATCH] Junio C Hamano
2010-09-19  9:54 ` [PATCH] Sam Ravnborg
2010-09-19 18:21   ` [PATCH] Junio C Hamano
2010-09-19 19:31     ` [PATCH] Sam Ravnborg
2010-09-20 12:11     ` [PATCH] Michal Marek
2010-08-14 12:43 [PATCH] Sam Ravnborg
2009-04-07 16:20 [PATCH] Christoph Hellwig
2008-10-15  7:03 [PATCH] Tim Shimmin
2007-12-03 15:54 [PATCH] Andries E. Brouwer
2007-12-03 17:06 ` [PATCH] Alan Cox
2007-04-01 18:13 [PATCH 0/16] Assorted patches Jan Engelhardt
2007-04-01 18:15 ` [PATCH 07/16] kconfig-dynamic-frequency.diff Jan Engelhardt
2007-04-01 18:39   ` Kyle Moffett
2007-04-01 18:42     ` Jan Engelhardt
2007-04-01 18:52       ` Kyle Moffett
2007-04-01 19:01         ` Jan Engelhardt
2007-04-01 19:42           ` [PATCH] Kyle Moffett
2007-04-01 19:47             ` [PATCH] Jan Engelhardt
2007-04-01 20:07               ` [PATCH] Kyle Moffett
2007-04-01 23:03             ` [PATCH] Andi Kleen
2007-02-21 21:23 [PATCH] James Simmons
2006-07-15 18:43 [PATCH] Chris Boot
2006-03-24 23:07 [PATCH] Daniel Walker
2006-03-24 23:19 ` [PATCH] john stultz
2006-03-24 23:22   ` [PATCH] Daniel Walker
2006-03-10 14:47 [PATCH] Kumar Gala
2006-03-10 15:05 ` [PATCH] Kumar Gala
2005-06-15 11:41 [PATCH] Jan Beulich
2004-11-18 20:17 [PATCH] Colin Leroy
2004-08-10  2:49 [PATCH] Roland McGrath
2004-08-05 13:51 [PATCH] Michal Ludvig
2004-08-05 14:11 ` [PATCH] James Morris
2004-08-05 19:49   ` [PATCH] Jean-Luc Cooke
2004-08-06  2:47     ` [PATCH] James Morris
2004-08-06  2:03       ` [PATCH] Michael Halcrow
2004-08-06  4:58         ` [PATCH] Linus Torvalds
2004-08-06 13:03           ` [PATCH] Jean-Luc Cooke
2004-08-06  3:36       ` [PATCH] YOSHIFUJI Hideaki / 吉藤英明
2004-08-06  4:21         ` [PATCH] David S. Miller
2004-08-06  4:28         ` [PATCH] Jean-Luc Cooke
2004-08-06  4:42           ` [PATCH] James Morris
2004-08-06 12:54             ` [PATCH] Jean-Luc Cooke
2004-08-06 18:26               ` [PATCH] David S. Miller
2004-08-06 18:36                 ` [PATCH] Jean-Luc Cooke
2004-08-06 23:24               ` [PATCH] Matt Mackall
2004-08-07  3:01                 ` [PATCH] Jean-Luc Cooke
2004-08-07 22:26               ` [PATCH] Theodore Ts'o
2004-08-08 15:38                 ` [PATCH] Jean-Luc Cooke
2004-08-09 18:43                   ` [PATCH] Theodore Ts'o
2004-08-09 18:49                     ` [PATCH] Jean-Luc Cooke
2004-08-10  0:22                       ` [PATCH] Theodore Ts'o
2003-08-11 13:40 [PATCH] davej
2003-07-30 16:31 [patch] Adrian Bunk
2002-04-15 18:39 [PATCH] Andre Hedrick
2002-04-15 19:09 ` [PATCH] Josh McKinney
2002-04-15 19:16   ` [PATCH] Andre Hedrick
2002-04-15 19:59   ` [PATCH] Andre Hedrick
2002-04-16  3:11     ` [PATCH] Josh McKinney
2002-04-16  4:11       ` [PATCH] Andre Hedrick
2002-04-16  5:53 ` [PATCH] Jens Axboe
2002-04-16  6:51   ` [PATCH] Andre Hedrick
2002-04-16  6:54     ` [PATCH] Jens Axboe
2002-04-16  7:04       ` [PATCH] Andre Hedrick
2001-10-25 17:24 [PATCH] Christoph Hellwig
2000-11-07 23:20 [PATCH] Bartlomiej Zolnierkiewicz
2000-11-07 23:09 [PATCH] Bartlomiej Zolnierkiewicz
2000-11-07 23:30 ` [PATCH] Bartlomiej Zolnierkiewicz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=15696.21984.645493.409103@argo.ozlabs.ibm.com \
    --to=paulus@samba.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).