Re: [patch 22/53] PNP: factor pnp_init_resource_table() and pnp_clean_resource_table()

Previous thread: [patch 27/53] PNP: convert resource checks to use pnp_get_resource(), not pnp_resource_table by Bjorn Helgaas on Friday, April 18, 2008 - 1:50 pm. (1 message)

Next thread: [patch 21/53] PNP: use dev_printk when possible by Bjorn Helgaas on Friday, April 18, 2008 - 1:50 pm. (1 message)
From: Bjorn Helgaas
Date: Friday, April 18, 2008 - 1:50 pm

Move the common part of pnp_init_resource_table() and
pnp_clean_resource_table() into a new pnp_init_resource().
This reduces a little code duplication and will be
useful later to initialize an individual resource.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

---
 drivers/pnp/base.h    |    2 +
 drivers/pnp/manager.c |   86 +++++++++++++++++++-------------------------------
 2 files changed, 36 insertions(+), 52 deletions(-)

Index: work8/drivers/pnp/base.h
===================================================================
--- work8.orig/drivers/pnp/base.h	2008-04-10 16:47:29.000000000 -0600
+++ work8/drivers/pnp/base.h	2008-04-10 16:48:43.000000000 -0600
@@ -16,3 +16,5 @@
 int pnp_check_mem(struct pnp_dev * dev, int idx);
 int pnp_check_irq(struct pnp_dev * dev, int idx);
 int pnp_check_dma(struct pnp_dev * dev, int idx);
+
+void pnp_init_resource(struct resource *res);
Index: work8/drivers/pnp/manager.c
===================================================================
--- work8.orig/drivers/pnp/manager.c	2008-04-10 16:48:34.000000000 -0600
+++ work8/drivers/pnp/manager.c	2008-04-10 16:48:43.000000000 -0600
@@ -200,6 +200,24 @@
 	*flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
 }
 
+void pnp_init_resource(struct resource *res)
+{
+	unsigned long type;
+
+	type = res->flags & (IORESOURCE_IO  | IORESOURCE_MEM |
+			     IORESOURCE_IRQ | IORESOURCE_DMA);
+
+	res->name = NULL;
+	res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET;
+	if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) {
+		res->start = -1;
+		res->end = -1;
+	} else {
+		res->start = 0;
+		res->end = 0;
+	}
+}
+
 /**
  * pnp_init_resources - Resets a resource table to default values.
  * @table: pointer to the desired resource table
@@ -209,34 +227,14 @@
 	struct pnp_resource_table *table = &dev->res;
 	int idx;
 
-	for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
-		table->irq_resource[idx].name = NULL;
-		table->irq_resource[idx].start = -1;
-		table->irq_resource[idx].end = ...
From: Rene Herman
Date: Friday, April 18, 2008 - 3:29 pm

... it's not being set.

Rene.
--

From: Bjorn Helgaas
Date: Friday, April 18, 2008 - 8:57 pm

Yep, you're right.  I fixed it, but it requires changes to a couple
other patches down the line, so I'll wait to repost the series until
next week in case you find more problems.

I think this is only a problem for bisection.  By the time you
apply the whole series, we start with an empty resource list, and
every time we add one, we set the type in pnp_new_resource().

That makes me wonder whether pnp_init_resources() should just
free the whole list, so we just start again with an empty list.

Bjorn
--

From: Rene Herman
Date: Friday, April 18, 2008 - 9:43 pm

Probably. Just a quick heads up; if you don't beat me to it I'll look at it 
in more detail over the weekend but with the current series ISAPnP is quite 
decidedly broken. Forget the OOPS for now which seems just a symptom of the 
same thing as the "too many" warnings". Result of "modprobe snd-cs4236".

I believe it's pnp_assign_resources() which has all the pnp_assign_foo() 
helpers fail due to there not being any yet. I guess pnp_assign_mem() and 
friends should allocate upon not finding one available and not fail?

Don't get why isapnp_get_resources() didn't allocate though. As said, unless 
you beat me to it I'll look into it more tomorrow or sunday.

===
pnp: the driver 'cs4236_isapnp' has been registered
cs4236_isapnp 01:01.00: driver attached
cs4236_isapnp 01:01.02: driver attached
cs4236_isapnp 01:01.03: driver attached
cs4236_isapnp 01:01.00: too many I/O port resources
cs4236_isapnp 01:01.00: too many I/O port resources
cs4236_isapnp 01:01.00: too many I/O port resources
cs4236_isapnp 01:01.00: too many IRQ resources
cs4236_isapnp 01:01.00: too many DMA resources
cs4236_isapnp 01:01.00: too many DMA resources
cs4236_isapnp 01:01.00: activated
BUG: unable to handle kernel NULL pointer dereference at 00000000
IP: [<f0c604da>] :snd_cs4236:snd_cs423x_pnpc_detect+0x104/0x390
*pde = 00000000
Oops: 0000 [#1] PREEMPT
Modules linked in: snd_cs4236(+) snd_opl3_lib snd_hwdep snd_cs4236_lib 
snd_mpu401_uart snd_rawmidi snd_seq_device snd_cs4231_lib snd_pcm snd_timer 
snd soundcore snd_page_alloc nfsd lockd nfs_acl sunrpc exportfs

Pid: 1198, comm: modprobe Not tainted (2.6.25 #2)
EIP: 0060:[<f0c604da>] EFLAGS: 00010202 CPU: 0
EIP is at snd_cs423x_pnpc_detect+0x104/0x390 [snd_cs4236]
EAX: 00000000 EBX: ef868c00 ECX: ef868d6c EDX: 00000000
ESI: 00000000 EDI: f0c63004 EBP: ef84d600 ESP: eed4ce88
  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
Process modprobe (pid: 1198, ti=eed4c000 task=eecf0aa0 task.ti=eed4c000)
Stack: ef312d40 ef84d7b8 ef843200 ef312d40 f0c63004 00000003 ...
From: Rene Herman
Date: Friday, April 18, 2008 - 9:46 pm

Oh, yes, 01:01.00 has three port resources, 1 IRQ resource and 2 DMA resources.

Rene.
--

From: Rene Herman
Date: Monday, April 21, 2008 - 11:41 am

isapnp_get_resources didn't allocate simply since it hasn't been called yet; 
there's nothing to get from an inactive device. It is pnp_assign_resources 
which constructs the table which isapnp_set_resources then puts to the hardware.

Currently with the list, pnp_assign_resources doesn't construct anything. It 
finds an empty resource list and then fails all pnp_assign_foo() helpers. I 
can get things functional by making pnp_assign_foo do a pnp_add_foo_resource 
upon not finding one yet but that's a hack -- things are just not very right 
at the moment.

Getting things working also needs setting pnp_res->index (to nport, nmem, 
nirq, ndma in pnp_assign_resources) so that the isapnp_set_resources which 
follows sets to the correct hardware index, but at that point position in 
the list and the index are mixing together in unhealthy ways -- in the 
pnp_assign_foo helpers, pnp_get_resource(.., idx) just get the "idx-th" 
resource of the correct type in the list but it seems it really should be 
getting the resource of the correct type with its ->index set to "idx".

Just making it do that then again disagrees with pnpbios/acpi which do not 
set the index field, nor do I know if you'd want them to or want to keep the 
index totally isapnp specific.

Anyways, currently things really don't work though, due to

1) pnp_assign_resources needing to construct the list and
2) it needing to match resources by their index.

(do note that pnp_assign_foo are the only callers of pnp_check_foo and they 
could be either merged together or at least not communicate via "idx" but 
simply by passing the res/pnp_res).

Also note -- manually set resources are skipped in pnp_assign_resources, yet 
they also definitely need their index initialized for use by 
isapnp_set_resources.

No patches due to the huge series where I don't know where you want to take 
a different turn to end up right. Also many, many opportunities for more 
cleanup of drivers/pnp/manager.c in its post-series state but I ...
From: Bjorn Helgaas
Date: Monday, April 21, 2008 - 4:10 pm

Yes, right.  I reproduced this on an ACPI system where the BIOS leaves

I don't mind setting pnp_res->index in the generic pnp_assign_* code.
We have to do that already in pnp_set_current_resources() (the /sys
interface), and I don't see a good way around it.

In pnp_assign_resources(), we currently assume that all independent
options appear before any dependent ones because we compute nport,
nmem, etc by iterating through the independent options first.  Then
we use those nport, nmem, etc values as the "index" (CSR index for
ISAPNP, nth resource type in the template for PNPBIOS and PNPACPI).
I don't know whether this assumption is in the spec, but at least
we've assumed it for a long time.

I'm trying to figure out the cases where pnp_assign_resources()
has to pay attention to pre-existing configuration.  It looks like
the common case is that we'll start with an empty resource list, and
we can just find non-conflicting values and use pnp_add_foo_resource().

But I'm concerned about all the IORESOURCE_AUTO stuff.  Seems like
we should only get to pnp_assign_foo() with !IORESOURCE_AUTO if
(a) we've used /sys to set some but not all resources, or (b) the
BIOS described fewer things in _CRS than in _PRS (which seems like

Yes, I'd like to do that.  But I think I'd better wait or I'll never

Yes.  "Manually set resources" includes ones from /sys and also the
resources we discover from active devices.  We should already be setting
those in the /sys and ISAPNP "read resources" paths.

Bjorn
--

From: Rene Herman
Date: Tuesday, April 22, 2008 - 2:01 pm

Ah, good, not just  isapnp then. I was starting to feel lonely here, sitting 

Did this just address my position/index worry above?

It seems you designed the list to be basically in any order, judging by 
things such as pnp_new_resource which'll happily reuse resources of the 
correct type at any position in the list. Yet, pnp_assign_foo() and friends 
retrieve resources (through pnp_get_resource) by position in the list and 
not by the index. I'm not overly sure of failure scenarios but isn't this 


Sounds right to me. Note that the /sys stuff is also not a corner case 
situation either, as it's the way to force at least ISAPnP hardware to 

Well, the idea here was that getting rid of one "idx" here so that things 

Hmm, yes, that sounds true...

Rene.
--

From: Bjorn Helgaas
Date: Wednesday, April 23, 2008 - 4:08 pm

Yes, I think you're right.

My idea is that the list should end up in the same order as the
resource list from the BIOS, e.g., the _CRS and _PRS lists for
ACPI.  In the case of ISAPNP, it'll be in the order that we read
things from the hardware registers.

I think I should probably make pnp_new_resource() always allocate
a new resource and get rid of the idea of reusing something already

Yup.  I ended up doing this after all.

I updated the patches and my ACPI box with the inactive devices now
boots (it failed with the v3 patches).  I'll work on the
pnp_new_resource() thing tomorrow, but I'll send you the current
patches now in case you have a chance to try them on your ISA box.

Bjorn
--

From: Rene Herman
Date: Wednesday, April 23, 2008 - 6:26 pm

Could do a quick test and its cs4236 soundcard works fine with them. There 
are a few "current resources: after pnp_assign_resources (failed)" in there 
but they might be expected, I didn't yet look. There's a dmesg from booting 
it and "modprobe snd-cs4236" at:

http://members.home.nl/rene.herman/dmesg-2.6.25-pnpv3.9

Matching "options" files:

root@6bap:~# for OPTIONS in /sys/devices/pnp1/01\:01/01\:01.0?/options; do 
echo; echo $OPTIONS; echo; cat $OPTIONS; done

/sys/devices/pnp1/01:01/01:01.00/options

Dependent: 01 - Priority preferred
    port 0x534-0x534, align 0x3, size 0x4, 16-bit address decoding
    port 0x388-0x388, align 0x7, size 0x4, 16-bit address decoding
    port 0x220-0x220, align 0x1f, size 0x10, 16-bit address decoding
    irq 5 High-Edge
    dma 1 8-bit byte-count compatible
    dma 0,1 8-bit byte-count compatible
Dependent: 02 - Priority acceptable
    port 0x534-0xffc, align 0x3, size 0x4, 16-bit address decoding
    port 0x388-0x388, align 0x7, size 0x4, 16-bit address decoding
    port 0x220-0x260, align 0x1f, size 0x10, 16-bit address decoding
    irq 5,7,2/9,11,12,15 High-Edge
    dma 1,3 8-bit byte-count compatible
    dma 0,1,3 8-bit byte-count compatible
Dependent: 03 - Priority functional
    port 0x534-0xffc, align 0x3, size 0x4, 16-bit address decoding
    port 0x388-0x3f8, align 0x7, size 0x4, 16-bit address decoding
    port 0x220-0x300, align 0x1f, size 0x10, 16-bit address decoding
    irq 5,7,2/9,11,12,15 High-Edge
    dma 0,1,3 8-bit byte-count compatible

/sys/devices/pnp1/01:01/01:01.01/options

Dependent: 01 - Priority preferred
    port 0x200-0x200, align 0x7, size 0x8, 16-bit address decoding
Dependent: 02 - Priority acceptable
    port 0x208-0x208, align 0x7, size 0x8, 16-bit address decoding

/sys/devices/pnp1/01:01/01:01.02/options

port 0x120-0xff8, align 0x7, size 0x8, 16-bit address decoding

/sys/devices/pnp1/01:01/01:01.03/options

Dependent: 01 - Priority preferred
    port 0x330-0x330, align 0x7, size ...
From: Rene Herman
Date: Wednesday, April 23, 2008 - 6:39 pm

Oh, this was on v2.6.25 vanilla + 0093cb1199ec551f179562ca9fbd6f64fb750645 
(only post 2.6.25 change to drivers/pnp).

Rene
--

From: Bjorn Helgaas
Date: Thursday, April 24, 2008 - 3:45 pm

Here's something interesting.  I was mistaken about the ordering
of independent vs. dependent options coming from BIOS -- I have
several examples where the dependent ones come first, including
this one:

    pnp 00:0a: parse resource options
    pnp 00:0a: new independent option
    pnp 00:0a: new dependent option (priority 0x1)
    pnp 00:0a:   io  min 0x3f8 max 0x3f8 align 1 size 8 flags 0x1
    pnp 00:0a: new dependent option (priority 0x1)
    pnp 00:0a:   io  min 0x2e8 max 0x2e8 align 1 size 8 flags 0x1
    pnp 00:0a: new dependent option (priority 0x1)
    pnp 00:0a:   io  min 0x2f8 max 0x2f8 align 1 size 8 flags 0x1
    pnp 00:0a: new dependent option (priority 0x1)
    pnp 00:0a:   io  min 0x3e8 max 0x3e8 align 1 size 8 flags 0x1
    pnp 00:0a: end dependent options
    pnp 00:0a:   irq bitmask 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000cf8 flags 0x1
    pnp 00:0a:   io  min 0x100 max 0x130 align 16 size 8 flags 0x1
    pnp 00:0a:   dma bitmask 0xe flags 0x2
    pnp 00:0a: Plug and Play ACPI device, IDs SMCf010 (disabled)

The interesting thing here is that this IRDA device comes up disabled,
and we use pnp_assign_resources() before enabling it.  But we
assign independent options first, so we end up reversing the order
of these IO regions:

    state = active
    io 0x100-0x107
    io 0x2e8-0x2ef
    irq 5
    dma 1

The driver for this device (smsc-ircc2.c) currently can't claim it
via PNP, but by long painful trial and error, I figured out last
summer that I could get the PNP claim code to work if I manually
swapped the IO regions!

I haven't done anything about this yet, but it sure looks to me like
we need to preserve the order of the independent/dependent options
as we get them from the BIOS.

Bjorn
--

Previous thread: [patch 27/53] PNP: convert resource checks to use pnp_get_resource(), not pnp_resource_table by Bjorn Helgaas on Friday, April 18, 2008 - 1:50 pm. (1 message)

Next thread: [patch 21/53] PNP: use dev_printk when possible by Bjorn Helgaas on Friday, April 18, 2008 - 1:50 pm. (1 message)