Page 1 of 1

What am I doing wrong? (ps2atad)

Posted: Sat Nov 13, 2004 7:35 am
by mharris
I haven't done much IOP programming, so it's likely I've made a blunder somewhere. Can anyone see something that I'm doing wrong? What I want to do is read directly from the HDD, not using the hddfds.irx, since my HDD is formatted in ext2 (Linux Kit).

It looks like the ps2dev9.irx and ps2atad.irx are loading OK, as I see their banners on the pksh console. My module will load OK if the start() routine does nothing. But when my module's start() tries to call ata_get_devinfo(), the PS2 hangs. I hear a clunk from the HDD, like something's being turned on, but that's it.

I have included the IRXs inline (irx2s) in the elf file, and they seem to be loading and initializing OK. Here are snippets of code, let me know if you need more:

exports.tab:

Code: Select all

DECLARE_EXPORT_TABLE(ext2fs, 1, 2)
        DECLARE_EXPORT(_start)
        DECLARE_EXPORT(_retonly)
        DECLARE_EXPORT(shutdown)
        DECLARE_EXPORT(_retonly)
END_EXPORT_TABLE

void _retonly() {}
imports.lst:

Code: Select all

stdio_IMPORTS_start
I_printf
stdio_IMPORTS_end

atad_IMPORTS_start
I_ata_get_devinfo
I_ata_device_dma_transfer
I_ata_device_sec_unlock
I_ata_device_idle
I_ata_device_sce_security_init
I_ata_device_smart_get_status
I_ata_device_smart_save_attr
I_ata_device_flush_cache
atad_IMPORTS_end
Main IOP routine:

Code: Select all

#define MODNAME "ext2fs"
IRX_ID(MODNAME, 1, 1);

int _start(void)
{
        int drive = 0;
        ata_devinfo_t * devinfo;

        printf("ext2fs: calling ata_get_devinfo(%d)\n", drive);
        devinfo = ata_get_devinfo(drive);
        if (devinfo == 0) {
                printf("ext2fs: ata_get_devinfo() failed for drive %d\n", drive);
                return 1;
        }
        printf("ext2fs: ata_get_devinfo(%d) success!\n", drive);
        printf("ext2fs:          exists = %d\n", devinfo->exists);
        printf("ext2fs:      has_packet = %d\n", devinfo->has_packet);
        printf("ext2fs:   total_sectors = %u\n", devinfo->total_sectors);
        printf("ext2fs: security_status = %u\n", devinfo->security_status);
        return 0;
}

int shutdown(void)
{
        return 0;
}
Test EE module:

Code: Select all

int main(int argc, char * argv[])
{
        SifInitRpc(0);
        sbv_patch_enable_lmb();

        if (loadModule(usbd_IRX_START,    usbd_IRX_SIZE,    "usbd"))     goto err;
        if (loadModule(ps2kbd_IRX_START,  ps2kbd_IRX_SIZE,  "ps2kbd"))   goto err;
        if (loadModule(poweroff_IRX_START,poweroff_IRX_SIZE,"poweroff")) goto err;
        if (loadModule(iomanX_IRX_START,  iomanX_IRX_SIZE,  "iomanX"))   goto err;
        if (loadModule(fileXio_IRX_START, fileXio_IRX_SIZE, "fileXio"))  goto err;
        if (loadModule(ps2dev9_IRX_START, ps2dev9_IRX_SIZE, "ps2dev9"))  goto err;
        if (loadModule(ps2atad_IRX_START, ps2atad_IRX_SIZE, "ps2atad"))  goto err;

        npmPuts("--loading my lib--\n");
        if (loadModule(ext2fs_IRX_START, ext2fs_IRX_SIZE, "ext2fs"))  goto err;
        npmPuts("--my lib loaded--\n");

        kbd_loop();
 err:
        npmPuts("-------EXITING-------\n");
        SleepThread();
        return 0;
}
I've obviously omitted a couple things here -- loadModule(), all of the #include lines, etc. -- in the interest of brevity.

thx, m

Posted: Thu Nov 18, 2004 3:59 am
by mharris
Here are some more details. I'm still having no luck, but I'm able to narrow down what's happening before hanging. I've added printf() calls to the ps2atad IRX module; of course these printfs might be intrusive and could affect what's happening, since we're talking about device drivers here...

Here's what I'm seeing: HDD-0 is detected (and it correctly detects that there is no HDD-1); the "IDENTIFY DEVICE" command on HDD-0 also seems to work. But when the ata_init_devices() routine attempts to set HDD-0 to enter Ultra DMA mode 4, the system hangs in ata_io_start(), in the block of code that begins with "Finally! We send off the ATA command with arguments."

Is it possible that my drive or net adapter do not support Ultra DMA mode 4? This is just sheer speculation on my part... I don't know the other parameters to tell it to go into a different mode, so there's not much I can test.

FWIW, any .elf files I've tried that attempt to access the HDD seem to fail as well. However, I've verified that it still works fine for PS2 Linux, so it doesn't appear to be a hardware problem. Is there anything unusual about the disk and/or the NA that came with the Linux Kit?

Posted: Thu Nov 18, 2004 4:14 am
by mrbrown
One way you can verify what DMA modes your drive supports is to plug it into a Linux box and run hdparm -I /dev/hdX. In the "Capabilities:" section you can see the supported DMA modes.

Another way is to go to the website of the HDD's manufacturer :).

In any case, that's bad behavior for ps2atad to assume the drive can support that mode. Linux is much more robust and will probe the drive's capabilities before setting any explicit DMA modes.

Any takers to fix ps2atad?

Posted: Thu Nov 18, 2004 6:22 am
by mharris
mrbrown wrote:One way you can verify what DMA modes your drive supports is to plug it into a Linux box and run hdparm -I /dev/hdX. In the "Capabilities:" section you can see the supported DMA modes.
Hmm, it's already in a Linux box ;-) What are the odds that PS2 Linux has hdparm in it's distro? I'll post tonight when I get a chance to sit in front of the machine.
mrbrown wrote:Another way is to go to the website of the HDD's manufacturer :).
It would be Sony's logo in this case... on top of a Maxtor logo. The Maxtor information may or may not be valid anymore, because who knows what Sony has done to the firmware?
mrbrown wrote:In any case, that's bad behavior for ps2atad to assume the drive can support that mode. Linux is much more robust and will probe the drive's capabilities before setting any explicit DMA modes.

Any takers to fix ps2atad?
/me lowers hand quickly

I will take a peek at the PS2 Linux source to see how they're detecting and setting the drive parameters, if it's available in the kernel and not the RTE.

Posted: Thu Nov 18, 2004 7:18 am
by mrbrown
Hmm, I didn't know you were using an official HDD. AFAIK they are all supposed to support UDMA4. Is this a PS2/Linux HDD or a FFXI HDD? I'm thinking either ps2atad can't handle some new quirks in the drive (or there's a bug in ps2atad), or there's something wrong with your HDD. You'd think that if software was trying to set a mode the drive didn't support, the drive wouldn't just die - but I don't know enough about ATA specs to know if that's the case.

IIRC, I grabbed hdparm (is it in util-linux?) and compiled it for PS2/Linux. It's only one source file.

Posted: Thu Nov 18, 2004 1:53 pm
by Guest
I found an interesting web site that discusses the ins and outs of ATA modes.

http://www.storagereview.com/guide2000/ ... sUDMA.html

Anyhow, some key points:

1. Both the drive and the controller must support UDMA4 (or whatever mode is used), and both must have the mode enabled, either by default, or through a mode change. In theory, the drive SHOULD be able to fall back to a mode that works, but that doesn't always work out well.

2. The cabling must be 80-conducter cabling to use modes over 2. If it is not 80-conducter wiring, then 66 MB/s and 100 MB/s (or greater) operations will not be used.

Now for my humble opinion: It sounds nice to be able to use UDMA4 modes, but I don't think 80-conductor wiring is used in the HDD adapter. Well, I KNOW its not used. ;) Most importantly, we all know that the IOP isn't all that fantastic trying to pump 100Mb/s (12.5 MB/s) fast ethernet or 400Mb/s (50MB/s) IEEE 1394/ilink. I am not sure UDMA4 is useful on the PS2 for anything other than an academic exercise.

But, if its academic exercise you want, lets keep discussing how to make it work! :)

My feeling is that the ATAD should default to a mode that is most reasonable for both compatibility and performance capabilities of both the ATA chipset and the IOP, allowing for people to tweak it themselves for the aforementioned academic exercises.

Posted: Thu Nov 18, 2004 4:06 pm
by mrbrown
FYI I consistently got 20-25MB/s throughput from the HDD under PS2 Linux. And that's with it transferring through the EE Linux driver. As always it depends on what the IOP is doing - you can't just say "it can't do this much bandwidth" unless you have a specific set of modules you're applying that metric to. But I digress...

I still believe it's a problem with his drive, I've tried both my PS2 Linux and FFXI drives and they work fine with the latest ps2atad.

Posted: Thu Nov 18, 2004 4:39 pm
by Guest
mrbrown wrote:FYI I consistently got 20-25MB/s throughput from the HDD under PS2 Linux.
Ok, but my one of my original points is that if the typical transfer rate is well under UDMA4 transfer rates, thus why make that a default mode ? UDMA mode 4 is 66 MB/s.

And again, per one of my suggestions, maybe the default mode for ATAD should be the one that comes closest to 20-25 MB/s ? That would be Mode 1 or Mode 2 by the way.

And while I agree that its most likely the drive, again per one of my points is that even if you got both the drive and the ATA chipset to agree to use UDMA4, there is no 80-conducter cable attaching it to the HDD adapter, so the highest UDMA4 speed would be 44MB/s (which is equivalent to mode 3), if that was even possible to achieve on the PS2 hardware.

So back to one of my final points, and given that there are likely to be hard drive combinations out there where this trouble occurs, and there is no point in asking for a transfer rate faster than is capable, should we make the default be mode 2 ?

Actually, I don't really care that much because I only use Sony drives, but it made sense to me thats why I am making the suggestions. Feel free to ignore. ;)

Posted: Sun Nov 21, 2004 3:22 am
by mharris
Hmm. Well I won't say it's *not* a hardware problem with the disk. I get identical results with two different network adaptors (the network-only one that came w/ PS2 Linux, and the retail ethernet+modem). I only have one drive that will fit this adaptor, so I can't try swapping the drive.

And the odd thing is that it works fine under PS2 Linux. Here's the output from hdparm (v3.6):

Code: Select all

Model=aMtxro4 0D042H, FwRev=AD0H710K, SerialNo=2DW2G3EC
 Config={ Fixed }
 RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=57
 BuffType=3(DualPortCache), BuffSize=2048kB, MaxMultSect=16, MultSect=off
 DblWordIO=no, OldPIO=2, DMA=yes, OldDMA=0
 CurCHS=16383/16/63, CurSects=-66060037, LBA=yes, LBAsects=78125000
 tDMA={min:120,rec:120}, DMA modes: mword0 mword1 mword2
 IORDY=on/off, tPIO={min:120,w/IORDY:120}, PIO modes: mode3 mode4
 UDMA modes: mode0 mode1 mode2 mode3 *mode4 mode5
... so it should be capable of UDMA4; in fact, PS2 Linux seems to be using it in this mode. Of course, maybe there's not be a problem with using this mode at all... there could be something else, and this is just when it manifests itself.

Well, I'll continue poking around to see what I can discover.

Posted: Sun Nov 21, 2004 3:46 am
by mrbrown
That information you gleaned from PS2 Linux is very useful. Well it may or may not be a hardware issue - now I'm leaning towards the drive is fine. And since your drive returns meaningful info (and because you use it all the time) in PS2 Linux, we know that at the very least ps2atad should be fixed to work with your drive.

Hmm, the two possible culrpits technically are ps2dev9 and ps2atad.

It's still strange that my drives work and yours does not. A HDD firmware issue?

Posted: Sun Nov 21, 2004 4:43 am
by mharris
... or, it could be the most obvious -- that I don't know what I'm doing :-P

Here's my environment: I'm using ps2link v1.0, and since I've had erratic problems with loading modules via the host: interface, I've embedded them all into the body of the .elf file. I couldn't find an irx2s anywhere, though I've seen references, so I wrote my own (it's simple enough).

The IRXs seem to be getting initialized OK; for example, I'm using the ps2kbd.irx module and the SCE usbd.irx and all is good with the keyboard, so I'm assuming I've encoded and loaded all of the IRXs OK.

The only issue I have is with the IRX that I wrote myself, since this is all new stuff to me. I don't know if there's anything I need to do to initialize the atad libraries beyond what I'm doing. I've looked at code in ps2drv for hints, and AFAIK I'm not doing anything differently. On the EE side, I'm just calling SifInitRpc(0) and sbv_patch_enable_lmb() before loading the libraries via SifExecModuleBuffer(). Do I need to call SifIopSync() or anything like that?

Posted: Sun Nov 21, 2004 4:48 am
by mrbrown
Hooray for the obvious! ;P IIRC, ps2link 1.0 couldn't handle ps2dev9 and ps2atad, because it took control over the network adapter exclusively.

Upgrade to ps2link 1.24 (or whatever the last released one is) and see if that fixes it. I just assumed you were using a recent version of ps2link :).

Posted: Sun Nov 21, 2004 6:06 am
by mharris
mrbrown wrote:Hooray for the obvious! ;P IIRC, ps2link 1.0 couldn't handle ps2dev9 and ps2atad, because it took control over the network adapter exclusively.
Well, shoot. That clears up a lot. Many many thanks.

I set this up long ago and it worked for me, and I've been reluctant to mess with it unless I had a compelling reason to do so. Well, now I do... I have a spare memcard with the exploit on it in case I louse anything up, which has always been my biggest fear.

Posted: Thu Nov 25, 2004 11:05 am
by mharris
Here's the happy ending:

After spending the better part of a day upgrading to ps2link 1.24 (don't ask...) I was somewhat peeved to see that it had the same problems as I was experiencing before. Of course, I had hacked ps2atad all to hell with printf()s, so I took most of them out, but no luck.

The the light dawned on me that ps2link is already loading ps2dev9.irx and iomanx.irx, so maybe double-loading them was causing problems. I took out the loads in my program, and success!

Thanks for all the help in nailing this down.

This is OT: One thing I notice w/ the newer ps2link (or the newer ps2ip.irx, or something) is that I'm getting a lot more dropped packets. I'm doing a lot of printf()s, and it seems like a bunch of them are getting lost and output to the pksh console is hanging for several seconds from time to time. I wasn't seeing this as much w/ the older ps2link.

Posted: Wed Apr 27, 2005 1:16 am
by BraveDog
Ok, hate to dig up old topics, but I got bit by this just recently.
I used to debug with naplink, now I switched to ps2link.
I had problems with my code hanging becuase these irx's are already loaded.
So is there a better solution than commenting out code to do debuging?
Should I write code to see if the module is already loaded and skip it?
Or do most people just comment out certain irx's during debugging then add in a SifIopReset and bring them back in when they are done?

Posted: Wed Apr 27, 2005 2:03 am
by boomint
IIRC this functionality is already in place to find a module by name in iopmgr with:

smod_get_mod_by_name()

See header :
http://cvs.ps2dev.org/ps2sdk/iop/system ... e/iopmgr.h


Implementation:
http://cvs.ps2dev.org/ps2sdk/iop/system ... cvs-markup

Posted: Wed Apr 27, 2005 3:47 am
by BraveDog
Ok, I can give that a try. I am also wondering how to handle the call to fileXioInit(). It seems like this call should just return if it is already inited. I'll have to double check to see if it was hanging here. If it was I guess I only call fileXioInit() if iomanx needs to be loaded.
I am just surprized I didn't find others adding code to do this, which lead me to believe that I am doing something wrong.