* Re: [PATCH 4/5] Relocation support
From: Mohan Kumar M @ 2008-08-13 18:22 UTC (permalink / raw)
To: Paul Mackerras; +Cc: ppcdev, miltonm
In-Reply-To: <18594.28433.827798.249177@cargo.ozlabs.ibm.com>
Paul Mackerras wrote:
> Mohan Kumar M writes:
>
Hi Paul,
Thanks for your comments.
I will update the patches as per your comment and will give a detailed
description for each patch.
Regards,
Mohan.
>
>> static inline int in_kernel_text(unsigned long addr)
>> {
>> - if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end)
>> + if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end
>> + + kernel_base)
>
> Your patch adds kernel_base to some addresses but not to all of them,
> so your patch description should have told us why you added it in the
> those places and not others. If you tell us the general principle
> you're following (even if it seems obvious to you) it will be useful
> to people chasing bugs or adding new code later on, or even just
> trying to understand what the code does.
>
>> - RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
>> +#ifndef CONFIG_RELOCATABLE_PPC64
>> + RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000);
>> +#else
>> + RELOC(alloc_bottom) = PAGE_ALIGN((unsigned long)&RELOC(_end) + 0x4000 +
>> + RELOC(reloc_delta));
>> +#endif
>
> Ifdefs in code inside a function are frowned upon in the Linux
> kernel. Try to find an alternative way to do this, such as ensuring
> that reloc_delta is 0 when CONFIG_RELOCATABLE_PPC64 is not set.
> Also it's not clear (to me at least) why you need to add reloc_data in
> the relocatable case.
>
>> +#ifndef CONFIG_RELOCATABLE_PPC64
>> unsigned long *spinloop
>> = (void *) LOW_ADDR(__secondary_hold_spinloop);
>> unsigned long *acknowledge
>> = (void *) LOW_ADDR(__secondary_hold_acknowledge);
>> +#else
>> + unsigned long *spinloop
>> + = (void *) &__secondary_hold_spinloop;
>> + unsigned long *acknowledge
>> + = (void *) &__secondary_hold_acknowledge;
>> +#endif
>
> This also needs some explanation. (Put it in the patch description or
> in a comment in the code, not in a reply to this mail. :)
>
>> +#ifndef CONFIG_RELOCATABLE_PPC64
>> ld r4,htab_hash_mask@got(2)
>> +#else
>> + LOAD_REG_IMMEDIATE(r4,htab_hash_mask)
>> +#endif
>> ld r27,0(r4) /* htab_hash_mask -> r27 */
>
> Here and in the other similar places, I would prefer you just changed
> it to LOAD_REG_ADDR and not have any ifdef.
>
> Paul.
^ permalink raw reply
* Re: libfdt: Implement fdt_get_property_namelen() and fdt_getprop_namelen()
From: Jon Loeliger @ 2008-08-13 18:09 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20080806045049.GC6690@yookeroo.seuss>
> As well as fdt_subnode_offset(), libfdt includes an
> fdt_subnode_offset_namelen() function that takes the subnode name to
> look up not as a NUL-terminated string, but as a string with an
> explicit length. This can be useful when the caller has the name as
> part of a longer string, such as a full path.
>
> However, we don't have corresponding 'namelen' versions for
> fdt_get_property() and fdt_getprop(). There are less obvious use
> cases for these variants on property names, but there are
> circumstances where they can be useful e.g. looking up property names
> which need to be parsed from a longer string buffer such as user input
> or a configuration file, or looking up an alias in a path with
> IEEE1275 style aliases.
>
> So, since it's very easy to implement such variants, this patch does
> so. The original NUL-terminated variants are, of course, implemented
> in terms of the namelen versions.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Applied.
jdl
^ permalink raw reply
* Re: dtc: Make many functions 'static'
From: Jon Loeliger @ 2008-08-13 18:09 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev, devicetree-discuss
In-Reply-To: <20080804053013.GC7086@yookeroo.seuss>
> This patch marks various functions not shared between c files
> 'static', as they should be. There are a couple of functions in dtc,
> and many in the testsuite.
>
> This is *almost* enough to enable the -Wmissing-prototypes warning.
> It's not quite enough, because there's a mess of junk in the flex
> generated code which triggers that warning which I'm not yet sure how
> to deal with.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Applied.
jdl
^ permalink raw reply
* use plb_tft_cntlr_ref_d meet the problem
From: killyouatonce @ 2008-08-13 17:25 UTC (permalink / raw)
To: Linuxppc-dev
Has anybody add the plb_tft_cntlr_ref to the desgin ? I add
the pcores whcih copy from slideshow which is a reference desgin.
>
> Something is wrong. I show the image in my design , the plb_tft_cnt=
lr_ref ip core is works ,but it not work very well . The image shows in t=
he lcd is fuzzy. The problem is not the software , beacause it use some sof=
tware as reference desgin.
The image in the reference desgin is clear=EF=BC=8Cbut it fuzzy in my =
design .Why ???
Many Thanks
^ permalink raw reply
* use plb_tft_cntlr_ref_d meet the problem
From: yanlong wang @ 2008-08-13 17:17 UTC (permalink / raw)
To: linuxppc-embedded
ICAgICBIYXMgYW55Ym9keSBhZGQgdGhlIHBsYl90ZnRfY250bHJfcmVmICB0byB0aGUgZGVzZ2lu
ID8gSSBhZGQKdGhlIHBjb3JlcyB3aGNpaCBjb3B5IGZyb20gc2xpZGVzaG93IHdoaWNoIGlzIGEg
cmVmZXJlbmNlIGRlc2dpbi4KPgo+ICAgICBTb21ldGhpbmcgaXMgIHdyb25nLiBJIHNob3cgdGhl
ICBpbWFnZSBpbiBteSBkZXNpZ24gLCB0aGUgcGxiX3RmdF9jbnRscl9yZWYgIGlwIGNvcmUgaXMg
d29ya3MgLGJ1dCBpdCAgbm90IHdvcmsgdmVyeSB3ZWxsIC4gVGhlIGltYWdlIHNob3dzIGluIHRo
ZSBsY2QgaXMgZnV6enkuIFRoZSBwcm9ibGVtIGlzIG5vdCB0aGUgc29mdHdhcmUgLCBiZWFjYXVz
ZSBpdCB1c2Ugc29tZSBzb2Z0d2FyZSBhcyByZWZlcmVuY2UgZGVzZ2luLgogICAgIFRoZSBpbWFn
ZSBpbiB0aGUgcmVmZXJlbmNlIGRlc2dpbiBpcyBjbGVhcqOsYnV0IGl0IGZ1enp5IGluIG15CmRl
c2lnbiAuV2h5ID8/PwogTWFueSBUaGFua3MK
^ permalink raw reply
* RE: ml507 initrd problem
From: John Linn @ 2008-08-13 16:43 UTC (permalink / raw)
To: Stu Bershtein, linuxppc-embedded
In-Reply-To: <8BB04FAC749BD24BBA250E9D09F2F18B220AD6@MAIL-SJC.quantum3d.com>
[-- Attachment #1: Type: text/plain, Size: 7712 bytes --]
Stu,
I'm assuming you're using arch/powerpc. The command line we use in the
device tree file, arch/powerpc/boot/dts/ml507.dts, is bootargs =
"console=ttyS0 ip=on root=/dev/ram";
It sounds like you're getting console output til it switches from kernel
to user in the ram disk, but your message is a little confusing on that.
You should expect the shell output to be on the same serial port at the
same baud rate as the boot output of the kernel.
Yes the ML507 uses the 9 pin serial connector at 9600 baud.
We have removed the linux_support*.gz file when I put the bit streams
and ram disk on the wiki site. If you have these files you have
everything.
You should be able to following the directions on the wiki site to get a
baseline working, although I didn't specifically say on the wiki to put
the ram disk image in the boot directory before you build or the make
command line.
The ram disk on our site should work correctly if you are using our
kernel with the default configuration, ml507_defconfig. I always advice
people to get a good baseline with our stuff then make changes after you
see if baselined.
-- John
________________________________
From: Stu Bershtein [mailto:sbershtein@Quantum3D.com]
Sent: Wednesday, August 13, 2008 9:34 AM
To: John Linn; linuxppc-embedded@ozlabs.org
Subject: RE: ml507 initrd problem
Morning John,
Thanks for the tip. Running said ramdisk things certainly look lively,
I'll add a list of opens that I see at boot up at the bottom of this
email. Looks like it's opening a shell and everything and yet I see no
serial communication from the shell, just quiet. Am I correct to expect
the console to be the serial port (9pin DB) on the ml507 board at 9600
baud? Also, if you could spare a desperate person a moment, could you
send me the boot command line that you use for testing with the ramdisk?
Finally, another member of this form suggested that there is a fully
build BSP (rootfs and all) available as 'linux_support.tar.gz' on the
Xilinx site. Are you familiar with this? I tried locating it a few
days ago to no avail.
Thanks very much for your help!
Stu
Freeing unused kernel memory: 144k init
open /dev/console
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfdb9f00
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
open /dev/console
open /dev/console
open /etc/TZ
open /etc/inittab
open /dev/console
open /etc/TZ
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfd65eb0
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
open /etc/rc.sh
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfef2ea0
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
open /etc/mtab
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bf9a8e90
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
code 10000000 - 10039640, data 10039000 - 10039640, stack bfa47e70
open /lib/libm.so.0
open /lib/libcrypt.so.0
open /lib/libc.so.0
open /dev/null
open /tmp/xinetd.pid
open /etc/xinetd.conf
open /etc/xinetd.d
open /dev/console
open /etc/TZ
open /etc/xinetd.d/ftpd
open /dev/console
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfda3ea0
open /etc/TZ
open /etc/TZ
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bf9c5ec0
open /etc/passwd
open /etc/xinetd.d/telnet
open /lib/libcrypt.so.0
open /etc/TZ
open /lib/libm.so.0
open /lib/libcrypt.so.0
open /etc/passwd
open /lib/libc.so.0
open /lib/libm.so.0
open /etc/protocols
open /bin/application
open /lib/libc.so.0
open /etc/services
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bffa9ea0
open .profile
open /etc/services
open /etc/profile
open /etc/protocols
open /etc/passwd
open /etc/services
open /lib/libcrypt.so.0
open /etc/services
open /lib/libm.so.0
open /etc/TZ
open /lib/libc.so.0
open /etc/TZ
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfaa5eb0
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
________________________________
From: John Linn [mailto:John.Linn@xilinx.com]
Sent: Wednesday, August 13, 2008 7:11 AM
To: Stu Bershtein; linuxppc-embedded@ozlabs.org
Subject: RE: ml507 initrd problem
Hi Stu,
I realize you are trying to get your own ram disk to work, but if you
want to get a baseline you can use one we have on our wiki site, at
http://xilinx.wikidot.com/open-source-linux, under Files To Download.
This is the same ram disk that is included in the ELDK.
This is the ram disk that I use to test the ML507 design in our Git
tree. I also use NFS a lot for testing.
Looks like you're close with yours, but I'm certainly no expert in that
area as I typically have something that works and don't change it.
Good luck,
John
________________________________
From: linuxppc-embedded-bounces+john.linn=xilinx.com@ozlabs.org
[mailto:linuxppc-embedded-bounces+john.linn=xilinx.com@ozlabs.org] On
Behalf Of Stu Bershtein
Sent: Tuesday, August 12, 2008 5:28 PM
To: linuxppc-embedded@ozlabs.org
Subject: ml507 initrd problem
I have been trying to boot linux on an ml507 board for a few days now.
I am using xilinx's linux-2.6-xlnx.git kernel. The rootfs is home
rolled. I have had experience with NFS mounted root filesystems (not an
option here), cramfs, and romfs but have never tried running root out of
a ramdisk. Because of that I am quite sure I have dorked this up. Any
help will be appreciated! I have added printk's in the kernel at
do_sys_open to get an idea what is going on. Here is a snip of the boot
output:
.
Kernel command line: console=ttyS0,9600 ip=on init=/linuxrc
root=/dev/ram rw ram disk_size=9000
.
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing
disabled 83e00000.serial: ttyS0 at MMIO 0x83e00003 (irq = 16) is a
16550A
.
eth0: XLlTemac: Send Threshold = 0, Receive Threshold = 0
eth0: XLlTemac: Send Wait bound = 0, Receive Wait bound = 0
IP-Config: Incomplete network configuration information.
open /dev/ram
fd 0
open /initrd.image
fd 1
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem).
Freeing unused kernel memory: 144k init
open /dev/console
fd 0
code 10000000 - 1019854c, data 10195000 - 1019854c, stack bf85df00
open /dev/null
fd 3
open /etc/inittab
fd 3
And it gets very quiet at that point. The kernel is still running in
ppc44x_idle. Does this suggest anything to anyone? I'll be more than
happy to send or describe any config files to any one who might take
pity.
Thanks,
Stu
This email and any attachments are intended for the sole use of the
named recipient(s) and contain(s) confidential information that may be
proprietary, privileged or copyrighted under applicable law. If you are
not the intended recipient, do not read, copy, or forward this email
message or any attachments. Delete this email message and any
attachments immediately.
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
[-- Attachment #2: Type: text/html, Size: 35080 bytes --]
^ permalink raw reply
* Re: [PATCH 5121 pci 1/3] powerpc: 83xx: pci: Remove need for get_immrbase from mpc83xx_add_bridge.
From: John Rigby @ 2008-08-13 16:30 UTC (permalink / raw)
To: Grant Likely; +Cc: Scott Wood, linuxppc-dev, Kumar Gala
In-Reply-To: <fa686aa40808130923q2ef7d4b7ha5a9225ce0afd061@mail.gmail.com>
Grant Likely wrote:
> On Wed, Aug 13, 2008 at 10:06 AM, John Rigby <jrigby@freescale.com> wrote:
>
>>> On Thu, Aug 07, 2008 at 11:36:25AM -0600, John Rigby wrote:
>>> Can you use something like 'fsl,primary-pci-bridge' instead? 'primary'
>>> is a little too generic for my taste. Also, the purpose of identifying
>>> one of the PCI bridges as primary should be documented (This is me
>>> pushing against encoding Linux internal implementation details into the
>>> device tree, I suspect that 'primary' doesn't belong in the device tree
>>> at all).
>>>
>>>
>> Ok, I got the primary idea from sam440ep.dts, I'm willing to do something
>> different.
>>
>> I have thought about adding an is_primary argument to mpc83xx_add_bridge
>> like fsl_add_bridge has and make the callers figure out which is primary.
>>
>> The simple case is the platform that have only one bus:
>> for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
>> fsl_add_bridge(np, 1);
>>
>> Callers with multiple bridges do something like this:
>> for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
>> struct resource rsrc;
>> of_address_to_resource(np, 0, &rsrc);
>> if ((rsrc.start & 0xfffff) == 0x8000)
>> fsl_add_bridge(np, 1);
>> else
>> fsl_add_bridge(np, 0);
>> }
>>
>> So now we are using hardcoded offsets again.
>>
>
> Go with the hardcoded offset. Linux is broken, so the workaround
> should be in Linux code until Linux PCI code is fixed.
>
> g.
>
>
Ok, I'll leave the offset checking in mpc83xx_add_bridge rather than
having it duplicated in the eight different callers.
^ permalink raw reply
* Re: [PATCH 5121 pci 1/3] powerpc: 83xx: pci: Remove need for get_immrbase from mpc83xx_add_bridge.
From: Grant Likely @ 2008-08-13 16:23 UTC (permalink / raw)
To: John Rigby; +Cc: Scott Wood, linuxppc-dev, Kumar Gala
In-Reply-To: <48A3068F.20409@freescale.com>
On Wed, Aug 13, 2008 at 10:06 AM, John Rigby <jrigby@freescale.com> wrote:
>> On Thu, Aug 07, 2008 at 11:36:25AM -0600, John Rigby wrote:
>> Can you use something like 'fsl,primary-pci-bridge' instead? 'primary'
>> is a little too generic for my taste. Also, the purpose of identifying
>> one of the PCI bridges as primary should be documented (This is me
>> pushing against encoding Linux internal implementation details into the
>> device tree, I suspect that 'primary' doesn't belong in the device tree
>> at all).
>>
>
> Ok, I got the primary idea from sam440ep.dts, I'm willing to do something
> different.
>
> I have thought about adding an is_primary argument to mpc83xx_add_bridge
> like fsl_add_bridge has and make the callers figure out which is primary.
>
> The simple case is the platform that have only one bus:
> for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
> fsl_add_bridge(np, 1);
>
> Callers with multiple bridges do something like this:
> for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
> struct resource rsrc;
> of_address_to_resource(np, 0, &rsrc);
> if ((rsrc.start & 0xfffff) == 0x8000)
> fsl_add_bridge(np, 1);
> else
> fsl_add_bridge(np, 0);
> }
>
> So now we are using hardcoded offsets again.
Go with the hardcoded offset. Linux is broken, so the workaround
should be in Linux code until Linux PCI code is fixed.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH 5121 pci 1/3] powerpc: 83xx: pci: Remove need for get_immrbase from mpc83xx_add_bridge.
From: Grant Likely @ 2008-08-13 16:20 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Kumar Gala, John Rigby
In-Reply-To: <48A30772.4030508@freescale.com>
On Wed, Aug 13, 2008 at 10:10 AM, Scott Wood <scottwood@freescale.com> wrote:
> John Rigby wrote:
>>
>> As I type this I'm coming to like the primary flag more and more.
>> I'm willing to change it to 'fsl,primary-pci-bridge' though I don't
>> really agree with your argument against the generic name. It is in
>> the context of an 'fsl,pci-whatever' node so it does not have to be
>> specific.
>
> It *does* have to be specific; what if "primary" comes to mean something
> else in a broader context?
exactly
>> And maybe generic is good, a universal generic solution would be to
>> require all primary pci nodes to have the property then
>> pci_process_bridge_OF_ranges could get it out of the device node
>> instead of having it passed in.
>
> The "universal generic solution" would be to encode legacy I/O devices in
> the device tree, and fix Linux to not assume that they're all on one bus.
... So my argument is; since Linux is broken in this regard, hard code
the fix into the device driver and don't pollute the device tree with
stuff that doesn't actually describe the hardware. In this case,
primary is entirely a Linux internal implementation detail that will
change in the future.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH 5121 pci 1/3] powerpc: 83xx: pci: Remove need for get_immrbase from mpc83xx_add_bridge.
From: Scott Wood @ 2008-08-13 16:10 UTC (permalink / raw)
To: John Rigby; +Cc: linuxppc-dev, Kumar Gala
In-Reply-To: <48A3068F.20409@freescale.com>
John Rigby wrote:
> As I type this I'm coming to like the primary flag more and more.
> I'm willing to change it to 'fsl,primary-pci-bridge' though I don't
> really agree with your argument against the generic name. It is in
> the context of an 'fsl,pci-whatever' node so it does not have to be
> specific.
It *does* have to be specific; what if "primary" comes to mean something
else in a broader context?
> And maybe generic is good, a universal generic solution would be to
> require all primary pci nodes to have the property then
> pci_process_bridge_OF_ranges could get it out of the device node
> instead of having it passed in.
The "universal generic solution" would be to encode legacy I/O devices
in the device tree, and fix Linux to not assume that they're all on one bus.
If we must have a property, how about something like "pci-legacy-io"?
-Scott
^ permalink raw reply
* Re: [PATCH 5121 pci 1/3] powerpc: 83xx: pci: Remove need for get_immrbase from mpc83xx_add_bridge.
From: John Rigby @ 2008-08-13 16:06 UTC (permalink / raw)
To: Grant Likely, kim.phillips, Kumar Gala, Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080813050924.GD17587@secretlab.ca>
Grant Likely wrote:
> On Thu, Aug 07, 2008 at 11:36:25AM -0600, John Rigby wrote:
>
>> Modify mpc83xx_add_bridge to get config space register base address from the device
>> tree instead of immr + hardcoded offset.
>>
>> 83xx pci nodes have these changes:
>> register properties now contain two address length tuples:
>> First is the pci bridge register base, this has always been there.
>> Second is the config base, this is new.
>> The primary pci bus should have the "primary" property.
>>
>> These are documented in Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt
>>
>
> Looks mostly good to me. I only have one comment on the device tree
> binding...
>
>
>> diff --git a/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt b/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt
>> new file mode 100644
>> index 0000000..51214a0
>> --- /dev/null
>> +++ b/Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt
>> @@ -0,0 +1,43 @@
>> +* Freescale 83xx and 512x PCI bridges
>> +
>> +Freescale 83xx and 512x SOCs include the same pci bridge core.
>> +
>> +83xx/512x specific notes:
>> +- reg: should contain two address length tuples
>> + The first is for the internal pci bridge registers
>> + The second is for the pci config space access registers
>> +- primary:
>> + This property should be present for the primary pci bridge
>>
>
> Can you use something like 'fsl,primary-pci-bridge' instead? 'primary'
> is a little too generic for my taste. Also, the purpose of identifying
> one of the PCI bridges as primary should be documented (This is me
> pushing against encoding Linux internal implementation details into the
> device tree, I suspect that 'primary' doesn't belong in the device tree
> at all).
>
Ok, I got the primary idea from sam440ep.dts, I'm willing to do
something different.
I have thought about adding an is_primary argument to mpc83xx_add_bridge
like fsl_add_bridge has and make the callers figure out which is primary.
The simple case is the platform that have only one bus:
for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
fsl_add_bridge(np, 1);
Callers with multiple bridges do something like this:
for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
struct resource rsrc;
of_address_to_resource(np, 0, &rsrc);
if ((rsrc.start & 0xfffff) == 0x8000)
fsl_add_bridge(np, 1);
else
fsl_add_bridge(np, 0);
}
So now we are using hardcoded offsets again.
As I type this I'm coming to like the primary flag more and more. I'm
willing to change it to 'fsl,primary-pci-bridge' though I don't really
agree with your argument against the generic name. It is in the context
of an 'fsl,pci-whatever' node so it does not have to be specific. And
maybe generic is good, a universal generic solution would be to require
all primary pci nodes to have the property then
pci_process_bridge_OF_ranges could get it out of the device node instead
of having it passed in.
I would like to hear what the 83xx folks think about this.
John
>
^ permalink raw reply
* RE: ml507 initrd problem
From: Stu Bershtein @ 2008-08-13 15:33 UTC (permalink / raw)
To: John Linn, linuxppc-embedded
In-Reply-To: <20080813141107.92D4B948071@mail62-wa4.bigfish.com>
[-- Attachment #1: Type: text/plain, Size: 5919 bytes --]
Morning John,
Thanks for the tip. Running said ramdisk things certainly look lively,
I'll add a list of opens that I see at boot up at the bottom of this
email. Looks like it's opening a shell and everything and yet I see no
serial communication from the shell, just quiet. Am I correct to expect
the console to be the serial port (9pin DB) on the ml507 board at 9600
baud? Also, if you could spare a desperate person a moment, could you
send me the boot command line that you use for testing with the ramdisk?
Finally, another member of this form suggested that there is a fully
build BSP (rootfs and all) available as 'linux_support.tar.gz' on the
Xilinx site. Are you familiar with this? I tried locating it a few
days ago to no avail.
Thanks very much for your help!
Stu
Freeing unused kernel memory: 144k init
open /dev/console
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfdb9f00
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
open /dev/console
open /dev/console
open /etc/TZ
open /etc/inittab
open /dev/console
open /etc/TZ
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfd65eb0
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
open /etc/rc.sh
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfef2ea0
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
open /etc/mtab
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bf9a8e90
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
code 10000000 - 10039640, data 10039000 - 10039640, stack bfa47e70
open /lib/libm.so.0
open /lib/libcrypt.so.0
open /lib/libc.so.0
open /dev/null
open /tmp/xinetd.pid
open /etc/xinetd.conf
open /etc/xinetd.d
open /dev/console
open /etc/TZ
open /etc/xinetd.d/ftpd
open /dev/console
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfda3ea0
open /etc/TZ
open /etc/TZ
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bf9c5ec0
open /etc/passwd
open /etc/xinetd.d/telnet
open /lib/libcrypt.so.0
open /etc/TZ
open /lib/libm.so.0
open /lib/libcrypt.so.0
open /etc/passwd
open /lib/libc.so.0
open /lib/libm.so.0
open /etc/protocols
open /bin/application
open /lib/libc.so.0
open /etc/services
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bffa9ea0
open .profile
open /etc/services
open /etc/profile
open /etc/protocols
open /etc/passwd
open /etc/services
open /lib/libcrypt.so.0
open /etc/services
open /lib/libm.so.0
open /etc/TZ
open /lib/libc.so.0
open /etc/TZ
code 10000000 - 1009c134, data 1009a128 - 1009c134, stack bfaa5eb0
open /lib/libcrypt.so.0
open /lib/libm.so.0
open /lib/libc.so.0
________________________________
From: John Linn [mailto:John.Linn@xilinx.com]
Sent: Wednesday, August 13, 2008 7:11 AM
To: Stu Bershtein; linuxppc-embedded@ozlabs.org
Subject: RE: ml507 initrd problem
Hi Stu,
I realize you are trying to get your own ram disk to work, but if you
want to get a baseline you can use one we have on our wiki site, at
http://xilinx.wikidot.com/open-source-linux, under Files To Download.
This is the same ram disk that is included in the ELDK.
This is the ram disk that I use to test the ML507 design in our Git
tree. I also use NFS a lot for testing.
Looks like you're close with yours, but I'm certainly no expert in that
area as I typically have something that works and don't change it.
Good luck,
John
________________________________
From: linuxppc-embedded-bounces+john.linn=xilinx.com@ozlabs.org
[mailto:linuxppc-embedded-bounces+john.linn=xilinx.com@ozlabs.org] On
Behalf Of Stu Bershtein
Sent: Tuesday, August 12, 2008 5:28 PM
To: linuxppc-embedded@ozlabs.org
Subject: ml507 initrd problem
I have been trying to boot linux on an ml507 board for a few days now.
I am using xilinx's linux-2.6-xlnx.git kernel. The rootfs is home
rolled. I have had experience with NFS mounted root filesystems (not an
option here), cramfs, and romfs but have never tried running root out of
a ramdisk. Because of that I am quite sure I have dorked this up. Any
help will be appreciated! I have added printk's in the kernel at
do_sys_open to get an idea what is going on. Here is a snip of the boot
output:
.
Kernel command line: console=ttyS0,9600 ip=on init=/linuxrc
root=/dev/ram rw ram disk_size=9000
.
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing
disabled 83e00000.serial: ttyS0 at MMIO 0x83e00003 (irq = 16) is a
16550A
.
eth0: XLlTemac: Send Threshold = 0, Receive Threshold = 0
eth0: XLlTemac: Send Wait bound = 0, Receive Wait bound = 0
IP-Config: Incomplete network configuration information.
open /dev/ram
fd 0
open /initrd.image
fd 1
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem).
Freeing unused kernel memory: 144k init
open /dev/console
fd 0
code 10000000 - 1019854c, data 10195000 - 1019854c, stack bf85df00
open /dev/null
fd 3
open /etc/inittab
fd 3
And it gets very quiet at that point. The kernel is still running in
ppc44x_idle. Does this suggest anything to anyone? I'll be more than
happy to send or describe any config files to any one who might take
pity.
Thanks,
Stu
This email and any attachments are intended for the sole use of the
named recipient(s) and contain(s) confidential information that may be
proprietary, privileged or copyrighted under applicable law. If you are
not the intended recipient, do not read, copy, or forward this email
message or any attachments. Delete this email message and any
attachments immediately.
[-- Attachment #2: Type: text/html, Size: 29974 bytes --]
^ permalink raw reply
* facing problem with io_p2v() function
From: Misbah khan @ 2008-08-13 15:31 UTC (permalink / raw)
To: linuxppc-embedded
Hi all,
I am using io_p2v() function in my driver to get the virtual address mapping
timer control registers
i am passing address as 0x48304024 as base and after getting the virtual
address of it i am reading and writing to it but my any attempt to read the
location or write is giving segmentation fault
If i use __pa() to read the corresponding location it returning as
0x98304024 insted of 0x48304024
I dont know where the mapping is going wrong
Even when i tried using ioremap() i got the same kernel panic
Below is the error message
-------------------------------------------------------------------------------------------------------
In init function
Read reg address virt 0xd8304024 and phy 0x98304024 are
Unhandled fault: external abort on non-linefetch (0x1028) at 0xd8304024
Internal error: : 1028 [#1]
Modules linked in: omap_timer
CPU: 0 Not tainted (2.6.22.1-omap3 #1)
PC is at omap_timer_read_register+0x30/0x3c [omap_timer]
LR is at release_console_sem+0x1c0/0x1d4
pc : [<bf000160>] lr : [<c005f650>] psr: 60000013
sp : c7f1bea0 ip : c7f1bdd8 fp : c7f1beb4
r10: c8858000 r9 : 00000026 r8 : 00000027
r7 : c06dfdf0 r6 : 00000000 r5 : bf001018 r4 : 00000024
r3 : d8304000 r2 : 00000000 r1 : 60000013 r0 : 0000003d
Flags: nZCv IRQs on FIQs on Mode SVC_32 Segment user
Control: 00c5387f Table: 80694018 DAC: 00000015
Process insmod (pid: 306, stack limit = 0xc7f1a2d0)
Stack: (0xc7f1bea0 to 0xc7f1c000)
bea0: 00000000 bf001018 c7f1bed4 c7f1beb8 bf0001c4 bf00013c 00000000
bf001280
bec0: bf001100 c06dfdf0 c7f1bef4 c7f1bed8 bf0030c4 bf0001b0 00000000
c006b5c4
bee0: c06dfdc4 c06dfc00 c7f1bfa4 c7f1bef8 c007f514 bf00300c 00000000
c0024380
bf00: 000ce008 00000000 00000000 00000000 00000000 00000000 00000000
00000000
bf20: 00000000 00000000 00000000 00000000 00000000 00000000 c886ca30
c07fc200
bf40: 00000000 c8867c88 c88678f0 00000000 00000054 00000054 0000000a
c886758f
bf60: c8867cd8 bf00110c c8867cb0 00000024 00000000 c035da98 c0030184
000a81fc
bf80: bebf5d74 00014cdd 00000080 c0029f68 c7f1a000 00000000 00000000
c7f1bfa8
bfa0: c0029dc0 c007e1d8 000a81fc bebf5d74 000ce018 00014cdd 000ce008
00000001
bfc0: 000a81fc bebf5d74 00014cdd 00000080 00000000 bebf5d74 bebf5e54
00000061
bfe0: bebf5a20 bebf5a10 0001e1c0 401d2ec0 60000010 000ce018 00000017
0011b8d8
Backtrace:
[<bf000130>] (omap_timer_read_register+0x0/0x3c [omap_timer]) from
[<bf0001c4>] (omap_dm_timer_set_l
oad+0x20/0x5c [omap_timer])
r5:bf001018 r4:00000000
[<bf0001a4>] (omap_dm_timer_set_load+0x0/0x5c [omap_timer]) from
[<bf0030c4>] (omap_gp_timer_init_mo
de+0xc4/0xf0 [omap_timer])
r7:c06dfdf0 r6:bf001100 r5:bf001280 r4:00000000
[<bf003000>] (omap_gp_timer_init_mode+0x0/0xf0 [omap_timer]) from
[<c007f514>] (sys_init_module+0x13
48/0x1400)
r5:c06dfc00 r4:c06dfdc4
[<c007e1cc>] (sys_init_module+0x0/0x1400) from [<c0029dc0>]
(ret_fast_syscall+0x0/0x2c)
Code: e1a01003 e59f000c eb417e8b e5953010 (e7930004)
Segmentation fault
-----------------------------------------------------------------------------------------------------------
Looking forward for the suggestion for the above problem
----- Misbah <><
--
View this message in context: http://www.nabble.com/facing-problem-with-io_p2v%28%29-function-tp18965524p18965524.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* Re: [RFC/PATCH 2/3] of: add of_lookup_stdout() utility function
From: Timur Tabi @ 2008-08-13 14:32 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, paulus, miltonm
In-Reply-To: <20080813054121.GG17587@secretlab.ca>
Grant Likely wrote:
> So, seeing as settling on a way to determine stdout still up in the air,
> it probably makes sense to condense that code down to a single
> authoritative function so that changes in this area are contained in one
> place. For now, I'll stick with decoding linux,stdout-path and on Sparc
> decoding the ihandle with the expectation that there will be further
> refinements to be made.
Ack.
--
Timur Tabi
Linux Kernel Developer @ Freescale
^ permalink raw reply
* RE: ml507 initrd problem
From: John Linn @ 2008-08-13 14:11 UTC (permalink / raw)
To: Stu Bershtein, linuxppc-embedded
In-Reply-To: <8BB04FAC749BD24BBA250E9D09F2F18B220ABB@MAIL-SJC.quantum3d.com>
[-- Attachment #1: Type: text/plain, Size: 2821 bytes --]
Hi Stu,
I realize you are trying to get your own ram disk to work, but if you
want to get a baseline you can use one we have on our wiki site, at
http://xilinx.wikidot.com/open-source-linux, under Files To Download.
This is the same ram disk that is included in the ELDK.
This is the ram disk that I use to test the ML507 design in our Git
tree. I also use NFS a lot for testing.
Looks like you're close with yours, but I'm certainly no expert in that
area as I typically have something that works and don't change it.
Good luck,
John
________________________________
From: linuxppc-embedded-bounces+john.linn=xilinx.com@ozlabs.org
[mailto:linuxppc-embedded-bounces+john.linn=xilinx.com@ozlabs.org] On
Behalf Of Stu Bershtein
Sent: Tuesday, August 12, 2008 5:28 PM
To: linuxppc-embedded@ozlabs.org
Subject: ml507 initrd problem
I have been trying to boot linux on an ml507 board for a few days now.
I am using xilinx's linux-2.6-xlnx.git kernel. The rootfs is home
rolled. I have had experience with NFS mounted root filesystems (not an
option here), cramfs, and romfs but have never tried running root out of
a ramdisk. Because of that I am quite sure I have dorked this up. Any
help will be appreciated! I have added printk's in the kernel at
do_sys_open to get an idea what is going on. Here is a snip of the boot
output:
.
Kernel command line: console=ttyS0,9600 ip=on init=/linuxrc
root=/dev/ram rw ram disk_size=9000
.
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing
disabled 83e00000.serial: ttyS0 at MMIO 0x83e00003 (irq = 16) is a
16550A
.
eth0: XLlTemac: Send Threshold = 0, Receive Threshold = 0
eth0: XLlTemac: Send Wait bound = 0, Receive Wait bound = 0
IP-Config: Incomplete network configuration information.
open /dev/ram
fd 0
open /initrd.image
fd 1
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem).
Freeing unused kernel memory: 144k init
open /dev/console
fd 0
code 10000000 - 1019854c, data 10195000 - 1019854c, stack bf85df00
open /dev/null
fd 3
open /etc/inittab
fd 3
And it gets very quiet at that point. The kernel is still running in
ppc44x_idle. Does this suggest anything to anyone? I'll be more than
happy to send or describe any config files to any one who might take
pity.
Thanks,
Stu
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
[-- Attachment #2: Type: text/html, Size: 11962 bytes --]
^ permalink raw reply
* Re: [BUG] fec_mpc52xx: Don't call mpc52xx_fec_reset() in ISR
From: Wolfgang Grandegger @ 2008-08-13 14:12 UTC (permalink / raw)
To: Juergen Beisert; +Cc: linuxppc-dev, Wolfram Sang, domen.puncer
In-Reply-To: <200808131548.11813.jbe@pengutronix.de>
Hi Jürgen,
Juergen Beisert wrote:
> On Donnerstag, 10. Juli 2008, Grant Likely wrote:
>> On Thu, Jul 10, 2008 at 02:39:09PM +0200, Wolfram Sang wrote:
>>> Hello,
>>>
>>> today, I was debugging a kernel crash on a board with a MPC5200B using
>>> 2.6.26-rc9. I found the following code in drivers/net/fec_mpc52xx.c:
>> <snip>
>>
>>> I assume the proper thing to do is to set a flag in the ISR and handle
>>> the soft reset later in some other context. Having never dealt with the
>>> network core and its drivers so far, I am not sure which place would be
>>> the right one to perform the soft reset. To not make things worse, I
>>> hope people with more insight to network stuff can deliver a suitable
>>> solution to this problem.
>> Thanks for the bug report. I'll take a look.
>
> Some update:
>
> Enabling XLB pipelining let occure this error less often. Kernel disables this
> feature by default yet.
> The comment talks about "cfr errate 292." that is valid for MPC5200A, but
> _it_seems_ no longer for MPC5200B. Has anybody experience if we can enabling
> pipelining on MPC5200B CPUs without triggering this bug?
No, I haven't...
> We currently are playing with this setting:
>
> Index: arch/powerpc/platforms/52xx/mpc52xx_common.c
> ===================================================================
> --- arch/powerpc/platforms/52xx/mpc52xx_common.c.orig
> +++ arch/powerpc/platforms/52xx/mpc52xx_common.c
> @@ -99,11 +99,11 @@
> out_be32(&xlb->master_pri_enable, 0xff);
> out_be32(&xlb->master_priority, 0x11111111);
>
> - /* Disable XLB pipelining
> - * (cfr errate 292. We could do this only just before ATA PIO
> - * transaction and re-enable it afterwards ...)
> + /*
> + * Enable pipelining, fixes FEC problems. The previous workaround seems
> + * not needed, as we have an MPC5200B (not A).
> */
> - out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
> + out_be32(&xlb->config, in_be32(&xlb->config) & ~MPC52xx_XLB_CFG_PLDIS);
>
> iounmap(xlb);
> }
...but I prepared a patch to do the reset in the process context. Would be
nice if you could give the patch below a try.
Wolfgang.
===================================================================
From: Wolfgang Grandegger <wg@grandegger.com>
Subject: [PATCH] powerpc: fec_mpc52xx: Don't call mpc52xx_fec_reset() in ISR
Calling mpc52xx_fec_reset() in the ISR is a bug. This patch puts a task
for resetting the FEC into the kernel-global workqueue to be processed
lateron savely in process context.
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
drivers/net/fec_mpc52xx.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
Index: linux-2.6.26/drivers/net/fec_mpc52xx.c
===================================================================
--- linux-2.6.26.orig/drivers/net/fec_mpc52xx.c
+++ linux-2.6.26/drivers/net/fec_mpc52xx.c
@@ -24,6 +24,7 @@
#include <linux/crc32.h>
#include <linux/hardirq.h>
#include <linux/delay.h>
+#include <linux/workqueue.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
@@ -57,6 +58,8 @@ struct mpc52xx_fec_priv {
struct bcom_task *tx_dmatsk;
spinlock_t lock;
int msg_enable;
+ struct work_struct reset_task;
+ struct net_device *ndev;
/* MDIO link details */
int phy_addr;
@@ -83,6 +86,19 @@ static int debug = -1; /* the above defa
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "debugging messages level");
+static void mpc52xx_fec_reset_task(struct work_struct *work)
+{
+ struct mpc52xx_fec_priv *priv =
+ container_of(work, struct mpc52xx_fec_priv, reset_task);
+ struct net_device *dev = priv->ndev;
+
+ dev_warn(&dev->dev, "deferred FEC reset due to errors\n");
+
+ mpc52xx_fec_reset(dev);
+
+ netif_wake_queue(dev);
+}
+
static void mpc52xx_fec_tx_timeout(struct net_device *dev)
{
dev_warn(&dev->dev, "transmit timed out\n");
@@ -355,6 +371,8 @@ static int mpc52xx_fec_close(struct net_
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+ flush_scheduled_work();
+
netif_stop_queue(dev);
mpc52xx_fec_stop(dev);
@@ -522,9 +540,9 @@ static irqreturn_t mpc52xx_fec_interrupt
if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
- mpc52xx_fec_reset(dev);
-
- netif_wake_queue(dev);
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+ schedule_work(&priv->reset_task);
return IRQ_HANDLED;
}
@@ -934,7 +952,9 @@ mpc52xx_fec_probe(struct of_device *op,
priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
- spin_lock_init(&priv->lock);
+ priv->ndev = ndev;
+ spin_lock_init(&priv->lock);
+ INIT_WORK(&priv->reset_task, mpc52xx_fec_reset_task);
/* ioremap the zones */
priv->fec = ioremap(mem.start, sizeof(struct mpc52xx_fec));
@@ -1068,6 +1088,9 @@ mpc52xx_fec_remove(struct of_device *op)
ndev = dev_get_drvdata(&op->dev);
priv = netdev_priv(ndev);
+ if (netif_running(ndev))
+ mpc52xx_fec_close(ndev);
+
unregister_netdev(ndev);
irq_dispose_mapping(ndev->irq);
^ permalink raw reply
* Re: [BUG] fec_mpc52xx: Don't call mpc52xx_fec_reset() in ISR
From: Juergen Beisert @ 2008-08-13 13:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Wolfram Sang, domen.puncer
In-Reply-To: <20080710153101.GD446@secretlab.ca>
On Donnerstag, 10. Juli 2008, Grant Likely wrote:
> On Thu, Jul 10, 2008 at 02:39:09PM +0200, Wolfram Sang wrote:
> > Hello,
> >
> > today, I was debugging a kernel crash on a board with a MPC5200B using
> > 2.6.26-rc9. I found the following code in drivers/net/fec_mpc52xx.c:
>
> <snip>
>
> > I assume the proper thing to do is to set a flag in the ISR and handle
> > the soft reset later in some other context. Having never dealt with the
> > network core and its drivers so far, I am not sure which place would be
> > the right one to perform the soft reset. To not make things worse, I
> > hope people with more insight to network stuff can deliver a suitable
> > solution to this problem.
>
> Thanks for the bug report. I'll take a look.
Some update:
Enabling XLB pipelining let occure this error less often. Kernel disables t=
his=20
feature by default yet.
The comment talks about "cfr errate 292." that is valid for MPC5200A, but=20
_it_seems_ no longer for MPC5200B. Has anybody experience if we can enablin=
g=20
pipelining on MPC5200B CPUs without triggering this bug?
We currently are playing with this setting:
Index: arch/powerpc/platforms/52xx/mpc52xx_common.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2D-- arch/powerpc/platforms/52xx/mpc52xx_common.c.orig
+++ arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -99,11 +99,11 @@
out_be32(&xlb->master_pri_enable, 0xff);
out_be32(&xlb->master_priority, 0x11111111);
=20
=2D /* Disable XLB pipelining
=2D * (cfr errate 292. We could do this only just before ATA PIO
=2D * transaction and re-enable it afterwards ...)
+ /*
+ * Enable pipelining, fixes FEC problems. The previous workaround seems
+ * not needed, as we have an MPC5200B (not A).
*/
=2D out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
+ out_be32(&xlb->config, in_be32(&xlb->config) & ~MPC52xx_XLB_CFG_PLDIS);
=20
iounmap(xlb);
}
jbe
=2D-=20
Dipl.-Ing. Juergen Beisert | http://www.pengutronix.de
=A0Pengutronix - Linux Solutions for Science and Industry
=A0 Handelsregister: Amtsgericht Hildesheim, HRA 2686
=A0 =A0 =A0 Vertretung Sued/Muenchen, Germany
Phone: +49-8766-939 228 | Fax: +49-5121-206917-9
^ permalink raw reply
* Re: details, details ...
From: Arnd Bergmann @ 2008-08-13 13:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Kevin Diggs
In-Reply-To: <48A2CD2A.5020107@hypersurf.com>
On Wednesday 13 August 2008, Kevin Diggs wrote:
> In cpu exit function of a cpufreq driver:
>=20
> =A0 =A0 =A0 =A0 =A0while (test_bit(cf750gxmChangingPllBit, &cf750gxvState=
Bits))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msleep(1);
>=20
> This bit will get cleared by a notifier callback.
>=20
> In module_exit function of a related module:
>=20
> =A0 =A0 =A0 =A0 =A0while (test_bit(PLL_LOCK_BIT, (unsigned long *)&boot_r=
atio)) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0msleep(1);
> =A0 =A0 =A0 =A0 =A0}
>=20
> This bit will get cleared by a timer. It will also fire the notifiers=20
> needed above.
>=20
> I don't think these are in interrupt context. The sleeps ok here?
Technically ok, but not nice. Besides the coding style issues,
it's still a busy loop that should be replaced by wait_for_completion().
> Also, from checkpatch:
>=20
> ERROR: do not initialise externals to 0 or NULL
> #2483: FILE: arch/powerpc/kernel/cpu/pll_if.c:486:
> +int rval =3D 0;
>=20
> ERROR: do not initialise statics to 0 or NULL
> #2058: FILE: arch/powerpc/kernel/cpu/pll_if.c:61:
> +static unsigned int override_bus_clock =3D 0;
>=20
> Huh? What? Anyone care to teach an old dog a new trick???
Don't bother. Old gcc variants would put these variables into .data
instead of .bss, but with a new (less than 5 years or so) gcc, both
will result in .bss storage that is initialized to zero at boot time.
Arnd <><
^ permalink raw reply
* details, details ...
From: Kevin Diggs @ 2008-08-13 12:01 UTC (permalink / raw)
To: linuxppc-dev
Hi,
In cpu exit function of a cpufreq driver:
while (test_bit(cf750gxmChangingPllBit, &cf750gxvStateBits))
msleep(1);
This bit will get cleared by a notifier callback.
In module_exit function of a related module:
while (test_bit(PLL_LOCK_BIT, (unsigned long *)&boot_ratio)) {
msleep(1);
}
This bit will get cleared by a timer. It will also fire the notifiers
needed above.
I don't think these are in interrupt context. The sleeps ok here?
Also, from checkpatch:
ERROR: do not initialise externals to 0 or NULL
#2483: FILE: arch/powerpc/kernel/cpu/pll_if.c:486:
+int rval = 0;
ERROR: do not initialise statics to 0 or NULL
#2058: FILE: arch/powerpc/kernel/cpu/pll_if.c:61:
+static unsigned int override_bus_clock = 0;
Huh? What? Anyone care to teach an old dog a new trick???
kevin
^ permalink raw reply
* Re: Help
From: Arnd Bergmann @ 2008-08-13 12:02 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Boris Shteinbock
In-Reply-To: <136898.86066.qm@web50608.mail.re2.yahoo.com>
On Wednesday 13 August 2008, Boris Shteinbock wrote:
> Help
Don't panic!
^ permalink raw reply
* Help
From: Boris Shteinbock @ 2008-08-13 9:26 UTC (permalink / raw)
To: linuxppc-dev
Help
^ permalink raw reply
* Re: Mounting PRAMFS support
From: Pieter @ 2008-08-13 9:30 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-embedded
In-Reply-To: <20080812181138.BEF53248BF@gemini.denx.de>
[-- Attachment #1.1: Type: text/plain, Size: 8213 bytes --]
Hi Wolfgang
thanks for your quick reply. Below i have placed the boot message,
Another question I have that might help is that in DULG section 5.10
where the environmental variable "pram" is defined, the documentation
states "If the "Protected RAM" feature is enabled in your board's
configuration"
Is the PRAMFS support built in and available when CONFIG_PRAM and the
"pram" environmental variable is defined in the board config or are
there other elements to be configured or activated on the linux side
aswell?. (mpc8548 board using ELDK 4.1 ppc_85xx)
The boot message:
U-Boot 1.2.0 (Aug 12 2008 - 16:21:15)
CPU: 8548_E, Version: 1.1, (0x80390011)
Core: E500, Version: 1.0, (0x80210010)
Clock Configuration:
CPU: 990 MHz, CCB: 396 MHz,
DDR: 198 MHz, LBC: 49 MHz
L1: D-cache 32 kB enabled
I-cache 32 kB enabled
Board: Equus MPC8548
PCI1: 64 bit, 66 MHz, sync
I2C: ready
DRAM: Initializing
DDR: 512 MB
FLASH: 128 MB
L2 cache 512KB: enabled
*** Warning - bad CRC, using default environment
BIE:
serial number = EQ_0002
build level = EQUUS-1.1
set ethaddr to 00:50:C2:52:50:FC
set eth1addr to 00:50:C2:52:50:FD
set eth2addr to 00:50:C2:52:50:FE
set bootsrc to factory
Running boot diagnostics
In: serial
Out: serial
Err: serial
Net: eTSEC0, eTSEC1, eTSEC2
boot count loaded 1
boot count stored 2
Hit any key to stop autoboot: 0
### CRAMFS loading '/boot/uImage' to 0x200000
### CRAMFS load complete: 1067930 bytes loaded to 0x200000
## Booting image at 00200000 ...
Image Name: Linux-2.6.19.2
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 1067866 Bytes = 1 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Memory CAM mapping: CAM0=256Mb, CAM1=64Mb, CAM2=64Mb residual: 64Mb
Linux version 2.6.19.2 (root@sdh-ts2) (gcc version 4.0.0 (DENX ELDK 4.1
4.0.0)) #1 Tue Aug 12 15:56:47 SAST 2008
Zone PFN ranges:
DMA 0 -> 98304
Normal 98304 -> 98304
early_node_map[1] active PFN ranges
0: 0 -> 98304
Built 1 zonelists. Total pages: 97536
Kernel command line: root=/dev/mtdblock0 ro console=ttyS0,115200 mem=458752k
OpenPIC Version 1.2 (1 CPUs and 60 IRQ sources) at fcfbb000
PID hash table entries: 2048 (order: 11, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 387328k available (1712k kernel code, 500k data, 136k init, 0k
highmem)
Mount-cache hash table entries: 512
NET: Registered protocol family 16
PCI: Probing PCI hardware
PCI: Cannot allocate resource region 0 of device 0000:00:00.0
PCI: Cannot allocate resource region 1 of device 0000:00:00.0
PCI: Failed to allocate mem resource #1:80000000@0 for 0000:00:00.0
Generic PHY: Registered new driver
NET: Registered protocol family 2
IP route cache hash table entries: 4096 (order: 2, 16384 bytes)
TCP established hash table entries: 16384 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 16384 bind 8192)
TCP reno registered
JFFS2 version 2.2. (NAND) (C) 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Generic RTC Driver v1.07
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0xe0004500 (irq = 26) is a 16550A
serial8250.0: ttyS1 at MMIO 0xe0004600 (irq = 26) is a 16550A
RAMDISK driver initialized: 16 RAM disks of 32768K size 1024 blocksize
loop: loaded (max 8 devices)
Gianfar MII Bus: probed
eth0: Gianfar Ethernet Controller Version 1.2(MW), 00:50:c2:52:50:fc
eth0: Running with NAPI enabled
eth0: 256/1024 RX/TX BD ring size
eth1: Gianfar Ethernet Controller Version 1.2(MW), 00:50:c2:52:50:fd
eth1: Running with NAPI enabled
eth1: 256/1024 RX/TX BD ring size
eth2: Gianfar Ethernet Controller Version 1.2(MW), 00:50:c2:52:50:fe
eth2: Running with NAPI enabled
eth2: 256/1024 RX/TX BD ring size
Cicada Cis8204: Registered new driver
Cicada Cis8201: Registered new driver
0: Found 2 x16 devices at 0x0 in 32-bit bank
Amd/Fujitsu Extended Query Table at 0x0040
0: CFI does not contain boot bank location. Assuming top.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
Equus flash bank 0: Using static image bank1 partition definition
Creating 9 MTD partitions on "0":
0x00000000-0x01000000 : "factory-image"
mtd: Giving out device 0 to factory-image
0x01000000-0x02000000 : "app-image-1"
mtd: Giving out device 1 to app-image-1
0x02000000-0x03000000 : "app-image-2"
mtd: Giving out device 2 to app-image-2
0x03000000-0x04000000 : "jffs2"
mtd: Giving out device 3 to jffs2
0x04000000-0x05000000 : "testing"
mtd: Giving out device 4 to testing
0x05000000-0x07f40000 : "reserved"
mtd: Giving out device 5 to reserved
0x07f40000-0x07f80000 : "u-boot-env"
mtd: Giving out device 6 to u-boot-env
0x07f80000-0x08000000 : "u-boot-app"
mtd: Giving out device 7 to u-boot-app
0x00000000-0x08000000 : "all"
mtd: Giving out device 8 to all
i2c /dev entries driver
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
VFS: Mounted root (cramfs filesystem) readonly.
Freeing unused kernel memory: 136k init
INIT: version 2.85 booting
$Mounting /dev/mtdblock2 to /usr/config
jffs2 Mount Sucsesfull. Checking config files
cron.daily file missing - Copy from defaults
cron.hourly file missing - Copy from defaults
cron.weekly file missing - Copy from defaults
ifcfg-eth0 file exist - Skipping
ifcfg-eth1 file exist - Skipping
ifcfg-eth2 file exist - Skipping
logrotate.conf file exist - Skipping
ntp.conf file exist - Skipping
resolv.conf file exist - Skipping
syslog.conf file exist - Skipping
$ Welcome to $DENX Embedded$ Linux Environment
$ VAStech SDH Gateway
$ Press 'I' to enter interactive startup.
$ done[ $OK ]
$Setting clock : Thu Jan 1 00:00:01 UTC 1970 [ $OK ]
$Setting hostname sdh-gateway: [ $OK ]
$Mounting local filesystems: [ $OK ]
INIT: Entering runlevel: 3
current directory/etc/sysconfig/network-scripts
$Bringing up loopback interface: Hardware Address
[ $OK ]
$Bringing up interface eth0: Hardware Address
[ $OK ]
$Bringing up interface eth1: Hardware Address
[ $OK ]
$Bringing up interface eth2: Hardware Address
[ $OK ]
$Starting system logger: [ $OK ]
$Starting kernel logger: [ $OK ]
$Starting xinetd: [ $OK ]
$Starting ntpd: [ $OK ]
$Starting periodic command scheduler : [ $OK ]
DENX ELDK version 4.0 build 2006-01-12
Linux 2.6.19.2 on a ppc
When i then try to mount the PRAMFS i get the following:
sh\$ mount -t pramfs -o physaddr=0x1c000000,init=0x4000000 none /tmp/test/
mount: mounting none on /tmp/test/ failed: No such device
sh\$
I might be missing something simple. There are no recent documentation
regarding PRAMFS is it still suported or has it been abandoned?
thanks for your time Pieter
Wolfgang Denk wrote:
> Dear Pieter,
>
> In message <48A15FC3.3060008@vastech.co.za> you wrote:
>
>> Im using a ppc85xx processor with Denx ELDK (4.1) The board has 512MB
>> DDR2 and the board config reserves 64M for pram. during bootup the
>> mem=$mem argument is passed to the linux kernel command line and linux
>> boots successfully.
>>
>
> So what are the exact boot messages of your kernel?
>
>
>> I am unable to mount the PRAMFS - all documentation leads me to use
>>
>> mount -t pramfs -o physaddr=0x1c000000,init=0x4000000 none /mnt
>>
> -------------------------------------------------------------^^^^
>
>> witch fails with the message:
>> mounting none on /mtd failed: no such devise
>>
> -------------------^^^^
>
> /mnt != /mtd
>
--------------^^^^
This was a typo
> There is something worng, probably your description. It would be
> better if you showed the precise commands and outpout from your
> target system.
>
> Best regards,
>
> Wolfgang Denk
>
>
--
Pieter Henning
VASTech
Tel: +27 (0)21 850 5921
Fax: +27 (0)86 503 8941
e-mail: phenning@vastech.co.za
[-- Attachment #1.2: Type: text/html, Size: 10831 bytes --]
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/x-pkcs7-signature, Size: 2722 bytes --]
^ permalink raw reply
* Re: [PATCH]: [MPC5200] Add ATA DMA support
From: Tim Yamin @ 2008-08-13 9:07 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20080813061135.GH17587@secretlab.ca>
[-- Attachment #1: Type: text/plain, Size: 268 bytes --]
On Wed, Aug 13, 2008 at 7:11 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> Sounds good to me. You will get more testers that way. I can pick it
> up for -next if everything else looks good.
Here are the new patches; tested against 2.6.27-rc3.
Thanks,
Tim
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bestcomm-ata-fixes.patch --]
[-- Type: text/x-diff; name=bestcomm-ata-fixes.patch, Size: 4212 bytes --]
1) ata.h has dst_pa in the wrong place (needs to match what the BestComm
task microcode in bcom_ata_task.c expects); fix it.
2) The BestComm ATA task priority was changed to maximum in bestcomm_priv.h;
this fixes a deadlock issue I was experiencing when heavy DMA was
occuring on both the ATA and Ethernet BestComm tasks, e.g. when
downloading a large file over a LAN to disk.
3) The ATA BestComm driver uses bcom_ata_bd which is bigger than bcom_bd
and this causes problems because the various bcom_... functions do not
dereference the correct location. I've introduced bcom_get_bd which
uses bcom_task.bd_size and this fixes the problem.
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
diff -urp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/ata.h linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/ata.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/ata.h 2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/ata.h 2008-07-03 16:17:05.000000000 +0100
@@ -16,8 +16,8 @@
struct bcom_ata_bd {
u32 status;
- u32 dst_pa;
u32 src_pa;
+ u32 dst_pa;
};
extern struct bcom_task *
diff -urp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.h linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm.h 2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm.h 2008-07-03 16:17:05.000000000 +0100
@@ -38,7 +38,7 @@ struct bcom_task {
unsigned int flags;
int irq;
- struct bcom_bd *bd;
+ void *bd;
phys_addr_t bd_pa;
void **cookie;
unsigned short index;
@@ -140,15 +140,29 @@ bcom_queue_full(struct bcom_task *tsk)
}
/**
+ * bcom_get_bd - Get a BD from the queue
+ * @tsk: The BestComm task structure
+ * index: Index of the BD to fetch
+ */
+static inline struct bcom_bd
+*bcom_get_bd(struct bcom_task *tsk, unsigned int index)
+{
+ return tsk->bd + index * tsk->bd_size;
+}
+
+/**
* bcom_buffer_done - Checks if a BestComm
* @tsk: The BestComm task structure
*/
static inline int
bcom_buffer_done(struct bcom_task *tsk)
{
+ struct bcom_bd *bd;
if (bcom_queue_empty(tsk))
return 0;
- return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
+
+ bd = bcom_get_bd(tsk, tsk->outdex);
+ return !(bd->status & BCOM_BD_READY);
}
/**
@@ -160,16 +174,21 @@ bcom_buffer_done(struct bcom_task *tsk)
static inline struct bcom_bd *
bcom_prepare_next_buffer(struct bcom_task *tsk)
{
- tsk->bd[tsk->index].status = 0; /* cleanup last status */
- return &tsk->bd[tsk->index];
+ struct bcom_bd *bd;
+
+ bd = bcom_get_bd(tsk, tsk->index);
+ bd->status = 0; /* cleanup last status */
+ return bd;
}
static inline void
bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
{
+ struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
+
tsk->cookie[tsk->index] = cookie;
mb(); /* ensure the bd is really up-to-date */
- tsk->bd[tsk->index].status |= BCOM_BD_READY;
+ bd->status |= BCOM_BD_READY;
tsk->index = _bcom_next_index(tsk);
if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
bcom_enable(tsk);
@@ -179,10 +198,12 @@ static inline void *
bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
{
void *cookie = tsk->cookie[tsk->outdex];
+ struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
+
if (p_status)
- *p_status = tsk->bd[tsk->outdex].status;
+ *p_status = bd->status;
if (p_bd)
- *p_bd = &tsk->bd[tsk->outdex];
+ *p_bd = bd;
tsk->outdex = _bcom_next_outdex(tsk);
return cookie;
}
diff -urp linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
--- linux-2.6.26-rc6/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h 2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.26-rc6-ata/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h 2008-07-03 16:17:05.000000000 +0100
@@ -198,8 +198,8 @@ struct bcom_task_header {
#define BCOM_IPR_SCTMR_1 2
#define BCOM_IPR_FEC_RX 6
#define BCOM_IPR_FEC_TX 5
-#define BCOM_IPR_ATA_RX 4
-#define BCOM_IPR_ATA_TX 3
+#define BCOM_IPR_ATA_RX 7
+#define BCOM_IPR_ATA_TX 7
#define BCOM_IPR_SCPCI_RX 2
#define BCOM_IPR_SCPCI_TX 2
#define BCOM_IPR_PSC3_RX 2
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: pata_mpc52xx-add-dma.patch --]
[-- Type: text/x-diff; name=pata_mpc52xx-add-dma.patch, Size: 18055 bytes --]
This patch adds MDMA/UDMA support (using BestComm for DMA) on the MPC5200
platform. Patch requires the ATA BestComm fixes to function properly.
Based heavily on previous work by Freescale (Bernard Kuhn, John Rigby)
and Domen Puncer.
Using a SanDisk Extreme IV CF card I get read speeds of approximately
26.70 MB/sec.
Comments and testing would of course be very welcome.
Thanks,
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
diff -urp linux-2.6.27-rc3/arch/powerpc/sysdev/bestcomm/bestcomm.c linux-2.6.27-rc3-ata/arch/powerpc/sysdev/bestcomm/bestcomm.c
--- linux-2.6.27-rc3/arch/powerpc/sysdev/bestcomm/bestcomm.c 2008-04-17 03:49:44.000000000 +0100
+++ linux-2.6.27-rc3-ata/arch/powerpc/sysdev/bestcomm/bestcomm.c 2008-07-03 16:17:05.000000000 +0100
@@ -330,11 +330,16 @@ bcom_engine_init(void)
/* Init 'always' initiator */
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
+ /* If ATA DMA is enabled, always turn prefetch off (it breaks things) */
+#ifndef CONFIG_PATA_MPC52xx_DMA
/* Disable COMM Bus Prefetch on the original 5200; it's broken */
if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
+#endif
regval = in_be16(&bcom_eng->regs->PtdCntrl);
out_be16(&bcom_eng->regs->PtdCntrl, regval | 1);
+#ifndef CONFIG_PATA_MPC52xx_DMA
}
+#endif
/* Init lock */
spin_lock_init(&bcom_eng->lock);
diff -urp linux-2.6.27-rc3/drivers/ata/Kconfig linux-2.6.27-rc3-ata/drivers/ata/Kconfig
--- linux-2.6.27-rc3/drivers/ata/Kconfig 2008-07-03 13:06:35.000000000 +0100
+++ linux-2.6.27-rc3-ata/drivers/ata/Kconfig 2008-07-03 16:16:32.000000000 +0100
@@ -462,6 +462,15 @@ config PATA_MPC52xx
If unsure, say N.
+config PATA_MPC52xx_DMA
+ bool "Freescale MPC52xx SoC internal IDE DMA (Experimental)"
+ depends on PATA_MPC52xx
+ help
+ This option enables support for DMA on the MPC52xx SoC PATA
+ controller.
+
+ If unsure, say N.
+
config PATA_MPIIX
tristate "Intel PATA MPIIX support"
depends on PCI
diff -urp linux-2.6.27-rc3/drivers/ata/pata_mpc52xx.c linux-2.6.27-rc3-ata/drivers/ata/pata_mpc52xx.c
--- linux-2.6.27-rc3/drivers/ata/pata_mpc52xx.c 2008-07-03 13:06:35.000000000 +0100
+++ linux-2.6.27-rc3-ata/drivers/ata/pata_mpc52xx.c 2008-07-03 16:16:32.000000000 +0100
@@ -6,6 +6,9 @@
* Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
*
+ * UDMA support based on patches by Freescale (Bernard Kuhn, John Rigby),
+ * Domen Puncer and Tim Yamin.
+ *
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
@@ -17,28 +20,47 @@
#include <linux/delay.h>
#include <linux/libata.h>
#include <linux/of_platform.h>
+#include <asm/cacheflush.h>
#include <asm/types.h>
#include <asm/prom.h>
#include <asm/mpc52xx.h>
+#include <sysdev/bestcomm/bestcomm.h>
+#include <sysdev/bestcomm/bestcomm_priv.h>
+#include <sysdev/bestcomm/ata.h>
#define DRV_NAME "mpc52xx_ata"
#define DRV_VERSION "0.1.2"
-
/* Private structures used by the driver */
struct mpc52xx_ata_timings {
u32 pio1;
u32 pio2;
+ u32 mdma1;
+ u32 mdma2;
+ u32 udma1;
+ u32 udma2;
+ u32 udma3;
+ u32 udma4;
+ u32 udma5;
+ int using_udma;
};
struct mpc52xx_ata_priv {
unsigned int ipb_period;
struct mpc52xx_ata __iomem * ata_regs;
+ phys_addr_t ata_regs_pa;
int ata_irq;
struct mpc52xx_ata_timings timings[2];
int csel;
+
+ /* DMA */
+ struct bcom_task *dmatsk;
+ const struct udmaspec *udmaspec;
+ const struct mdmaspec *mdmaspec;
+ int mpc52xx_ata_dma_last_write;
+ int waiting_for_dma;
};
@@ -53,6 +75,107 @@ static const int ataspec_ta[5] = { 35
#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
+/* ======================================================================== */
+
+/* ATAPI-4 MDMA specs (in clocks) */
+struct mdmaspec {
+ u32 t0M;
+ u32 td;
+ u32 th;
+ u32 tj;
+ u32 tkw;
+ u32 tm;
+ u32 tn;
+};
+
+static const struct mdmaspec mdmaspec66[3] = {
+ { .t0M = 32, .td = 15, .th = 2, .tj = 2, .tkw = 15, .tm = 4, .tn = 1 },
+ { .t0M = 10, .td = 6, .th = 1, .tj = 1, .tkw = 4, .tm = 2, .tn = 1 },
+ { .t0M = 8, .td = 5, .th = 1, .tj = 1, .tkw = 2, .tm = 2, .tn = 1 },
+};
+
+static const struct mdmaspec mdmaspec132[3] = {
+ { .t0M = 64, .td = 29, .th = 3, .tj = 3, .tkw = 29, .tm = 7, .tn = 2 },
+ { .t0M = 20, .td = 11, .th = 2, .tj = 1, .tkw = 7, .tm = 4, .tn = 1 },
+ { .t0M = 16, .td = 10, .th = 2, .tj = 1, .tkw = 4, .tm = 4, .tn = 1 },
+};
+
+/* ATAPI-4 UDMA specs (in clocks) */
+struct udmaspec {
+ u32 tcyc;
+ u32 t2cyc;
+ u32 tds;
+ u32 tdh;
+ u32 tdvs;
+ u32 tdvh;
+ u32 tfs;
+ u32 tli;
+ u32 tmli;
+ u32 taz;
+ u32 tzah;
+ u32 tenv;
+ u32 tsr;
+ u32 trfs;
+ u32 trp;
+ u32 tack;
+ u32 tss;
+};
+
+static const struct udmaspec udmaspec66[6] = {
+ { .tcyc = 8, .t2cyc = 16, .tds = 1, .tdh = 1, .tdvs = 5, .tdvh = 1,
+ .tfs = 16, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
+ .tsr = 3, .trfs = 5, .trp = 11, .tack = 2, .tss = 4,
+ },
+ { .tcyc = 5, .t2cyc = 11, .tds = 1, .tdh = 1, .tdvs = 4, .tdvh = 1,
+ .tfs = 14, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
+ .tsr = 2, .trfs = 5, .trp = 9, .tack = 2, .tss = 4,
+ },
+ { .tcyc = 4, .t2cyc = 8, .tds = 1, .tdh = 1, .tdvs = 3, .tdvh = 1,
+ .tfs = 12, .tli = 10, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
+ .tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
+ },
+ { .tcyc = 3, .t2cyc = 6, .tds = 1, .tdh = 1, .tdvs = 2, .tdvh = 1,
+ .tfs = 9, .tli = 7, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
+ .tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
+ },
+ { .tcyc = 2, .t2cyc = 4, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
+ .tfs = 8, .tli = 8, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
+ .tsr = 2, .trfs = 4, .trp = 7, .tack = 2, .tss = 4,
+ },
+ { .tcyc = 2, .t2cyc = 2, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
+ .tfs = 6, .tli = 5, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
+ .tsr = 2, .trfs = 4, .trp = 6, .tack = 2, .tss = 4,
+ },
+};
+
+static const struct udmaspec udmaspec132[6] = {
+ { .tcyc = 15, .t2cyc = 31, .tds = 2, .tdh = 1, .tdvs = 10, .tdvh = 1,
+ .tfs = 30, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
+ .tsr = 7, .trfs = 10, .trp = 22, .tack = 3, .tss = 7,
+ },
+ { .tcyc = 10, .t2cyc = 21, .tds = 2, .tdh = 1, .tdvs = 7, .tdvh = 1,
+ .tfs = 27, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
+ .tsr = 4, .trfs = 10, .trp = 17, .tack = 3, .tss = 7,
+ },
+ { .tcyc = 6, .t2cyc = 12, .tds = 1, .tdh = 1, .tdvs = 5, .tdvh = 1,
+ .tfs = 23, .tli = 20, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
+ .tsr = 3, .trfs = 8, .trp = 14, .tack = 3, .tss = 7,
+ },
+ { .tcyc = 7, .t2cyc = 12, .tds = 1, .tdh = 1, .tdvs = 3, .tdvh = 1,
+ .tfs = 15, .tli = 13, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
+ .tsr = 3, .trfs = 8, .trp = 14, .tack = 3, .tss = 7,
+ },
+ { .tcyc = 2, .t2cyc = 5, .tds = 0, .tdh = 0, .tdvs = 1, .tdvh = 1,
+ .tfs = 16, .tli = 14, .tmli = 2, .taz = 1, .tzah = 2, .tenv = 2,
+ .tsr = 2, .trfs = 7, .trp = 13, .tack = 2, .tss = 6,
+ },
+ { .tcyc = 3, .t2cyc = 6, .tds = 1, .tdh = 1, .tdvs = 1, .tdvh = 1,
+ .tfs = 12, .tli = 10, .tmli = 3, .taz = 2, .tzah = 3, .tenv = 3,
+ .tsr = 3, .trfs = 7, .trp = 12, .tack = 3, .tss = 7,
+ },
+};
+
+/* ======================================================================== */
/* Bit definitions inside the registers */
#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
@@ -66,6 +189,7 @@ static const int ataspec_ta[5] = { 35
#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */
#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */
+#define MPC52xx_ATA_FIFOSTAT_ERROR 0x40 /* FIFO Error */
#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */
#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */
@@ -75,6 +199,8 @@ static const int ataspec_ta[5] = { 35
#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */
#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
+#define MAX_DMA_BUFFERS 128
+#define MAX_DMA_BUFFER_SIZE 0x20000u
/* Structure of the hardware registers */
struct mpc52xx_ata {
@@ -165,6 +294,41 @@ mpc52xx_ata_compute_pio_timings(struct m
return 0;
}
+static int
+mpc52xx_ata_compute_mdma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+ struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+ const struct mdmaspec *s = &priv->mdmaspec[speed];
+
+ if (speed < 0 || speed > 2)
+ return -EINVAL;
+
+ timing->mdma1 = (s->t0M << 24) | (s->td << 16) | (s->tkw << 8) | (s->tm);
+ timing->mdma2 = (s->th << 24) | (s->tj << 16) | (s->tn << 8);
+ timing->using_udma = 0;
+
+ return 0;
+}
+
+static int
+mpc52xx_ata_compute_udma_timings(struct mpc52xx_ata_priv *priv, int dev, int speed)
+{
+ struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+ const struct udmaspec *s = &priv->udmaspec[speed];
+
+ if (speed < 0 || speed > 2)
+ return -EINVAL;
+
+ timing->udma1 = (s->t2cyc << 24) | (s->tcyc << 16) | (s->tds << 8) | (s->tdh);
+ timing->udma2 = (s->tdvs << 24) | (s->tdvh << 16) | (s->tfs << 8) | (s->tli);
+ timing->udma3 = (s->tmli << 24) | (s->taz << 16) | (s->tenv << 8) | (s->tsr);
+ timing->udma4 = (s->tss << 24) | (s->trfs << 16) | (s->trp << 8) | (s->tack);
+ timing->udma5 = (s->tzah << 24);
+ timing->using_udma = 1;
+
+ return 0;
+}
+
static void
mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
{
@@ -173,14 +337,13 @@ mpc52xx_ata_apply_timings(struct mpc52xx
out_be32(®s->pio1, timing->pio1);
out_be32(®s->pio2, timing->pio2);
- out_be32(®s->mdma1, 0);
- out_be32(®s->mdma2, 0);
- out_be32(®s->udma1, 0);
- out_be32(®s->udma2, 0);
- out_be32(®s->udma3, 0);
- out_be32(®s->udma4, 0);
- out_be32(®s->udma5, 0);
-
+ out_be32(®s->mdma1, timing->mdma1);
+ out_be32(®s->mdma2, timing->mdma2);
+ out_be32(®s->udma1, timing->udma1);
+ out_be32(®s->udma2, timing->udma2);
+ out_be32(®s->udma3, timing->udma3);
+ out_be32(®s->udma4, timing->udma4);
+ out_be32(®s->udma5, timing->udma5);
priv->csel = device;
}
@@ -245,6 +408,29 @@ mpc52xx_ata_set_piomode(struct ata_port
mpc52xx_ata_apply_timings(priv, adev->devno);
}
static void
+mpc52xx_ata_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ int rv;
+
+ if (adev->dma_mode >= XFER_UDMA_0) {
+ int dma = adev->dma_mode - XFER_UDMA_0;
+ rv = mpc52xx_ata_compute_udma_timings(priv, adev->devno, dma);
+ } else {
+ int dma = adev->dma_mode - XFER_MW_DMA_0;
+ rv = mpc52xx_ata_compute_mdma_timings(priv, adev->devno, dma);
+ }
+
+ if (rv) {
+ dev_alert(ap->dev,
+ "Trying to select invalid DMA mode %d\n",
+ adev->dma_mode);
+ return;
+ }
+
+ mpc52xx_ata_apply_timings(priv, adev->devno);
+}
+static void
mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
{
struct mpc52xx_ata_priv *priv = ap->host->private_data;
@@ -255,16 +441,187 @@ mpc52xx_ata_dev_select(struct ata_port *
ata_sff_dev_select(ap,device);
}
+static int
+mpc52xx_ata_build_dmatable(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE), si;
+ struct scatterlist *sg;
+ int count = 0;
+
+ if (read)
+ bcom_ata_rx_prepare(priv->dmatsk);
+ else
+ bcom_ata_tx_prepare(priv->dmatsk);
+
+ for_each_sg(qc->sg, sg, qc->n_elem, si) {
+ dma_addr_t cur_addr = sg_dma_address(sg);
+ u32 cur_len = sg_dma_len(sg);
+
+ while (cur_len) {
+ unsigned int tc = min(cur_len, MAX_DMA_BUFFER_SIZE);
+ struct bcom_ata_bd *bd = (struct bcom_ata_bd *) bcom_prepare_next_buffer(priv->dmatsk);
+
+ if (read) {
+ bd->status = tc;
+ bd->src_pa = (__force u32) priv->ata_regs_pa +
+ offsetof(struct mpc52xx_ata, fifo_data);
+ bd->dst_pa = (__force u32) cur_addr;
+ } else {
+ bd->status = tc;
+ bd->src_pa = (__force u32) cur_addr;
+ bd->dst_pa = (__force u32) priv->ata_regs_pa +
+ offsetof(struct mpc52xx_ata, fifo_data);
+ }
+
+ bcom_submit_next_buffer(priv->dmatsk, NULL);
+
+ cur_addr += tc;
+ cur_len -= tc;
+ count++;
+
+ if (count > MAX_DMA_BUFFERS) {
+ dev_alert(ap->dev, "dma table"
+ "too small\n");
+ goto use_pio_instead;
+ }
+ }
+ }
+ return 1;
+
+ use_pio_instead:
+ bcom_ata_reset_bd(priv->dmatsk);
+ return 0;
+}
+
+static void
+mpc52xx_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+
+ unsigned int read = !(qc->tf.flags & ATA_TFLAG_WRITE);
+ u8 dma_mode;
+
+ if (!mpc52xx_ata_build_dmatable(qc))
+ dev_alert(ap->dev, "%s: %i, return 1?\n",
+ __func__, __LINE__);
+
+ /* Check FIFO is OK... */
+ if(in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
+ dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
+ __func__, in_8(&priv->ata_regs->fifo_status));
+
+ if (read) {
+ dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_READ |
+ MPC52xx_ATA_DMAMODE_FE;
+
+ /* Setup FIFO if direction changed */
+ if (priv->mpc52xx_ata_dma_last_write != 0) {
+ priv->mpc52xx_ata_dma_last_write = 0;
+
+ /* Configure FIFO with granularity to 7 */
+ out_8(®s->fifo_control, 7);
+ out_be16(®s->fifo_alarm, 128);
+
+ /* Set FIFO Reset bit (FR) */
+ out_8(®s->dma_mode, MPC52xx_ATA_DMAMODE_FR);
+ }
+ } else {
+ dma_mode = MPC52xx_ATA_DMAMODE_IE | MPC52xx_ATA_DMAMODE_WRITE;
+
+ /* Setup FIFO if direction changed */
+ if (priv->mpc52xx_ata_dma_last_write != 1) {
+ priv->mpc52xx_ata_dma_last_write = 1;
+
+ /* Configure FIFO with granularity to 4 */
+ out_8(®s->fifo_control, 4);
+ out_be16(®s->fifo_alarm, 128);
+ }
+ }
+
+ if (priv->timings[qc->dev->devno].using_udma)
+ dma_mode |= MPC52xx_ATA_DMAMODE_UDMA;
+
+ out_8(®s->dma_mode, dma_mode);
+ priv->waiting_for_dma = ATA_DMA_ACTIVE;
+
+ ata_wait_idle(ap);
+ ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+static void
+mpc52xx_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+ bcom_set_task_auto_start(priv->dmatsk->tasknum, priv->dmatsk->tasknum);
+ bcom_enable(priv->dmatsk);
+}
+
+static void
+mpc52xx_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+ bcom_disable(priv->dmatsk);
+ bcom_ata_reset_bd(priv->dmatsk);
+ priv->waiting_for_dma = 0;
+
+ /* Check FIFO is OK... */
+ if(in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR)
+ dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
+ __func__, in_8(&priv->ata_regs->fifo_status));
+}
+
+static u8
+mpc52xx_bmdma_status(struct ata_port *ap)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+ /* Check FIFO is OK... */
+ if(in_8(&priv->ata_regs->fifo_status) & MPC52xx_ATA_FIFOSTAT_ERROR) {
+ dev_alert(ap->dev, "%s: FIFO error detected: 0x%02x!\n",
+ __func__, in_8(&priv->ata_regs->fifo_status));
+ return priv->waiting_for_dma | ATA_DMA_ERR;
+ }
+
+ return priv->waiting_for_dma;
+}
+
+static irqreturn_t
+mpc52xx_ata_task_irq(int irq, void *vpriv)
+{
+ struct mpc52xx_ata_priv *priv = vpriv;
+ while (bcom_buffer_done(priv->dmatsk))
+ bcom_retrieve_buffer(priv->dmatsk, NULL, NULL);
+
+ priv->waiting_for_dma |= ATA_DMA_INTR;
+
+ return IRQ_HANDLED;
+}
+
static struct scsi_host_template mpc52xx_ata_sht = {
ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations mpc52xx_ata_port_ops = {
.inherits = &ata_sff_port_ops,
- .sff_dev_select = mpc52xx_ata_dev_select,
- .cable_detect = ata_cable_40wire,
+
.set_piomode = mpc52xx_ata_set_piomode,
- .post_internal_cmd = ATA_OP_NULL,
+ .set_dmamode = mpc52xx_ata_set_dmamode,
+ .sff_dev_select = mpc52xx_ata_dev_select,
+
+ .bmdma_setup = mpc52xx_bmdma_setup,
+ .bmdma_start = mpc52xx_bmdma_start,
+ .bmdma_stop = mpc52xx_bmdma_stop,
+ .bmdma_status = mpc52xx_bmdma_status,
+
+ .qc_prep = ata_noop_qc_prep,
};
static int __devinit
@@ -281,9 +643,11 @@ mpc52xx_ata_init_one(struct device *dev,
ap = host->ports[0];
ap->flags |= ATA_FLAG_SLAVE_POSS;
- ap->pio_mask = 0x1f; /* Up to PIO4 */
- ap->mwdma_mask = 0x00; /* No MWDMA */
- ap->udma_mask = 0x00; /* No UDMA */
+ ap->pio_mask = ATA_PIO4; /* Up to PIO4 */
+#ifdef CONFIG_PATA_MPC52xx_DMA
+ ap->mwdma_mask = ATA_MWDMA2; /* Up to MWDMA2 */
+ ap->udma_mask = ATA_UDMA2; /* Up to UDMA2 */
+#endif
ap->ops = &mpc52xx_ata_port_ops;
host->private_data = priv;
@@ -333,7 +697,7 @@ mpc52xx_ata_probe(struct of_device *op,
int ata_irq;
struct mpc52xx_ata __iomem *ata_regs;
struct mpc52xx_ata_priv *priv;
- int rv;
+ int rv, ret, task_irq;
/* Get ipb frequency */
ipb_freq = mpc52xx_find_ipb_freq(op->node);
@@ -389,8 +753,32 @@ mpc52xx_ata_probe(struct of_device *op,
priv->ipb_period = 1000000000 / (ipb_freq / 1000);
priv->ata_regs = ata_regs;
+ priv->ata_regs_pa = res_mem.start;
priv->ata_irq = ata_irq;
priv->csel = -1;
+ priv->mpc52xx_ata_dma_last_write = -1;
+
+ if (ipb_freq/1000000 == 66) {
+ priv->mdmaspec = mdmaspec66;
+ priv->udmaspec = udmaspec66;
+ } else {
+ priv->mdmaspec = mdmaspec132;
+ priv->udmaspec = udmaspec132;
+ }
+
+ priv->dmatsk = bcom_ata_init(MAX_DMA_BUFFERS, MAX_DMA_BUFFER_SIZE);
+ if (!priv->dmatsk) {
+ dev_alert(&op->dev, "Failed to initialize BestComm task!\n");
+ rv = -ENOMEM;
+ goto err;
+ }
+
+ task_irq = bcom_get_task_irq(priv->dmatsk);
+ ret = request_irq(task_irq, &mpc52xx_ata_task_irq, IRQF_DISABLED,
+ "ATA task", priv);
+ if (ret)
+ dev_alert(&op->dev, "request_irq failed with: "
+ "%i\n", ret);
/* Init the hw */
rv = mpc52xx_ata_hw_init(priv);
^ permalink raw reply
* Re: [PATCH]: [MPC5200] Add ATA DMA support
From: Grant Likely @ 2008-08-13 6:11 UTC (permalink / raw)
To: Tim Yamin; +Cc: linuxppc-dev
In-Reply-To: <792f5f410808122306u478b3ere8167016ef892323@mail.gmail.com>
On Wed, Aug 13, 2008 at 07:06:27AM +0100, Tim Yamin wrote:
> On Wed, Aug 13, 2008 at 7:02 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> > While on this topic; have you had a chance to address the comments you
> > received on v2 of your patch? I'm keen to get your change merged in,
> > but there are a few more things that need to be sorted out.
>
> I'm still trying to determine whether the locking stuff is needed or
> not. I think ultimately it might be a bug caused by hardware problems
> at this end as opposed to silicon problems affecting everybody, but I
> won't have an answer regarding this for a while because new hardware
> needs to be prototyped to test out this theory.
>
> I think the patch can probably be resubmitted with the locking stuff
> removed, and the driver can be marked as experimental for everybody to
> try out: if people experience any corruption problems I'm sure they
> can speak up :-)
>
> Any objections?
Sounds good to me. You will get more testers that way. I can pick it
up for -next if everything else looks good.
g.
^ permalink raw reply
* Re: [PATCH]: [MPC5200] Add ATA DMA support
From: Tim Yamin @ 2008-08-13 6:06 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40808122302g197a8e90idc721796aa35ff05@mail.gmail.com>
On Wed, Aug 13, 2008 at 7:02 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> While on this topic; have you had a chance to address the comments you
> received on v2 of your patch? I'm keen to get your change merged in,
> but there are a few more things that need to be sorted out.
I'm still trying to determine whether the locking stuff is needed or
not. I think ultimately it might be a bug caused by hardware problems
at this end as opposed to silicon problems affecting everybody, but I
won't have an answer regarding this for a while because new hardware
needs to be prototyped to test out this theory.
I think the patch can probably be resubmitted with the locking stuff
removed, and the driver can be marked as experimental for everybody to
try out: if people experience any corruption problems I'm sure they
can speak up :-)
Any objections?
Tim
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox