PIO Mode 4 for DTC2278 Secondary interface

Michael J. Greger (greger@tornado.rutgers.edu)
Sat, 27 Jul 1996 01:39:15 -0500 (CDT)


Hello fellow hackers,

I have previously posted here asking about a kernel driver for the
dtc2278 hard drive controller. The current driver only allows hdparm
to set the PIO mode for the 1st interface. I have a WD32500 (2.5GB)
drive on the second interface, first drive that I would like to put
into PIO mode 4...

I attempted to contact the author of the current dtc driver, but got no
response after more than a month. So, I decided to give it a try for
myself...

First, I was unable to determine exactly what the current druver was doing.
After searching ide.c and other driver code, I saw the IDE_*_REG macros
that should allow me to access the various IDE registers. The current
2278 code writes to ports 0xb0 and 0xb4. What are these??? The inb(0x3f6)'s
make sense...

Anyway, I grabbed the ATA-2 and ATA-3 specs and put some code into
a tune_proc:

ide_hwif_t *hwif;
unsigned long flags;
int i;
byte status;

save_flags(flags);
cli();

hwif = HWIF(drive);
status=IN_BYTE(IDE_ALTSTATUS_REG);
printk("Status=0x%x\n", status);

/* Select drive 0 on the interface (a1= drive 1)*/
OUT_BYTE(0xa0,IDE_SELECT_REG);
printk("IDE_SELECT_REG=0x%x (Should be 0xa0)\n",
IN_BYTE(IDE_SELECT_REG));
status=IN_BYTE(IDE_ALTSTATUS_REG);
printk("Status=0x%x\n", status);

/* Select subfeature 0x3 (Set transfer mode) */
OUT_BYTE(0x03,IDE_FEATURE_REG);
status=IN_BYTE(IDE_ALTSTATUS_REG);
printk("Status=0x%x\n", status);

/* Set the transfer mode to PIO mode 4 */
OUT_BYTE(0x0c,IDE_NSECTOR_REG);
printk("IDE_NSECTOR_REG=0x%x (Should be 0x0c)\n",
IN_BYTE(IDE_NSECTOR_REG));
status=IN_BYTE(IDE_ALTSTATUS_REG);
printk("Status=0x%x\n", status);

/* Execute command 0xEF (Set Features) */
OUT_BYTE(0xEF,IDE_COMMAND_REG);
printk("Command executed...\n");

/* Check the status and error code */
for(i=0;i<10;i++) {
status=IN_BYTE(IDE_ALTSTATUS_REG);
printk("Status=0x%x\n", status);
}
status=IN_BYTE(IDE_ERROR_REG);
printk("Error=0x%x\n", status);

restore_flags(flags);

After doing a 'hdparm -p4 /dev/hdc', I get:

Status=0x50 <-- 0x50 = DRDY, DSC (no error)
IDE_SELECT_REG=0xa0 (Should be 0xa0)
Status=0x50
Status=0x50
IDE_NSECTOR_REG=0xc (Should be 0x0c)
Status=0x50
Command executed...
Status=0xd0 <-- 0xd0 = Busy (as expected)
Status=0xd0
Status=0x50
Status=0x50
Status=0x50
Status=0x50
Status=0x50
Status=0x50
Status=0x50
Status=0x50
Error=0x0 <-- No error!

OK, everything seems OK to me... When I run hdparm -t /dev/hdc, I get
the same speed as before, about 2.5MB/s, for buffered disk reads.

More info on my machine:
Controller: DTC2278E (VL, bus speed 33MHz, only VL device in the system)
Processor: 486 dx4-120
256k, 15ns Cache
20MB memory
DTCspeed program supplied with card says 6-8MB/s reads

The questions:

1. Is this really all I can get out of this drive?
2. Assuming my hardware/drive should be able to go faster, what did I
do wrong on the above code???? The dtcspeed program says I get
much faster reads. Is it totally broken?

*ANY* help is very appreciated!!! I really would like to see this drive
go faster if possible!!!!!!!

Thanks,
Mike