LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Microwindows on Icecube/CoralP
From: Mark Chambers @ 2005-02-07 20:30 UTC (permalink / raw)
  Cc: linuxppc-embedded
In-Reply-To: <20050207195520.D8B4DC108D@atlas.denx.de>

> 
> This will not work. Microwindows can only  use  a  plain  framebuffer
> interface,  but  the Coral-P does not allow for such a driver because
> of the fact that it has a little-endian register interface.  

Or is it because 5200 swaps bytes around on PCI.  It sure looks to me
like Freescale has made a major screwup in their implementation of
PCI on the 5200.  I'd love for somebody to prove me wrong about this,
but I'm afraid I'm right.  I was under the impression that CoralP worked
nicely on 5200, but now I see that it also requires software tweaks to work
on 5200.  

Mark Chambers

^ permalink raw reply

* Re: Microwindows on Icecube/CoralP
From: Wolfgang Denk @ 2005-02-07 19:55 UTC (permalink / raw)
  To: francois.ruvoen@libertysurf.fr; +Cc: linuxppc-embedded
In-Reply-To: <IBJDLO$2F7CB4091C41824099E5E47AB0570FD3@tiscali.fr>

Dear Francois,

in message <IBJDLO$2F7CB4091C41824099E5E47AB0570FD3@tiscali.fr> you wrote:
>
> I have been playing with the CoralP, Icecube and Debian.
> Works fine, thanks to the tutorial on the Denx site.
> I now would like to see the microwindows stuff working. I

This will not work. Microwindows can only  use  a  plain  framebuffer
interface,  but  the Coral-P does not allow for such a driver because
of the fact that it has a little-endian register interface.  For  the
frameboffer,  each color is defined by a bit offset and the number of
(contiguous bits) in a data word. For example, assuming a color depth
of 16 bpp you could have something like this:

	MSB          LSB
	rrrrrrgggggbbbbb

In this case the "green" color has bit offset 5 and is 5  bits  wide,
while  "red" has offset 10 and is 6 bits wide. On the Coral-P you see
the bytes swapped, i. e.

	MSB          LSB
	gggbbbbbrrrrrrgg

The "green" bits are  split  into  two  non-contiguous  groups  which
cannot  be  desribed  in  the  way  it  is  needed  for a framebuffer
interface.

You will need a custom graphics driver which  swaps  all  color  data
that  get  written  to  the  Coral-P.  Standard Microwindows does not
support this mode of operation.

> have been trying the demos from the ELDK but I get strange
> colors, it seems my palette is all wrong. The same happens

Yes, this is the effect explained above.

> when I recompile the latest version of microwindows (except
> I get yet another palette).

Again, thisis only to be expected.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
"Here's a fish hangs in the net like a poor man's right in  the  law.
'Twill hardly come out."     - Shakespeare, Pericles, Act II, Scene 1

^ permalink raw reply

* Re: Microwindows on Icecube/CoralP
From: francois.ruvoen @ 2005-02-07 15:24 UTC (permalink / raw)
  To: linuxppc-embedded

Thanks. Tweaking a little the source code and I now get the=0D=0Aright co=
lours. The funny thing is that byte swapping was:=0D=0A0x1234567 =3D> 0x3=
4126745. I initially thought I could just=0D=0Aswap the two least signifi=
cant bytes as I am pretty sure I=0D=0Aam using a 16-bit mode (fbset repor=
ts that anyway). Now I'd=0D=0Alike to see that in 640x480 and not just 10=
24x768 but that=0D=0Aissue seems tied the frame buffer driver this time.=0D=
=0A=0D=0A---------- Initial Header -----------=0D=0A=0D=0AFrom      : "Ma=
rk Chambers" <markc@mail.com>=0D=0ATo          :=0D=0A<francois.ruvoen@li=
bertysurf.fr>,"linuxppc-embedded"=0D=0A<linuxppc-embedded@ozlabs.org>=0D=0A=
Cc          : =0D=0ADate      : Mon, 7 Feb 2005 07:59:16 -0500=0D=0ASubje=
ct : Re: Microwindows on Icecube/CoralP=0D=0A=0D=0A=0D=0A>I have been pla=
ying with the CoralP, Icecube and Debian.=0D=0A>Works fine, thanks to the=
 tutorial on the Denx site.=0D=0A>I now would like to see the microwindow=
s stuff working. I=0D=0A>have been trying the demos from the ELDK but I g=
et strange=0D=0A>colors, it seems my palette is all wrong. The same happe=
ns=0D=0A>when I recompile the latest version of microwindows (except=0D=0A=
>I get yet another palette).=0D=0A>Any pointers?=0D=0A=0D=0AOne unexpecte=
d thing about the 5200 is that it swaps bytes=0D=0Ato/from the PCI buss. =
 So if you write a 32 bit pixel, for=0D=0Ainstance 0x12345678, it will be=
 written to PCI as=0D=0A0x78563412.  Presumably this is based on an assum=
ption=0D=0Athat PCI targets will be little-endian.  So you might try=0D=0A=
reversing bytes and see if the palettes make sense.=0D=0A=0D=0AMark Chamb=
ers=0D=0A=0D=0A=0D=0A=0A************************ ADSL JUSQU'A 16 MEGA + T=
ELEPHONE GRATUIT ************************=0AL'ultra haut d=E9bit =E0 30EU=
R/mois seulement ! Et vous t=E9l=E9phonez gratuitement en France vers les=
 postes fixes, hors num=E9ros sp=E9ciaux.=0APour profiter de cette offre =
exceptionnelle, cliquez ici : http://register.tiscali.fr/adsl/  (voir con=
ditions sur le site)=0A=0A

^ permalink raw reply

* Re: usage of  interruptible_sleep_on( ) function call
From: David Bruce @ 2005-02-07 14:46 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <20050206010004.3890267A7A@ozlabs.org>

I had the same problem with the i2c-algo-8260.c when loading a module. 
It's the __pa() translation. Replace _ALL_ __pa with iopa. It worked for 
me. I discovered it from this link:
http://ozlabs.org/pipermail/linuxppc-dev/2002-February/013260.html

linuxppc-embedded-request@ozlabs.org wrote:
> Send Linuxppc-embedded mailing list submissions to
> 	linuxppc-embedded@ozlabs.org
> 
> To subscribe or unsubscribe via the World Wide Web, visit
> 	https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> or, via email, send a message with subject or body 'help' to
> 	linuxppc-embedded-request@ozlabs.org
> 
> You can reach the person managing the list at
> 	linuxppc-embedded-owner@ozlabs.org
> 
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Linuxppc-embedded digest..."
> 
> 
> Today's Topics:
> 
>    1. question re usage of  interruptible_sleep_on( ) function call
>       in	cpm_iic_tryaddress( ) function (in i2c-algo-8xx.c)
>       (Povolotsky, Alexander)
> 
> 
> ----------------------------------------------------------------------
> 
> Message: 1
> Date: Sat, 5 Feb 2005 12:30:06 -0500 
> From: "Povolotsky, Alexander" <Alexander.Povolotsky@marconi.com>
> Subject: question re usage of  interruptible_sleep_on( ) function call
> 	in	cpm_iic_tryaddress( ) function (in i2c-algo-8xx.c)
> To: "'linuxppc-dev@ozlabs.org'" <linuxppc-dev@ozlabs.org>,
> 	"'linuxppc-embedded@ozlabs.org'" <linuxppc-embedded@ozlabs.org>,
> 	"'etux@embeddedtux.org'" <etux@embeddedtux.org>
> Message-ID:
> 	<313680C9A886D511A06000204840E1CF0A6475F1@whq-msgusr-02.pit.comms.marconi.com>
> 	
> Content-Type: text/plain;	charset="ISO-8859-1"
> 
> Hello,
> 
>> 
>>I have MPC880 microprocessor based board with single 24C02 I2C EEPROM,
>>connected to the I2C bus.
>>
>>Currently booting of the board hangs in the I2C driver after invocation of
>>interruptible_sleep_on( )
> 
>  function call  in cpm_iic_tryaddress( ) function (in i2c-algo-8xx.c file).
> 
> Is it appropriate to use the interruptible_sleep_on( ) function at the
> kernel booting stage ?
>  (I personally do not think so - since such usage prevents further kernel
> booting - as observed).
> What should be done in this code to avoid slleping ?
> 
> I presume that the usage of the interruptible_sleep_on( ) function would be
> appropriate if the 
> I2C would be configured as a module (after the kernel booting is completed)
> ?
> Follow up question:  is it really expected to do I2C initialization ONLY as
> a module after the kernel booting ?
> (is it documented anyplace ?) 
> 
> 
>>The (end of) log buffer shows following:
>>....
>><6>i2c /dev entries driver.
>><7>device class 'i2c-dev': registering.
>><7>bus i2c:add driver dev_driver.
>><7>i2c-core: driver dev_driver registered
>><6>i2c-rpx: i2c MPC8xx driver.
>><7>DEV: registering device: ID ='i2c-0'.
>><7>CLASS: registering class device: ID= 'i2c-0'.
>><7>i2c_adapter i2c-0:Registered as minor 0.
>><7>CLASS:registering class device: ID = 'i2c-0'
>><7>i2c_adapter i2c-0: registered as adapter #0.
>><4>cpm_iic_init() - iip=fa203c80.
>><4>cpm_iic_init[132] Install ISR for IRQ 16.
>><6>CPM interrupt c0105d90 replacing c01f7a8c.
>><3>request_irq() returned -22  for CPM vector 32.
>><6> i2c-algo-8xx.o: scanning bus m8xx........
>><4>cpm_iic_tryaddress(cpm=c019b9f8,addr=0).
>><4>iip fa203c80, dp_addr 0x800.
>><4>iic_tbase 2048, r_tbase 2048
>><4>about to sleep
>>.ABOVE LINE IS THE LAST ENTRY IN THE LOG BUFFER - THE BOOT HANGS
>>THEREAFTER ... 
>>
> 
> Here is the fragment of the cpm_iic_tryaddress( ) function in
> i2c-algo-8xx.c,
> where the problem takes place:
> .... 
> //      save_flags(flags); cli();
>         i2c->i2c_i2cer = 0xff;
>         i2c->i2c_i2cmr = 0x13;  /* Enable some interupts */
>         i2c->i2c_i2mod = 1;     /* Enable */
>         i2c->i2c_i2com = 0x81;  /* Start master */
> //      restore_flags(flags);
> 
>         if (cpm_debug > 1) printk("about to sleep\n");
> 
>         /* wait for IIC transfer */
> interruptible_sleep_on(&iic_wait);
> if (signal_pending(current))
>         return -EIO;
> 
> if (cpm_debug > 1) printk("back from sleep\n");
> 
> if (tbdf->cbd_sc & BD_SC_NAK) {
>         if (cpm_debug > 1) printk("IIC try; no ack\n");
>         return 0;
> }
> 
> if (tbdf->cbd_sc & BD_SC_READY) {
>         printk("IIC try; complete but tbuf ready\n");
> }
> 
> return 1;
> 
> ........
> 
>>Thanks,
>>Best Regards,
>>Alex 
>>
>>
> 
> 
> 
> ------------------------------
> 
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> End of Linuxppc-embedded Digest, Vol 6, Issue 12
> ************************************************
> 
> 

-- 
David Bruce
MIT Lincoln Laboratory
244 Wood Street
Lexington, MA 02420
781.981.3863
mailto:dbruce@ll.mit.edu

^ permalink raw reply

* Creating a configuration for my custom MPC875 board
From: Peter Asemann @ 2005-02-07 14:53 UTC (permalink / raw)
  To: linuxppc-embedded

Some days ago I was told on this mailinglist I needed to create a custom 
configuration in order to get linux running on my custom hardware.

So I did as I was told and created an own <name>_defconfig and entries 
in the menu via editing arch/ppc/config.in and so on.

Well, every board seems to include it's custom header file from 
platforms/<NAME>.h in the include/asm/mpc8xx.h header file.
Now I'm curious if I also need to include something?

It seems there usually isn't much stuff in the <name>.h file, only an 
IMAP_ADDR define and the definition of struct bd_info.

Do I need this stuff - or how do I find out?

Best regards,

Peter Asemann

^ permalink raw reply

* Re: question on symbol exports
From: Chris Friesen @ 2005-02-07 14:44 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc64-dev, Arjan van de Ven, Linux Kernel list,
	linuxppc-dev list
In-Reply-To: <1107595148.30302.5.camel@gaston>

Benjamin Herrenschmidt wrote:
>>It turns out that to call ptep_clear_flush_dirty() on ppc64 from a 
>>module I needed to export the following symbols:
>>
>>__flush_tlb_pending
>>ppc64_tlb_batch
>>hpte_update
> 
> 
> Any reason why you need to call that from a module ? Is the module
> GPL'd ?

I explained this at the beginning of the thread, but I'll do so again. 
The module will be released under the GPL.

The basic idea is that we want to be able to track pages dirtied by a 
userspace process.  The system has no swap, so we use the dirty bit for 
this.  On demand we look up the page tables for an address range 
specified by the caller, store the addresses of any dirty pages, then 
mark them clean so that the next write causes them to get marked dirty 
again.  It is this act of marking them clean that requires the 
additional exports.

I've included the current code below.  If there is any way to accomplish 
this without the additional exports, I'd love to hear about it.

Chris








Note: this code is run while holding &mm->mmap_sem and &mm->page_table_lock.


for(addr=start&PAGE_MASK; addr<=end; addr+=PAGE_SIZE) {
	pte_t *ptep=0;

	ptep = va_to_ptep_map(mm, addr);
	if (!ptep)
		goto unmap_continue;

	if (!pte_dirty(*ptep))
		goto unmap_continue;

	/* We have a user readable dirty page.  Count it.*/
	dirty_count++;

	if (dirty_count <= entries) {
		__put_user(addr, buf);
		buf++;
		ptep_clear_flush_dirty(find_vma(mm, addr), addr, ptep);

		/* Handle option to stop early. */
		if ((dirty_count == entries) &&
			(options & STOP_WHEN_BUF_FULL))
			addr=end+1;
	}

unmap_continue:
	if (ptep)
		pte_unmap(ptep);		
}

^ permalink raw reply

* Re: Microwindows on Icecube/CoralP
From: Mark Chambers @ 2005-02-07 12:59 UTC (permalink / raw)
  To: francois.ruvoen, linuxppc-embedded
In-Reply-To: <IBJDLO$2F7CB4091C41824099E5E47AB0570FD3@tiscali.fr>


>I have been playing with the CoralP, Icecube and Debian.
>Works fine, thanks to the tutorial on the Denx site.
>I now would like to see the microwindows stuff working. I
>have been trying the demos from the ELDK but I get strange
>colors, it seems my palette is all wrong. The same happens
>when I recompile the latest version of microwindows (except
>I get yet another palette).
>Any pointers?

One unexpected thing about the 5200 is that it swaps bytes
to/from the PCI buss.  So if you write a 32 bit pixel, for
instance 0x12345678, it will be written to PCI as
0x78563412.  Presumably this is based on an assumption
that PCI targets will be little-endian.  So you might try
reversing bytes and see if the palettes make sense.

Mark Chambers

^ permalink raw reply

* Microwindows on Icecube/CoralP
From: francois.ruvoen @ 2005-02-07 10:10 UTC (permalink / raw)
  To: linuxppc-embedded

Hi all,=0D=0A=0D=0AI have been playing with the CoralP, Icecube and Debia=
n.=0D=0AWorks fine, thanks to the tutorial on the Denx site.=0D=0AI now w=
ould like to see the microwindows stuff working. I=0D=0Ahave been trying =
the demos from the ELDK but I get strange=0D=0Acolors, it seems my palett=
e is all wrong. The same happens=0D=0Awhen I recompile the latest version=
 of microwindows (except=0D=0AI get yet another palette).=0D=0AAny pointe=
rs?=0D=0A=0D=0AI am using the latest CVS for linuxppc_2_4_devel, ELDK 3.0=
=0D=0Aand Microwindows 0.90. The Lite5200 is a Rev 2 and the=0D=0ACoralP =
a Rev 5.=0A************************ ADSL JUSQU'A 16 MEGA + TELEPHONE GRAT=
UIT ************************=0AL'ultra haut d=E9bit =E0 30EUR/mois seulem=
ent ! Et vous t=E9l=E9phonez gratuitement en France vers les postes fixes=
, hors num=E9ros sp=E9ciaux.=0APour profiter de cette offre exceptionnell=
e, cliquez ici : http://register.tiscali.fr/adsl/  (voir conditions sur l=
e site)=0A=0A

^ permalink raw reply

* Re: make -j12 all fails in uImage target
From: Olaf Hering @ 2005-02-07  8:29 UTC (permalink / raw)
  To: Tom Rini, linuxppc-dev, Sam Ravnborg
In-Reply-To: <20050206225323.GA16821@mars.ravnborg.org>

 On Sun, Feb 06, Sam Ravnborg wrote:

> Something like this may do the trick:
> 
> $(obj)/images: $(addprefix $(obj)/,$(subdir-y) $(bootdir-y))
> 	$(Q)$(MAKE) $(build)=$@
> 
> And then delete the assignment of images to subdir-y

That still doesnt work right, I touched one .c file which lead to a new
vmlinux, now zImage.rs6k is too small:

diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc/boot/Makefile ./arch/ppc/boot/Makefile
--- ../linux-2.6.11-rc3.orig/arch/ppc/boot/Makefile     2005-02-03 02:56:10.000000000 +0100
+++ ./arch/ppc/boot/Makefile    2005-02-07 09:24:38.713179331 +0100
@@ -17,8 +17,10 @@ BOOT_TARGETS = zImage zImage.initrd znet
 
 bootdir-y                      := simple
 bootdir-$(CONFIG_PPC_OF)       += openfirmware
-subdir-y                       := lib common images
+subdir-y                       := lib common
 subdir-$(CONFIG_PPC_OF)                += of1275
+$(obj)/images: $(addprefix $(obj)/,$(subdir-y) $(bootdir-y))
+       $(Q)$(MAKE) $(build)=$@
 
 # for cleaning
 subdir-                                += simple openfirmware

  CHK     include/linux/version.h
make[2]: `arch/ppc/kernel/asm-offsets.s' is up to date.
  CHK     include/asm-ppc/offsets.h
  CHK     usr/initramfs_list
  CHK     include/linux/compile.h
  CC      arch/ppc/platforms/chrp_nvram.o
  LD      arch/ppc/platforms/built-in.o
  GEN     .version
  CHK     include/linux/compile.h
  UPD     include/linux/compile.h
  CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
  KSYM    .tmp_kallsyms1.S
  AS      .tmp_kallsyms1.o
  LD      .tmp_vmlinux2
  KSYM    .tmp_kallsyms2.S
  AS      .tmp_kallsyms2.o
  LD      vmlinux
  SYSMAP  System.map
  SYSMAP  .tmp_System.map
  OBJCOPY arch/ppc/boot/images/vmlinux.bin
  GZIP    arch/ppc/boot/images/vmlinux.gz
  AS      arch/ppc/boot/simple/head.o
  AS      arch/ppc/boot/simple/relocate.o
  CC      arch/ppc/boot/simple/prepmap.o
  GEN     arch/ppc/boot/openfirmware/image.o
  CC      arch/ppc/boot/simple/misc.o
  GEN     arch/ppc/boot/images/miboot.image
  COFF    arch/ppc/boot/openfirmware/coffboot
  ELF     arch/ppc/boot/images/vmlinux.elf-pmac
  CHRP    arch/ppc/boot/images/zImage.chrp
  CC      arch/ppc/boot/simple/misc-prep.o
  CC      arch/ppc/boot/simple/mpc10x_memory.o
  COFF    arch/ppc/boot/images/vmlinux.coff
  ADDNOTE arch/ppc/boot/images/zImage.chrp-rs6k
  kernel: zImage is ready (arch/ppc/boot/images/vmlinux.coff)
...
../O-2.6.11-rc3-b50/arch/ppc/boot/images/:
total 6.2M
drwxr-xr-x  2 olaf users  496 2005-02-07 09:26 ./   
drwxr-xr-x  9 olaf users  224 2005-02-07 09:25 ../  
-rw-r--r--  1 olaf users  256 2005-02-07 09:26 .uImage.cmd
-rw-r--r--  1 olaf users  100 2005-02-07 09:26 .vmlinux.bin.cmd
-rw-r--r--  1 olaf users  119 2005-02-07 09:26 .vmlinux.gz.cmd
-rw-r--r--  1 olaf users  49K 2005-02-07 09:26 miboot.image
-rwxr-xr-x  1 olaf users 2.8M 2005-02-07 09:26 vmlinux.bin*
-rwxr-xr-x  1 olaf users  79K 2005-02-07 09:26 vmlinux.coff*
-rwxr-xr-x  1 olaf users 146K 2005-02-07 09:26 vmlinux.elf-pmac*
-rw-r--r--  1 olaf users 1.3M 2005-02-07 09:26 vmlinux.gz
-rwxr-xr-x  1 olaf users 575K 2005-02-07 09:26 zImage.bugboot*
-rwxr-xr-x  1 olaf users 146K 2005-02-07 09:26 zImage.chrp*
-rw-r--r--  1 olaf users 146K 2005-02-07 09:26 zImage.chrp-rs6k
-rwxr-xr-x  1 olaf users 639K 2005-02-07 09:26 zImage.elf*
lrwxrwxrwx  1 olaf users   12 2005-02-07 09:26 zImage.pmac -> vmlinux.coff*
-rwxr-xr-x  1 olaf users 576K 2005-02-07 09:26 zImage.prep*

^ permalink raw reply

* Re: [PATCH] remove .tmp_gas_check
From: Olaf Hering @ 2005-02-07  8:23 UTC (permalink / raw)
  To: Tom Rini; +Cc: linuxppc-dev
In-Reply-To: <20050206224306.GG7686@smtp.west.cox.net>

 On Sun, Feb 06, Tom Rini wrote:

> On Sun, Feb 06, 2005 at 10:56:00PM +0100, Olaf Hering wrote:
> >  On Sun, Feb 06, Tom Rini wrote:
> > 
> > > On Sun, Feb 06, 2005 at 10:15:06PM +0100, Olaf Hering wrote:
> > > 
> > > >  On Sun, Feb 06, Tom Rini wrote:
> > > > 
> > > > > I agree you shouldn't have to see it.  I'm saying the problem is the
> > > > > variable shouldn't be evaluated.
> > > > 
> > > > This patch seems to work for me.
> > > 
> > > What I don't like is that checkbin shouldn't be evaluated for 'tags' or
> > > other non-compile targets, so you don't need those explicit rm's.  Also,
> > > you forgot the signed-off-by line :)
> > 
> > Why should make tags or oldconfig ever care about the installed toolchain?
> 
> It shouldn't, and 'tags' at least shouldn't depend on 'checkbin'

tags does not call checkbin, so this part is ok.

> > How should the tmpfile disappear if one calls make checkbin with success?
> 
> On make clean, like the other .tmp files that are around at the end of a
> kernel compile (kallsyms/modules/maybe something else).

Thats ok now.

> > Maybe I misunderstood you.
> 
> I think so.  We both agree there should be no ppc-specific .tmp files
> around after certain make targets.  I'm saying that there's always some
> .tmp files generated on every arch for certain targets, and removed with
> a clean.  PPC should only create .tmp files (And leave them alone) in
> the cases where every arch generates some .tmp files.

Signed-off-by: Olaf Hering <olh@suse.de>

diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc/Makefile ./arch/ppc/Makefile
--- ../linux-2.6.11-rc3.orig/arch/ppc/Makefile	2005-02-03 02:57:05.000000000 +0100
+++ ./arch/ppc/Makefile	2005-02-07 09:21:25.941904406 +0100
@@ -112,26 +112,24 @@ include/asm-$(ARCH)/offsets.h: arch/$(AR
 TOUT	:= .tmp_gas_check
 # Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
 # instructions.
-AS_ALTIVEC	:= $(shell echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; echo $$?)
 # gcc-3.4 and binutils-2.14 are a fatal combination.
 GCC_VERSION	:= $(call cc-version)
-BAD_GCC_AS	:= $(shell echo mftb 5 | $(AS) -mppc -many -o $(TOUT) >/dev/null 2>&1 && echo 0 || echo 1)
 
 checkbin:
-ifeq ($(GCC_VERSION)$(BAD_GCC_AS),03041)
-	@echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '
-	@echo 'correctly with gcc-3.4 and your version of binutils.'
-	@echo '*** Please upgrade your binutils or downgrade your gcc'
-	@false
-endif
-ifneq ($(AS_ALTIVEC),0)
-	echo $(AS_ALTIVEC)
-	@echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '
-	@echo 'correctly with old versions of binutils.'
-	@echo '*** Please upgrade your binutils to 2.12.1 or newer'
-	@false
-endif
-	@true
+	@if test "$(GCC_VERSION)" = "0304" ; then \
+		if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
+			echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
+			echo 'correctly with gcc-3.4 and your version of binutils.'; \
+			echo '*** Please upgrade your binutils or downgrade your gcc'; \
+			false; \
+		fi ; \
+	fi
+	@if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
+		echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
+		echo 'correctly with old versions of binutils.' ; \
+		echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
+		false ; \
+	fi
 
 CLEAN_FILES +=	include/asm-$(ARCH)/offsets.h \
 		arch/$(ARCH)/kernel/asm-offsets.s \

^ permalink raw reply

* Re: make -j12 all fails in uImage target
From: Sam Ravnborg @ 2005-02-07  5:39 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Tom Rini, Olaf Hering, Sam Ravnborg, linuxppc-dev list
In-Reply-To: <1107733391.30303.66.camel@gaston>

 
> We should maybe also have an explicit dependency on vmlinux no ? Or is
> this handled already for the boot dir as a whole ?

This is handled in arch/ppc/MAkefile - so already dealt with.

	Sam

^ permalink raw reply

* [PATCH][PPC32] ibmstb4 ocp fix
From: Andre' Draszik @ 2005-02-07  4:38 UTC (permalink / raw)
  To: linuxppc-embedded

this one fixes the OCP device definition for STB04.
Please consider applying.

Signed-off-by: Andre' Draszik <andid@gmx.net>

diff -urN linuxppc-2.5.orig/arch/ppc/platforms/4xx/ibmstb4.c linuxppc-2.5/arch/ppc/platforms/4xx/ibmstb4.c
--- linuxppc-2.5.orig/arch/ppc/platforms/4xx/ibmstb4.c	2005-02-06 00:16:33.000000000 +0100
+++ linuxppc-2.5/arch/ppc/platforms/4xx/ibmstb4.c	2005-02-05 21:20:58.000000000 +0100
@@ -22,7 +22,7 @@
  };
  OCP_SYSFS_IIC_DATA()

-struct ocp_def core_ocp[] __initdata = {
+struct ocp_def core_ocp[] = {
  	{ .vendor	= OCP_VENDOR_IBM,
  	  .function	= OCP_FUNC_16550,
  	  .index	= 0,
@@ -46,6 +46,7 @@
  	},
  	{ .vendor	= OCP_VENDOR_IBM,
  	  .function	= OCP_FUNC_IIC,
+	  .index	= 0,
  	  .paddr	= IIC0_BASE,
  	  .irq		= IIC0_IRQ,
  	  .pm		= IBM_CPM_IIC0,
@@ -54,6 +55,7 @@
  	},
  	{ .vendor	= OCP_VENDOR_IBM,
  	  .function	= OCP_FUNC_IIC,
+	  .index	= 1,
  	  .paddr	= IIC1_BASE,
  	  .irq		= IIC1_IRQ,
  	  .pm		= IBM_CPM_IIC1,

^ permalink raw reply

* [PATCH][PPC32] mktree fix
From: Andre' Draszik @ 2005-02-07  4:34 UTC (permalink / raw)
  To: linuxppc-embedded

This one fixes mktree. The image size stored in the header is pretty off without
this patch. (yes, it can make a difference of upto almost 64k)

Signed-off-by: Andre' Draszik <andid@gmx.net>

diff -urN linuxppc-2.5.orig/arch/ppc/boot/utils/mktree.c linuxppc-2.5/arch/ppc/boot/utils/mktree.c
--- linuxppc-2.5.orig/arch/ppc/boot/utils/mktree.c	2005-02-03 20:20:39.000000000 +0100
+++ linuxppc-2.5/arch/ppc/boot/utils/mktree.c	2005-02-06 03:13:27.000000000 +0100
@@ -113,7 +113,8 @@
  		exit(4);
  	}

-	nblks -= (64 * 1024) / IMGBLK;
+	nblks -= (64 * 1024 - sizeof (bt)) / IMGBLK;
+	bt.bb_num_512blocks = htonl(nblks + 1);

  	/* And away we go......
  	*/
@@ -122,7 +123,7 @@
  		exit(5);
  	}

-	while (nblks-- > 0) {
+	while (--nblks > 0) {
  		if (read(in_fd, tmpbuf, IMGBLK) < 0) {
  			perror("zImage read");
  			exit(5);

^ permalink raw reply

* [PATCH][PPC32] PPC4xx ocp ide rewrite/cleanup
From: Andre' Draszik @ 2005-02-07  4:24 UTC (permalink / raw)
  To: linuxppc-embedded

Hi,

this is a rewrite of the ibm4xx ocp ide driver. In its current state it
doesn't compile with current 2.6 and is completely broken in many other
aspects anyway.
Please consider applying (or tell me how the patch should be changed to
qualify for applying :)

Signed-off-by: Andre' Draszik <andid@gmx.net>

diff -urN -X dontdiff linuxppc-2.5.orig/drivers/ide/Kconfig linuxppc-2.5/drivers/ide/Kconfig
--- linuxppc-2.5.orig/drivers/ide/Kconfig	2005-02-03 20:18:54.000000000 +0100
+++ linuxppc-2.5/drivers/ide/Kconfig	2005-02-06 06:10:56.000000000 +0100
@@ -930,7 +930,7 @@
  endchoice

  config BLK_DEV_IDE_STB04xxx
-	bool "STB04xxx (Redwood-5) IDE support"
+	tristate "STB04xxx (Redwood-5) IDE support"
  	depends on BLK_DEV_IDE && REDWOOD_5
  	help
  	  This option provides support for IDE on IBM STB04xxx Redwood-5
@@ -1016,11 +1016,11 @@
  endif

  config BLK_DEV_IDEDMA
-	def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS
+	def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_STB04xxx

  config IDEDMA_IVB
  	bool "IGNORE word93 Validation BITS"
-	depends on BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS
+	depends on BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_STB04xxx
  	---help---
  	  There are unclear terms in ATA-4 and ATA-5 standards how certain
  	  hardware (an 80c ribbon) should be detected. Different interpretations
@@ -1035,7 +1035,7 @@
  	  It is normally safe to answer Y; however, the default is N.

  config IDEDMA_AUTO
-	def_bool IDEDMA_PCI_AUTO || IDEDMA_ICS_AUTO
+	def_bool IDEDMA_PCI_AUTO || IDEDMA_ICS_AUTO || BLK_DEV_IDE_STB04xxx

  endif

diff -urN -X dontdiff linuxppc-2.5.orig/drivers/ide/Makefile linuxppc-2.5/drivers/ide/Makefile
--- linuxppc-2.5.orig/drivers/ide/Makefile	2005-02-03 20:18:59.000000000 +0100
+++ linuxppc-2.5/drivers/ide/Makefile	2005-02-06 06:10:56.000000000 +0100
@@ -38,6 +38,11 @@
  # built-in only drivers from ppc/
  ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ppc/mpc8xx.o
  ide-core-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ppc/pmac.o
+ifeq ($(CONFIG_BLK_DEV_IDE_STB04xxx),y)
+ide-core-$(CONFIG_BLK_DEV_IDE_STB04xxx)	+= ppc/ibm_ocp_ide.o
+else
+obj-$(CONFIG_BLK_DEV_IDE_STB04xxx)	+= ppc/ibm_ocp_ide.o
+endif

  # built-in only drivers from h8300/
  ide-core-$(CONFIG_H8300)		+= h8300/ide-h8300.o
diff -urN -X dontdiff linuxppc-2.5.orig/drivers/ide/ppc/ibm_ocp_ide.c linuxppc-2.5/drivers/ide/ppc/ibm_ocp_ide.c
--- linuxppc-2.5.orig/drivers/ide/ppc/ibm_ocp_ide.c	2005-02-03 20:18:54.000000000 +0100
+++ linuxppc-2.5/drivers/ide/ppc/ibm_ocp_ide.c	2005-02-07 04:54:12.000000000 +0100
@@ -1,14 +1,26 @@
  /*
- *    Copyright 2002 MontaVista Software Inc.
- *      Completed implementation.
- *      Author: Armin Kuster <akuster@mvista.com>
- *      MontaVista Software, Inc.  <source@mvista.com>
+ * IDE driver for IBM On-chip IDE contollers
+ *    Copyright 2001 - 2002 MontaVista Software Inc.
+ *    Dan Malek.
   *
- *    Module name: ibm_ocp_ide.c
+ *    Version 1.2 (01/30/12) Armin
+ *    Converted to ocp
+ *    merger up to new ide-timing.h
   *
- *    Description:
+ *    Version 2.0 (05/02/15) - armin
+ *    converted to new core_ocp and only supports one interface for now.
   *
- *    Based on ocp_stbxxxx.c
+ *    Version 2.1 (05/25/02) - armin
+ *      name change from *_driver to *_dev
+ *    Version 2.2 06/13/02 - Armin
+ *      changed irq_resource array to just irq
+ *
+ *    Version 2.3 (Feb 2005) - andre
+ *      - big rewrite to fix some serious bugs
+ *      - bring up to date with ide in 2.6.11-rc3
+ *      - DMA works correctly now, even with non-hard-disks
+ *        I snagged bits and pieces from a variety of drivers, primarily
+ *        ide-pmac.c and ide-dma.c .....thanks to previous authors!
   */

  #include <linux/types.h>
@@ -17,54 +29,47 @@
  #include <linux/hdreg.h>
  #include <linux/delay.h>
  #include <linux/ide.h>
-#include "../ide-timing.h"
+#include <ide-timing.h>
  #include <asm/ocp.h>
  #include <asm/io.h>
  #include <asm/scatterlist.h>
-#include <asm/ppc4xx_dma.h>
-
-#include "ide_modes.h"
+#include <asm/dma-mapping.h>

-#define IDE_VER			"2.0"
-ppc_dma_ch_t dma_ch;
+#define OCPVR	"2.3"

-/* use DMA channel 2 for IDE DMA operations */
-#define IDE_DMACH	2	/* 2nd DMA channel */
-#define IDE_DMA_INT	6	/* IDE dma channel 2 interrupt */

-#define WMODE	0		/* default to DMA line mode */
-#define PIOMODE	0

  #define MK_TIMING(AS, DIOP, DIOY, DH) \
-	((FIT((AS),    0, 15) << 27) | \
-	 (FIT((DIOP),  0, 63) << 20) | \
-	 (FIT((DIOY),  0, 63) << 13) | \
-	 (FIT((DH),    0,  7) << 9))
+	((FIT((AS),    0, 0x0f) << 27) | \
+	 (FIT((DIOP),  0, 0x3f) << 20) | \
+	 (FIT((DIOY),  0, 0x3f) << 13) | \
+	 (FIT((DH),    0, 0x07) <<  9))

  #define UTIMING_SETHLD	(EZ(20 /*tACK*/, SYS_CLOCK_NS) - 1 /*fixed cycles*/)
  #define UTIMING_ENV	(EZ(20 /*tENV*/, SYS_CLOCK_NS) - 1 /*fixed cycles*/)
  #define UTIMING_SS	(EZ(50 /*tSS */, SYS_CLOCK_NS) - 3 /*fixed cycles*/)
+
  #define MK_UTIMING(CYC, RP) \
-	((FIT(UTIMING_SETHLD, 0, 15) << 27) | \
-	 (FIT(UTIMING_ENV,    0, 15) << 22) | \
-	 (FIT((CYC),          0, 15) << 17) | \
-	 (FIT((RP),           0, 63) << 10) | \
-	 (FIT(UTIMING_SS,     0, 15) << 5)  | \
+	((FIT(UTIMING_SETHLD, 0, 0x0f) << 27) | \
+	 (FIT(UTIMING_ENV,    0, 0x0f) << 22) | \
+	 (FIT((CYC),          0, 0x0f) << 17) | \
+	 (FIT((RP),           0, 0x3f) << 10) | \
+	 (FIT(UTIMING_SS,     0, 0x0f) <<  5) | \
  	 1 /* Turn on Ultra DMA */)

  /* Define the period of the STB clock used to generate the
   * IDE bus timing.  The clock is actually 63 MHz, but it
- * get rounded in a favorable direction.
+ * gets rounded in a favorable direction.
   */
  #define IDE_SYS_FREQ	63	/* MHz */
-#define SYS_CLOCK_NS	(1000 / IDE_SYS_FREQ)
+#define SYS_CLOCK_NS	(1000 / IDE_SYS_FREQ)   /* 1clock == SYS_CLOCK_NS nanoseconds */

  struct whold_timing {
  	short mode;
  	short whold;
  };

-static struct whold_timing whold_timing[] = {
+static const struct whold_timing whold_timing[] = {

  	{XFER_UDMA_5, 0},
  	{XFER_UDMA_4, 0},
@@ -101,10 +106,10 @@
   * but rather "fast" and "slow" timing.  We have to determeine
   * which is the "fast" device based upon their capability.
   */
-static int pio_mode[2];
+static int pio_mode[2] = { -1, -1 };
+

-/* Structure of the memory mapped IDE control.
-*/
+/* structure of the memory mapped IDE control */
  typedef struct ide_regs {
  	unsigned int si_stat;	/* IDE status */
  	unsigned int si_intenable;	/* IDE interrupt enable */
@@ -114,8 +119,8 @@
  	unsigned int si_c0fpt;	/* Chan 0 Fast PIO transfer timing */
  	unsigned int si_c0timo;	/* Chan 0 timeout */
  	unsigned int pad1[2];
-	unsigned int si_c0d0u;	/* Chan 0 UDMA transfer timing */
-#define si_c0d0m si_c0d0u	/* Chan 0 Multiword DMA timing */
+	unsigned int si_c0d0u;	/* Chan 0 dev 0 UDMA timing */
+#define si_c0d0m si_c0d0u	/* Chan 0 dev 0 Multiword DMA timing */
  	unsigned int pad2;
  	unsigned int si_c0d1u;	/* Chan 0 dev 1 UDMA timing */
  #define si_c0d1m si_c0d1u	/* Chan 0 dev 1 Multiword DMA timing */
@@ -148,84 +153,74 @@
  	unsigned int prd_physptr;
  	unsigned int prd_count;	/* Count only in lower 16 bits */
  } prd_entry_t;
-#define PRD_EOT		(uint)0x80000000	/* Set in prd_count */
+#define PRD_EOT		0x80000000lu	/* Set in prd_count */

  /* The number of PRDs required in a single transfer from the upper IDE
- * functions.  I believe the maximum number is 128, but most seem to
- * code to 256.  It's probably best to keep this under one page......
+ * functions. The maximum number is 128 (ide.h), but most seem to code to
+ * 256 (because of having two IDE channels). must be less than one page.
   */
-#define NUM_PRD	256
+#define NUM_PRD 256

-static volatile ide_t *idp;
-/* Virtual and physical address of the PRD page.
-*/
-static prd_entry_t *prd_table;
-static dma_addr_t prd_phys;
-
-/* Function Prototypes */
-static void ocp_ide_tune_drive(ide_drive_t *, byte);
-static int ocp_ide_dma_off(ide_drive_t * drive);

-/* The STB04 has a fixed number of cycles that get added in
- * regardless.  Adjust an ide_timing struct to accommodate that.
- */
-static void
-ocp_ide_adjust_timing(struct ide_timing *t)
-{
-	t->setup -= 2;
-	t->act8b -= 1;
-	t->rec8b -= 1;
-	t->active -= 1;
-	t->recover -= 1;
-}

-/* this iis barrowed from ide_timing_find_mode so we can find the proper
- * whold parameter
+/* this is borrowed from ide_timing_find_mode so we can find the proper
+ * whold parameter
   */
-
  static short
  whold_timing_find_mode(short speed)
  {
-	struct whold_timing *t;
+	const struct whold_timing *t;
+
+	for (t = whold_timing; likely (t->mode >= 0); t++)
+		if (t->mode == speed)
+			return t->whold;

-	for (t = whold_timing; t->mode != speed; t++)
-		if (t->mode < 0)
-			return 0;
-	return t->whold;
+	return 0;
+}
+
+/* The STB04 has a fixed number of cycles that get added in
+ * regardless.  Adjust an ide_timing struct to accommodate that.
+ */
+static void
+stb04xxx_ide_adjust_timing(struct ide_timing * const t)
+{
+	t->setup   -= 2;
+	t->act8b   -= 1;
+	t->rec8b   -= 1;
+	t->active  -= 1;
+	t->recover -= 1;
  }

  static int
-ocp_ide_set_drive(ide_drive_t * drive, unsigned char speed)
+stb04xxx_ide_tune_chipset (ide_drive_t * const drive,
+			   u8           speed)
  {
-	ide_drive_t *peer;
-	struct ide_timing d, p, merge, *fast;
-	int fast_device;
-	unsigned int ctl;
-	volatile unsigned int *dtiming;
+	volatile ide_t __iomem * const ide_regs  = HWIF (drive)->hwif_data;
+	ide_drive_t       *peer        = HWIF (drive)->drives + (~drive->dn & 1);
+	struct ide_timing  t, p, merge, *fast;
+	int                fast_device;
+	unsigned int       ctl;

  	if (speed != XFER_PIO_SLOW && speed != drive->current_speed)
  		if (ide_config_drive_speed(drive, speed))
-			printk(KERN_WARNING
-			       "ide%d: Drive %d didn't accept speed setting. Oh, well.\n",
-			       drive->dn >> 1, drive->dn & 1);
-
-	ide_timing_compute(drive, speed, &d, SYS_CLOCK_NS, SYS_CLOCK_NS);
-	ocp_ide_adjust_timing(&d);
+			printk (KERN_WARNING
+				"ide%d: Drive %d didn't accept speed setting. "
+				"Oh, well.\n",
+				drive->dn >> 1, drive->dn & 1);

-	/* This should be set somewhere else, but it isn't.....
-	 */
-	drive->dn = ((drive->select.all & 0x10) != 0);
-	peer = HWIF(drive)->drives + (~drive->dn & 1);
+	ide_timing_compute(drive, speed, &t, SYS_CLOCK_NS, SYS_CLOCK_NS);
+	stb04xxx_ide_adjust_timing(&t);

+	/* peer is the other, i.e. not current, drive */
  	if (peer->present) {
  		ide_timing_compute(peer, peer->current_speed, &p,
  				   SYS_CLOCK_NS, SYS_CLOCK_NS);
-		ocp_ide_adjust_timing(&p);
-		ide_timing_merge(&p, &d, &merge,
+		stb04xxx_ide_adjust_timing(&p);
+		ide_timing_merge(&p, &t, &merge,
  				 IDE_TIMING_8BIT | IDE_TIMING_SETUP);
-	} else {
-		merge = d;
  	}
+	else
+		merge = t;

  	if (!drive->init_speed)
  		drive->init_speed = speed;
@@ -235,58 +230,59 @@
  	 * interface timing.  It would sure be nice if they would
  	 * have just had the timing registers for each device......
  	 */
-	if (drive->dn & 1)
-		pio_mode[1] = (int) speed;
-	else
-		pio_mode[0] = (int) speed;
-
-	if (pio_mode[0] > pio_mode[1])
-		fast_device = 0;
-	else
-		fast_device = 1;
+	/* change pio_mode of current drive */
+	pio_mode[(drive->dn & 1)] = (int) speed;

  	/* Now determine which of the drives
  	 * the first call we only know one device, and on subsequent
  	 * calls the user may manually change drive parameters.
  	 * Make timing[0] the fast device and timing[1] the slow.
  	 */
+
+	/* compare pio_mode of both drives, one of them is
+	   faster than the other */
+	if (pio_mode[0] >= pio_mode[1])
+		fast_device = 0;
+	else
+		fast_device = 1;
+
  	if (fast_device == (drive->dn & 1))
-		fast = &d;
+		/* if fast drive == current drive */
+		fast = &t;
  	else
+		/* if fast drive == peer (other) drive */
  		fast = &p;

  	/* Now we know which device is the fast one and which is
  	 * the slow one.  The merged timing goes into the "regular"
  	 * timing registers and represents the slower of both times.
  	 */
-
-	idp->si_c0rt = MK_TIMING(merge.setup, merge.act8b,
-				 merge.rec8b,
-				 whold_timing_find_mode(merge.mode));
-
-	idp->si_c0fpt = MK_TIMING(fast->setup, fast->act8b,
-				  fast->rec8b,
-				  whold_timing_find_mode(fast->mode));
-
-	/* Tell the interface which drive is the fast one.
-	 */
-	ctl = idp->si_c0c;	/* Chan 0 Control */
-	ctl &= ~0x10000000;
+	ide_regs->si_c0rt = MK_TIMING(merge.setup, merge.act8b,
+				      merge.rec8b,
+				      whold_timing_find_mode(merge.mode));
+
+	ide_regs->si_c0fpt = MK_TIMING(fast->setup, fast->act8b,
+				       fast->rec8b,
+				       whold_timing_find_mode(fast->mode));
+
+	/* tell the interface which drive is the fast one. 	 */
+	ctl = ide_regs->si_c0c; /* Chan 0 Control */
+	ctl &= ~0x10000000ul;
  	ctl |= fast_device << 28;
-	idp->si_c0c = ctl;
+	ide_regs->si_c0c = ctl;

-	/* Set up DMA timing.
-	 */
+	/* Set up DMA timing. */
  	if ((speed & XFER_MODE) != XFER_PIO) {
  		/* NOTE: si_c0d0m and si_c0d0u are two different names
  		 * for the same register.  Whether it is used for
  		 * Multi-word DMA timings or Ultra DMA timings is
  		 * determined by the LSB written into it.  This is also
  		 * true for si_c0d1m and si_c0d1u.  */
+		volatile unsigned int __iomem *dtiming;
  		if (drive->dn & 1)
-			dtiming = &(idp->si_c0d1m);
+			dtiming = &(ide_regs->si_c0d1u);
  		else
-			dtiming = &(idp->si_c0d0m);
+			dtiming = &(ide_regs->si_c0d0u);

  		if ((speed & XFER_MODE) == XFER_UDMA) {
  			static const int tRP[] = {
@@ -295,18 +291,18 @@
  				EZ(100, SYS_CLOCK_NS) - 2 /*fixed cycles */ ,
  				EZ(100, SYS_CLOCK_NS) - 2 /*fixed cycles */ ,
  				EZ(100, SYS_CLOCK_NS) - 2 /*fixed cycles */ ,
-				EZ(85, SYS_CLOCK_NS) - 2	/*fixed cycles */
+				EZ( 85, SYS_CLOCK_NS) - 2 /*fixed cycles */
  			};
  			static const int NUMtRP =
  			    (sizeof (tRP) / sizeof (tRP[0]));
  			*dtiming =
-			    MK_UTIMING(d.udma,
+			    MK_UTIMING(t.udma,
  				       tRP[FIT(speed & 0xf, 0, NUMtRP - 1)]);
  		} else {
-			/* Multi-word DMA.  Note that d.recover/2 is an
+			/* Multi-word DMA.  Note that t.recover/2 is an
  			 * approximation of MAX(tH, MAX(tJ, tN)) */
-			*dtiming = MK_TIMING(d.setup, d.active,
-					     d.recover, d.recover / 2);
+			*dtiming = MK_TIMING(t.setup, t.active,
+					     t.recover, t.recover / 2);
  		}
  		drive->using_dma = 1;
  	}
@@ -314,590 +310,547 @@
  	return 0;
  }

+/**
+ *	stb04xxx_ide_tune_drive - tune a drive attached to a stb04
+ *	@drive: drive to tune
+ *	@pio: desired PIO mode (255 for "best possible")
+ *
+ *	Set the interface PIO mode.
+ */
  static void
-ocp_ide_tune_drive(ide_drive_t * drive, byte pio)
+stb04xxx_ide_tune_drive (ide_drive_t * const drive,
+			 u8           pio)
  {
-	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+	pio = ide_get_best_pio_mode (drive, pio, 4, NULL);
+	stb04xxx_ide_tune_chipset(drive, XFER_PIO_0 + pio);
  }

-/*
- * Fill in the next PRD entry.
- */
-
-static int ocp_ide_build_prd_entry(prd_entry_t **table, unsigned int paddr,
-				   unsigned int size, int *count)
+static int
+stb04xxx_ide_dma_host_off (ide_drive_t * const drive)
  {
+	return 0;
+}
+static int stb04xxx_ide_dma_host_on (ide_drive_t * const drive) __attribute__((alias("stb04xxx_ide_dma_host_off")));

-	/*
-	 * Note that one PRD entry can transfer
-	 * at most 65535 bytes.
-	 */
-
-	while (size) {
-		unsigned int tc = (size < 0xfe00) ? size : 0xfe00;
+static int
+stb04xxx_ide_dma_off_quietly (ide_drive_t * const drive)
+{
+	drive->using_dma = 0;
+	return stb04xxx_ide_dma_host_off (drive);
+}

-		if (++(*count) >= NUM_PRD) {
-		  printk(KERN_WARNING "DMA table too small\n");
-			return 0;	/* revert to PIO for this request */
-		}
-		(*table)->prd_physptr = (paddr & 0xfffffffe);
+#if 0
+static int
+config_drive_for_dma (ide_drive_t * const drive)
+{
+	struct hd_driveid * const id   = drive->id;
+	ide_hwif_t        * const hwif = HWIF (drive);

-		if ((*table)->prd_physptr & 0xF) {
-			printk(KERN_WARNING "DMA buffer not 16 byte aligned.\n");
-			return 0;	/* revert to PIO for this request */
-		}
-		
-		(*table)->prd_count = (tc & 0xfffe);
-		paddr += tc;
-		size -= tc;
-		++(*table);
+	if ((id->capability & 1) && hwif->autodma) {
+		/* Consult the list of known "bad" drives */
+		if (0)
+			return stb04xxx_ide_dma_off_quietly (drive);
+
+		/* enable DMA on any drive that has
+		   UltraDMA (mode 0/1/2/3/4/5) enabled */
+                if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x3f))
+			return stb04xxx_ide_dma_on (drive);
+
+		/* enable DMA on any drive that has mode2 DMA
+		   (multi) enabled */
+		if (id->field_valid & 2)
+                        if ((id->dma_mword & 0x404) == 0x404)
+				return stb04xxx_ide_dma_on (drive);
+
+		/* Consult the list of known "good" drives */
+		if (1)
+			return stb04xxx_ide_dma_on (drive);
  	}
-
-	return 1;
+	return stb04xxx_ide_dma_off_quietly (drive);
  }
+#endif

-
+/**
+ *	stb04xxx_ide_dma_check - set up for DMA if possible
+ *	@drive: IDE drive to set up
+ *
+ *	Set up the drive for the highest supported speed considering the
+ *	driver, controller and cable
+ */
  static int
-ocp_ide_build_dmatable(ide_drive_t * drive, int wr)
+stb04xxx_ide_dma_check (ide_drive_t * const drive)
  {
-	prd_entry_t *table;
-	int count = 0;
-	struct request *rq = HWGROUP(drive)->rq;
-	unsigned long size, vaddr, paddr;
-	unsigned long prd_size, prd_paddr = 0;
-	struct bio_vec *bvec, *bvprv;
-	struct bio *bio;
-	int i;
+#if 0
+	return config_drive_for_dma (drive);
+#else
+	/* Allow UDMA_66 only if an 80 conductor cable is connected. */
+	u16 w80 = HWIF (drive)->udma_four;

-	table = prd_table;
+	/* Section 1.6.2.6 "IDE Controller, ATA/ATAPI-5" in the STB04xxx
+	 * Datasheet says the following modes are supported:
+	 *   PIO modes 0 to 4
+	 *   Multiword DMA modes 0 to 2
+	 *   UltraDMA modes 0 to 4
+	 */
+	int modes = XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA
+		    | (w80 ? XFER_UDMA_66 : 0);
+	int mode;
+
+	/* XFER_EPIO includes both PIO modes 4 and 5.  Mode 5 is not
+	 * valid for the STB04, so mask it out of consideration just
+	 * in case some drive sets it...
+	 */
+	drive->id->eide_pio_modes &= ~4;

-	bvprv = NULL;
-	rq_for_each_bio(bio, rq) {
-		bio_for_each_segment(bvec, bio, i) {
-			paddr = bvec_to_phys(bvec);
-			vaddr = (unsigned long) __va(paddr);
-			size = bvec->bv_len;
-			if (wr)
-				consistent_sync((void *)vaddr,
-						size, PCI_DMA_TODEVICE);
-			else
-				consistent_sync((void *)vaddr,
-						size, PCI_DMA_FROMDEVICE);
-
-			if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) {
-				if (ocp_ide_build_prd_entry(&table,
-							    prd_paddr,
-							    prd_size,
-							    &count) == 0)
-					return 0; /* use PIO */
-				prd_paddr = 0;
-			}
-
-			if (prd_paddr == 0) {
-				prd_paddr = paddr;
-				prd_size = size;
-			} else {
-			  prd_size += size;
-			}
-
-			bvprv = bvec;
-		} /* segments in bio */
-	} /* bios in rq */
-
-	if (prd_paddr) {
-		if (ocp_ide_build_prd_entry(&table,
-					    prd_paddr,
-					    prd_size,
-					    &count) == 0)
-			return 0; /* use PIO */
-	}
+	mode = ide_find_best_mode (drive, modes);

-	/* Add the EOT to the last table entry.
-	 */
-	if (count) {
-		table--;
-		table->prd_count |= PRD_EOT;
-	} else {
-		printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
-	}
+	drive->using_dma = 0;
+	stb04xxx_ide_tune_chipset (drive, mode);
+	if (HWIF (drive)->autodma
+	    && (((mode & XFER_MODE) == XFER_PIO)
+		|| ((mode & XFER_MODE) == XFER_EPIO)))
+		drive->using_dma = 0;

-	return 1;
+	return 0;
+#endif
  }

-/*
- * ocp_ide_dma_intr() is the handler for disk read/write DMA interrupts
- * This is taken directly from ide-dma.c, which we can't use because
- * it requires PCI support.
- */
-ide_startstop_t
-ocp_ide_dma_intr(ide_drive_t * drive)
+static int
+stb04xxx_ide_dma_on (ide_drive_t * const drive)
  {
-	int i;
-	byte stat, dma_stat;
-
-	dma_stat = HWIF(drive)->ide_dma_end(drive);
-	stat = HWIF(drive)->INB(IDE_STATUS_REG);	/* get drive status */
-	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
-		if (!dma_stat) {
-			struct request *rq = HWGROUP(drive)->rq;
-			rq = HWGROUP(drive)->rq;
-			for (i = rq->nr_sectors; i > 0;) {
-				i -= rq->current_nr_sectors;
-				ide_end_request(drive, 1,
-						rq->current_nr_sectors );
-			}
-			return ide_stopped;
-		}
-		printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
-		       drive->name, dma_stat);
-	}
-	return ide_error(drive, "dma_intr", stat);
+	drive->using_dma = 1;
+	return stb04xxx_ide_dma_host_on (drive);
  }

-/* ....and another one....
-*/
-int
-report_drive_dmaing(ide_drive_t * drive)
-{
-	struct hd_driveid *id = drive->id;

-	if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-	    (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
-		if ((id->dma_ultra >> 13) & 1) {
-			printk(", UDMA(100)");	/* UDMA BIOS-enabled! */
-		} else if ((id->dma_ultra >> 12) & 1) {
-			printk(", UDMA(66)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(44)");	/* UDMA BIOS-enabled! */
-		}
-	} else if ((id->field_valid & 4) &&
-		   (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
-		if ((id->dma_ultra >> 10) & 1) {
-			printk(", UDMA(33)");	/* UDMA BIOS-enabled! */
-		} else if ((id->dma_ultra >> 9) & 1) {
-			printk(", UDMA(25)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(16)");	/* UDMA BIOS-enabled! */
-		}
-	} else if (id->field_valid & 4) {
-		printk(", (U)DMA");	/* Can be BIOS-enabled! */
-	} else {
-		printk(", DMA");
-	}
-	return 1;
-}

+/* fill in the next PRD entry
+   note that one PRD entry can transfer at most 65536 bytes */
  static int
-ocp_ide_check_dma(ide_drive_t * drive)
+build_prd_entry (prd_entry_t **table,
+		 u32           paddr,
+		 u32           size,
+		 int          *count)
  {
-	struct hd_driveid *id = drive->id;
-	int enable = 1;
-	int speed;
+	while (size) {
+		u16 tc = size & 0xffff;

-	drive->using_dma = 0;
+		if (unlikely (*count >= NUM_PRD)) {
+//			printk (KERN_WARNING "%s: DMA table too small\n",
+//					     __FUNCTION__);
+			return 0;	/* revert to PIO for this request */
+		}

-	if (drive->media == ide_floppy)
-		enable = 0;
+		/* data must be 16 byte aligned */
+		if (unlikely (paddr & 0xf)) {
+//			printk (KERN_WARNING
+//				"%s: DMA buffer not 16 byte aligned.\n",
+//				__FUNCTION__);
+			return 0;	/* revert to PIO for this request */
+		}

-	/* Check timing here, we may be able to include XFER_UDMA_66
-	 * and XFER_UDMA_100.  This basically tells the 'best_mode'
-	 * function to also consider UDMA3 to UDMA5 device timing.
-	 */
-	if (enable) {
-		/* Section 1.6.2.6 "IDE Controller, ATA/ATAPI-5" in the STB04xxx
-		 * Datasheet says the following modes are supported:
-		 *   PIO modes 0 to 4
-		 *   Multiword DMA modes 0 to 2
-		 *   UltraDMA modes 0 to 4
-		 */
-		int map = XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA;
-		/* XFER_EPIO includes both PIO modes 4 and 5.  Mode 5 is not
-		 * valid for the STB04, so mask it out of consideration just
-		 * in case some drive sets it...
-		 */
-		id->eide_pio_modes &= ~4;
-
-		/* Allow UDMA_66 only if an 80 conductor cable is connected. */
-		if (eighty_ninty_three(drive))
-			map |= XFER_UDMA_66;
-
-		speed = ide_find_best_mode(drive, map);
-		ocp_ide_set_drive(drive, speed);
-
-		if (HWIF(drive)->autodma &&
-		    (((speed & XFER_MODE) == XFER_PIO) ||
-		     ((speed & XFER_MODE) == XFER_EPIO))) {
-			drive->using_dma = 0;
+		/* transfer count must be a multiple of 16 */
+		if (unlikely (tc & 0x0f)) {
+//			printk (KERN_WARNING
+//				"%s: invalid DMA transfer count.\n",
+//				__FUNCTION__);
+			return 0;	/* revert to PIO for this request */
  		}
+		
+		(*table)->prd_physptr = paddr;
+		(*table)->prd_count   = tc;
+
+		paddr += (tc ? : 65536);
+		size  -= (tc ? : 65536);
+
+		++(*table);
+		++(*count);
  	}

-	return 0;
+	return 1;
  }

-static int ocp_ide_dma_off_quietly(ide_drive_t * drive)
+static int
+stb04xxx_ide_build_sglist (ide_drive_t        * const drive,
+			   ide_hwif_t         * const hwif,
+			   struct request     * const rq,
+			   struct scatterlist *sg)
  {
-	drive->using_dma = 0;
-	return 0;
-}
+	if ((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256)
+		BUG();

-static int ocp_ide_dma_off(ide_drive_t * drive)
-{
-	printk(KERN_INFO "%s: DMA disabled\n", drive->name);
-	return ocp_ide_dma_off_quietly(drive);
-}
+	ide_map_sg(drive, rq);

-static int ocp_ide_dma_on(ide_drive_t * drive)
-{
-	return ocp_ide_check_dma(drive);
+	hwif->sg_dma_direction = (rq_data_dir (rq) == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+	
+	return dma_map_sg(/* hwif->pci_dev */ NULL, sg, hwif->sg_nents,
+			  hwif->sg_dma_direction);
  }

-static int ocp_ide_dma_check(ide_drive_t * drive)
+static int
+stb04xxx_ide_build_dmatable (ide_drive_t    * const drive,
+			     ide_hwif_t     * const hwif,
+			     struct request * const rq)
  {
-	return ocp_ide_dma_on(drive);
-}
+	prd_entry_t  *table = (prd_entry_t *) hwif->dmatable_cpu;
+	unsigned int  count = 0;
+	int i;
+	struct scatterlist *sg = hwif->sg_table;

-static int __ocp_ide_dma_begin(ide_drive_t * drive, int writing)
-{
-	idp->si_c0tb = (unsigned int) prd_phys;
-	idp->si_c0s0 = 0xdc800000;	/* Clear all status */
-	idp->si_c0ie = 0x90000000;	/* Enable all intr */
-	idp->si_c0dcm = 0;
-	idp->si_c0dcm =
-		(writing ? 0x09000000 : 0x01000000);
-	return 0;
+	hwif->sg_nents = i = stb04xxx_ide_build_sglist (drive, hwif, rq, sg);
+
+	if (unlikely (!i))
+		goto use_pio_instead;
+	
+	++i;
+	while (--i) {
+		if (unlikely (!build_prd_entry (&table,
+						sg_dma_address (sg),
+						sg_dma_len (sg),
+						&count)))
+			goto use_pio_instead;
+
+		++sg;
+	}
+
+	if (likely (count)) {
+		--table;
+		table->prd_count |= PRD_EOT;
+		return count;
+	}
+
+	printk (KERN_ERR "%s: empty DMA table?\n", drive->name);
+
+use_pio_instead:
+	dma_unmap_sg (NULL,
+		      hwif->sg_table, hwif->sg_nents, hwif->sg_dma_direction);
+	
+	return 0; /* revert to PIO for this request */
  }
+	

-static int ocp_ide_dma_begin(ide_drive_t * drive)
+static void
+stb04xxx_ide_destroy_dmatable (ide_drive_t * const drive)
  {
-	idp->si_c0tb = (unsigned int) prd_phys;
-	idp->si_c0s0 = 0xdc800000;	/* Clear all status */
-	idp->si_c0ie = 0x90000000;	/* Enable all intr */
-	idp->si_c0dcm = 0;
-	idp->si_c0dcm =	0x01000000;
-	return 0;
+	ide_hwif_t *hwif = drive->hwif;
+	int nents = hwif->sg_nents;
+	
+	if (nents) {
+		dma_unmap_sg (NULL, hwif->sg_table, nents,
+			      hwif->sg_dma_direction);
+		hwif->sg_nents = 0;
+	}
  }

-static int ocp_ide_dma_io(ide_drive_t * drive, int writing)
+
+static int
+stb04xxx_dma_setup (ide_drive_t * const drive)
  {
-	if (!ocp_ide_build_dmatable(drive, writing))
+	ide_hwif_t             * const hwif = HWIF (drive);
+	volatile ide_t __iomem * const ide_regs = (ide_t *) hwif->hwif_data;
+	struct request         * const rq = HWGROUP (drive)->rq;
+
+	/* PRD table */
+	if (unlikely (!stb04xxx_ide_build_dmatable (drive, hwif, rq))) {
+		/* try PIO instead of DMA */
+		ide_map_sg (drive, rq);
  		return 1;
+	}
+
+	ide_regs->si_c0tb = hwif->dmatable_dma; /* address of sg list */
+	ide_regs->si_c0s0 = 0xdc800000ul;       /* clear all status */
+	ide_regs->si_c0ie = 0x90000000ul;       /* enable all intr */
+	/* specify r/w */
+	ide_regs->si_c0dcm = (rq_data_dir (rq) == READ) ? 0x00000000ul : 0x08000000ul;

  	drive->waiting_for_dma = 1;
-	if (drive->media != ide_disk)
-		return 0;
-	ide_set_handler(drive, &ocp_ide_dma_intr, WAIT_CMD, NULL);
-	HWIF(drive)->OUTB(writing ? WIN_WRITEDMA : WIN_READDMA,
-		 IDE_COMMAND_REG);
-	return __ocp_ide_dma_begin(drive, writing);
+	return 0;
  }

-static int ocp_ide_dma_read(ide_drive_t * drive)
+static void
+stb04xxx_dma_exec_cmd (ide_drive_t * const drive,
+		       u8           command)
  {
-	return ocp_ide_dma_io(drive, 0);
+	ide_execute_command (drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
  }

-static int ocp_ide_dma_write(ide_drive_t * drive)
+static void
+stb04xxx_dma_start (ide_drive_t * const drive)
  {
-	return ocp_ide_dma_io(drive, 1);
+	volatile ide_t __iomem * const ide_regs  = (ide_t *) HWIF (drive)->hwif_data;
+
+	/* start DMA */
+	mb ();
+	ide_regs->si_c0dcm |= 0x01000000ul; /* kick it */
  }

-static int ocp_ide_dma_end(ide_drive_t * drive)
+static int
+stb04xxx_ide_dma_end (ide_drive_t * const drive)
  {
-	unsigned int dstat;
+	volatile ide_t __iomem * const ide_regs = (ide_t *) HWIF (drive)->hwif_data;
+	unsigned int    dstat;

  	drive->waiting_for_dma = 0;
-	dstat = idp->si_c0s1;
-	idp->si_c0s0 = 0xdc800000;	/* Clear all status */
+	/* stop DMA */
+	ide_regs->si_c0dcm &= ~0x01000000ul;
+	/* get DMA status */
+	dstat = ide_regs->si_c0s1;
+	/* clear all status bits */
+	ide_regs->si_c0s0 = 0xdc800000ul;
+	wmb ();
+	stb04xxx_ide_destroy_dmatable (drive);
  	/* verify good dma status */
-	return (dstat & 0x80000000);
-}
-
-static int ocp_ide_dma_test_irq(ide_drive_t * drive)
-{
-	return idp->si_c0s0 & 0x10000000 ? 1 : 0;
+	return (dstat & 0x10000000ul) ? 0 : 1; /* return true if DMA still active */
  }

-static int ocp_ide_dma_verbose(ide_drive_t * drive)
-{
-	return report_drive_dmaing(drive);
-}
-
-static unsigned int
-ocp_ide_spinup(int index)
+static int
+stb04xxx_ide_dma_test_irq (ide_drive_t * const drive)
  {
-	int i, ret;
-	ide_ioreg_t *io_ports;
+	/* return 1 if dma irq issued, 0 otherwise */
+	volatile ide_t __iomem * const ide = (ide_t *) HWIF (drive)->hwif_data;

-	ret = 1;
-	printk("OCP ide: waiting for drive spinup");
-	printk("ioports for drive %d @ %p\n",index,ide_hwifs[index].io_ports);
-	io_ports = ide_hwifs[index].io_ports;
-	printk(".");
-	
-	/* wait until drive is not busy (it may be spinning up) */
-	for (i = 0; i < 30; i++) {
-		unsigned char stat;
-		stat = inb_p(io_ports[7]);
-		/* wait for !busy & ready */
-		if ((stat & 0x80) == 0) {
-			break;
-		}
-		udelay(1000 * 1000);	/* 1 second */
+	if (ide->si_c0s0 & 0x10000000ul)
+		return 1;
+	if (!drive->waiting_for_dma) {
+		printk(KERN_WARNING "%s: (%s) called while not waiting\n",
+				    drive->name, __FUNCTION__);	
  	}

-	printk(".");
+	return 0;
+}

-	/* select slave */
-	outb_p(0xa0 | 0x10, io_ports[6]);

-	for (i = 0; i < 30; i++) {
-		unsigned char stat;
-		stat = inb_p(io_ports[7]);
-		/* wait for !busy & ready */
-		if ((stat & 0x80) == 0) {
-			break;
-		}
-		udelay(1000 * 1000);	/* 1 second */
-	}
-	if( i < 30){
-		outb_p(0xa0, io_ports[6]);
-		printk("Drive spun up \n");
-	} else {
-		printk("Drive spin up Failed !\n");
-		ret = 0;
-	}
-	return (ret);
+static int
+stb04xxx_ide_dma_lostirq (ide_drive_t * const drive)
+{
+	printk ("%s: DMA interrupt recovery neccessary\n", drive->name);
+	return 1;
  }

-int
-ocp_ide_default_irq(ide_ioreg_t base)
+static int
+stb04xxx_ide_dma_timeout (ide_drive_t * const drive)
  {
-	return IDE0_IRQ;
+	printk (KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+	if (stb04xxx_ide_dma_test_irq (drive))
+		return 0;
+	return stb04xxx_ide_dma_end (drive);
  }

-/*
- * setup_ocp_ide()
- * Completes the setup of a on-chip ide controller card, once found.
- */
-int __init setup_ocp_ide (struct ocp_device *pdev)
+static void
+stb04xxx_ide_setup_dma (ide_hwif_t * const hwif)
  {
-	ide_hwif_t	*hwif;
-	unsigned int uicdcr;
-	
-	hwif = &ide_hwifs[pdev->num];
-	hwif->index = pdev->num;
-#ifdef WMODE
-   /*Word Mode psc(11-12)=00,pwc(13-18)=000110, phc(19-21)=010, 22=1, 30=1  ----  0xCB02*/
-
-    dma_ch.mode	=TM_S_MM;	  /* xfer from peripheral to mem */
-    dma_ch.pwidth = PW_16;
-    dma_ch.pwc = 6;                     /* set the max wait cycles  */
-#else
-/*Line Mode psc(11-12)=00,pwc(13-18)=000001, phc(19-21)=010, 22=1, 30=1  ----  0x2B02*/
+	hwif->autodma = 1;
+	hwif->drives[0].autotune = hwif->drives[1].autotune = IDE_TUNE_AUTO;
+	hwif->drives[0].autodma  = hwif->drives[1].autodma  = hwif->autodma;
+
+	hwif->atapi_dma  = 1;
+	hwif->ultra_mask = hwif->udma_four ? 0x1f : 0x07;
+	hwif->mwdma_mask = 0x07;
+	hwif->swdma_mask = 0x00;
+
+	/* set everything to something != NULL */
+	hwif->ide_dma_host_off = &stb04xxx_ide_dma_host_off;
+	hwif->ide_dma_host_on  = &stb04xxx_ide_dma_host_on;
+
+	hwif->ide_dma_check = &stb04xxx_ide_dma_check;
+	hwif->ide_dma_off_quietly = &stb04xxx_ide_dma_off_quietly;
+	hwif->ide_dma_on          = &stb04xxx_ide_dma_on;
+
+	hwif->dma_setup    = &stb04xxx_dma_setup;
+	hwif->dma_exec_cmd = &stb04xxx_dma_exec_cmd;
+	hwif->dma_start    = &stb04xxx_dma_start;
+	hwif->ide_dma_end  = &stb04xxx_ide_dma_end;

-    dma_ch.mode	=DMA_MODE_MM_DEVATSRC;	  /* xfer from peripheral to mem */
-    dma_ch.pwidth = PW_64;		/* Line mode on stbs */
-    dma_ch.pwc = 1;                     /* set the max wait cycles  */
-#endif
+	hwif->ide_dma_test_irq = &stb04xxx_ide_dma_test_irq;

-    dma_ch.td	= DMA_TD;
-    dma_ch.buffer_enable = 0;
-    dma_ch.tce_enable = 0;
-    dma_ch.etd_output = 0;
-    dma_ch.pce = 0;
-    dma_ch.pl = EXTERNAL_PERIPHERAL;    /* no op */
-    dma_ch.dai = 1;
-    dma_ch.sai = 0;
-    dma_ch.psc = 0;                      /* set the max setup cycles */
-    dma_ch.phc = 2;                      /* set the max hold cycles  */
-    dma_ch.cp = PRIORITY_LOW;
-    dma_ch.int_enable = 0;
-    dma_ch.ch_enable = 0;		/* No chaining */
-    dma_ch.tcd_disable = 1;		/* No chaining */
-
-    if (hw_init_dma_channel(IDE_DMACH, &dma_ch) != DMA_STATUS_GOOD)
-        return -EBUSY;
-
-    /* init CIC select2 reg to connect external DMA port 3 to internal
-     * DMA channel 2
-     */
-    map_dma_port(IDE_DMACH,EXT_DMA_3,DMA_CHAN_2);
-
-    /* Enable the interface.
-     */
-    idp->si_control = 0x80000000;
-    idp->si_c0s0 = 0xdc800000;	/* Clear all status */
-    idp->si_intenable = 0x80000000;
-
-    /* Per the STB04 data sheet:
-     *  1)  tTO = ((8*RDYT) + 1) * SYS_CLK
-     * and:
-     *  2)  tTO >= 1250 + (2 * SYS_CLK) - t2
-     * Solving the first equation for RDYT:
-     *             (tTO/SYS_CLK) - 1
-     *  3)  RDYT = -----------------
-     *                     8
-     * Substituting equation 2) for tTO in equation 3:
-     *             ((1250 + (2 * SYS_CLK) - t2)/SYS_CLK) - 1
-     *  3)  RDYT = -----------------------------------------
-     *                                8
-     * It's just the timeout so having it too long isn't too
-     * significant, so we'll just assume t2 is zero.  All this math
-     * is handled by the compiler and RDYT ends up being 11 assuming
-     * that SYS_CLOCK_NS is 15.
-     */
-    idp->si_c0timo = (EZ(EZ(1250 + 2 * SYS_CLOCK_NS, SYS_CLOCK_NS) - 1, 8)) << 23;	/* Chan 0 timeout */
-
-    /* Stuff some slow default PIO timing.
-     */
-    idp->si_c0rt = MK_TIMING(6, 19, 15, 2);
-    idp->si_c0fpt = MK_TIMING(6, 19, 15, 2);
-
-    /* We should probably have UIC functions to set external
-     * interrupt level/edge.
-     */
-    uicdcr = mfdcr(DCRN_UIC_PR(UIC0));
-    uicdcr &= ~(0x80000000 >> IDE0_IRQ);
-    mtdcr(DCRN_UIC_PR(UIC0), uicdcr);
-    mtdcr(DCRN_UIC_TR(UIC0), 0x80000000 >> IDE0_IRQ);
-
-    /* Grab a page for the PRD Table.
-     */
-    prd_table = (prd_entry_t *) consistent_alloc(GFP_KERNEL,
-						 NUM_PRD *
-						 sizeof
-						 (prd_entry_t),
-						 &prd_phys);
-
-
-    if(!ocp_ide_spinup(hwif->index))
-	    return 0;
-
-    return 1;
+	hwif->ide_dma_lostirq = &stb04xxx_ide_dma_lostirq;
+	hwif->ide_dma_timeout = &stb04xxx_ide_dma_timeout;
  }

-
-static int __devinit ocp_ide_probe(struct ocp_device *pdev)
+static int __init
+stb04xxx_ide_probe (struct ocp_device * const ocp)
  {
-	int i;
-	unsigned int index;
-	hw_regs_t * hw;
-	unsigned char *ip;
-
-	printk("IBM STB04xxx IDE driver version %s\n", IDE_VER);
-
-	hw = kmalloc(sizeof(*hw), GFP_KERNEL);
-	if (!hw)
-		return 0;
-	memset(hw, 0, sizeof(*hw));
-
-	if (!request_region(pdev->paddr, IDE0_SIZE, "IDE")) {
-		printk(KERN_WARNING "ocp_ide: failed request_region\n");
-		return -1;
-	}
-
-	if ((idp = (ide_t *) ioremap(pdev->paddr,
-				     IDE0_SIZE)) == NULL) {
-		printk(KERN_WARNING "ocp_ide: failed ioremap\n");
-		return -1;
+	int                     err;
+	unsigned int            uicdcr;
+	volatile ide_t __iomem *ide_regs;
+	unsigned long           flags;
+	ide_hwif_t             * const hwif = &ide_hwifs[0];
+	unsigned char          * ip;
+	int                     i;
+
+	printk ("IBM STB04xxx OCP IDE driver version %s\n", OCPVR);
+
+	if (!request_region (ocp->def->paddr, sizeof (ide_t), "ide"))
+		return -ENOMEM;
+
+	ocp_force_power_on (ocp);
+
+	ide_regs = ioremap (ocp->def->paddr, sizeof (ide_t));
+	if (unlikely (!ide_regs)) {
+		err = -ENOMEM;
+		goto error1;
  	}

-	pdev->dev.driver_data = (void *) idp;

-	pdev->ocpdev  = (void *) hw;
-	index = pdev->num;
-	ip = (unsigned char *) (&(idp->si_c0d));	/* Chan 0 data */
+	/* Enable the interface. */
+	ide_regs->si_control = 0x80000000ul;
+	ide_regs->si_c0s0 = 0xdc800000ul;       /* Clear all status */
+	ide_regs->si_intenable = 0x80000000ul;
+	/* Per the STB04 data sheet:
+	 *  1)  tTO = ((8*RDYT) + 1) * SYS_CLK
+	 * and:
+	 *  2)  tTO >= 1250 + (2 * SYS_CLK) - t2
+	 * Solving the first equation for RDYT:
+	 *             (tTO/SYS_CLK) - 1
+	 *  3)  RDYT = -----------------
+	 *                     8
+	 * Substituting equation 2) for tTO in equation 3:
+	 *             ((1250 + (2 * SYS_CLK) - t2)/SYS_CLK) - 1
+	 *  3)  RDYT = -----------------------------------------
+	 *                                8
+	 * It's just the timeout so having it too long isn't too
+	 * significant, so we'll just assume t2 is zero.  All this math
+	 * is handled by the compiler and RDYT ends up being 11 assuming
+	 * that SYS_CLOCK_NS is 15.
+	 */
+	ide_regs->si_c0timo = (EZ(EZ(1250 + 2 * SYS_CLOCK_NS, SYS_CLOCK_NS) - 1, 8)) << 23;	/* Chan 0 timeout */

-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = (unsigned long) (ip++);
+	/* stuff some slow default PIO timing */
+	ide_regs->si_c0rt = MK_TIMING(6, 19, 15, 2);
+	ide_regs->si_c0fpt = MK_TIMING(6, 19, 15, 2);
+
+	/* enable 32bit access on both devices */
+	ide_regs->si_c0c |= 0x00008040ul;
+
+	/* we should probably have UIC functions to set external
+	   interrupt level/edge */
+	local_irq_save (flags);
+	uicdcr = mfdcr (DCRN_UIC_PR (UIC0));
+	uicdcr &= ~(0x80000000ul >> IDE0_IRQ);
+	mtdcr (DCRN_UIC_PR(UIC0), uicdcr);
+	mtdcr (DCRN_UIC_TR(UIC0),
+	       mfdcr (DCRN_UIC_TR (UIC0)) | (0x80000000ul >> IDE0_IRQ));
+	local_irq_restore (flags);
+
+
+	/* initialize */
+	hwif->gendev.parent = &ocp->dev;
+	ocp_set_drvdata (ocp, hwif);
+
+	/* setup MMIO ops */
+	default_hwif_mmiops (hwif);
+
+	/* tell common code _not_ to mess with resources */
+	hwif->mmio = 2;
+	ide_set_hwifdata (hwif, (void *) ide_regs);
+
+	ip = (unsigned char *) (&(ide_regs->si_c0d));    /* Chan 0 data */
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
+		hwif->hw.io_ports[i] = (int) (ip++);
+	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (int) (&(ide_regs->si_c0adc));
+	memcpy (hwif->io_ports, hwif->hw.io_ports, sizeof (hwif->hw.io_ports));
+	hwif->chipset = ide_generic;
+	hwif->irq     = ocp->def->irq;
+	hwif->noprobe = 0;
+	hwif->hold    = 1;
+	/* Figure out if an 80 conductor cable is connected */
+	hwif->udma_four = (ide_regs->si_c0s1 & 0x20000000ul) != 0;
+	hwif->tuneproc  = &stb04xxx_ide_tune_drive;
+	hwif->speedproc = &stb04xxx_ide_tune_chipset;
+	hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1;
+	hwif->drives[0].unmask   = hwif->drives[1].unmask   = 1;
+	pio_mode[0] = pio_mode[1] = -1;
+	stb04xxx_ide_setup_dma (hwif);
+	
+	/* grab a page for the PRD table. this is save with respect to not
+	   crossing a 64k border because returned memory is page aligned
+	   and NUM_PRD*sizeof(prd_entry_t) end up being 2048 bytes, i.e.
+	   less than one page. */
+	hwif->dmatable_cpu = dma_alloc_coherent (NULL,
+						 NUM_PRD * sizeof (prd_entry_t),
+						 &hwif->dmatable_dma,
+						 GFP_KERNEL | GFP_DMA);
+	if (unlikely (!hwif->dmatable_cpu)) {
+		err = -ENOMEM;
+		goto error2;
  	}
+	hwif->sg_max_nents = NUM_PRD;

-	hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long) (&(idp->si_c0adc));
-	hw->irq = pdev->irq;
-
-	/* use DMA channel 2 for IDE DMA operations */
-	hw->dma = IDE_DMACH;
+	probe_hwif_init (hwif);

-	ide_hwifs[index].tuneproc = &ocp_ide_tune_drive;
-	ide_hwifs[index].drives[0].autotune = 1;
-	ide_hwifs[index].autodma = 1;
-	ide_hwifs[index].ide_dma_off = &ocp_ide_dma_off;
-	ide_hwifs[index].ide_dma_off_quietly = &ocp_ide_dma_off_quietly;
-	ide_hwifs[index].ide_dma_host_off = &ocp_ide_dma_off_quietly;
-	ide_hwifs[index].ide_dma_on = &ocp_ide_dma_on;
-	ide_hwifs[index].ide_dma_host_on = &ocp_ide_dma_on;
-	ide_hwifs[index].ide_dma_check = &ocp_ide_dma_check;
-	ide_hwifs[index].ide_dma_read = &ocp_ide_dma_read;
-	ide_hwifs[index].ide_dma_write = &ocp_ide_dma_write;
-	ide_hwifs[index].ide_dma_begin = &ocp_ide_dma_begin;
-	ide_hwifs[index].ide_dma_end = &ocp_ide_dma_end;
-	ide_hwifs[index].ide_dma_test_irq = &ocp_ide_dma_test_irq;
-	ide_hwifs[index].ide_dma_verbose = &ocp_ide_dma_verbose;
-	ide_hwifs[index].speedproc = &ocp_ide_set_drive;
-	ide_hwifs[index].noprobe = 0;
+	create_proc_ide_interfaces ();

-	memcpy(ide_hwifs[index].io_ports, hw->io_ports, sizeof (hw->io_ports));
-	ide_hwifs[index].irq = pdev->irq;
+	return 0;

-	ocp_force_power_on(pdev);
-	return 1;
+error2:
+	ide_set_hwifdata (hwif, NULL);
+	hwif->noprobe = 1;
+	hwif->chipset = ide_unknown;
+	ocp_set_drvdata (ocp, NULL);
+	iounmap (ide_regs);
+error1:
+	ocp_force_power_off (ocp);
+	release_region (ocp->def->paddr, sizeof (ide_t));
+	return err;
  }

-static void __devexit ocp_ide_remove_one (struct ocp_device *pdev)
+static void
+stb04xxx_ide_remove (struct ocp_device * const ocp)
  {
-	ocp_force_power_off(pdev);
+	ide_hwif_t             * const hwif = ocp_get_drvdata (ocp);
+	volatile ide_t __iomem * const ide_regs = ide_get_hwifdata (hwif);
+
+	/* ide_unregister () can't ever handle these correctly for us */
+	dma_free_coherent (NULL, NUM_PRD * sizeof (prd_entry_t),
+			   hwif->dmatable_cpu, hwif->dmatable_dma);
+	hwif->dmatable_cpu = NULL;
+	hwif->dmatable_dma = 0;
+
+	ide_unregister (hwif->index);
+	iounmap (ide_regs);
+	release_region (ocp->def->paddr, sizeof (ide_t));
+	
+	ocp_force_power_off (ocp);
  }

-static struct ocp_device_id ocp_ide_id_tbl[] __devinitdata = {
-	{OCP_VENDOR_IBM,OCP_FUNC_IDE},
-	{0,}
+
+static struct ocp_device_id stb04xxx_ide_ids[] __devinitdata =
+{
+        { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IDE},
+        { .vendor = OCP_VENDOR_INVALID }
  };

-MODULE_DEVICE_TABLE(ocp,ocp_ide_id_tbl );
+MODULE_DEVICE_TABLE (ocp, stb04xxx_ide_ids);

-static struct ocp_driver ocp_ide_driver = {
-	.name		= "ocp_ide",
-	.id_table	= ocp_ide_id_tbl,
-	.probe		= ocp_ide_probe,
-	.remove		= __devexit_p(ocp_ide_remove_one),
+static struct ocp_driver stb04xxx_ide_driver = {
+	.name     = "ide",
+	.id_table = stb04xxx_ide_ids,
+	.probe    = stb04xxx_ide_probe,
+	.remove   = __devexit_p (stb04xxx_ide_remove),
  #if defined(CONFIG_PM)
-	.suspend	= ocp_generic_suspend,
-	.resume		= ocp_generic_resume,
-#endif /* CONFIG_PM */
+	.suspend  = NULL,
+	.resume   = NULL,
+#endif
  };


-void __init std_ide_cntl_scan(void)
-{
-	struct ocp_device *dev;
-	int i, max;
-	printk("OCP ide ver:%s\n", IDE_VER);
-
-	ocp_module_init(&ocp_ide_driver);
-	max = ocp_get_num(OCP_FUNC_IDE);
-	for(i = 0; i < max; i++){
-		dev = ocp_get_dev(OCP_FUNC_IDE,i);
-		if(!dev)	
-		  setup_ocp_ide(dev);
-	}
-}
-#if 0
-#if defined (CONFIG_MODULE)
+
  static int __init
-ocp_ide_init(void)
+stb04xxx_ide_init (void)
  {
-	printk("OCP ide ver:%s\n", IDE_VER);
-	return ocp_module_init(&ocp_ide_driver);
+	return ocp_register_driver (&stb04xxx_ide_driver);
  }

-void __exit
-ocp_ide_fini(void)
+static void __exit
+stb04xxx_ide_exit (void)
  {
-	ocp_unregister_driver(&ocp_ide_driver);
+	ocp_unregister_driver (&stb04xxx_ide_driver);
  }

-module_init(ocp_ide_init);
-module_exit(ocp_ide_fini);
-#endif
-#endif
+/* needs to be called after ide has been initialized */
+late_initcall (stb04xxx_ide_init);
+module_exit (stb04xxx_ide_exit);

+MODULE_LICENSE ("GPL");
+MODULE_AUTHOR ("André Draszik <andid@gmx.net>");
+MODULE_DESCRIPTION ("driver for IBM OCP IDE on STB04xxx");

^ permalink raw reply

* Fw: IDE DMA on ppc405 with via VT82C686
From: John F Davis @ 2005-02-07  0:54 UTC (permalink / raw)
  To: linuxppc-embedded

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

----- Forwarded by John F Davis/Raleigh/IBM on 02/06/2005 07:54 PM -----

John F Davis/Raleigh/IBM 
02/06/2005 03:41 PM

To
linuxppc-embedded-bounces@ozlabs.org
cc
andre@linux-ide.org, vojtech@suse.cz, maratbn@yahoo.com, 
jean-luc.coulon@fnac.net
Subject
IDE DMA on ppc405 with via VT82C686





Hello

I am still trying to get this IDE DMA code working.  I have modified 
(hacked) the ide_build_dmatable so that it flushes the buffer for each 
range of 
memory that is modified by the dma bus master.  I am certain I have 
flushed
the cache properly as shown below, but the problem persists.

Below are two traces.  The first one is from my 
log buffer utility which shows the operation of the modified 
ide_build_dmatable routine.
The second one is from the logic analyzer and it corresponds to the first
dma operation. 

Lastly, I have the entire ide_build_dmatable routine for reference as
well as the resulting ksymoops.  Note, this code appears to be rock solid
for running multiple consecutive hdparm tests.  ie. enable dma and then
issue "while true; do hdparm -t /dev/hda; done" in four logins to the 
target
with ssh.

However, I get the oops when I start playback of a video in Xine from
the disk.

I am at the point now, where my next task is to try this board with a 
different
IDE controller and see if its a problem with the IDE DMA code for this
non cache coherent processor or if its a problem in the VIA driver.

JD


Truncated portion of my log buffer.
----------------------------------------------------

IBM john f. davis utils
**************************************
ide_build_dmatable
ide_build_sglist
sg_table -> dma/prd table 16
bcount = f000 
table (cpu view) = b2009000 (bus view) = fefd000
        cpu view addr [b2009000] = 10c00e
        cpu view data [b2009004] = 100000
        bus view addr [fefd000] = ec01000
        bus view data [fefd004] = 1000
flush_dcache_range (aec01000, aec02000)
sg_table -> dma/prd table 15
bcount = 10000 
table (cpu view) = b2009008 (bus view) = fefd008
        cpu view addr [b2009008] = c00e
        cpu view data [b200900c] = 100000
        bus view addr [fefd008] = ec00000
        bus view data [fefd00c] = 1000
flush_dcache_range (aec00000, aec01000)
sg_table -> dma/prd table 14
bcount = 1000 
table (cpu view) = b2009010 (bus view) = fefd010
        cpu view addr [b2009010] = f0bf0e
        cpu view data [b2009014] = 100000
        bus view addr [fefd010] = ebff000
        bus view data [fefd014] = 1000
flush_dcache_range (aebff000, aec00000)
...
...




Truncated portion of Logic Analyzer Trace
----------------------------------------------------

Listing(Listing<1>) - 22 May 2003 (23:45)

State Number        ADDR           FUTUREPLUS SYSTEMS c 1996 
Decimal             Hex            PCI BUS TRANSACTIONS REV 1.2 
________________    ___________    ____________________________________ 

...
...  
44                  0000FFD4       I/O WRITE ADR=0000FFD4 
45                  0FEFD000          D32=0FEFD000 
46                  0FEFD000       IDLE 
47                  0000FFD4       IDLE 
 
...
...
...  
71                  0FEFD000       MEM READ ADR=0FEFD000 
72                  0BF9D000          STOP-NO DATA XFERED-RETRY 
 
73                  0FEFD000       MEM READ ADR=0FEFD000 
74                  0EC01000          D32=0EC01000 
75                  00001000          D32=00001000 
76                  00001000       IDLE 
77                  00001000       IDLE 
 
78                  000000A1       I/O WRITE ADR=000000A1 
79                  3F3F3F3F          D32=xxxx3Fxx          STOP# 
80                  3F3F3F3F       IDLE 
81                  000000A1       IDLE 
 
82                  00000021       I/O WRITE ADR=00000021 
83                  F9F9F9F9          D32=xxxxF9xx          STOP# 
84                  F9F9F9F9       IDLE 
85                  00000021       IDLE 
 
86                  0EC01000       MEM WRITE ADR=0EC01000 
87                  1000B8FA          D32=1000B8FA 
88                  00BCD08E          D32=00BCD08E 
89                  0000B8B0          D32=0000B8B0 
90                  C08ED88E          D32=C08ED88E 
91                  7C00BEFB          D32=7C00BEFB 
92                  B90600BF          D32=B90600BF 


Modified ide_build_dma_table routine
----------------------------------------------------


/* JFD NOTES
 * This is called second after the dma_read is started.
 */ 
int ide_build_dmatable (ide_drive_t *drive, struct request *rq, int ddir)
{
        ide_hwif_t *hwif        = HWIF(drive);
        unsigned int *table     = hwif->dmatable_cpu;  /* JFD Blach table 
gets the non cached memory */
        volatile unsigned int *tableJFD;
        unsigned int is_trm290  = (hwif->chipset == ide_trm290) ? 1 : 0;
        unsigned int count = 0;
        unsigned int countJFD;
        int i,m;
        struct scatterlist *sg;
        unsigned int *prd_entry;
        unsigned int flush_start_addr;
        unsigned int flush_length;
 

//      jd_print_it("ide_build_dmatable\n");

        if (rq->cmd == IDE_DRIVE_TASKFILE) {
                printk("calling ide_raw_build_sglist\n");
                hwif->sg_nents = i = ide_raw_build_sglist(hwif, rq);
        } else {
                /* JFD we call this routine each time */
                // printk("calling ide_build_sglist\n");
                hwif->sg_nents = i = ide_build_sglist(hwif, rq, ddir);
        }


        if (!i)
                return 0;

        sg = hwif->sg_table;
        while (i && sg_dma_len(sg)) {
                u32 cur_addr;
                u32 cur_len;

                cur_addr = sg_dma_address(sg);  /* jfd blach these are 
real addresses */
                cur_len = sg_dma_len(sg);
//              jd_print_it("sg_table -> dma/PRD table %i\n", i);

                /*
                 * Fill in the dma table, without crossing any 64kB 
boundaries.
                 * Most hardware requires 16-bit alignment of all blocks,
                 * but the trm290 requires 32-bit alignment.
                 */

                while (cur_len) {
                        tableJFD=table;
                        if (count++ >= PRD_ENTRIES) {
                                printk("%s: DMA table too small\n", 
drive->name);
                                goto use_pio_instead;
                        } else {
                                u32 xcount, bcount = 0x10000 - (cur_addr & 
0xffff);

                                jd_print_it("bcount = %x \n",bcount);
                                if (bcount > cur_len)
                                        bcount = cur_len;

                                // JFD writes the address to the PRD table
                                *table++ = cpu_to_le32(cur_addr);
                                xcount = bcount & 0xffff;
                                countJFD=xcount;
                                if (is_trm290)
                                        xcount = ((xcount >> 2) - 1) << 
16;
                                if (xcount == 0x0000) {
        /* 
         * Most chipsets correctly interpret a length of 0x0000 as 64KB,
         * but at least one (e.g. CS5530) misinterprets it as zero (!).
         * So here we break the 64KB entry into two 32KB entries instead.
         */
                                        if (count++ >= PRD_ENTRIES) {
                                                printk("%s: DMA table too 
small\n", drive->name);
                                                goto use_pio_instead;
                                        }
 
                                        // JFD Write the truncated length 
to the PRD table
                                        *table++ = cpu_to_le32(0x8000);
                                        // JFD Write the address for the 
next truncated length to the PRD table
                                        *table++ = cpu_to_le32(cur_addr + 
0x8000);
                                        xcount = 0x8000;

// cut out the logging for real test
#if 0

                                        jd_print_it("table-trunc (cpu 
view) = %x (bus view) = %x\n",tableJFD, virt_to_bus(tableJFD));
                                        jd_print_it("\tCPU View ADDR [%x] 
= %x\n",tableJFD, *tableJFD);
                                        jd_print_it("\tCPU View DATA [%x] 
= %x\n",tableJFD+1, *(tableJFD+1));

                                        jd_print_it("\tBUS View ADDR [%x] 
= %x\n",virt_to_bus(tableJFD), le32_to_cpu(*tableJFD));
                                        jd_print_it("\tBUS View DATA [%x] 
= %x\n",virt_to_bus(tableJFD+1), le32_to_cpu(*(tableJFD+1)));

#endif
                                        flush_start_addr = 
bus_to_virt((unsigned int *)le32_to_cpu(*tableJFD));
                                        flush_length = 
le32_to_cpu(*(tableJFD+1));

//                                      jd_print_it("flush_dcache_range 
(%x, %x)\n", flush_start_addr, flush_start_addr + flush_length);
                                        flush_dcache_range 
(flush_start_addr, flush_start_addr + flush_length );
  
                                        // have to increment  our pointer 
to the next PRD address loc as well.
                                        tableJFD++;
                                        tableJFD++;
                                }


                                // JFD Write the length (could be trucated 
per above) to the PRD table
                                *table++ = cpu_to_le32(xcount);
                                cur_addr += bcount;
                                cur_len -= bcount;
                        }

// cut out the logging for real test.
#if 0
                                        jd_print_it("table (cpu view) = %x 
(bus view) = %x\n",tableJFD, virt_to_bus(tableJFD));
                                        jd_print_it("\tCPU View ADDR [%x] 
= %x\n",tableJFD, *tableJFD);
                                        jd_print_it("\tCPU View DATA [%x] 
= %x\n",tableJFD+1, *(tableJFD+1));

                                        jd_print_it("\tBUS View ADDR [%x] 
= %x\n",virt_to_bus(tableJFD), le32_to_cpu(*tableJFD));
                                        jd_print_it("\tBUS View DATA [%x] 
= %x\n",virt_to_bus(tableJFD+1), le32_to_cpu(*(tableJFD+1)));

#endif
                                        flush_start_addr = 
bus_to_virt((unsigned int *)le32_to_cpu(*tableJFD));
                                        flush_length = 
le32_to_cpu(*(tableJFD+1));

//                                      jd_print_it("flush_dcache_range 
(%x, %x)\n", flush_start_addr, flush_start_addr + flush_length);
                                        flush_dcache_range 
(flush_start_addr, flush_start_addr + flush_length );


 
#if 0
                        // Lets try to read that address into a variable 
to see if it "flushes that cache entry"
                        for (m=0; m< 0x1000;m++) {
                                ulFoo = *(unsigned int*) 
bus_to_virt(le32_to_cpu(*tableJFD++));
                        }
#endif

                }




                sg++;
                i--;
        }

        if (count) {
                if (!is_trm290)
                        *--table |= cpu_to_le32(0x80000000);
                return count;
        }
        printk("%s: empty DMA table?\n", drive->name);
use_pio_instead:
        pci_unmap_sg(hwif->pci_dev,
                     hwif->sg_table,
                     hwif->sg_nents,
                     hwif->sg_dma_direction);
        hwif->sg_dma_active = 0;
        return 0; /* revert to PIO for this request */
}




Ksymoops dump
----------------------------------------------------

003AF9C A002F770 A002EC18 A003B14C A003B288 A003B5E8 A003C1E4 
AA003AF9C A002F770 A002EC18 A003B14C A003B288 A003B5E8 A003C1E4 
007CA8C A0027690 A0028044 A0028518 A0028A5C A003840C A000279C 
0A007CA8C A0027690 A0028044 A0028518 A0028A5C A003840C A000279C 
FECCB68 0F833B80 0F59D02C 0F59D298 0F59C830 0FF5B278 0FEC7914 
00FECCB68 0F833B80 0F59D02C 0F59D298 0F59C830 0FF5B278 0FEC7914 
FC0B408 
0FC0B408 
Warning (Oops_read): Code line not seen, dumping what data is available


>>NIP; a002fc68 <kmem_find_general_cachep+da4/2bb4>   <=====

>>GPR1; ac803cf0 <_end+c55ffc8/125f6420>
>>GPR2; ac802000 <_end+c55e2d8/125f6420>
>>GPR3; a02eb1c8 <_end+474a0/125f6420>
>>GPR4; ac0b4000 <_end+be102d8/125f6420>
>>GPR9; ac12c020 <_end+be882f8/125f6420>
>>GPR11; a02eb1d0 <_end+474a8/125f6420>
>>GPR18; a00288ec <do_generic_file_read+74c/814>
>>GPR19; ad3fc834 <_end+d158b0c/125f6420>
>>GPR20; ac803ed8 <_end+c5601b0/125f6420>
>>GPR21; a007c768 <journal_blocks_per_page+4390/8868>
>>GPR25; a04ff860 <_end+25bb38/125f6420>
>>GPR29; a02eb1c8 <_end+474a0/125f6420>
>>GPR30; ac0b4f60 <_end+be11238/125f6420>
>>GPR31; a02eb1c8 <_end+474a0/125f6420>

Trace; a003af9c <bread+10/138>
Trace; a002f770 <kmem_find_general_cachep+8ac/2bb4>
Trace; a002ec18 <kmem_cache_alloc+10/20>
Trace; a003b14c <get_unused_buffer_head+68/c8>
Trace; a003b288 <set_bh_page+dc/350>
Trace; a003b5e8 <create_empty_buffers+24/960>
Trace; a003c1e4 <block_read_full_page+2c0/2ec>
Trace; a007ca8c <journal_blocks_per_page+46b4/8868>
Trace; a0027690 <filemap_fdatawait+424/4ec>
Trace; a0028044 <grab_cache_page_nowait+230/38c>
Trace; a0028518 <do_generic_file_read+378/814>
Trace; a0028a5c <generic_file_read+a8/9e4>
Trace; a003840c <default_llseek+340/e28>
Trace; a000279c <set_context+3b4/5e0>
Trace; 0feccb68 Before first symbol
Trace; 0f833b80 Before first symbol
Trace; 0f59d02c Before first symbol
Trace; 0f59d298 Before first symbol
Trace; 0f59c830 Before first symbol
Trace; 0ff5b278 Before first symbol
Trace; 0fec7914 Before first symbol
Trace; 0fc0b408 Before first symbol


5 warnings and 2 errors issued.  Results may not be reliable.


[-- Attachment #2: Type: text/html, Size: 40992 bytes --]

^ permalink raw reply

* Re: make -j12 all fails in uImage target
From: Tom Rini @ 2005-02-06 23:50 UTC (permalink / raw)
  To: Olaf Hering, linuxppc-dev, Sam Ravnborg
In-Reply-To: <20050206225323.GA16821@mars.ravnborg.org>

On Sun, Feb 06, 2005 at 11:53:23PM +0100, Sam Ravnborg wrote:
> On Sun, Feb 06, 2005 at 02:51:31PM -0700, Tom Rini wrote:
> > On Sun, Feb 06, 2005 at 01:40:14PM +0100, Olaf Hering wrote:
> > > 
> > > this is what I got with 2.6.11rc3:
> > > 
> > > make ARCH=ppc O=../O-2.6.11-rc3-b50-SMP -j12 all
> > > ...
> > >   LD      vmlinux
> > >   SYSMAP  System.map
> > >   SYSMAP  .tmp_System.map
> > >   OBJCOPY arch/ppc/boot/images/vmlinux.bin
> > >   HOSTCC  arch/ppc/boot/utils/addnote
> > >   HOSTCC  arch/ppc/boot/utils/mknote
> > >   HOSTCC  arch/ppc/boot/utils/mkprep
> > >   LD      arch/ppc/boot/lib/built-in.o
> > >   HOSTCC  arch/ppc/boot/utils/hack-coff
> > >   HOSTCC  arch/ppc/boot/utils/mkbugboot
> > >   OBJCOPY arch/ppc/boot/images/vmlinux.bin
> > >   GZIP    arch/ppc/boot/images/vmlinux.gz
> > > /bin/sh: line 1: arch/ppc/boot/images/vmlinux.bin: No such file or directory
> > > make[2]: *** [arch/ppc/boot/images/vmlinux.gz] Error 1
> > > make[1]: *** [uImage] Error 2
> > > make[1]: *** Waiting for unfinished jobs....
> > > 
> > > also, one time that zImage.chrp was only 570K instead of the expected
> > > 1.4M, so netboot failed. But I got no build error.
> > > Any idea what dependency is missing?
> > 
> > That is kinda odd.  My thought is that arch/ppc/boot/ just isn't fully
> > safe for -j'ing.  Sam, any ideas on how to debug this kinda problem?
> 
> The problem is that the images/ sub directory is visited before the
> prerequisites are finished.
> I have no good way to debug this - I can see it based on the Makefile and
> the output Olaf included.
> 
> Also the problem Olaf describe is just a cp of a half finished file.
> 
> 
> So the fix is to let the images/ directory depends on the rest of the
> directories.
> 
> Something like this may do the trick:
> 
> $(obj)/images: $(addprefix $(obj)/,$(subdir-y) $(bootdir-y))
> 	$(Q)$(MAKE) $(build)=$@
> 
> And then delete the assignment of images to subdir-y
> 
> 
> Another solution would be to get rid on the images/ drectory and place
> outputfiles where they are being built.

Hopefully the first works, since I really do like having all the various
images we create end up in one spot. :)

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply

* Re: make -j12 all fails in uImage target
From: Benjamin Herrenschmidt @ 2005-02-06 23:43 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: Tom Rini, Olaf Hering, linuxppc-dev list
In-Reply-To: <20050206225323.GA16821@mars.ravnborg.org>

On Sun, 2005-02-06 at 23:53 +0100, Sam Ravnborg wrote:

> The problem is that the images/ sub directory is visited before the
> prerequisites are finished.
> I have no good way to debug this - I can see it based on the Makefile and
> the output Olaf included.
> 
> Also the problem Olaf describe is just a cp of a half finished file.

We had a similar problem with paul recently where the build worked but
the resulting zImage contained a corrupted file as the
objcopy/gzip/whatever wasn't fully finished when the zImage file got
linked.
> 
> So the fix is to let the images/ directory depends on the rest of the
> directories.
> 
> Something like this may do the trick:

We should maybe also have an explicit dependency on vmlinux no ? Or is
this handled already for the boot dir as a whole ?

> $(obj)/images: $(addprefix $(obj)/,$(subdir-y) $(bootdir-y))
> 	$(Q)$(MAKE) $(build)=$@
> 
> And then delete the assignment of images to subdir-y
> 
> 
> Another solution would be to get rid on the images/ drectory and place
> outputfiles where they are being built.
> 
> 	Sam
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
-- 
Benjamin Herrenschmidt <benh@kernel.crashing.org>

^ permalink raw reply

* Re: make -j12 all fails in uImage target
From: Sam Ravnborg @ 2005-02-06 22:53 UTC (permalink / raw)
  To: Tom Rini; +Cc: linuxppc-dev, Sam Ravnborg, Olaf Hering
In-Reply-To: <20050206215131.GF7686@smtp.west.cox.net>

On Sun, Feb 06, 2005 at 02:51:31PM -0700, Tom Rini wrote:
> On Sun, Feb 06, 2005 at 01:40:14PM +0100, Olaf Hering wrote:
> > 
> > this is what I got with 2.6.11rc3:
> > 
> > make ARCH=ppc O=../O-2.6.11-rc3-b50-SMP -j12 all
> > ...
> >   LD      vmlinux
> >   SYSMAP  System.map
> >   SYSMAP  .tmp_System.map
> >   OBJCOPY arch/ppc/boot/images/vmlinux.bin
> >   HOSTCC  arch/ppc/boot/utils/addnote
> >   HOSTCC  arch/ppc/boot/utils/mknote
> >   HOSTCC  arch/ppc/boot/utils/mkprep
> >   LD      arch/ppc/boot/lib/built-in.o
> >   HOSTCC  arch/ppc/boot/utils/hack-coff
> >   HOSTCC  arch/ppc/boot/utils/mkbugboot
> >   OBJCOPY arch/ppc/boot/images/vmlinux.bin
> >   GZIP    arch/ppc/boot/images/vmlinux.gz
> > /bin/sh: line 1: arch/ppc/boot/images/vmlinux.bin: No such file or directory
> > make[2]: *** [arch/ppc/boot/images/vmlinux.gz] Error 1
> > make[1]: *** [uImage] Error 2
> > make[1]: *** Waiting for unfinished jobs....
> > 
> > also, one time that zImage.chrp was only 570K instead of the expected
> > 1.4M, so netboot failed. But I got no build error.
> > Any idea what dependency is missing?
> 
> That is kinda odd.  My thought is that arch/ppc/boot/ just isn't fully
> safe for -j'ing.  Sam, any ideas on how to debug this kinda problem?

The problem is that the images/ sub directory is visited before the
prerequisites are finished.
I have no good way to debug this - I can see it based on the Makefile and
the output Olaf included.

Also the problem Olaf describe is just a cp of a half finished file.


So the fix is to let the images/ directory depends on the rest of the
directories.

Something like this may do the trick:

$(obj)/images: $(addprefix $(obj)/,$(subdir-y) $(bootdir-y))
	$(Q)$(MAKE) $(build)=$@

And then delete the assignment of images to subdir-y


Another solution would be to get rid on the images/ drectory and place
outputfiles where they are being built.

	Sam

^ permalink raw reply

* Re: [PATCH] remove .tmp_gas_check
From: Tom Rini @ 2005-02-06 22:43 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20050206215600.GA2062@suse.de>

On Sun, Feb 06, 2005 at 10:56:00PM +0100, Olaf Hering wrote:
>  On Sun, Feb 06, Tom Rini wrote:
> 
> > On Sun, Feb 06, 2005 at 10:15:06PM +0100, Olaf Hering wrote:
> > 
> > >  On Sun, Feb 06, Tom Rini wrote:
> > > 
> > > > I agree you shouldn't have to see it.  I'm saying the problem is the
> > > > variable shouldn't be evaluated.
> > > 
> > > This patch seems to work for me.
> > 
> > What I don't like is that checkbin shouldn't be evaluated for 'tags' or
> > other non-compile targets, so you don't need those explicit rm's.  Also,
> > you forgot the signed-off-by line :)
> 
> Why should make tags or oldconfig ever care about the installed toolchain?

It shouldn't, and 'tags' at least shouldn't depend on 'checkbin'
(oldconfig I _believe_ actually invokes HOSTCC and creates other .tmp
files, but I don't have a tree handy).

> How should the tmpfile disappear if one calls make checkbin with success?

On make clean, like the other .tmp files that are around at the end of a
kernel compile (kallsyms/modules/maybe something else).

> Maybe I misunderstood you.

I think so.  We both agree there should be no ppc-specific .tmp files
around after certain make targets.  I'm saying that there's always some
.tmp files generated on every arch for certain targets, and removed with
a clean.  PPC should only create .tmp files (And leave them alone) in
the cases where every arch generates some .tmp files.

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply

* Re: make -j12 all fails in uImage target
From: Olaf Hering @ 2005-02-06 21:57 UTC (permalink / raw)
  To: Tom Rini; +Cc: linuxppc-dev, Sam Ravnborg
In-Reply-To: <20050206215131.GF7686@smtp.west.cox.net>

 On Sun, Feb 06, Tom Rini wrote:

> >   GZIP    arch/ppc/boot/images/vmlinux.gz

> > Any idea what dependency is missing?

Sometimes I see that GZIP twice.

^ permalink raw reply

* Re: [PATCH] remove .tmp_gas_check
From: Olaf Hering @ 2005-02-06 21:56 UTC (permalink / raw)
  To: Tom Rini; +Cc: linuxppc-dev
In-Reply-To: <20050206214951.GE7686@smtp.west.cox.net>

 On Sun, Feb 06, Tom Rini wrote:

> On Sun, Feb 06, 2005 at 10:15:06PM +0100, Olaf Hering wrote:
> 
> >  On Sun, Feb 06, Tom Rini wrote:
> > 
> > > I agree you shouldn't have to see it.  I'm saying the problem is the
> > > variable shouldn't be evaluated.
> > 
> > This patch seems to work for me.
> 
> What I don't like is that checkbin shouldn't be evaluated for 'tags' or
> other non-compile targets, so you don't need those explicit rm's.  Also,
> you forgot the signed-off-by line :)

Why should make tags or oldconfig ever care about the installed toolchain?
How should the tmpfile disappear if one calls make checkbin with success?
Maybe I misunderstood you.

^ permalink raw reply

* Re: make -j12 all fails in uImage target
From: Tom Rini @ 2005-02-06 21:51 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev, Sam Ravnborg
In-Reply-To: <20050206124014.GA5880@suse.de>

On Sun, Feb 06, 2005 at 01:40:14PM +0100, Olaf Hering wrote:
> 
> this is what I got with 2.6.11rc3:
> 
> make ARCH=ppc O=../O-2.6.11-rc3-b50-SMP -j12 all
> ...
>   LD      vmlinux
>   SYSMAP  System.map
>   SYSMAP  .tmp_System.map
>   OBJCOPY arch/ppc/boot/images/vmlinux.bin
>   HOSTCC  arch/ppc/boot/utils/addnote
>   HOSTCC  arch/ppc/boot/utils/mknote
>   HOSTCC  arch/ppc/boot/utils/mkprep
>   LD      arch/ppc/boot/lib/built-in.o
>   HOSTCC  arch/ppc/boot/utils/hack-coff
>   HOSTCC  arch/ppc/boot/utils/mkbugboot
>   OBJCOPY arch/ppc/boot/images/vmlinux.bin
>   GZIP    arch/ppc/boot/images/vmlinux.gz
> /bin/sh: line 1: arch/ppc/boot/images/vmlinux.bin: No such file or directory
> make[2]: *** [arch/ppc/boot/images/vmlinux.gz] Error 1
> make[1]: *** [uImage] Error 2
> make[1]: *** Waiting for unfinished jobs....
> 
> also, one time that zImage.chrp was only 570K instead of the expected
> 1.4M, so netboot failed. But I got no build error.
> Any idea what dependency is missing?

That is kinda odd.  My thought is that arch/ppc/boot/ just isn't fully
safe for -j'ing.  Sam, any ideas on how to debug this kinda problem?
Thanks.

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply

* Re: [PATCH] remove .tmp_gas_check
From: Tom Rini @ 2005-02-06 21:49 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20050206211506.GA31123@suse.de>

On Sun, Feb 06, 2005 at 10:15:06PM +0100, Olaf Hering wrote:

>  On Sun, Feb 06, Tom Rini wrote:
> 
> > I agree you shouldn't have to see it.  I'm saying the problem is the
> > variable shouldn't be evaluated.
> 
> This patch seems to work for me.

What I don't like is that checkbin shouldn't be evaluated for 'tags' or
other non-compile targets, so you don't need those explicit rm's.  Also,
you forgot the signed-off-by line :)

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply

* Re: [PATCH] remove .tmp_gas_check
From: Olaf Hering @ 2005-02-06 21:15 UTC (permalink / raw)
  To: Tom Rini; +Cc: linuxppc-dev
In-Reply-To: <20050206202154.GD7686@smtp.west.cox.net>

 On Sun, Feb 06, Tom Rini wrote:

> I agree you shouldn't have to see it.  I'm saying the problem is the
> variable shouldn't be evaluated.

This patch seems to work for me.


diff -purNx tags ../linux-2.6.11-rc3.orig/arch/ppc/Makefile ./arch/ppc/Makefile
--- ../linux-2.6.11-rc3.orig/arch/ppc/Makefile	2005-02-03 02:57:05.000000000 +0100
+++ ./arch/ppc/Makefile	2005-02-06 22:13:01.093237836 +0100
@@ -112,26 +112,27 @@ include/asm-$(ARCH)/offsets.h: arch/$(AR
 TOUT	:= .tmp_gas_check
 # Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
 # instructions.
-AS_ALTIVEC	:= $(shell echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; echo $$?)
 # gcc-3.4 and binutils-2.14 are a fatal combination.
 GCC_VERSION	:= $(call cc-version)
-BAD_GCC_AS	:= $(shell echo mftb 5 | $(AS) -mppc -many -o $(TOUT) >/dev/null 2>&1 && echo 0 || echo 1)
 
 checkbin:
-ifeq ($(GCC_VERSION)$(BAD_GCC_AS),03041)
-	@echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '
-	@echo 'correctly with gcc-3.4 and your version of binutils.'
-	@echo '*** Please upgrade your binutils or downgrade your gcc'
-	@false
-endif
-ifneq ($(AS_ALTIVEC),0)
-	echo $(AS_ALTIVEC)
-	@echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '
-	@echo 'correctly with old versions of binutils.'
-	@echo '*** Please upgrade your binutils to 2.12.1 or newer'
-	@false
-endif
-	@true
+	@if test "$(GCC_VERSION)" = "0304" ; then \
+		if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
+			echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
+			echo 'correctly with gcc-3.4 and your version of binutils.'; \
+			echo '*** Please upgrade your binutils or downgrade your gcc'; \
+			rm -f $(TOUT) ;\
+			false; \
+		fi ; \
+	fi
+	@if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
+		echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
+		echo 'correctly with old versions of binutils.' ; \
+		echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
+		rm -f $(TOUT) ; \
+		false ; \
+	fi
+	@rm -f $(TOUT)
 
 CLEAN_FILES +=	include/asm-$(ARCH)/offsets.h \
 		arch/$(ARCH)/kernel/asm-offsets.s \

^ permalink raw reply

* Re: [PATCH] remove .tmp_gas_check
From: Tom Rini @ 2005-02-06 20:21 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20050206200802.GA28652@suse.de>

On Sun, Feb 06, 2005 at 09:08:02PM +0100, Olaf Hering wrote:
>  On Sun, Feb 06, Tom Rini wrote:
> 
> > Right.  But we only care about that if we're going to compile anything,
> > so perhaps we need to change the test somehow to only get evaluated when
> > needed (ala the -mcpu stuff?  Or is that always run as well?).
> 
> I dont want to see that file because its just a tmpfile.
> mkdir $foo
> make ARCH=ppc tags &
> make ARCH=ppc O=$foo -j menuconfig 
> make ARCH=ppc O=$foo -j all
> 
> Its just in the way when doing diffs. and make clean may remove the tags
> file. But its just silly to expect 'make tags; make clean' to get rid of it.

I agree you shouldn't have to see it.  I'm saying the problem is the
variable shouldn't be evaluated.

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply


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