LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: 2.6.23-rc6-mm1: Build failures on ppc64_defconfig
From: Satyam Sharma @ 2007-09-22  6:54 UTC (permalink / raw)
  To: Mel Gorman
  Cc: linuxppc-dev, Andrew Morton, Linux Kernel Mailing List, jeff,
	Linux Netdev Mailing List
In-Reply-To: <alpine.LFD.0.999.0709201903180.17093@enigma.security.iitk.ac.in>



On Thu, 20 Sep 2007, Satyam Sharma wrote:
> 
> BTW ppc64_defconfig didn't quite like 2.6.23-rc6-mm1 either ...
> IIRC I got build failures in:

> drivers/net/spider_net.c


[PATCH -mm] spider_net: Misc build fixes after recent netdev stats changes

Unbreak the following:

drivers/net/spider_net.c: In function 'spider_net_release_tx_chain':
drivers/net/spider_net.c:818: error: 'dev' undeclared (first use in this function)
drivers/net/spider_net.c:818: error: (Each undeclared identifier is reported only once
drivers/net/spider_net.c:818: error: for each function it appears in.)
drivers/net/spider_net.c: In function 'spider_net_xmit':
drivers/net/spider_net.c:922: error: 'dev' undeclared (first use in this function)
drivers/net/spider_net.c: In function 'spider_net_pass_skb_up':
drivers/net/spider_net.c:1018: error: 'dev' undeclared (first use in this function)
drivers/net/spider_net.c: In function 'spider_net_decode_one_descr':
drivers/net/spider_net.c:1215: error: 'dev' undeclared (first use in this function)
make[2]: *** [drivers/net/spider_net.o] Error 1

Signed-off-by: Satyam Sharma <satyam@infradead.org>

---

 drivers/net/spider_net.c |   24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff -ruNp a/drivers/net/spider_net.c b/drivers/net/spider_net.c
--- a/drivers/net/spider_net.c	2007-09-22 06:26:39.000000000 +0530
+++ b/drivers/net/spider_net.c	2007-09-22 12:12:23.000000000 +0530
@@ -795,6 +795,7 @@ spider_net_set_low_watermark(struct spid
 static int
 spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
 {
+	struct net_device *dev = card->netdev;
 	struct spider_net_descr_chain *chain = &card->tx_chain;
 	struct spider_net_descr *descr;
 	struct spider_net_hw_descr *hwdescr;
@@ -919,7 +920,7 @@ spider_net_xmit(struct sk_buff *skb, str
 	spider_net_release_tx_chain(card, 0);
 
 	if (spider_net_prepare_tx_descr(card, skb) != 0) {
-		dev->stats.tx_dropped++;
+		netdev->stats.tx_dropped++;
 		netif_stop_queue(netdev);
 		return NETDEV_TX_BUSY;
 	}
@@ -979,16 +980,12 @@ static void
 spider_net_pass_skb_up(struct spider_net_descr *descr,
 		       struct spider_net_card *card)
 {
-	struct spider_net_hw_descr *hwdescr= descr->hwdescr;
-	struct sk_buff *skb;
-	struct net_device *netdev;
-	u32 data_status, data_error;
-
-	data_status = hwdescr->data_status;
-	data_error = hwdescr->data_error;
-	netdev = card->netdev;
+	struct spider_net_hw_descr *hwdescr = descr->hwdescr;
+	struct sk_buff *skb = descr->skb;
+	struct net_device *netdev = card->netdev;
+	u32 data_status = hwdescr->data_status;
+	u32 data_error = hwdescr->data_error;
 
-	skb = descr->skb;
 	skb_put(skb, hwdescr->valid_size);
 
 	/* the card seems to add 2 bytes of junk in front
@@ -1015,8 +1012,8 @@ spider_net_pass_skb_up(struct spider_net
 	}
 
 	/* update netdevice statistics */
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += skb->len;
+	netdev->stats.rx_packets++;
+	netdev->stats.rx_bytes += skb->len;
 
 	/* pass skb up to stack */
 	netif_receive_skb(skb);
@@ -1184,6 +1181,7 @@ static int spider_net_resync_tail_ptr(st
 static int
 spider_net_decode_one_descr(struct spider_net_card *card)
 {
+	struct net_device *dev = card->netdev;
 	struct spider_net_descr_chain *chain = &card->rx_chain;
 	struct spider_net_descr *descr = chain->tail;
 	struct spider_net_hw_descr *hwdescr = descr->hwdescr;
@@ -1210,7 +1208,7 @@ spider_net_decode_one_descr(struct spide
 	     (status == SPIDER_NET_DESCR_PROTECTION_ERROR) ||
 	     (status == SPIDER_NET_DESCR_FORCE_END) ) {
 		if (netif_msg_rx_err(card))
-			dev_err(&card->netdev->dev,
+			dev_err(&dev->dev,
 			       "dropping RX descriptor with state %d\n", status);
 		dev->stats.rx_dropped++;
 		goto bad_desc;

^ permalink raw reply

* Re: [PATCH v2] pcmcia: Convert io_req_t to use kio_addr_t
From: Matthew Wilcox @ 2007-09-22  6:25 UTC (permalink / raw)
  To: Alan Cox
  Cc: linux-pcmcia, linux-kernel, linuxppc-dev, Olof Johansson,
	Andrew Morton, hch
In-Reply-To: <20070921233936.2aeb2504@the-village.bc.nu>

On Fri, Sep 21, 2007 at 11:39:36PM +0100, Alan Cox wrote:
> On Fri, 21 Sep 2007 17:15:16 -0500
> Olof Johansson <olof@lixom.net> wrote:
> 
> > Convert the io_req_t members to kio_addr_t, to allow use on machines with
> > more than 16 bits worth of IO ports (i.e. secondary busses on ppc64, etc).
> 
> What about the formatting and field widths ?
> 
> ulong would probably be a lot saner than kio_addr_t and yet more type
> obfuscation.

I don't think anyone uses ioports > 32bit.  Certainly i386 takes an int
port as parameter to {in,out}[bwl] (and it really only uses 16-bits).
parisc uses 24 bits.  I don't know what the various ppcs do, but pci
bars can only be 32-bit for ioports.  So my opinion is that ioports
should be uint, not ulong.

-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply

* Re: 2.6.23-rc6-mm1: Build failures on ppc64_defconfig
From: Satyam Sharma @ 2007-09-22  7:25 UTC (permalink / raw)
  To: Mel Gorman
  Cc: linuxppc-dev, Andrew Morton, Linux Kernel Mailing List,
	Jeff Garzik, Linux Netdev Mailing List
In-Reply-To: <alpine.LFD.0.999.0709201903180.17093@enigma.security.iitk.ac.in>



On Thu, 20 Sep 2007, Satyam Sharma wrote:
> 
> BTW ppc64_defconfig didn't quite like 2.6.23-rc6-mm1 either ...
> IIRC I got build failures in:

> drivers/net/spider_net.c

Fixing the above showed up another problem in another file of the
same driver (drivers/net/spider_net_ethtool.c)


[PATCH -mm] spider_net_ethtool: Keep up with recent netdev stats changes

Unbreak the following:

drivers/net/spider_net_ethtool.c: In function 'spider_net_get_ethtool_stats':
drivers/net/spider_net_ethtool.c:160: error: structure has no member named 'netdev_stats'
drivers/net/spider_net_ethtool.c:161: error: structure has no member named 'netdev_stats'
drivers/net/spider_net_ethtool.c:162: error: structure has no member named 'netdev_stats'
drivers/net/spider_net_ethtool.c:163: error: structure has no member named 'netdev_stats'
drivers/net/spider_net_ethtool.c:164: error: structure has no member named 'netdev_stats'
drivers/net/spider_net_ethtool.c:165: error: structure has no member named 'netdev_stats'
drivers/net/spider_net_ethtool.c:166: error: structure has no member named 'netdev_stats'
make[2]: *** [drivers/net/spider_net_ethtool.o] Error 1

Also do another ARRAY_SIZE() cleanup while at it.

Signed-off-by: Satyam Sharma <satyam@infradead.org>

---

 drivers/net/spider_net_ethtool.c |   18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff -ruNp a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c
--- a/drivers/net/spider_net_ethtool.c	2007-09-22 06:26:39.000000000 +0530
+++ b/drivers/net/spider_net_ethtool.c	2007-09-22 12:43:51.000000000 +0530
@@ -28,8 +28,6 @@
 #include "spider_net.h"
 
 
-#define SPIDER_NET_NUM_STATS 13
-
 static struct {
 	const char str[ETH_GSTRING_LEN];
 } ethtool_stats_keys[] = {
@@ -149,7 +147,7 @@ spider_net_ethtool_get_ringparam(struct 
 
 static int spider_net_get_stats_count(struct net_device *netdev)
 {
-	return SPIDER_NET_NUM_STATS;
+	return ARRAY_SIZE(ethtool_stats_keys);
 }
 
 static void spider_net_get_ethtool_stats(struct net_device *netdev,
@@ -157,13 +155,13 @@ static void spider_net_get_ethtool_stats
 {
 	struct spider_net_card *card = netdev->priv;
 
-	data[0] = card->netdev_stats.tx_packets;
-	data[1] = card->netdev_stats.tx_bytes;
-	data[2] = card->netdev_stats.rx_packets;
-	data[3] = card->netdev_stats.rx_bytes;
-	data[4] = card->netdev_stats.tx_errors;
-	data[5] = card->netdev_stats.tx_dropped;
-	data[6] = card->netdev_stats.rx_dropped;
+	data[0] = netdev->stats.tx_packets;
+	data[1] = netdev->stats.tx_bytes;
+	data[2] = netdev->stats.rx_packets;
+	data[3] = netdev->stats.rx_bytes;
+	data[4] = netdev->stats.tx_errors;
+	data[5] = netdev->stats.tx_dropped;
+	data[6] = netdev->stats.rx_dropped;
 	data[7] = card->spider_stats.rx_desc_error;
 	data[8] = card->spider_stats.tx_timeouts;
 	data[9] = card->spider_stats.alloc_rx_skb_error;

^ permalink raw reply

* Re: [PATCH v2] pcmcia: Convert io_req_t to use kio_addr_t
From: Christoph Hellwig @ 2007-09-22  9:13 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-pcmcia, linux-kernel, linuxppc-dev, Olof Johansson,
	Andrew Morton, hch, Alan Cox
In-Reply-To: <20070922062551.GE10625@parisc-linux.org>

On Sat, Sep 22, 2007 at 12:25:51AM -0600, Matthew Wilcox wrote:
> > What about the formatting and field widths ?
> > 
> > ulong would probably be a lot saner than kio_addr_t and yet more type
> > obfuscation.
> 
> I don't think anyone uses ioports > 32bit.  Certainly i386 takes an int
> port as parameter to {in,out}[bwl] (and it really only uses 16-bits).
> parisc uses 24 bits.  I don't know what the various ppcs do, but pci
> bars can only be 32-bit for ioports.  So my opinion is that ioports
> should be uint, not ulong.

The kernel seems to mostly use int, sometimes uint.  I never quite got
why pcmcia had to have it's own strange typedef for them.

^ permalink raw reply

* Re: [PATCH 1/2] qemu platform, v2
From: Christoph Hellwig @ 2007-09-22  9:55 UTC (permalink / raw)
  To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Rob Landley, David Gibson
In-Reply-To: <qemu-8-01.miltonm@bga.com>

On Fri, Sep 21, 2007 at 06:08:31PM -0500, Milton Miller wrote:
> Here is the second rev of patches to boot a arch powerpc kernel on
> qemu with the prep architecture.

So if this is supposed to be prep why do you need additional kernel
support?  And if you really needed why isn't it under platforms/prep?

^ permalink raw reply

* Re: [patch 04/28] Add cmpxchg64 and cmpxchg64_local to powerpc
From: Mathieu Desnoyers @ 2007-09-22 14:35 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, akpm, linux-kernel
In-Reply-To: <18164.40462.991761.909735@cargo.ozlabs.ibm.com>

* Paul Mackerras (paulus@samba.org) wrote:
> Mathieu Desnoyers writes:
> 
> > Make sure that at least cmpxchg64_local is available on all architectures to use
> > for unsigned long long values.
> > 
> > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
> 
> Acked-by: Paul Mackerras <paulus@samba.org>

Thanks Paul,

Just make sure add-cmpxchg-local-to-generic-for-up.patch gets merged
before this one, since it needs asm-generic/cmpxchg-local.h.

Mathieu

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

^ permalink raw reply

* Re: [PATCH v2] pcmcia: Convert io_req_t to use kio_addr_t
From: Olof Johansson @ 2007-09-22 15:11 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-pcmcia, linux-kernel, linuxppc-dev, Andrew Morton, hch,
	Alan Cox
In-Reply-To: <20070922062551.GE10625@parisc-linux.org>

On Sat, Sep 22, 2007 at 12:25:51AM -0600, Matthew Wilcox wrote:
> On Fri, Sep 21, 2007 at 11:39:36PM +0100, Alan Cox wrote:
> > On Fri, 21 Sep 2007 17:15:16 -0500
> > Olof Johansson <olof@lixom.net> wrote:
> > 
> > > Convert the io_req_t members to kio_addr_t, to allow use on machines with
> > > more than 16 bits worth of IO ports (i.e. secondary busses on ppc64, etc).
> > 
> > What about the formatting and field widths ?
> > 
> > ulong would probably be a lot saner than kio_addr_t and yet more type
> > obfuscation.
> 
> I don't think anyone uses ioports > 32bit.  Certainly i386 takes an int
> port as parameter to {in,out}[bwl] (and it really only uses 16-bits).
> parisc uses 24 bits.  I don't know what the various ppcs do, but pci
> bars can only be 32-bit for ioports.  So my opinion is that ioports
> should be uint, not ulong.

PPC would do just fine with 32-bit as well, which is what I wanted in
the first place. I just went with the local coding standard of pcmcia
and switched to kio_addr_t.

I suppose it's a janitorial todo item but with the maintainer MIA I
don't want to mess around with it too much, since I can't really test
much besides the PPC stuff I have.

As for the formatting/padding widths: Some platforms had ioaddr_t's
that were 32 bit already, so it was already broken on those, and the
only drawback is missing 0-padding. It'd look a bit silly to pad to 16
0:s anyway at the moment, so I think I'd prefer to keep it the way it is.


-Olof

^ permalink raw reply

* Re: [PATCH 1/2] qemu platform, v2
From: Rob Landley @ 2007-09-22 19:16 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linuxppc-dev, Paul Mackerras, Milton Miller, David Gibson
In-Reply-To: <20070922095546.GA14185@lst.de>

On Saturday 22 September 2007 4:55:46 am Christoph Hellwig wrote:
> On Fri, Sep 21, 2007 at 06:08:31PM -0500, Milton Miller wrote:
> > Here is the second rev of patches to boot a arch powerpc kernel on
> > qemu with the prep architecture.
>
> So if this is supposed to be prep why do you need additional kernel
> support?  And if you really needed why isn't it under platforms/prep?

The device tree provided by qemu's open hackware violates some of the 
assumptions the Linux kernel is making?  (Although things like "the cpu cache 
size is zero" are, technically speaking, probably correct. :)

There are three different problems here:

1) porting prep from arch=ppc to arch=powerpc so you can build it on an arch 
that also supports make headers_install.

2) PowerPC uses a device tree supplied by the hardware to identify the 
available hardware, even for stuff living on PCI busses which it could 
theoretically probe for but doesn't.

3) The PPC firmware qemu comes with ("Open Hackware") sucks rocks, is hard to 
modify, isn't quite being maintained.  As mentioned above, the device tree it 
passes in (including "prep residual data" from which more nodes in the device 
tree can be constructed, and here my understanding goes all fuzzy) does not 
make for a happy Linux kernel.

Proposed solutions to all this involve various combinations of creating a 
target platform aimed directly at qemu and not pretending to be prep at all 
(so it doesn't have to parse residual data), creating our own boot rom image 
out of some of the wrapper code the linux kernel's already got and feeding 
that to qemu instead of using open hackware at all, hard wiring a device tree 
into the kernel and not looking at the one open hackware passes in...)

I'd be following this more closely if compiling a device tree didn't currently 
require an external utility (dtc or some such) that doesn't come with the 
Linux kernel.  No other target platform I've built kernels for requires such 
an environmental dependency.  (This is a problem both for hardwiring the 
device tree into the kernel and for building a new boot rom from the linux 
kernel's ppc boot wrapper that would contain such a device tree to feed to 
the kernel.)

Rob
-- 
"One of my most productive days was throwing away 1000 lines of code."
  - Ken Thompson.

^ permalink raw reply

* Re: [PATCH 0/3] usb: ehci ppc device-tree-aware driver
From: Hollis Blanchard @ 2007-09-22 23:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: linux-usb-devel
In-Reply-To: <20070917125039.GA29525@ru.mvista.com>

On Mon, 17 Sep 2007 16:50:39 +0400, Valentine Barshak wrote:

> Some PowerPC systems have a built-in EHCI controller.
> This is a device tree aware version of the EHCI controller driver.
> Currently it's been tested on the PowerPC 440EPx Sequoia board.
> Other platforms can be added later.
> The code is based on the ehci-ppc-soc driver by Stefan Roese <sr@denx.de>.

We're having a strange issue on our Sequoia where the network stops
functioning when USB is active. Jerone can supply more detail...

Have you seen anything like that?

-- 
Hollis Blanchard
IBM Linux Technology Center

^ permalink raw reply

* Re: [PATCH 1/2] qemu platform, v2
From: Paul Mackerras @ 2007-09-23  4:27 UTC (permalink / raw)
  To: Rob Landley; +Cc: linuxppc-dev, Christoph Hellwig, Milton Miller, David Gibson
In-Reply-To: <200709221416.21580.rob@landley.net>

Rob Landley writes:

Just to correct a few misconceptions:

> 2) PowerPC uses a device tree supplied by the hardware to identify the 
> available hardware, even for stuff living on PCI busses which it could 
> theoretically probe for but doesn't.

The device tree doesn't have to include anything that can be probed
for.  On some platforms (e.g. pSeries) we choose to use the device
tree rather than probing, but on most other platforms we probe.

> I'd be following this more closely if compiling a device tree didn't currently 
> require an external utility (dtc or some such) that doesn't come with the 
> Linux kernel.  No other target platform I've built kernels for requires such 
> an environmental dependency.

No?  You haven't built kernels for other platforms that have external
dependencies such as perl, gcc, make, binutils, etc.? :)

>  (This is a problem both for hardwiring the 
> device tree into the kernel and for building a new boot rom from the linux 
> kernel's ppc boot wrapper that would contain such a device tree to feed to 
> the kernel.)

It's only really been a problem for ps3 so far, since the embedded
guys don't seem to have any difficulty with installing dtc.  We are
looking at what to do for ps3 and prep, and the answer may well
involve bundling dtc in the kernel source (it's not too big, around
3400 lines).

Paul.

^ permalink raw reply

* Re: Sequoia kernel crash workaround.
From: Benjamin Herrenschmidt @ 2007-09-23  8:21 UTC (permalink / raw)
  To: Josh Boyer
  Cc: linuxppc-dev, Olof Johansson, Josh Boyer, Stefan Roese,
	David Gibson
In-Reply-To: <20070920122919.32dd8061@weaponx.rchland.ibm.com>


On Thu, 2007-09-20 at 12:29 -0500, Josh Boyer wrote:
> On Thu, 20 Sep 2007 12:25:06 -0500
> Olof Johansson <olof@lixom.net> wrote:
> 
> > On Thu, Sep 20, 2007 at 08:56:32PM +0400, Valentine Barshak wrote:
> > >
> > > I was thinking about it. Looks like it's the best place, but the code that 
> > > actually calls setup_cpu is under ifdef CONFIG_PPC64, while lots of 
> > > cpu_setup functions are defined for ppc32 processors.
> > > Is it OK to remove this ifdef, or should I do CONFIG_PPC64 || CONFIG_44x?
> > 
> > Sounds like something that went wrong at the merge of ppc and ppc64.
> > 
> > Take out the ifdef, even if there's fallout we should deal with it
> > instead of adding more complex ifdefs.
> 
> Yeah.  Looks like BenH did this in commit:
> 
> 42c4aaadb737e0e672b3fb86b2c41ff59f0fb8bc
> 
> Ben, any reason you ifdef'd it for ppc64?

I'll have to check on monday what's up there, but isn't setup_cpu called
from a different place on 32 bits? There are some subtle difference with
the way the cpu feature stuff is initialized /done between 32 and 64
bits that we haven't fully reconciled yet. 

Ben.

^ permalink raw reply

* Downtime
From: Stephen Rothwell @ 2007-09-23 13:02 UTC (permalink / raw)
  To: ppc-dev; +Cc: ppc-embedded

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

Hi all,

Just letting you all know that ozlabs.org will be down for about 5 hours from 1:54 am Canberra time (UTC+10) Monday morning (i.e. about 2 hours 40 minutes from now) due to electrical work in our hosting data centre.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: Linux doesn not boot from u-boot on ML403
From: Miroslaw Dach @ 2007-09-23 13:27 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-embedded

Hi Grant,

Thank you very much for your advices which were very valuable for me.

Recently I have followed your advice to move from kernel 2.6.21 to the
higher one in order to have the possibility to boot the kernel from
u-boot. I have copied across from you git tree the latest version of linux
kernel 2.6.23 rc-2.

It compiles successfully with some warnings like below:
  MODPOST vmlinux.o
WARNING: vmlinux.o(.text+0x223c): Section mismatch: reference to .init.text:early_init (between 'start_here' and 'initial_mmu')
WARNING: vmlinux.o(.text+0x2254): Section mismatch: reference to .init.text:machine_init (between 'start_here' and 'initial_mmu')
WARNING: vmlinux.o(.text+0x2258): Section mismatch: reference to .init.text:MMU_init (between 'start_here' and 'initial_mmu')
WARNING: vmlinux.o(.text+0x22b2): Section mismatch: reference to .init.text:start_kernel (between 'start_here' and 'initial_mmu')
WARNING: vmlinux.o(.text+0x22b6): Section mismatch: reference to .init.text:start_kernel (between 'start_here' and 'initial_mmu')
   LD      vmlinux


My observation is that the linux 2.6.23 rc-2 is not that stable as 2.6.21.
In most cases It boots successfully (ie. zImage.elf) but occasionally it
fails during booting. It has never occurred with 2.6.21 which I also
copied from your side.

For both kernels I use the same xparamerets_ml403.h file and very similar
.config file

Do you have some idea if it is known problem with booting in 2.6.23 rc-2?  
It of course could be something wrong with my ml403 board but I just
wanted to get your opinion about the stability issue. Maybe it is better
to use 2.6.22?

Second question:

In addition I wanted to ask you about u-boot tree which you have mentioned
in the post on u-boot mailing list. This post was about uart lite for
ml403 in u-boot.

I was not able to find the project which you have mentioned there:
git://git.secretlab.ca/git/u-boot.git

This what interests me in particular concerning u-boot is the uart lite
and temac interfaces from ml403.

Thank you very much in advance for any hint

Best Regards

Mirek

^ permalink raw reply

* Re: Linux doesn not boot from u-boot on ML403
From: Grant Likely @ 2007-09-23 15:32 UTC (permalink / raw)
  To: Miroslaw Dach; +Cc: linuxppc-embedded
In-Reply-To: <Pine.LNX.4.44.0709231519510.25165-100000@slslc02.psi.ch>

On 9/23/07, Miroslaw Dach <miroslaw.dach@psi.ch> wrote:
> Hi Grant,
>
> Thank you very much for your advices which were very valuable for me.
>
> Recently I have followed your advice to move from kernel 2.6.21 to the
> higher one in order to have the possibility to boot the kernel from
> u-boot. I have copied across from you git tree the latest version of linux
> kernel 2.6.23 rc-2.
>
> It compiles successfully with some warnings like below:
>   MODPOST vmlinux.o
> WARNING: vmlinux.o(.text+0x223c): Section mismatch: reference to .init.text:early_init (between 'start_here' and 'initial_mmu')
> WARNING: vmlinux.o(.text+0x2254): Section mismatch: reference to .init.text:machine_init (between 'start_here' and 'initial_mmu')
> WARNING: vmlinux.o(.text+0x2258): Section mismatch: reference to .init.text:MMU_init (between 'start_here' and 'initial_mmu')
> WARNING: vmlinux.o(.text+0x22b2): Section mismatch: reference to .init.text:start_kernel (between 'start_here' and 'initial_mmu')
> WARNING: vmlinux.o(.text+0x22b6): Section mismatch: reference to .init.text:start_kernel (between 'start_here' and 'initial_mmu')
>    LD      vmlinux

Yes, I see this warning too.  I haven't had a chance to debug it.
>
>
> My observation is that the linux 2.6.23 rc-2 is not that stable as 2.6.21.
> In most cases It boots successfully (ie. zImage.elf) but occasionally it
> fails during booting. It has never occurred with 2.6.21 which I also
> copied from your side.

Hmm, what failure mode are you seeing?  I haven't experienced that
problem.  However, -rc7 is now out, so I'd recommend moving up to it.
(Hint: use git to make it easy to pull the latest version and either
'quilt' or 'stgit' to manage your changes on top of the mainline tree;
it will make up/downgrading to different kernel version much easier)

> Second question:
>
> In addition I wanted to ask you about u-boot tree which you have mentioned
> in the post on u-boot mailing list. This post was about uart lite for
> ml403 in u-boot.
>
> I was not able to find the project which you have mentioned there:
> git://git.secretlab.ca/git/u-boot.git

That's because there is not such tree.  :-)  I retired that tree a
while ago because it's no longer current.  You can use the mainline
u-boot tree:

git://www.denx.de/git/u-boot.git

>
> This what interests me in particular concerning u-boot is the uart lite
> and temac interfaces from ml403.

:-(  I don't think either uartlite or temac drivers has been ported to u-boot.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* [PATCH0/4] Various bug fixes
From: Jochen Friedrich @ 2007-09-23 20:16 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: linux-kernel

Here is a series fixing some bugs for 8xx powerpc CPUs.

1. [POWERPC] Fix copy'n'paste typo in commproc.c
2. [PPC] Fix cpm_dpram_addr returning phys mem instead of virt mem
3. [PPC] Compile fix for 8xx CPM Ehernet driver
4. [POWERPC] Fix cpm_uart driver

This series can be pulled from git://git.bocc.de/dbox2.git ppc-fixes

Thanks,
Jochen

^ permalink raw reply

* [PATCH1/4] [POWERPC] Fix copy'n'paste typo in commproc.c
From: Jochen Friedrich @ 2007-09-23 20:17 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 992 bytes --]


The powerpc version of commproc.c doesn't export cpm_dpram_addr twice
and cpm_dpram_phys not at all due to a typo. This patch fixes this
problem.

CC      arch/powerpc/sysdev/commproc.o
arch/powerpc/sysdev/commproc.c:398: error: redefinition of '__kcrctab_cpm_dpram_addr'
arch/powerpc/sysdev/commproc.c:392: error: previous definition of '__kcrctab_cpm_dpram_addr' was here
arch/powerpc/sysdev/commproc.c:398: error: redefinition of '__kstrtab_cpm_dpram_addr'
arch/powerpc/sysdev/commproc.c:392: error: previous definition of '__kstrtab_cpm_dpram_addr' was here
arch/powerpc/sysdev/commproc.c:398: error: redefinition of '__ksymtab_cpm_dpram_addr'
arch/powerpc/sysdev/commproc.c:392: error: previous definition of '__ksymtab_cpm_dpram_addr' was here
make[1]: *** [arch/powerpc/sysdev/commproc.o] Error 1
make: *** [arch/powerpc/sysdev] Error 2

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/powerpc/sysdev/commproc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

[-- Attachment #2: 828fc894599eb4bb5a015277687adbb75bb94cc0.diff --]
[-- Type: text/x-patch, Size: 355 bytes --]

diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index 4f67b89..dd5417a 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -395,4 +395,4 @@ uint cpm_dpram_phys(u8* addr)
 {
 	return (dpram_pbase + (uint)(addr - dpram_vbase));
 }
-EXPORT_SYMBOL(cpm_dpram_addr);
+EXPORT_SYMBOL(cpm_dpram_phys);


^ permalink raw reply related

* [PATCH2/4] [PPC] Fix cpm_dpram_addr returning phys mem instead of virt mem
From: Jochen Friedrich @ 2007-09-23 20:17 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 515 bytes --]


cpm_dpram_addr returns physical memory of the DP RAM instead of
iomapped virtual memory. As there usually is a 1:1 MMU map of
the IMMR area, this is often not noticed. However, cpm_dpram_phys
assumes this iomapped virtual memory and returns garbage on the
1:1 mapped memory causing CPM1 uart console to fail.

This patch fixes the problem (copied from the powerpc tree).

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/ppc/8xx_io/commproc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

[-- Attachment #2: 7a0161f68ca0e487c0119bbc7ee09189b87c1b06.diff --]
[-- Type: text/x-patch, Size: 399 bytes --]

diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index 7088428..9da880b 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -459,7 +459,7 @@ EXPORT_SYMBOL(cpm_dpdump);
 
 void *cpm_dpram_addr(unsigned long offset)
 {
-	return ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem + offset;
+	return (void *)(dpram_vbase + offset);
 }
 EXPORT_SYMBOL(cpm_dpram_addr);
 


^ permalink raw reply related

* [PATCH3/4] [PPC] Compile fix for 8xx CPM Ehernet driver
From: Jochen Friedrich @ 2007-09-23 20:17 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 492 bytes --]


Add #include <asm/cacheflush.h> for flush_dcache_range
to make the driver compile again.

  CC      arch/ppc/8xx_io/enet.o
arch/ppc/8xx_io/enet.c: In function 'scc_enet_start_xmit':
arch/ppc/8xx_io/enet.c:240: error: implicit declaration of function
'flush_dcache_range'
make[1]: *** [arch/ppc/8xx_io/enet.o] Error 1
make: *** [arch/ppc/8xx_io] Error 2

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/ppc/8xx_io/enet.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

[-- Attachment #2: c10ab471b95ac13c93b0ae36d169756ae694a77d.diff --]
[-- Type: text/x-patch, Size: 308 bytes --]

diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index 703d47e..eace3bc 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -44,6 +44,7 @@
 #include <asm/mpc8xx.h>
 #include <asm/uaccess.h>
 #include <asm/commproc.h>
+#include <asm/cacheflush.h>
 
 /*
  *				Theory of Operation


^ permalink raw reply related

* [PATCH4/4] [POWERPC] Fix cpm_uart driver
From: Jochen Friedrich @ 2007-09-23 20:17 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 424 bytes --]


In cpm_uart_core, functions cpm_uart_init_bd and cpm_uart_init_scc
an offset into DP RAM is calculated by substracting a physical
memory constant from an virtual address. This patch fixes the
problem by converting the virtual address into a physical
first.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 drivers/serial/cpm_uart/cpm_uart_core.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

[-- Attachment #2: 2c5cf6868e9aa6eadea285e524d88859cc5e54fb.diff --]
[-- Type: text/x-patch, Size: 1298 bytes --]

diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index cefde58..7f5db7c 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -752,8 +752,10 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo)
 	sup = pinfo->sccup;
 
 	/* Store address */
-	pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE;
-	pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE;
+	pinfo->sccup->scc_genscc.scc_rbase = 
+		(u_char *)cpm_dpram_phys((u8 *)pinfo->rx_bd_base) - DPRAM_BASE;
+	pinfo->sccup->scc_genscc.scc_tbase = 
+		(u_char *)cpm_dpram_phys((u8 *)pinfo->tx_bd_base) - DPRAM_BASE;
 
 	/* Set up the uart parameters in the
 	 * parameter ram.
@@ -813,8 +815,10 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
 	up = pinfo->smcup;
 
 	/* Store address */
-	pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE;
-	pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE;
+	pinfo->smcup->smc_rbase = 
+		(u_char *)cpm_dpram_phys((u8 *)pinfo->rx_bd_base) - DPRAM_BASE;
+	pinfo->smcup->smc_tbase = 
+		(u_char *)cpm_dpram_phys((u8 *)pinfo->tx_bd_base) - DPRAM_BASE;
 
 /*
  *  In case SMC1 is being relocated...


^ permalink raw reply related

* Re: Linux doesn not boot from u-boot on ML403
From: Josh Boyer @ 2007-09-23 19:44 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-embedded, Miroslaw Dach
In-Reply-To: <fa686aa40709230832m1d4a083ao2e43b57cc39e088@mail.gmail.com>

On Sun, 23 Sep 2007 09:32:25 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:

> On 9/23/07, Miroslaw Dach <miroslaw.dach@psi.ch> wrote:
> > Hi Grant,
> >
> > Thank you very much for your advices which were very valuable for me.
> >
> > Recently I have followed your advice to move from kernel 2.6.21 to the
> > higher one in order to have the possibility to boot the kernel from
> > u-boot. I have copied across from you git tree the latest version of linux
> > kernel 2.6.23 rc-2.
> >
> > It compiles successfully with some warnings like below:
> >   MODPOST vmlinux.o
> > WARNING: vmlinux.o(.text+0x223c): Section mismatch: reference to .init.text:early_init (between 'start_here' and 'initial_mmu')
> > WARNING: vmlinux.o(.text+0x2254): Section mismatch: reference to .init.text:machine_init (between 'start_here' and 'initial_mmu')
> > WARNING: vmlinux.o(.text+0x2258): Section mismatch: reference to .init.text:MMU_init (between 'start_here' and 'initial_mmu')
> > WARNING: vmlinux.o(.text+0x22b2): Section mismatch: reference to .init.text:start_kernel (between 'start_here' and 'initial_mmu')
> > WARNING: vmlinux.o(.text+0x22b6): Section mismatch: reference to .init.text:start_kernel (between 'start_here' and 'initial_mmu')
> >    LD      vmlinux
> 
> Yes, I see this warning too.  I haven't had a chance to debug it.

This warning should be fixed in arch/powerpc.  You could probably look
at the fix there and port it to arch/ppc.

josh

^ permalink raw reply

* [patch v3] Cell: Wrap master run control bit
From: Geoff Levand @ 2007-09-23 20:50 UTC (permalink / raw)
  To: jk; +Cc: Masato Noguchi, linuxppc-dev@ozlabs.org, Arnd Bergmann
In-Reply-To: <46DD4783.9040103@am.sony.com>

Subject: Cell: Wrap master run control bit

From: Masato Noguchi <Masato.Noguchi@jp.sony.com>

Add platform specific SPU run control routines to the spufs.  The current
spufs implementation uses the SPU master run control bit (MFC_SR1[S]) to
control SPE execution, but the PS3 hypervisor does not support the use of
this feature.

This change adds the run control wrapper routies spu_enable_spu() and
spu_disable_spu().  The bare metal routines use the master run control
bit, and the PS3 specific routines use the priv2 run control register.

An outstanding enhancement for the PS3 would be to add a guard to check
for incorrect access to the spu problem state when the spu context is
disabled.  This check could be implemented with a flag added to the spu
context that would inhibit mapping problem state pages, and a routine
to unmap spu problem state pages.  When the spu is enabled with
ps3_enable_spu() the flag would be set allowing pages to be mapped,
and when the spu is disabled with ps3_disable_spu() the flag would be
cleared and mapped problem state pages would be unmapped.

Signed-off-by: Masato Noguchi <Masato.Noguchi@jp.sony.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---

Jeremy,

Here is an updated version for 2.6.24.  Noguchi-san will
work on the LS unmapping feature for 2.6.25.

-Geoff

v2:
 o Added comments about unmapping PS pages when disabled.
v3:
 o Changed routines to return void instead of int.
 o Rebased to apply to Jeremy's 2.6.23-rc work-around.

 arch/powerpc/platforms/cell/spu_manage.c        |   13 +++++++++++
 arch/powerpc/platforms/cell/spufs/backing_ops.c |    6 +++++
 arch/powerpc/platforms/cell/spufs/hw_ops.c      |   10 ++++++++
 arch/powerpc/platforms/cell/spufs/run.c         |    4 +--
 arch/powerpc/platforms/cell/spufs/spufs.h       |    1 
 arch/powerpc/platforms/ps3/spu.c                |   27 ++++++++++++++++++++++--
 include/asm-powerpc/spu_priv1.h                 |   15 +++++++++++++
 7 files changed, 72 insertions(+), 4 deletions(-)

--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -35,6 +35,7 @@
 #include <asm/firmware.h>
 #include <asm/prom.h>
 
+#include "spufs/spufs.h"
 #include "interrupt.h"
 
 struct device_node *spu_devnode(struct spu *spu)
@@ -369,6 +370,16 @@ static int of_destroy_spu(struct spu *sp
 	return 0;
 }
 
+static void enable_spu_by_master_run(struct spu_context *ctx)
+{
+	ctx->ops->master_start(ctx);
+}
+
+static void disable_spu_by_master_run(struct spu_context *ctx)
+{
+	ctx->ops->master_stop(ctx);
+}
+
 /* Hardcoded affinity idxs for qs20 */
 #define QS20_SPES_PER_BE 8
 static int qs20_reg_idxs[QS20_SPES_PER_BE] =   { 0, 2, 4, 6, 7, 5, 3, 1 };
@@ -535,5 +546,7 @@ const struct spu_management_ops spu_mana
 	.enumerate_spus = of_enumerate_spus,
 	.create_spu = of_create_spu,
 	.destroy_spu = of_destroy_spu,
+	.enable_spu = enable_spu_by_master_run,
+	.disable_spu = disable_spu_by_master_run,
 	.init_affinity = init_affinity,
 };
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -285,6 +285,11 @@ static void spu_backing_runcntl_write(st
 	spin_unlock(&ctx->csa.register_lock);
 }
 
+static void spu_backing_runcntl_stop(struct spu_context *ctx)
+{
+	spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
+}
+
 static void spu_backing_master_start(struct spu_context *ctx)
 {
 	struct spu_state *csa = &ctx->csa;
@@ -381,6 +386,7 @@ struct spu_context_ops spu_backing_ops =
 	.get_ls = spu_backing_get_ls,
 	.runcntl_read = spu_backing_runcntl_read,
 	.runcntl_write = spu_backing_runcntl_write,
+	.runcntl_stop = spu_backing_runcntl_stop,
 	.master_start = spu_backing_master_start,
 	.master_stop = spu_backing_master_stop,
 	.set_mfc_query = spu_backing_set_mfc_query,
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -220,6 +220,15 @@ static void spu_hw_runcntl_write(struct 
 	spin_unlock_irq(&ctx->spu->register_lock);
 }
 
+static void spu_hw_runcntl_stop(struct spu_context *ctx)
+{
+	spin_lock_irq(&ctx->spu->register_lock);
+	out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
+	while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
+		cpu_relax();
+	spin_unlock_irq(&ctx->spu->register_lock);
+}
+
 static void spu_hw_master_start(struct spu_context *ctx)
 {
 	struct spu *spu = ctx->spu;
@@ -321,6 +330,7 @@ struct spu_context_ops spu_hw_ops = {
 	.get_ls = spu_hw_get_ls,
 	.runcntl_read = spu_hw_runcntl_read,
 	.runcntl_write = spu_hw_runcntl_write,
+	.runcntl_stop = spu_hw_runcntl_stop,
 	.master_start = spu_hw_master_start,
 	.master_stop = spu_hw_master_stop,
 	.set_mfc_query = spu_hw_set_mfc_query,
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -302,7 +302,7 @@ long spufs_run_spu(struct spu_context *c
 	if (mutex_lock_interruptible(&ctx->run_mutex))
 		return -ERESTARTSYS;
 
-	ctx->ops->master_start(ctx);
+	spu_enable_spu(ctx);
 	ctx->event_return = 0;
 
 	spu_acquire(ctx);
@@ -376,7 +376,7 @@ long spufs_run_spu(struct spu_context *c
 		ctx->stats.libassist++;
 
 
-	ctx->ops->master_stop(ctx);
+	spu_disable_spu(ctx);
 	ret = spu_run_fini(ctx, npc, &status);
 	spu_yield(ctx);
 
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -170,6 +170,7 @@ struct spu_context_ops {
 	char*(*get_ls) (struct spu_context * ctx);
 	 u32 (*runcntl_read) (struct spu_context * ctx);
 	void (*runcntl_write) (struct spu_context * ctx, u32 data);
+	void (*runcntl_stop) (struct spu_context * ctx);
 	void (*master_start) (struct spu_context * ctx);
 	void (*master_stop) (struct spu_context * ctx);
 	int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -28,6 +28,7 @@
 #include <asm/spu_priv1.h>
 #include <asm/lv1call.h>
 
+#include "../cell/spufs/spufs.h"
 #include "platform.h"
 
 /* spu_management_ops */
@@ -419,10 +420,34 @@ static int ps3_init_affinity(void)
 	return 0;
 }
 
+/**
+ * ps3_enable_spu - Enable SPU run control.
+ *
+ * An outstanding enhancement for the PS3 would be to add a guard to check
+ * for incorrect access to the spu problem state when the spu context is
+ * disabled.  This check could be implemented with a flag added to the spu
+ * context that would inhibit mapping problem state pages, and a routine
+ * to unmap spu problem state pages.  When the spu is enabled with
+ * ps3_enable_spu() the flag would be set allowing pages to be mapped,
+ * and when the spu is disabled with ps3_disable_spu() the flag would be
+ * cleared and the mapped problem state pages would be unmapped.
+ */
+
+static void ps3_enable_spu(struct spu_context *ctx)
+{
+}
+
+static void ps3_disable_spu(struct spu_context *ctx)
+{
+	ctx->ops->runcntl_stop(ctx);
+}
+
 const struct spu_management_ops spu_management_ps3_ops = {
 	.enumerate_spus = ps3_enumerate_spus,
 	.create_spu = ps3_create_spu,
 	.destroy_spu = ps3_destroy_spu,
+	.enable_spu = ps3_enable_spu,
+	.disable_spu = ps3_disable_spu,
 	.init_affinity = ps3_init_affinity,
 };
 
@@ -505,8 +530,6 @@ static void mfc_sr1_set(struct spu *spu,
 	static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
 		| MFC_STATE1_PROBLEM_STATE_MASK);
 
-	sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK;
-
 	BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));
 
 	spu_pdata(spu)->cache.sr1 = sr1;
--- a/include/asm-powerpc/spu_priv1.h
+++ b/include/asm-powerpc/spu_priv1.h
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 
 struct spu;
+struct spu_context;
 
 /* access to priv1 registers */
 
@@ -178,6 +179,8 @@ struct spu_management_ops {
 	int (*enumerate_spus)(int (*fn)(void *data));
 	int (*create_spu)(struct spu *spu, void *data);
 	int (*destroy_spu)(struct spu *spu);
+	void (*enable_spu)(struct spu_context *ctx);
+	void (*disable_spu)(struct spu_context *ctx);
 	int (*init_affinity)(void);
 };
 
@@ -207,6 +210,18 @@ spu_init_affinity (void)
 	return spu_management_ops->init_affinity();
 }
 
+static inline void
+spu_enable_spu (struct spu_context *ctx)
+{
+	spu_management_ops->enable_spu(ctx);
+}
+
+static inline void
+spu_disable_spu (struct spu_context *ctx)
+{
+	spu_management_ops->disable_spu(ctx);
+}
+
 /*
  * The declarations folowing are put here for convenience
  * and only intended to be used by the platform setup code.

^ permalink raw reply

* FDT for Microblaze and PPC405
From: Michal Simek @ 2007-09-23 18:40 UTC (permalink / raw)
  To: linuxppc-dev

Hi,
I made EDK tcl script for generation DTS test scructure for FDT. Script
support Microblaze and PowerPC 405.
Script was primary built for generation U-BOOT configs files for Microblaze.
For Microblaze can you generate both files (FDT and U-BOOT).
For PowerPC can you generate only DTS file. Generation U-BOOT configs files
aren't supported yet. Script ends after generation DTS.
Script has 2.00.a mark.
It is available at www.monstr.eu.

Cheers,
Michal Simek

^ permalink raw reply

* Re: [PATCH 1/2] qemu platform, v2
From: Rob Landley @ 2007-09-23 22:01 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: linuxppc-dev, Christoph Hellwig, Milton Miller, David Gibson
In-Reply-To: <18165.60185.316393.213864@cargo.ozlabs.ibm.com>

On Saturday 22 September 2007 11:27:05 pm Paul Mackerras wrote:
> Rob Landley writes:
>
> Just to correct a few misconceptions:
> > 2) PowerPC uses a device tree supplied by the hardware to identify the
> > available hardware, even for stuff living on PCI busses which it could
> > theoretically probe for but doesn't.
>
> The device tree doesn't have to include anything that can be probed
> for.  On some platforms (e.g. pSeries) we choose to use the device
> tree rather than probing, but on most other platforms we probe.
>
> > I'd be following this more closely if compiling a device tree didn't
> > currently require an external utility (dtc or some such) that doesn't
> > come with the Linux kernel.  No other target platform I've built kernels
> > for requires such an environmental dependency.
>
> No?  You haven't built kernels for other platforms that have external
> dependencies such as perl, gcc, make, binutils, etc.? :)

Lemme clarify.

1) All of the other platforms have the _same_ requirements.  I never had to 
install anything to build "for arm", "for mips", "for sparc", or 
for "x86_64".

The minimal requirements are:  A compiler (gcc/binutils although I'm working 
on extending tcc to replace these), make, linux kernel, C library (uClibc), 
busybox, and bash.  That's it.  You can rebuild it under itself from source 
with that, on x86, x86-64, arm, mips...  Presumably sparc and m68k too (still 
debugging there).

2) Perl isn't needed to build any target platform I've tried.  (I even sent in 
some patches way back to turn a perl script into a sed script for User Mode 
Linux to _make_ this the case.)  Yes you need perl to build glibc, but not to 
build uClibc. :)

3) What I'm pointing out is that ppc needs an external dependency none of the 
other platforms I've tried need.  I consider this a bug.  I didn't start 
using "make headers_install" until it stopped needing an external unifdef.

> >  (This is a problem both for hardwiring the
> > device tree into the kernel and for building a new boot rom from the
> > linux kernel's ppc boot wrapper that would contain such a device tree to
> > feed to the kernel.)
>
> It's only really been a problem for ps3 so far, since the embedded
> guys don't seem to have any difficulty with installing dtc.

If the only target that interested me was ppc, then I'd happily install dtc 
for it.  But focusing on cross-platform support as I am, I notice when a 
platform has different requirements from any of the others.

> We are 
> looking at what to do for ps3 and prep, and the answer may well
> involve bundling dtc in the kernel source (it's not too big, around
> 3400 lines).

Sounds good to me...

> Paul.

Rob
-- 
"One of my most productive days was throwing away 1000 lines of code."
  - Ken Thompson.

^ permalink raw reply

* [PATCH 08/11] [POWERPC] iSeries: move detection of virtual cdroms
From: Stephen Rothwell @ 2007-09-23 16:50 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Christoph Hellwig
In-Reply-To: <20070921143750.4114b0b5.sfr@canb.auug.org.au>

Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties).  This way viocd.c gets all
the information about the devices from the device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/vio.c               |    3 -
 arch/powerpc/platforms/iseries/Makefile |    2 +-
 arch/powerpc/platforms/iseries/dt.c     |    4 -
 arch/powerpc/platforms/iseries/vio.c    |  317 +++++++++++++++++++++++++++++++
 drivers/cdrom/viocd.c                   |  116 ++----------
 include/asm-powerpc/iseries/vio.h       |   24 +++
 6 files changed, 361 insertions(+), 105 deletions(-)
 create mode 100644 arch/powerpc/platforms/iseries/vio.c

This version creates the device tree entries unconditionally.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 9e1ff21..aec5fff 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -257,9 +257,6 @@ static int __init vio_bus_init(void)
 	int err;
 	struct device_node *node_vroot;
 
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		iommu_vio_init();
-
 	err = bus_register(&vio_bus_type);
 	if (err) {
 		printk(KERN_ERR "failed to register VIO bus\n");
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index 60db509..a65f1b4 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -7,7 +7,7 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
 	hvcall.o proc.o htab.o iommu.o misc.o irq.o
 obj-$(CONFIG_PCI) += pci.o vpdinfo.o
 obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_VIOPATH) += viopath.o
+obj-$(CONFIG_VIOPATH) += viopath.o vio.o
 obj-$(CONFIG_MODULES) += ksyms.o
 
 quiet_cmd_dt_strings = DT_STR  $@
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 9e8a334..84fcee1 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -381,10 +381,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
 				"IBM,iSeries-viodasd", 1);
 	reg += HVMAXARCHITECTEDVIRTUALDISKS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
-		dt_do_vdevice(dt, "viocd", reg, i, device_type_block,
-				"IBM,iSeries-viocd", 1);
 	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
 
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
new file mode 100644
index 0000000..08f6884
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -0,0 +1,317 @@
+/*
+ * Legacy iSeries specific vio initialisation
+ * that needs to be built in (not a module).
+ *
+ * © Copyright 2007 IBM Corporation
+ *	Author: Stephen Rothwell
+ *	Some parts collected from various other files
+ *
+ * This program is free software;  you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/completion.h>
+#include <linux/proc_fs.h>
+
+#include <asm/firmware.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/iommu.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
+
+#define FIRST_VTY	0
+#define NUM_VTYS	1
+#define FIRST_VSCSI	(FIRST_VTY + NUM_VTYS)
+#define NUM_VSCSIS	1
+#define FIRST_VLAN	(FIRST_VSCSI + NUM_VSCSIS)
+#define NUM_VLANS	HVMAXARCHITECTEDVIRTUALLANS
+#define FIRST_VIODASD	(FIRST_VLAN + NUM_VLANS)
+#define NUM_VIODASDS	HVMAXARCHITECTEDVIRTUALDISKS
+#define FIRST_VIOCD	(FIRST_VIODASD + NUM_VIODASDS)
+#define NUM_VIOCDS	HVMAXARCHITECTEDVIRTUALCDROMS
+#define FIRST_VIOTAPE	(FIRST_VIOCD + NUM_VIOCDS)
+#define NUM_VIOTAPES	HVMAXARCHITECTEDVIRTUALTAPES
+
+static struct property * __init new_property(const char *name, int length,
+		const void *value)
+{
+	struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
+			GFP_KERNEL);
+
+	if (!np)
+		return NULL;
+	np->name = (char *)(np + 1);
+	np->value = np->name + strlen(name) + 1;
+	strcpy(np->name, name);
+	memcpy(np->value, value, length);
+	np->length = length;
+	return np;
+}
+
+static void __init free_property(struct property *np)
+{
+	kfree(np);
+}
+
+static struct device_node * __init new_node(const char *path,
+		struct device_node *parent)
+{
+	struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);
+
+	if (!np)
+		return NULL;
+	np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+	if (!np->full_name) {
+		kfree(np);
+		return NULL;
+	}
+	strcpy(np->full_name, path);
+	of_node_set_flag(np, OF_DYNAMIC);
+	kref_init(&np->kref);
+	np->parent = of_node_get(parent);
+	return np;
+}
+
+static void __init free_node(struct device_node *np)
+{
+	struct property *next;
+	struct property *prop;
+
+	next = np->properties;
+	while (next) {
+		prop = next;
+		next = prop->next;
+		free_property(prop);
+	}
+	of_node_put(np->parent);
+	kfree(np->full_name);
+	kfree(np);
+}
+
+static int __init add_string_property(struct device_node *np, const char *name,
+		const char *value)
+{
+	struct property *nprop = new_property(name, strlen(value) + 1, value);
+
+	if (!nprop)
+		return 0;
+	prom_add_property(np, nprop);
+	return 1;
+}
+
+static int __init add_raw_property(struct device_node *np, const char *name,
+		int length, const void *value)
+{
+	struct property *nprop = new_property(name, length, value);
+
+	if (!nprop)
+		return 0;
+	prom_add_property(np, nprop);
+	return 1;
+}
+
+struct viocd_waitevent {
+	struct completion	com;
+	int			rc;
+	u16			sub_result;
+};
+
+struct cdrom_info {
+	char	rsrcname[10];
+	char	type[4];
+	char	model[3];
+};
+
+static void __init handle_cd_event(struct HvLpEvent *event)
+{
+	struct viocdlpevent *bevent;
+	struct viocd_waitevent *pwe;
+
+	if (!event)
+		/* Notification that a partition went away! */
+		return;
+
+	/* First, we should NEVER get an int here...only acks */
+	if (hvlpevent_is_int(event)) {
+		printk(KERN_WARNING "handle_cd_event: got an unexpected int\n");
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+		return;
+	}
+
+	bevent = (struct viocdlpevent *)event;
+
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case viocdgetinfo:
+		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
+		pwe->rc = event->xRc;
+		pwe->sub_result = bevent->sub_result;
+		complete(&pwe->com);
+		break;
+
+	default:
+		printk(KERN_WARNING "handle_cd_event: "
+			"message with unexpected subtype %0x04X!\n",
+			event->xSubtype & VIOMINOR_SUBTYPE_MASK);
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+	}
+}
+
+static void __init get_viocd_info(struct device_node *vio_root)
+{
+	HvLpEvent_Rc hvrc;
+	u32 unit;
+	struct viocd_waitevent we;
+	struct cdrom_info *unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
+	int ret;
+
+	ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, 2);
+	if (ret) {
+		printk(KERN_WARNING
+			"get_viocd_info: error opening path to host partition %d\n",
+			viopath_hostLp);
+		return;
+	}
+
+	/* Initialize our request handler */
+	vio_setHandler(viomajorsubtype_cdio, handle_cd_event);
+
+	unitinfo = iseries_hv_alloc(
+			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
+			&unitinfo_dmaaddr, GFP_ATOMIC);
+	if (!unitinfo) {
+		printk(KERN_WARNING
+			"get_viocd_info: error allocating unitinfo\n");
+		goto clear_handler;
+	}
+
+	memset(unitinfo, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS);
+
+	init_completion(&we.com);
+
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_cdio | viocdgetinfo,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
+			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, 0);
+	if (hvrc != HvLpEvent_Rc_Good) {
+		printk(KERN_WARNING
+			"get_viocd_info: cdrom error sending event. rc %d\n",
+			(int)hvrc);
+		goto hv_free;
+	}
+
+	wait_for_completion(&we.com);
+
+	if (we.rc) {
+		printk(KERN_WARNING "get_viocd_info: bad rc %d:0x%04X\n",
+			we.rc, we.sub_result);
+		goto hv_free;
+	}
+
+	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
+			unitinfo[unit].rsrcname[0]; unit++) {
+		struct device_node *np;
+		char name[64];
+		u32 reg = FIRST_VIOCD + unit;
+
+		snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg);
+		np = new_node(name, vio_root);
+		if (!np)
+			goto hv_free;
+		if (!add_string_property(np, "name", "viocd") ||
+			!add_string_property(np, "device_type", "block") ||
+			!add_string_property(np, "compatible",
+				"IBM,iSeries-viocd") ||
+			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+			!add_raw_property(np, "linux,unit_address",
+				sizeof(unit), &unit) ||
+			!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(unitinfo[unit].rsrcname),
+				unitinfo[unit].rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(unitinfo[unit].type),
+				unitinfo[unit].type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(unitinfo[unit].model),
+				unitinfo[unit].model))
+			goto node_free;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+		of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+		if (vio_root->pde) {
+			struct proc_dir_entry *ent;
+
+			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
+					vio_root->pde);
+			if (ent)
+				proc_device_tree_add_node(np, ent);
+		}
+#endif
+		continue;
+
+ node_free:
+		free_node(np);
+		break;
+	}
+
+ hv_free:
+	iseries_hv_free(sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
+			unitinfo, unitinfo_dmaaddr);
+ clear_handler:
+	vio_clearHandler(viomajorsubtype_cdio);
+	viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
+}
+
+static int __init iseries_vio_init(void)
+{
+	struct device_node *vio_root;
+
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
+	iommu_vio_init();
+
+	vio_root = of_find_node_by_path("/vdevice");
+	if (!vio_root)
+		return -ENODEV;
+
+	if (viopath_hostLp == HvLpIndexInvalid) {
+		vio_set_hostlp();
+		/* If we don't have a host, bail out */
+		if (viopath_hostLp == HvLpIndexInvalid)
+			goto put_node;
+	}
+
+	get_viocd_info(vio_root);
+
+	return 0;
+
+ put_node:
+	of_node_put(vio_root);
+	return -ENODEV;
+}
+arch_initcall(iseries_vio_init);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index c081e54..880b5dc 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -56,30 +56,6 @@
 #define VIOCD_KERN_WARNING		KERN_WARNING "viocd: "
 #define VIOCD_KERN_INFO			KERN_INFO "viocd: "
 
-struct viocdlpevent {
-	struct HvLpEvent	event;
-	u32			reserved;
-	u16			version;
-	u16			sub_result;
-	u16			disk;
-	u16			flags;
-	u32			token;
-	u64			offset;		/* On open, max number of disks */
-	u64			len;		/* On open, size of the disk */
-	u32			block_size;	/* Only set on open */
-	u32			media_size;	/* Only set on open */
-};
-
-enum viocdsubtype {
-	viocdopen = 0x0001,
-	viocdclose = 0x0002,
-	viocdread = 0x0003,
-	viocdwrite = 0x0004,
-	viocdlockdoor = 0x0005,
-	viocdgetinfo = 0x0006,
-	viocdcheck = 0x0007
-};
-
 /*
  * Should probably make this a module parameter....sigh
  */
@@ -131,17 +107,13 @@ static struct capability_entry capability_table[] __initdata = {
 /* These are our internal structures for keeping track of devices */
 static int viocd_numdev;
 
-struct cdrom_info {
-	char	rsrcname[10];
-	char	type[4];
-	char	model[3];
-};
-
 struct disk_info {
 	struct gendisk			*viocd_disk;
 	struct cdrom_device_info	viocd_info;
 	struct device			*dev;
-	struct cdrom_info		unitinfo;
+	const char			*rsrcname;
+	const char			*type;
+	const char			*model;
 };
 static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
 
@@ -159,9 +131,9 @@ static int proc_viocd_show(struct seq_file *m, void *v)
 	for (i = 0; i < viocd_numdev; i++) {
 		seq_printf(m, "viocd device %d is iSeries resource %10.10s"
 				"type %4.4s, model %3.3s\n",
-				i, viocd_diskinfo[i].unitinfo.rsrcname,
-				viocd_diskinfo[i].unitinfo.type,
-				viocd_diskinfo[i].unitinfo.model);
+				i, viocd_diskinfo[i].rsrcname,
+				viocd_diskinfo[i].type,
+				viocd_diskinfo[i].model);
 	}
 	return 0;
 }
@@ -211,61 +183,6 @@ struct block_device_operations viocd_fops = {
 	.media_changed =	viocd_blk_media_changed,
 };
 
-/* Get info on CD devices from OS/400 */
-static void __init get_viocd_info(void)
-{
-	HvLpEvent_Rc hvrc;
-	int i;
-	struct viocd_waitevent we;
-	struct cdrom_info *viocd_unitinfo;
-	dma_addr_t unitinfo_dmaaddr;
-
-	viocd_unitinfo = iseries_hv_alloc(
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			&unitinfo_dmaaddr, GFP_ATOMIC);
-	if (viocd_unitinfo == NULL) {
-		printk(VIOCD_KERN_WARNING "error allocating unitinfo\n");
-		return;
-	}
-
-	memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD);
-
-	init_completion(&we.com);
-
-	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
-			HvLpEvent_Type_VirtualIo,
-			viomajorsubtype_cdio | viocdgetinfo,
-			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
-			viopath_sourceinst(viopath_hostLp),
-			viopath_targetinst(viopath_hostLp),
-			(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0);
-	if (hvrc != HvLpEvent_Rc_Good) {
-		printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n",
-				(int)hvrc);
-		goto error_ret;
-	}
-
-	wait_for_completion(&we.com);
-
-	if (we.rc) {
-		const struct vio_error_entry *err =
-			vio_lookup_rc(viocd_err_table, we.sub_result);
-		printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n",
-				we.rc, we.sub_result, err->msg);
-		goto error_ret;
-	}
-
-	for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) {
-		viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i];
-		viocd_numdev++;
-	}
-
-error_ret:
-	iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			viocd_unitinfo, unitinfo_dmaaddr);
-}
-
 static int viocd_open(struct cdrom_device_info *cdi, int purpose)
 {
         struct disk_info *diskinfo = cdi->handle;
@@ -576,7 +493,6 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
 					bevent->block_size / 512);
 		}
 		/* FALLTHROUGH !! */
-	case viocdgetinfo:
 	case viocdlockdoor:
 		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
 return_complete:
@@ -660,22 +576,30 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	int deviceno;
 	struct disk_info *d;
 	struct cdrom_device_info *c;
-	struct cdrom_info *ci;
 	struct request_queue *q;
+	struct device_node *node = vdev->dev.archdata.of_node;
 
 	deviceno = vdev->unit_address;
-	if (deviceno >= viocd_numdev)
+	if (deviceno > VIOCD_MAX_CD)
 		return -ENODEV;
+	if (!node)
+		return -ENODEV;
+
+	if (deviceno >= viocd_numdev)
+		viocd_numdev = deviceno + 1;
 
 	d = &viocd_diskinfo[deviceno];
+	d->rsrcname = of_get_property(node, "linux,vio_rsrcname", NULL);
+	d->type = of_get_property(node, "linux,vio_type", NULL);
+	d->model = of_get_property(node, "linux,vio_model", NULL);
+
 	c = &d->viocd_info;
-	ci = &d->unitinfo;
 
 	c->ops = &viocd_dops;
 	c->speed = 4;
 	c->capacity = 1;
 	c->handle = d;
-	c->mask = ~find_capability(ci->type);
+	c->mask = ~find_capability(d->type);
 	sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno);
 
 	if (register_cdrom(c) != 0) {
@@ -685,7 +609,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	}
 	printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s "
 			"type %4.4s, model %3.3s\n",
-			c->name, ci->rsrcname, ci->type, ci->model);
+			c->name, d->rsrcname, d->type, d->model);
 	q = blk_init_queue(do_viocd_request, &viocd_reqlock);
 	if (q == NULL) {
 		printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n",
@@ -794,8 +718,6 @@ static int __init viocd_init(void)
 	/* Initialize our request handler */
 	vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event);
 
-	get_viocd_info();
-
 	spin_lock_init(&viocd_reqlock);
 
 	ret = vio_register_driver(&viocd_driver);
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 5a5cd0f..e5a405b 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -51,6 +51,30 @@
  */
 #define VIO_MAX_SUBTYPES 8
 
+struct viocdlpevent {
+	struct HvLpEvent	event;
+	u32			reserved;
+	u16			version;
+	u16			sub_result;
+	u16			disk;
+	u16			flags;
+	u32			token;
+	u64			offset;		/* On open, max number of disks */
+	u64			len;		/* On open, size of the disk */
+	u32			block_size;	/* Only set on open */
+	u32			media_size;	/* Only set on open */
+};
+
+enum viocdsubtype {
+	viocdopen = 0x0001,
+	viocdclose = 0x0002,
+	viocdread = 0x0003,
+	viocdwrite = 0x0004,
+	viocdlockdoor = 0x0005,
+	viocdgetinfo = 0x0006,
+	viocdcheck = 0x0007
+};
+
 /*
  * Each subtype can register a handler to process their events.
  * The handler must have this interface.
-- 
1.5.3.2

^ permalink raw reply related

* [PATCH 09/11] [POWERPC] iSeries: move detection of virtual tapes
From: Stephen Rothwell @ 2007-09-23 16:52 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Christoph Hellwig
In-Reply-To: <20070921143841.37ad2a2f.sfr@canb.auug.org.au>

Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties).  This way viotape.c gets
all the information about the devices from the device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/platforms/iseries/dt.c  |    7 --
 arch/powerpc/platforms/iseries/vio.c |  149 ++++++++++++++++++++++++++++++----
 drivers/char/viotape.c               |  124 ++++------------------------
 include/asm-powerpc/iseries/vio.h    |   41 +++++++++
 4 files changed, 192 insertions(+), 129 deletions(-)

This version creates the device tree entries unconditionally.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 84fcee1..2e4ad6b 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -73,7 +73,6 @@ static char __initdata device_type_memory[] = "memory";
 static char __initdata device_type_serial[] = "serial";
 static char __initdata device_type_network[] = "network";
 static char __initdata device_type_block[] = "block";
-static char __initdata device_type_byte[] = "byte";
 static char __initdata device_type_pci[] = "pci";
 static char __initdata device_type_vdevice[] = "vdevice";
 static char __initdata device_type_vscsi[] = "vscsi";
@@ -380,12 +379,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
 		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
 				"IBM,iSeries-viodasd", 1);
-	reg += HVMAXARCHITECTEDVIRTUALDISKS;
-	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
-		dt_do_vdevice(dt, "viotape", reg, i, device_type_byte,
-				"IBM,iSeries-viotape", 1);
 
 	dt_end_node(dt);
 }
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 08f6884..b4f7433 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -45,6 +45,18 @@
 #define FIRST_VIOTAPE	(FIRST_VIOCD + NUM_VIOCDS)
 #define NUM_VIOTAPES	HVMAXARCHITECTEDVIRTUALTAPES
 
+struct vio_waitevent {
+	struct completion	com;
+	int			rc;
+	u16			sub_result;
+};
+
+struct vio_resource {
+	char	rsrcname[10];
+	char	type[4];
+	char	model[3];
+};
+
 static struct property * __init new_property(const char *name, int length,
 		const void *value)
 {
@@ -123,22 +135,10 @@ static int __init add_raw_property(struct device_node *np, const char *name,
 	return 1;
 }
 
-struct viocd_waitevent {
-	struct completion	com;
-	int			rc;
-	u16			sub_result;
-};
-
-struct cdrom_info {
-	char	rsrcname[10];
-	char	type[4];
-	char	model[3];
-};
-
 static void __init handle_cd_event(struct HvLpEvent *event)
 {
 	struct viocdlpevent *bevent;
-	struct viocd_waitevent *pwe;
+	struct vio_waitevent *pwe;
 
 	if (!event)
 		/* Notification that a partition went away! */
@@ -158,7 +158,7 @@ static void __init handle_cd_event(struct HvLpEvent *event)
 
 	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
 	case viocdgetinfo:
-		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
+		pwe = (struct vio_waitevent *)event->xCorrelationToken;
 		pwe->rc = event->xRc;
 		pwe->sub_result = bevent->sub_result;
 		complete(&pwe->com);
@@ -179,8 +179,8 @@ static void __init get_viocd_info(struct device_node *vio_root)
 {
 	HvLpEvent_Rc hvrc;
 	u32 unit;
-	struct viocd_waitevent we;
-	struct cdrom_info *unitinfo;
+	struct vio_waitevent we;
+	struct vio_resource *unitinfo;
 	dma_addr_t unitinfo_dmaaddr;
 	int ret;
 
@@ -286,6 +286,122 @@ static void __init get_viocd_info(struct device_node *vio_root)
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
 }
 
+/* Handle interrupt events for tape */
+static void __init handle_tape_event(struct HvLpEvent *event)
+{
+	struct vio_waitevent *we;
+	struct viotapelpevent *tevent = (struct viotapelpevent *)event;
+
+	if (event == NULL)
+		/* Notification that a partition went away! */
+		return;
+
+	we = (struct vio_waitevent *)event->xCorrelationToken;
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case viotapegetinfo:
+		we->rc = tevent->sub_type_result;
+		complete(&we->com);
+		break;
+	default:
+		printk(KERN_WARNING "handle_tape_event: weird ack\n");
+	}
+}
+
+static void __init get_viotape_info(struct device_node *vio_root)
+{
+	HvLpEvent_Rc hvrc;
+	u32 unit;
+	struct vio_resource *unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
+	size_t len = sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALTAPES;
+	struct vio_waitevent we;
+	int ret;
+
+	ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2);
+	if (ret) {
+		printk(KERN_WARNING "get_viotape_info: "
+			"error on viopath_open to hostlp %d\n", ret);
+		return;
+	}
+
+	vio_setHandler(viomajorsubtype_tape, handle_tape_event);
+
+	unitinfo = iseries_hv_alloc(len, &unitinfo_dmaaddr, GFP_ATOMIC);
+	if (!unitinfo)
+		goto clear_handler;
+
+	memset(unitinfo, 0, len);
+
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_tape | viotapegetinfo,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)(unsigned long)&we, VIOVERSION << 16,
+			unitinfo_dmaaddr, len, 0, 0);
+	if (hvrc != HvLpEvent_Rc_Good) {
+		printk(KERN_WARNING "get_viotape_info: hv error on op %d\n",
+				(int)hvrc);
+		goto hv_free;
+	}
+
+	wait_for_completion(&we.com);
+
+	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
+			unitinfo[unit].rsrcname[0]; unit++) {
+		struct device_node *np;
+		char name[64];
+		u32 reg = FIRST_VIOTAPE + unit;
+
+		snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
+		np = new_node(name, vio_root);
+		if (!np)
+			goto hv_free;
+		if (!add_string_property(np, "name", "viotape") ||
+			!add_string_property(np, "device_type", "byte") ||
+			!add_string_property(np, "compatible",
+				"IBM,iSeries-viotape") ||
+			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+			!add_raw_property(np, "linux,unit_address",
+				sizeof(unit), &unit) ||
+			!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(unitinfo[unit].rsrcname),
+				unitinfo[unit].rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(unitinfo[unit].type),
+				unitinfo[unit].type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(unitinfo[unit].model),
+				unitinfo[unit].model))
+			goto node_free;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+		of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+		if (vio_root->pde) {
+			struct proc_dir_entry *ent;
+
+			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
+					vio_root->pde);
+			if (ent)
+				proc_device_tree_add_node(np, ent);
+		}
+#endif
+		continue;
+
+ node_free:
+		free_node(np);
+		break;
+	}
+
+ hv_free:
+	iseries_hv_free(len, unitinfo, unitinfo_dmaaddr);
+ clear_handler:
+	vio_clearHandler(viomajorsubtype_tape);
+	viopath_close(viopath_hostLp, viomajorsubtype_tape, 2);
+}
+
 static int __init iseries_vio_init(void)
 {
 	struct device_node *vio_root;
@@ -307,6 +423,7 @@ static int __init iseries_vio_init(void)
 	}
 
 	get_viocd_info(vio_root);
+	get_viotape_info(vio_root);
 
 	return 0;
 
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 064c091..f1d60f0 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -92,47 +92,6 @@ struct viot_devinfo_struct {
 #define VIOTAPOP_SETPART       14
 #define VIOTAPOP_UNLOAD        15
 
-struct viotapelpevent {
-	struct HvLpEvent event;
-	u32 reserved;
-	u16 version;
-	u16 sub_type_result;
-	u16 tape;
-	u16 flags;
-	u32 token;
-	u64 len;
-	union {
-		struct {
-			u32 tape_op;
-			u32 count;
-		} op;
-		struct {
-			u32 type;
-			u32 resid;
-			u32 dsreg;
-			u32 gstat;
-			u32 erreg;
-			u32 file_no;
-			u32 block_no;
-		} get_status;
-		struct {
-			u32 block_no;
-		} get_pos;
-	} u;
-};
-
-enum viotapesubtype {
-	viotapeopen = 0x0001,
-	viotapeclose = 0x0002,
-	viotaperead = 0x0003,
-	viotapewrite = 0x0004,
-	viotapegetinfo = 0x0005,
-	viotapeop = 0x0006,
-	viotapegetpos = 0x0007,
-	viotapesetpos = 0x0008,
-	viotapegetstatus = 0x0009
-};
-
 enum viotaperc {
 	viotape_InvalidRange = 0x0601,
 	viotape_InvalidToken = 0x0602,
@@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
 #define VIOT_WRITING		2
 
 /* Our info on the tapes */
-struct tape_descr {
-	char rsrcname[10];
-	char type[4];
-	char model[3];
-};
-
-static struct tape_descr *viotape_unitinfo;
-static dma_addr_t viotape_unitinfo_token;
+static struct {
+	const char *rsrcname;
+	const char *type;
+	const char *model;
+} viotape_unitinfo[VIOTAPE_MAX_TAPE];
 
 static struct mtget viomtget[VIOTAPE_MAX_TAPE];
 
@@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
 	return -err->errno;
 }
 
-/* Get info on all tapes from OS/400 */
-static int get_viotape_info(void)
-{
-	HvLpEvent_Rc hvrc;
-	int i;
-	size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
-	struct op_struct *op = get_op_struct();
-
-	if (op == NULL)
-		return -ENOMEM;
-
-	viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
-		GFP_ATOMIC);
-	if (viotape_unitinfo == NULL) {
-		free_op_struct(op);
-		return -ENOMEM;
-	}
-
-	memset(viotape_unitinfo, 0, len);
-
-	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
-			HvLpEvent_Type_VirtualIo,
-			viomajorsubtype_tape | viotapegetinfo,
-			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
-			viopath_sourceinst(viopath_hostLp),
-			viopath_targetinst(viopath_hostLp),
-			(u64) (unsigned long) op, VIOVERSION << 16,
-			viotape_unitinfo_token, len, 0, 0);
-	if (hvrc != HvLpEvent_Rc_Good) {
-		printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
-				(int)hvrc);
-		free_op_struct(op);
-		return -EIO;
-	}
-
-	wait_for_completion(&op->com);
-
-	free_op_struct(op);
-
-	for (i = 0;
-	     ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
-	     i++)
-		viotape_numdev++;
-	return 0;
-}
-
-
 /* Write */
 static ssize_t viotap_write(struct file *file, const char *buf,
 		size_t count, loff_t * ppos)
@@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
 	tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
 	op = (struct op_struct *)event->xCorrelationToken;
 	switch (tapeminor) {
-	case viotapegetinfo:
 	case viotapeopen:
 	case viotapeclose:
 		op->rc = tevent->sub_type_result;
@@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 {
 	int i = vdev->unit_address;
 	int j;
+	struct device_node *node = vdev->dev.archdata.of_node;
 
-	if (i >= viotape_numdev)
+	if (i > VIOTAPE_MAX_TAPE)
+		return -ENODEV;
+	if (!node)
 		return -ENODEV;
 
+	if (i >= viotape_numdev)
+		viotape_numdev = i + 1;
+
 	tape_device[i] = &vdev->dev;
+	viotape_unitinfo[i].rsrcname = of_get_property(node,
+					"linux,vio_rsrcname", NULL);
+	viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
+					NULL);
+	viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
+					NULL);
 
 	state[i].cur_part = 0;
 	for (j = 0; j < MAX_PARTITIONS; ++j)
@@ -1044,11 +964,6 @@ int __init viotap_init(void)
 		goto unreg_chrdev;
 	}
 
-	if ((ret = get_viotape_info()) < 0) {
-		printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
-		goto unreg_class;
-	}
-
 	ret = vio_register_driver(&viotape_driver);
 	if (ret)
 		goto unreg_class;
@@ -1102,9 +1017,6 @@ static void __exit viotap_exit(void)
 	vio_unregister_driver(&viotape_driver);
 	class_destroy(tape_class);
 	unregister_chrdev(VIOTAPE_MAJOR, "viotape");
-	if (viotape_unitinfo)
-		iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
-				viotape_unitinfo, viotape_unitinfo_token);
 	viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
 	vio_clearHandler(viomajorsubtype_tape);
 	clear_op_struct_pool();
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index e5a405b..2555dfd 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -75,6 +75,47 @@ enum viocdsubtype {
 	viocdcheck = 0x0007
 };
 
+struct viotapelpevent {
+	struct HvLpEvent event;
+	u32 reserved;
+	u16 version;
+	u16 sub_type_result;
+	u16 tape;
+	u16 flags;
+	u32 token;
+	u64 len;
+	union {
+		struct {
+			u32 tape_op;
+			u32 count;
+		} op;
+		struct {
+			u32 type;
+			u32 resid;
+			u32 dsreg;
+			u32 gstat;
+			u32 erreg;
+			u32 file_no;
+			u32 block_no;
+		} get_status;
+		struct {
+			u32 block_no;
+		} get_pos;
+	} u;
+};
+
+enum viotapesubtype {
+	viotapeopen = 0x0001,
+	viotapeclose = 0x0002,
+	viotaperead = 0x0003,
+	viotapewrite = 0x0004,
+	viotapegetinfo = 0x0005,
+	viotapeop = 0x0006,
+	viotapegetpos = 0x0007,
+	viotapesetpos = 0x0008,
+	viotapegetstatus = 0x0009
+};
+
 /*
  * Each subtype can register a handler to process their events.
  * The handler must have this interface.
-- 
1.5.3.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox