Hi All,
 
 
I'm using IBM redwood6 stb025xx(ppc405gp) platform with 2.6.14 kernel. I'm trying to get DMA working for IDE interface (PIO is working). The problem I'm facing is that my DMA is completing and I'm getting a error in DMA status register that "A DMA  request from an external device is pending"
 
I'm attaching (inline) the console message(in red color) along with the sample code of the driver(in blue color). Please help me to resolve this issue. What I feel is that DMA is completing and IDE is not getting anything. ( IDE status register is giving 0x58).
 
Any pointers to same will be highly appreciated.
 
 
Regards,
Akhilesh
 
 
 
IBM Set-Top-Box BIOS 1.50 (Feb-16-2004)
 
Platform support <Redwood6/STBx25xx 1.03 (Jun/24/2002)>
 

Initializing devices, please wait.....
                                        
 
 ------- System Info --------
 
 Processor speed = 252 MHz
 
 EBIU speed      = 63 MHz
 
 Amount of RAM   = 64 MBytes
 
DM9000 : dmfe_probe() : Checking DM9000 chip
 
DM9000 : Chip Found ID : 90000a46
 

 --- Device Configuration ---
 
 Power-On Test Devices:
 
   000  Disabled  System Memory [RAM]
 
 ----------------------------
 
 Boot Sources:
 
   001  Disabled  Application in Flash [FLASH]
 
   002  Enabled   Ethernet [ENET]
 
                  local=192.168.18.28  remote=192.168.18.101  hwaddr=bad0add00000
 
   003  Disabled  Serial Port 1 [S1]
 
                  Baud = 9600
 
 ----------------------------
 
Update Flash  : Disabled
 
Automatic Boot: Disabled
 
 ----------------------------
 
  1 - Toggle Power-On Tests
 
  2 - Change a Boot Device
 
  3 - Change IP Addresses
 
  4 - Ping test
 
  5 - Change Baud Rate for S1 Boot
 
  6 - Toggle Update Flash
 
  7 - Toggle Automatic Boot
 
  B - Bootlogo Management
 
  D - Display Configuration
 
  S - Save Changes
 
  Z - Set Ethernet HW Address
 
  0 - Exit Menu and Boot Application
 
  C - Enable CHOIS Debug
 
->0
 
DM900 : dmfe_init_dm9000 : initialising dm9000
 
Booting from [ENET] Ethernet...
 
Sending bootp request ...
 
 bootp packets sent = 1
DM900 : dmfe_send : hold frame collision, outbound frame.
 

Got bootp response from : 192.168.18.101
 
       My ip address is : 192.168.18.28
 

Loading file "zImage.treeboot" by TFTP for net boot ...
 
 block  268
 block 1440
Transfer completed, 897568 bytes received
 
Loaded successfully ...
 
Entry point at 0x500000 ...
 

loaded at:     00500000 005DC164
 
relocated to:  00400000 004DC164
 
board data at: 004DA124 004DA164
 
relocated to:  0040515C 0040519C
 
zimage at:     0040591D 004D9A6C
 
avail ram:     004DD000 02000000
 

Linux/PPC load: ip=on
 
Uncompressing Linux...done.
 
Now booting the kernel
 
Linux version 2.6.14 (root@localhost.localdomain) (gcc version 4.0.0 (DENX ELDK 4.0 4.0.0)) #258 Wed Sep 13 16:12:58 IST 2006
 
ocp: ocp_early_init()...
 
ocp: ocp_add_one_device()...
 
ocp: ocp_add_one_device()...done
 
ocp: ocp_add_one_device()...
 
ocp: ocp_add_one_device()...done
 
ocp: ocp_add_one_device()...
 
ocp: ocp_add_one_device()...done
 
ocp: ocp_add_one_device()...
 
ocp: ocp_add_one_device()...done
 
ocp: ocp_add_one_device()...
 
ocp: ocp_add_one_device()...done
 
ocp: ocp_add_one_device()...
 
ocp: ocp_add_one_device()...done
 
ocp: ocp_early_init()... done.
 
IBM Redwood6 (STBx25XX) Platform
 
Port by MontaVista Software, Inc. (source@mvista.com)
 
Built 1 zonelists
 
Kernel command line: ip=on
 
PID hash table entries: 256 (order: 8, 4096 bytes)
 
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
 
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
 
Memory: 30488k available (1452k kernel code, 344k data, 96k init, 0k highmem)
 
Mount-cache hash table entries: 512
 
NET: Registered protocol family 16
 
ocp: ocp_driver_init()...
 
ocp: ocp_driver_init()... done.
 
Adding platform devices
 
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
 
ttyS0 at MMIO 0x0 (irq = 22) is a 16550A
 
ttyS1 at MMIO 0x0 (irq = 20) is a 16550A
 
ttyS2 at MMIO 0x0 (irq = 21) is a 16550A
 
io scheduler noop registered
 
io scheduler anticipatory registered
 
io scheduler deadline registered
 
io scheduler cfq registered
 
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
 
loop: loaded (max 8 devices)
 
dm9000 Ethernet Driver
 
dm9000_set_io : byte_width 2
 
eth0: dm9000 at c3000000,c3000004 IRQ 26 MAC: ba:d0:ad:d0:00:00
 
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
 
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
 
NET: Registered protocol family 2
 
IP route cache hash table entries: 512 (order: -1, 2048 bytes)
 
TCP established hash table entries: 2048 (order: 1, 8192 bytes)
 
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
 
TCP: Hash tables configured (established 2048 bind 2048)
 
TCP reno registered
 
TCP bic registered
 
NET: Registered protocol family 1
 
inside stb04xxx_ide_init
 
IBM STB025xx OCP IDE driver version 1.0 f2100000
 
ide_redwood: waiting for drive ready......Drive spun up
 
ocp_ide_setup_dma
 
probing for hda: present=0, media=32, probetype=ATA
 
hda: probing with STATUS(0x51) instead of ALTSTATUS(0x00)
 
hda: WDC WD400EB-00CPF0, ATA DISK drive
 
probing for hdb: present=0, media=32, probetype=ATA
 
probing for hdb: present=0, media=32, probetype=ATAPI
 
hdb: probing with STATUS(0x01) instead of ALTSTATUS(0x00)
 
ocp_ide_tune_drive pio 4
 
got ocp_ide_dma_off_quietly
 
got ocp_ide_dma_check
 
redwood_config_drive_for_dma 22
 
ocp_ide_tune_drive pio 4
 
got ocp_ide_dma_on
 
ide0 at 0xc3004000-0xc3004007,0xc3006000 on irq 27
 
hda: max request size: 128KiB
 
ide_execute_command : 0x91
 
ide_execute_command : 0x10
 
ide_execute_command : 0xf8
 
hda: 78165360 sectors (40020 MB) w/2048KiB Cache, CHS=65535/16/63, (U)DMA
 
hda: cache flushes not supported
 
 hda:__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c0340000 340000 count 8 dmastat 0
 
got ocp_ide_dma_test_irq
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 50
 
DMA complete stat 0 500000
 
 hda1
 
IDE probe finished
 
eth0: link up, 100Mbps, full-duplex, lpa 0x41E1
 
Sending BOOTP and RARP requests . OK
 
IP-Config: Got BOOTP answer from 192.168.18.101, my address is 192.168.18.28
 
IP-Config: Complete:
 
      device=eth0, addr=192.168.18.28, mask=255.255.255.0, gw=192.168.18.1,
 
     host=192.168.18.28, domain=, nis-domain=(none),
 
     bootserver=192.168.18.101, rootserver=192.168.18.101, rootpath=/opt/eldk/ppc_4xx
 
Looking up port of RPC 100003/2 on 192.168.18.101
 
Looking up port of RPC 100005/1 on 192.168.18.101
 
VFS: Mounted root (nfs filesystem) readonly.
 
Freeing unused kernel memory: 96k init
 
modprobe: FATAL: Could not load /lib/modules/2.6.14/modules.dep: No such file or directory
 
modprobe: FATAL: Could not load /lib/modules/2.6.14/modules.dep: No such file or directory
 

INIT: version 2.85 booting
 Came here in rc.sysinit creating var\n
mounting
ln: `/proc/mounts': File exists
  Welcome to DENX Embedded Linux Environment
  Press 'I' to enter interactive startup.
Building the cache [  OK  ]
 storage network audio done[  OK  ]
modprobe: FATAL: Could not load /lib/modules/2.6.14/modules.dep: No such file or directory
 
Cannot access the Hardware Clock via any known method.
Use the --debug option to see the details of our search for an access method.
Setting clock : Thu Jan  1 01:00:12 MET 1970 [  OK  ]
Setting hostname CHOISpad-110:  [  OK  ]
Mounting local filesystems:  [  OK  ]
Enabling swap space:  [  OK  ]
 
INIT: Entering runlevel: 3
Entering non-interactive startup
Bringing up loopback interface:  modprobe: FATAL: Could not load /lib/modules/2.6.14/modules.dep: No such file or directory
 
arping: socket: Address family not supported by protocol
Error, some other host already uses address 127.0.0.1.
[FAILED]
Starting system logger: [  OK  ]
Starting kernel logger: [  OK  ]
Starting portmap: [  OK  ]
Mounting NFS filesystems:  [  OK  ]
Mounting other filesystems:  [  OK  ]
Starting xinetd: [  OK  ]
 
DENX ELDK version 4.0 build 2006-01-11
Linux 2.6.14 on a ppc
 
CHOISpad-110 login: root
Last login: Thu Jan  1 01:00:19 on console
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00# hdparm -t  /dev/hda
 
/dev/hda:
 multcount    =  0 (off)
 I/O support  =  0 (default 16-bit)
 unmaskirq    =  1 (on)
 using_dma    =  1 (on)
 keepsettings =  0 (off)
 nowerr       =  0 (off)
 readonly     =  0 (off)
 readahead    = 256 (on)
 geometry     = 65535/16/63, sectors = 78165360, start = 0
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00# hdparm -t /dev/hda
 
/dev/hda:
 Timing buffered__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
 disk reads:  got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
ide_execute_command : 0x10
 
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
got ocp_ide_dma_off_quietly
 
ide0: reset: master: error (0x00?)
 
ide_execute_command : 0x91
 
ide_execute_command : 0x10
 
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
ide_execute_command : 0x10
 
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
 
got ocp_ide_dma_setup
 
ide_execute_command : 0xc8
 
got ocp_ide_dma_begin 0x1000
 
DMA addr c1238000 1238000 count 8 dmastat 0
 
DMA complete stat 20001000 0
 
hda: lost interrupt
 
got ocp_ide_dma_end 0 20000000
 
ide_dma_intr : stat 58
 
hda: dma_intr: status=0x58 { DriveReady SeekComplete DataRequest }
 
ide: failed opcode was: unknown
 
got ocp_ide_dma_off_quietly
 
ide0: reset: master: error (0x00?)
 
end_request: I/O error, dev hda, sector 0
 
Buffer I/O error on device hda, logical block 0
 
end_request: I/O error, dev hda, sector 8
 
Buffer I/O error on device hda, logical block 1
 
end_request: I/O error, dev hda, sector 16
 
Buffer I/O error on device hda, logical block 2
 
end_request: I/O error, dev hda, sector 24
 
Buffer I/O error on device hda, logical block 3
 
end_request: I/O error, dev hda, sector 32
 
Buffer I/O error on device hda, logical block 4
 
end_request: I/O error, dev hda, sector 40
 
Buffer I/O error on device hda, logical block 5
 
end_request: I/O error, dev hda, sector 48
 
Buffer I/O error on device hda, logical block 6
 
end_request: I/O error, dev hda, sector 56
 
Buffer I/O error on device hda, logical block 7
 
end_request: I/O error, dev hda, sector 64
 
Buffer I/O error on device hda, logical block 8
 
end_request: I/O error, dev hda, sector 72
 
Buffer I/O error on device hda, logical block 9
 
end_request: I/O error, dev hda, sector 80
 
end_request: I/O error, dev hda, sector 88
 
end_request: I/O error, dev hda, sector 96
 
end_request: I/O error, dev hda, sector 104
 
end_request: I/O error, dev hda, sector 112
 
end_request: I/O error, dev hda, sector 120
 
end_request: I/O error, dev hda, sector 128
 
end_request: I/O error, dev hda, sector 136
 
end_request: I/O error, dev hda, sector 144
 
end_request: I/O error, dev hda, sector 152
 
end_request: I/O error, dev hda, sector 160
 
end_request: I/O error, dev hda, sector 168
 
end_request: I/O error, dev hda, sector 176
 
end_request: I/O error, dev hda, sector 184
 
end_request: I/O error, dev hda, sector 192
 
end_request: I/O error, dev hda, sector 200
 
end_request: I/O error, dev hda, sector 208
 
end_request: I/O error, dev hda, sector 216
 
end_request: I/O error, dev hda, sector 224
 
end_request: I/O error, dev hda, sector 232
 
end_request: I/O error, dev hda, sector 240
 
end_request: I/O error, dev hda, sector 248
 
end_request: I/O error, dev hda, sector 256
 
end_request: I/O error, dev hda, sector 264
 
end_request: I/O error, dev hda, sector 272
 
end_request: I/O error, dev hda, sector 280
 
end_request: I/O error, dev hda, sector 288
 
end_request: I/O error, dev hda, sector 296
 
end_request: I/O error, dev hda, sector 304
 
end_request: I/O error, dev hda, sector 312
 
end_request: I/O error, dev hda, sector 320
 
end_request: I/O error, dev hda, sector 328
 
end_request: I/O error, dev hda, sector 336
 
end_request: I/O error, dev hda, sector 344
 
end_request: I/O error, dev hda, sector 352
 
end_request: I/O error, dev hda, sector 360
 
end_request: I/O error, dev hda, sector 368
 
end_request: I/O error, dev hda, sector 376
 
end_request: I/O error, dev hda, sector 384
 
end_request: I/O error, dev hda, sector 392
 
end_request: I/O error, dev hda, sector 400
 
end_request: I/O error, dev hda, sector 408
 
end_request: I/O error, dev hda, sector 416
 
end_request: I/O error, dev hda, sector 424
 
end_request: I/O error, dev hda, sector 432
 
end_request: I/O error, dev hda, sector 440
 
end_request: I/O error, dev hda, sector 448
 
end_request: I/O error, dev hda, sector 456
 
end_request: I/O error, dev hda, sector 464
 
end_request: I/O error, dev hda, sector 472
 
end_request: I/O error, dev hda, sector 480
 
end_request: I/O error, dev hda, sector 488
 
end_request: I/O error, dev hda, sector 496
 
end_request: I/O error, dev hda, sector 504
 
end_request: I/O error, dev hda, sector 0
 
read() failed: Input/output error
bash-3.00#
 
 
 
 
 
 
static void ocp_ide_dma_begin(ide_drive_t *drive){
int i,reading=0,length;
struct request * const rq = HWGROUP(drive)->rq;
unsigned long control;
 
 if(rq_data_dir (rq) == READ) reading = 1;
 
 printk("got ocp_ide_dma_begin 0x%x\n",mfdcr(DCRN_DMASR));
 /* enable DMA */
 ppc4xx_enable_dma_interrupt(IDE_DMACH);
 /*dmastat = mfdcr(DCRN_DMASR);
 mtdcr(DCRN_DMASR,((u32)DMA_CH2_ERR | (u32)DMA_CS2 | (u32)DMA_TS2));
 */
 mtdcr(DCRN_DMASR,0x22200120);
 /*Configure CIC reg for line mode DMA*/
#ifdef WMODE
 mtdcr(DCRN_CICCR,(mfdcr(DCRN_CICCR) | 0x00000400));
#else
 mtdcr(DCRN_CICCR,(mfdcr(DCRN_CICCR) & ~0x00000400));
 
#endif
 
 if(drive->media != ide_disk) {
  printk("ocp_ide_dma_begin : Invalid media \n");
  return;
 }
 if(ppc4xx_get_channel_config(IDE_DMACH,&dma_ch) & DMA_CHANNEL_BUSY){
   printk("DMA channel busy \n");
   return;
 }
 memset(rq->buffer,0,rq->current_nr_sectors*512);
 if(reading){
  
  dma_cache_inv((unsigned long) rq->buffer, rq->current_nr_sectors * 512);
#ifdef WMODE
  mtdcr(DCRN_DMASA2,(u32)0x00000000);// set src address for DMA channel 2
  mtdcr(DCRN_DMADA2,(u32)virt_to_bus(rq->buffer));//set dst address for DMA channel 2
  mtdcr(DCRN_DCRXBCR,0x00000000);
  control = 0xE600CB02;
#else
  mtdcr(DCRN_DMASA2,(u32)0xfce00000);// set src address for DMA channel 2
  mtdcr(DCRN_DMADA2,(u32)virt_to_bus(rq->buffer));//set dst address for DMA channel 2
  mtdcr(DCRN_DCRXBCR,0x90000000);
  control = 0xEE602b02;
#endif
 }
 else {
  dma_cache_wback_inv((unsigned long) rq->buffer, rq->current_nr_sectors * 512);
 
#ifdef WMODE
  mtdcr(DCRN_DMASA2,(u32)0x00000000);// set dst address for DMA channel 2
  mtdcr(DCRN_DMADA2,(u32)virt_to_bus(rq->buffer));// set src address for DMA channel 2
  mtdcr(DCRN_DCRXBCR,0x00000000);
  control = 0xC600CB02;
#else
  mtdcr(DCRN_DMADA2,(u32)0xfce00000);// set dst address for DMA channel 2
  mtdcr(DCRN_DMASA2,(u32)virt_to_bus(rq->buffer));// set src address for DMA channel 2
  mtdcr(DCRN_DCRXBCR,0xB0000000);
  control = 0xcd602b02;
#endif
 
 }
 
#ifdef WMODE
 length = (rq->current_nr_sectors *512)/2;
#else
 length = (rq->current_nr_sectors *512)/16;
#endif
 mtdcr(DCRN_DMACT2,length);
 
 /*control = mfdcr(DCRN_DMACR2);
 control |= DMA_CIE_ENABLE;  Channel Interrupt Enable
 */
 control &= ~DMA_CIE_ENABLE;
 mtdcr(DCRN_DMACR2, control);
 //ppc4xx_enable_dma_interrupt(IDE_DMACH);
 
 printk("DMA addr %x %x count %d dmastat %x\n",rq->buffer,virt_to_bus(rq->buffer),rq->current_nr_sectors,dmastat);
 /* wait for dma to complete (channel 2 terminal count) */
 for (i = 0; i < 500000; i++) {
  if(i%1000 == 0)
   dmastat = mfdcr(DCRN_DMASR);
  if (dmastat & DMA_CS2)
   break;
 }
 printk("DMA complete stat %x %d\n",dmastat,i);
 mtdcr(DCRN_DCRXBCR,0x00000000);
 mtdcr(DCRN_DMACR2, 0x00000000);
 drive->waiting_for_dma = 0;
 //dmastat = 0;
}
static int ocp_ide_dma_end(ide_drive_t *drive){
unsigned int tmp = mfdcr(DCRN_DMASR);
 
 mtdcr (DCRN_UIC_SR(UIC0),(0x80000000ul >> IDE_DMA_INT));
 mtdcr(DCRN_DMASR,0x22200120);
 dmastat = mfdcr(DCRN_DMASR);
 printk("got ocp_ide_dma_end %x %x\n",dmastat,tmp);
 drive->waiting_for_dma = 0;
 /* disable DMA */
 //ppc4xx_disable_dma_interrupt(IDE_DMACH);
 
 return 0;
}
 
static void
ocp_ide_setup_dma (ide_hwif_t * const hwif)
{
 printk("ocp_ide_setup_dma \n");
 

 hwif->dma = IDE_DMACH;
#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.td = DMA_TD;
 dma_ch.buffer_enable = FALSE;
 dma_ch.tce_enable = FALSE;
 dma_ch.etd_output = FALSE;
 dma_ch.pce = FALSE;
 dma_ch.pl = EXTERNAL_PERIPHERAL;    /* no op */
 dma_ch.pwidth = PW_16;
 dma_ch.dai = TRUE;
 dma_ch.sai = FALSE;
 dma_ch.psc = 0;                      /* set the max setup cycles */
 dma_ch.pwc = 6;                     /* set the max wait cycles  */
 dma_ch.phc = 2;                      /* set the max hold cycles  */
 dma_ch.cp = PRIORITY_LOW;
 dma_ch.int_enable = FALSE;
 dma_ch.ch_enable = FALSE;  /* No chaining */
 dma_ch.tcd_disable = TRUE;  /* No chaining */
#else
/*Line Mode psc(11-12)=00,pwc(13-18)=000001, phc(19-21)=010, 22=1, 30=1  ----  0x2B02*/
 
 dma_ch.mode =DMA_MODE_MM_DEVATSRC;   /* xfer from peripheral to mem */
 dma_ch.td = DMA_TD;
 dma_ch.buffer_enable = FALSE;
 dma_ch.tce_enable = FALSE;
 dma_ch.etd_output = FALSE;
 dma_ch.pce = FALSE;
 dma_ch.pl = EXTERNAL_PERIPHERAL;    /* no op */
 dma_ch.pwidth = PW_64;  /* Line mode on stbs */
 dma_ch.dai = TRUE;
 dma_ch.sai = FALSE;
 dma_ch.psc = 0;                      /* set the max setup cycles */
 dma_ch.pwc = 1;                     /* set the max wait cycles  */
 dma_ch.phc = 2;                      /* set the max hold cycles  */
 dma_ch.cp = PRIORITY_LOW;
 dma_ch.int_enable = FALSE;
 dma_ch.ch_enable = FALSE;  /* No chaining */
 dma_ch.tcd_disable = TRUE;  /* No chaining */
 
#endif
 if (ppc4xx_init_dma_channel(IDE_DMACH, &dma_ch) != DMA_STATUS_GOOD){
  printk("ppc4xx_init_dma_channel failed\n");
         return -EBUSY;
 }
 //ppc4xx_disable_dma_interrupt(IDE_DMACH);
 
 /*init CIC control register to enable IDE interface PIO mode*/
 mtdcr(DCRN_CICCR,(mfdcr(DCRN_CICCR) & 0xffff7bff) | 0x00000003);
 mtdcr(DCRN_DMACR2, 0);
 ppc4xx_clr_dma_status(IDE_DMACH);
 /* init CIC select2 reg to connect external DMA port 3 to internal
  * DMA channel 2
 
  */
 mtdcr(DCRN_DMAS2,(mfdcr(DCRN_DMAS2) & 0xfffffff0) | 0x00000002);
 

 hwif->autodma = 1;hwif->udma_four=0;
 hwif->drives[0].autotune = hwif->drives[1].autotune = IDE_TUNE_AUTO;
 hwif->drives[0].autodma  = hwif->drives[1].autodma  = hwif->autodma;
 
 hwif->atapi_dma  = 0;
 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   = &ocp_ide_dma_off_quietly;
 hwif->ide_dma_host_on     = &ocp_ide_dma_on;
 
 hwif->ide_dma_check   = &ocp_ide_dma_check;
 hwif->ide_dma_off_quietly   = &ocp_ide_dma_off_quietly;
 hwif->ide_dma_on            = &ocp_ide_dma_on;
 
 hwif->dma_setup      = &ocp_ide_dma_setup;
 hwif->dma_exec_cmd    = &ocp_dma_exec_cmd;
 hwif->dma_start       = &ocp_ide_dma_begin;
 hwif->ide_dma_end    = &ocp_ide_dma_end;
 
 hwif->ide_dma_test_irq   = &ocp_ide_dma_test_irq;
 
 hwif->ide_dma_lostirq    = &ocp_ide_dma_lostirq;
 hwif->ide_dma_timeout    = &ocp_ide_dma_timeout;
}
  
static int __init
stb025xx_ide_probe (struct ocp_device * const ocp)
{
 int                     err;
 unsigned int            uicdcr;
 volatile unsigned long ide_regs;
 unsigned long           flags,ioaddr;
 ide_hwif_t             * const hwif = &ide_hwifs[0];
 unsigned char          * ip;
 int                     i;
 
 printk ("IBM STB025xx OCP IDE driver version %s %x \n", IDEVR,ocp->def->paddr);
 if (!request_region(REDWOOD_IDE_CMD, 0x10, "IDE"))
  return -EBUSY;
 
 if (!request_region(REDWOOD_IDE_CTRL, 2, "IDE")) {
  release_region(REDWOOD_IDE_CMD, 0x10);
  return -EBUSY;
 }
 
 ide_regs = ioaddr = (unsigned long) ioremap(REDWOOD_IDE_CMD, 0x10);
 
 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
  hwif->io_ports[i] = ioaddr;
  ioaddr += 2;
 }
 hwif->io_ports[IDE_CONTROL_OFFSET] =
     (unsigned long) ioremap(REDWOOD_IDE_CTRL, 2);
 
 ocp_force_power_on (ocp);
 
 /* 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);
 
 hwif->chipset = ide_generic;
 hwif->irq     = IDE0_IRQ;
 hwif->noprobe = 0;
 hwif->hold    = 1;
 hwif->udma_four = 0;
 hwif->tuneproc  = &ocp_ide_tune_drive;
 hwif->speedproc = &ocp_ide_tune_chipset;
 hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 0;
 hwif->drives[0].unmask   = hwif->drives[1].unmask   = 1;
 pio_mode[0] = pio_mode[1] = -1;
 
 ibm25xx_ide_spinup(0);
 ocp_ide_setup_dma (hwif);
 probe_hwif_init (hwif);
 
 create_proc_ide_interfaces ();
 printk("IDE probe finished \n");
 return 0;
}
static int ocp_ide_dma_end(ide_drive_t *drive){
unsigned int tmp = mfdcr(DCRN_DMASR);
 
 mtdcr (DCRN_UIC_SR(UIC0),(0x80000000ul >> IDE_DMA_INT));
 mtdcr(DCRN_DMASR,0x22200120);
 dmastat = mfdcr(DCRN_DMASR);
 printk("got ocp_ide_dma_end %x %x\n",dmastat,tmp);
 drive->waiting_for_dma = 0;
 /* disable DMA */
 //ppc4xx_disable_dma_interrupt(IDE_DMACH);
 
 return 0;
}
static int ocp_ide_dma_test_irq(ide_drive_t *drive){
 
 printk("got ocp_ide_dma_test_irq\n");
 return 1; /* returns 1 if dma irq issued, 0 otherwise */
}
static int ocp_ide_dma_verbose(ide_drive_t *drive){
 
 printk("got ocp_ide_dma_verbose\n");
 return 1;
}
static int ocp_ide_dma_lostirq(ide_drive_t *drive){
 

 printk("got ocp_ide_dma_lostirq\n");
 return 1;
}
static int ocp_ide_dma_timeout(ide_drive_t *drive){
 
 printk("got ocp_ide_dma_timeout\n");
 return 1;
}
static void
ocp_dma_exec_cmd (ide_drive_t * const drive, u8 command){
ide_hwif_t *hwif = HWIF(drive);
 
 //hwif->OUTBSYNC(drive,command, IDE_COMMAND_REG);
 //printk("ide_dma_exec_cmd %x\n",command);
 ide_execute_command (drive, command,&ide_dma_intr, 2*WAIT_CMD, NULL);
}
static int ocp_ide_dma_setup(ide_drive_t * const drive){
 ide_hwif_t  * const hwif = HWIF(drive);
 struct request * const rq = HWGROUP(drive)->rq;
 
 printk("got ocp_ide_dma_setup \n");
 /*if(rq->current_nr_sectors < 2){
  printk("request for less no of sectors %d\n",rq->current_nr_sectors);
  ide_map_sg(drive,rq);drive->waiting_for_dma=0;
  return 1;
 }*/
 drive->waiting_for_dma = 1;
 return 0;