Search
lxdream.org :: lxdream/test/testide.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/testide.c
changeset 561:533f6b478071
prev263:6f641270b2aa
author nkeynes
date Thu Dec 11 23:26:03 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Disable the generational translation cache - I've got no evidence that it
actually helps performance, and it simplifies things to get rid of it (in
particular, translated code doesn't have to worry about being moved now).
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * IDE interface test cases. Covers all (known) IDE registers in the 
     5  * 5F7000 - 5F74FF range including DMA, but does not cover any GD-Rom
     6  * device behaviour (ie packet comands).
     7  *
     8  * These tests should be run with the drive empty.
     9  *
    10  * Copyright (c) 2006 Nathan Keynes.
    11  *
    12  * This program is free software; you can redistribute it and/or modify
    13  * it under the terms of the GNU General Public License as published by
    14  * the Free Software Foundation; either version 2 of the License, or
    15  * (at your option) any later version.
    16  *
    17  * This program is distributed in the hope that it will be useful,
    18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    20  * GNU General Public License for more details.
    21  */
    23 #include <stdlib.h>
    24 #include <stdio.h>
    25 #include "testdata.h"
    26 #include "lib.h"
    27 #include "ide.h"
    28 #include "asic.h"
    30 unsigned int test_count = 0, test_failures = 0;
    32 #define IDE_BASE 0xA05F7000
    34 #define IDE_ALTSTATUS IDE_BASE+0x018
    35 #define IDE_UNKNOWN   IDE_BASE+0x01C
    36 #define IDE_DATA      IDE_BASE+0x080 /* 16 bits */
    37 #define IDE_FEATURE   IDE_BASE+0x084
    38 #define IDE_COUNT     IDE_BASE+0x088
    39 #define IDE_LBA0      IDE_BASE+0x08C
    40 #define IDE_LBA1      IDE_BASE+0x090
    41 #define IDE_LBA2      IDE_BASE+0x094
    42 #define IDE_DEVICE    IDE_BASE+0x098
    43 #define IDE_COMMAND   IDE_BASE+0x09C
    44 #define IDE_ACTIVATE  IDE_BASE+0x4E4
    46 #define IDE_DISC       IDE_LBA0
    47 #define IDE_DEVCONTROL IDE_ALTSTATUS
    48 #define IDE_ERROR      IDE_FEATURE
    49 #define IDE_STATUS     IDE_COMMAND
    51 #define IDE_DMA_ADDR   IDE_BASE+0x404
    52 #define IDE_DMA_SIZE   IDE_BASE+0x408
    53 #define IDE_DMA_DIR    IDE_BASE+0x40C
    54 #define IDE_DMA_CTL1   IDE_BASE+0x414
    55 #define IDE_DMA_CTL2   IDE_BASE+0x418
    56 #define IDE_DMA_MAGIC  IDE_BASE+0x4B8
    57 #define IDE_DMA_STATUS IDE_BASE+0x4F8
    59 #define CHECK_REG_EQUALS( a, b, c ) if( b != c ) { fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", __FILE__, __LINE__, __func__, b, a, c ); return -1; }
    61 /* Wait for the standard timeout for an INTRQ. If none is received, print an
    62  * error and return -1
    63  */
    64 #define EXPECT_INTRQ() if( ide_wait_irq() != 0 ) { fprintf(stderr, "Timeout at %s:%d %s(): waiting for INTRQ\n", __FILE__, __LINE__, __func__ ); return -1; }
    66 /* Check if the INTRQ line is currently cleared (ie inactive) */
    67 #define CHECK_INTRQ_CLEAR() if ( (long_read( ASIC_STATUS1 ) & 1) != 0 ) { fprintf(stderr, "Assertion failed at %s:%d %s(): expected INTRQ to be cleared, but was raised.\n", __FILE__, __LINE__, __func__ ); return -1; }
    69 #define EXPECT_READY() if( ide_wait_ready() != 0 ) { fprintf(stderr, "Timeout at %s:%d %s(): waiting for BSY flag to clear\n", __FILE__, __LINE__, __func__ ); return -1; }
    71 int check_regs( uint32_t *regs,const char *file, int line, const char *fn ) 
    72 {
    73     int i;
    74     int rv = 0;
    75     for( i=0; regs[i] != 0; i+=2 ) {
    76 	uint32_t addr = regs[i];
    77 	uint32_t val = regs[i+1];
    78 	uint32_t actual;
    79 	if( addr == IDE_DATA ) {
    80 	    actual = (uint32_t)word_read(addr);
    81 	    if( val != actual ) { 
    82 		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %04X from register %08X, but was %04X\n", file, line, fn, val, addr, actual ); 
    83 		rv = -1;
    84 	    }
    85 	} else if( addr <= IDE_COMMAND ) {
    86 	    actual = (uint32_t)byte_read(addr);
    87 	    if( val != actual ) { 
    88 		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %02X from register %08X, but was %02X\n", file, line, fn, val, addr, actual ); 
    89 		rv = -1;
    90 	    }
    91 	} else {
    92 	    actual = long_read(addr);
    93 	    if( val != actual ) { 
    94 		fprintf(stderr, "Assertion failed at %s:%d %s(): expected %08X from register %08X, but was %08X\n", file, line, fn, val, addr, actual ); 
    95 		rv = -1;
    96 	    }
    97 	}
    98     }
    99     return rv;
   100 }
   102 #define CHECK_REGS( r ) if( check_regs(r, __FILE__, __LINE__, __func__) != 0 ) { return -1; }
   105 uint32_t post_packet_ready_regs[] = 
   106     { IDE_ALTSTATUS, 0x58,
   107       IDE_COUNT, 0x01,
   108       IDE_LBA1, 8,
   109       IDE_LBA2, 0,
   110       IDE_DEVICE, 0,
   111       IDE_STATUS, 0x58, 0, 0 };
   113 uint32_t post_packet_cmd_regs[] = 
   114     { IDE_ALTSTATUS, 0xD0,
   115       IDE_ERROR, 0x00,
   116       IDE_COUNT, 0x01,
   117       IDE_LBA1, 8,
   118       IDE_LBA2, 0,
   119       IDE_DEVICE, 0,
   120       IDE_STATUS, 0xD0, 0, 0 };
   122 uint32_t packet_cmd_error6_regs[] = 
   123     { IDE_ALTSTATUS, 0x51,
   124       IDE_ERROR, 0x60,
   125       IDE_COUNT, 0x03,
   126       IDE_LBA1, 8,
   127       IDE_LBA2, 0,
   128       IDE_DEVICE, 0,
   129       IDE_STATUS, 0x51, 0, 0 };
   131 uint32_t packet_data_ready_regs[] = 
   132     { IDE_ALTSTATUS, 0x58,
   133       IDE_ERROR, 0x00,
   134       IDE_COUNT, 0x02,
   135       IDE_LBA1, 0x0C,
   136       IDE_LBA2, 0,
   137       IDE_DEVICE, 0,
   138       IDE_STATUS, 0x58, 0, 0 };
   141 uint32_t post_packet_data_regs[] = 
   142     { IDE_ALTSTATUS, 0xD0,
   143       IDE_ERROR, 0x00,
   144       IDE_COUNT, 0x02,
   145       IDE_LBA1, 0x0C,
   146       IDE_LBA2, 0,
   147       IDE_DEVICE, 0,
   148       IDE_STATUS, 0xD0, 0, 0 };
   150 uint32_t packet_complete_regs[] = 
   151     { IDE_ALTSTATUS, 0x50,
   152       IDE_ERROR, 0x00,
   153       IDE_COUNT, 0x03,
   154       IDE_LBA1, 0x0C,
   155       IDE_LBA2, 0,
   156       IDE_DEVICE, 0,
   157       IDE_STATUS, 0x50, 0, 0 };
   159 int send_packet_command( const char *cmd )
   160 {
   161     unsigned short *spkt = (unsigned short *)cmd;
   162     int i;
   164     EXPECT_READY();
   165     byte_write( IDE_FEATURE, 0 );
   166     byte_write( IDE_COUNT, 0 );
   167     byte_write( IDE_LBA0, 0 );
   168     byte_write( IDE_LBA1, 8 );
   169     byte_write( IDE_LBA2, 0 );
   170     byte_write( IDE_DEVICE, 0 );
   171     byte_write( IDE_COMMAND, 0xA0 );
   172     byte_read(IDE_ALTSTATUS); /* delay 1 PIO cycle */
   173     EXPECT_READY(); /* Wait until device is ready to accept command (usually immediate) */
   174     CHECK_INTRQ_CLEAR();
   175     CHECK_REGS( post_packet_ready_regs );
   177     /* Write the command */
   178     for( i=0; i<6; i++ ) {
   179         word_write( IDE_DATA, spkt[i] );
   180     }
   182     byte_read(IDE_ALTSTATUS); 
   184     // CHECK_REGS( post_packet_cmd_regs );
   185     EXPECT_INTRQ();
   186     EXPECT_READY();
   187     return 0;
   188 }
   190 int read_pio( char *buf, int expected_length ) {
   191     uint32_t ready_regs[] = {
   192 	IDE_ALTSTATUS, 0x58,
   193 	IDE_ERROR, 0x00,
   194 	IDE_COUNT, 0x02,
   195 	IDE_LBA1, expected_length & 0xFF,
   196 	IDE_LBA2, (expected_length >> 8),
   197 	IDE_DEVICE, 0,
   198 	IDE_STATUS, 0x58, 
   199 	0, 0 };    
   201     int i;
   202     unsigned short *bufptr = (unsigned short *)buf;
   203     unsigned int length = 0, avail;
   204     int status;
   206     CHECK_REGS( ready_regs );
   207     for( i=0; i<expected_length; i+=2 ) {
   208 	*bufptr++ = word_read(IDE_DATA);
   209     }
   211     EXPECT_INTRQ();
   212     EXPECT_READY();
   213     ready_regs[1] = 0x50;
   214     ready_regs[5] = 0x03;
   215     ready_regs[13] = 0x50;
   216     CHECK_REGS( ready_regs );
   217     return 0;
   218 }
   220 #define IDE_TEST_PACKET_OK( c,e,l ) if( ide_test_packet_ok( __FILE__, __LINE__, __func__, c, e, l ) != 0 ) { return -1; }
   221 int ide_test_packet_ok( const char *file, int line, const char *func, 
   222 			const char *cmd, char *expect, int expect_len ) 
   223 {
   224     char buf[expect_len];
   225     int status = send_packet_command(cmd);
   226     if( status != 0 ) {
   227 	return status;
   228     }
   229     status = byte_read( IDE_ALTSTATUS );
   230     if( status & 1 ) { /* Error */
   231 	status = ide_get_sense_code();
   232 	fprintf( stderr, "Assertion failed at %s:%d %s(): Unexpected error %04X\n",
   233 		 file, line, func, status );
   234 	return -1;
   235     }
   237     status = read_pio( buf, expect_len );
   238     if( status != 0 ) {
   239 	return status;
   240     }
   241     if( expect != NULL && memcmp( expect, buf, expect_len ) != 0 ) {
   242 	fprintf(stderr, "Assertion failed at %s:%d %s(): Results differ from expected:\n",file,line,func );
   243 	fwrite_diff( stderr, expect, expect_len, buf, expect_len );
   244 	return -1;
   245     }
   246     return 0;
   247 }
   249 #define IDE_TEST_PACKET_ERROR( c,e ) if( ide_test_packet_error( __FILE__, __LINE__, __func__, c, e ) != 0 ) { return -1; }
   250 int ide_test_packet_error( char *file, int line, char *func,
   251 			   char *cmd, int expect_error )
   252 {
   253     uint32_t error_regs[] = 
   254     { IDE_ALTSTATUS, 0x51,
   255       IDE_ERROR, (expect_error & 0x0F)<<4,
   256       IDE_COUNT, 0x03,
   257       IDE_DEVICE, 0,
   258       IDE_STATUS, 0x51, 0, 0 };
   259     uint32_t error_code;
   260     int status = send_packet_command(cmd);
   261     if( status != 0 ) {
   262 	return status;
   263     }
   264     CHECK_REGS(error_regs);
   265     error_code = ide_get_sense_code();
   266     CHECK_IEQUALS( expect_error, error_code );
   268     return 0;
   269 }
   272 uint32_t abort_regs[] = {
   273     IDE_ALTSTATUS, 0x51,
   274     IDE_ERROR, 0x04,
   275     IDE_COUNT, 0x02,
   276     IDE_LBA1, 0x00,
   277     IDE_LBA2, 0x50,
   278     IDE_DEVICE, 0,
   279     IDE_DATA, 0x0000,
   280     IDE_STATUS, 0x51, 
   281     0, 0 };
   283 uint32_t post_reset_regs[] = {
   284     IDE_ALTSTATUS, 0x00,
   285     IDE_ERROR, 0x01,
   286     IDE_COUNT, 0x01,
   287     IDE_LBA1, 0x14,
   288     IDE_LBA2, 0xEB,
   289     IDE_DEVICE, 0,
   290     IDE_DATA, 0xFFFF,
   291     IDE_STATUS, 0x00, 
   292     0, 0 };
   294 uint32_t post_set_feature_regs[] = {
   295     IDE_ALTSTATUS, 0x50,
   296     IDE_ERROR, 0x00,
   297     IDE_COUNT, 0x0B,
   298     IDE_LBA1, 0x00,
   299     IDE_LBA2, 0x00,
   300     IDE_DEVICE, 0,
   301     IDE_DATA, 0xFFFF,
   302     IDE_STATUS, 0x50, 
   303     0, 0 };    
   305 uint32_t post_set_feature2_regs[] = {
   306     IDE_ALTSTATUS, 0x50,
   307     IDE_ERROR, 0x00,
   308     IDE_COUNT, 0x22,
   309     IDE_LBA1, 0x00,
   310     IDE_LBA2, 0x00,
   311     IDE_DEVICE, 0,
   312     IDE_DATA, 0xFFFF,
   313     IDE_STATUS, 0x50, 
   314     0, 0 };    
   316 /************************** Interface Tests *******************************/
   318 /**
   319  * Test enable/disable of the IDE interface via port
   320  * 0x4E4. 
   321  */
   322 int test_enable()
   323 {
   324     int i;
   325     int failed = 0;
   326     /* ensure deactivated */
   327     long_write( IDE_ACTIVATE, 0x00042FE );
   329     /* test registers to ensure all return 0xFF (need to wait a few cycles?) */
   330     for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
   331 	CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
   332     }
   334     /* enable interface */
   335     ide_activate();
   337     /* test registers have default settings */
   338     //    CHECK_REGS( post_reset_regs );
   341     /* disable interface and re-test */
   342     long_write( IDE_ACTIVATE, 0x00042FE );
   344     /* Test registers all 0xFF */
   345     for( i= IDE_BASE; i< IDE_BASE+0x400; i+= 4 ) {
   346 	CHECK_REG_EQUALS( i, 0xFFFFFFFF, long_read( i ) );
   347     }
   349     /* Finally leave the interface in an enabled state */
   350     ide_activate();
   351     return 0;
   352 }
   355 uint32_t drive_ready_regs[] = {
   356     IDE_ALTSTATUS, 0x50,
   357     IDE_ERROR, 0x00,
   358     IDE_COUNT, 0x03,
   359     IDE_LBA1, 0x08,
   360     IDE_LBA2, 0x00,
   361     IDE_DEVICE, 0,
   362     IDE_DATA, 0xFFFF,
   363     IDE_STATUS, 0x50, 
   364     0, 0 };    
   366 /**
   367  * Test the reset command
   368  */
   369 int test_reset()
   370 {
   371     byte_write( IDE_COMMAND, 0x08 );
   372     EXPECT_READY();
   373     CHECK_INTRQ_CLEAR();
   374     CHECK_REGS( post_reset_regs );
   376     /** Set Default PIO mode */
   377     byte_write( IDE_FEATURE, 0x03 );
   378     byte_write( IDE_COUNT, 0x0B );
   379     byte_write( IDE_COMMAND, 0xEF );
   380     EXPECT_READY();
   381     CHECK_REGS( post_set_feature_regs );
   383     /** Set Multi-word DMA mode 2 */
   384     long_write( 0xA05F7490, 0x222 );
   385     long_write( 0xA05F7494, 0x222 );
   386     byte_write( IDE_FEATURE, 0x03 );
   387     byte_write( IDE_COUNT, 0x22 );
   388     byte_write( IDE_COMMAND, 0xEF );
   389     EXPECT_READY();
   390     CHECK_INTRQ_CLEAR();
   391     CHECK_REGS( post_set_feature2_regs );
   393     char test_ready_cmd[12] = { 0,0,0,0, 0,0,0,0, 0,0,0,0 };
   394     if( send_packet_command(test_ready_cmd) != 0 ) {
   395 	return -1;
   396     }
   398     CHECK_REGS( packet_cmd_error6_regs );
   399     int sense = ide_get_sense_code();
   400     CHECK_IEQUALS( 0x2906, sense );
   402     if( send_packet_command(test_ready_cmd) != 0 ) {
   403 	return -1;
   404     }
   405     CHECK_REGS( drive_ready_regs );
   406     return 0;
   407 }
   409 char expect_ident[] = { 0x00, 0xb4, 0x19, 0x00,
   410 			0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20 };
   412 /**
   413  * Test the PACKET command (using the Inquiry command)
   414  */
   415 int test_packet()
   416 {
   417     int i;
   418     char cmd[12] = { 0x11, 0, 4, 0,  12, 0, 0, 0,  0, 0, 0, 0 };
   419     // char cmd[12] = { 0x00,0,0,0, 0,0,0,0, 0,0,0,0 };
   420     unsigned short *spkt;
   421     char result[12];
   423     send_packet_command( cmd );
   424     CHECK_REGS( packet_data_ready_regs );
   425     spkt = (unsigned short *)result;
   426     *spkt++ = word_read(IDE_DATA);
   427     *spkt++ = word_read(IDE_DATA);
   428     *spkt++ = word_read(IDE_DATA);
   429     *spkt++ = word_read(IDE_DATA);
   430     CHECK_REGS( packet_data_ready_regs );
   431     *spkt++ = word_read(IDE_DATA);
   432     *spkt++ = word_read(IDE_DATA);
   433 //    CHECK_REGS( post_packet_data_regs );
   434     EXPECT_READY();
   435     EXPECT_INTRQ();
   436     CHECK_REGS( packet_complete_regs );
   438     if( memcmp( result, expect_ident, 12 ) != 0 ) {
   439 	fwrite_diff( stderr, expect_ident, 12, result, 12 );
   440 	return -1;
   441     }
   442     return 0;
   443 }
   445 /**
   446  * Test the SET FEATURE command
   447  */
   448 int test_set_feature()
   449 {
   450     return 0;
   451 }
   455 /**
   456  * Test DMA transfer (using the Inquiry packet comand)
   457  */
   458 int test_dma()
   459 {
   460     return 0;
   461 }
   463 /**
   464  * Test DMA abort
   465  */
   466 int test_dma_abort()
   467 {
   468     return 0;
   469 }
   471 /***************************** GD-Rom Tests **********************************/
   473 int test_read_toc()
   474 {
   475     char cmd[12] = { 0x14,0,0,0x00, 0x0C,0,0,0, 0,0,0,0 };
   476     char expect[12] = { 0x41, 0,0, 0x96, 0x41, 0, 0x2E, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF };
   478     IDE_TEST_PACKET_OK( cmd, expect, 12 );
   479     return 0;
   480 }
   482 int test_read_pio()
   483 {
   484     int i,j;
   485     char cmd[12] = {0x30, 0x28, 0, 0x2E,  0x4C, 0, 0, 0,  0, 0, 7, 0 };
   486     uint32_t read_pio_ready_regs[] = 
   487 	{ IDE_ALTSTATUS, 0x58,
   488 	  IDE_ERROR, 0x00,
   489 	  IDE_COUNT, 0x02,
   490 	  IDE_LBA1, 0x00,
   491 	  IDE_LBA2, 0x08,
   492 	  IDE_DEVICE, 0,
   493 	  IDE_STATUS, 0x58, 0, 0 };
   495     if( send_packet_command(cmd) != 0 ) {
   496 	return -1;
   497     }
   499     for( j=0; j<7; j++ ) {
   500 	CHECK_REGS(read_pio_ready_regs);
   501 	CHECK_INTRQ_CLEAR();
   502 	for( i=0; i<0x0800; i+=2 ) {
   503 	    word_read(IDE_DATA); // throw away for now.
   504 	}
   506 	EXPECT_INTRQ();
   507 	EXPECT_READY();
   508     }
   510     read_pio_ready_regs[1] = 0x50;
   511     read_pio_ready_regs[5] = 0x03;
   512     read_pio_ready_regs[13] = 0x50;
   513     CHECK_REGS( read_pio_ready_regs );
   514     return 0;
   515 }
   517 /**
   518  * Test interaction of Read CD (0x30) with Status (0x40,1)
   519  */
   520 int test_status1() 
   521 {
   522     char cmd[12] = { 0x40, 0x01, 0, 0, 16,0,0,0, 0,0,0,0 };
   523     char read1cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4C, 0, 0, 0, 0, 0,1,0 };
   524     char expect1[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,1,0,0, 0x2E,0x4D,0,0 };
   525     char read2cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4D, 0, 0, 0, 0, 0,1,0 };
   526     char expect2[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,4,0,0, 0x2E,0x50,0,0 };
   527     char read3cmd[12] = { 0x30, 0x28, 0, 0x2E, 0x4E, 0, 0, 0, 0, 0,1,0 };
   528     char expect3[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,5,0,0, 0x2E,0x51,0,0 };
   529     char expect4[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,2,0,0, 0x2E,0x4E,0,0 };
   530     char read5cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x01, 0, 0, 0, 0, 0,1,0 };
   531     char expect5[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0,0xB6,0,0, 0x2F,0x02,0,0 };
   532     char read6cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x50, 0, 0, 0, 0, 0,1,0 };
   533     char expect6[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0x01,0x05,0,0, 0x2F,0x51,0,0 };
   534     char read7cmd[12] = { 0x30, 0x28, 0, 0x2F, 0x51, 0, 0, 0, 0, 0,1,0 };
   535     char expect7[16] = { 0,0x15,0,0x0E, 0x41,2,1,0, 0x01,0x06,0,0, 0x2F,0x52,0,0 };
   538     IDE_TEST_PACKET_OK(read1cmd, NULL, 2048);
   539     IDE_TEST_PACKET_OK(cmd, expect1, 14 );
   540     IDE_TEST_PACKET_OK(read2cmd, NULL, 2048);
   541     IDE_TEST_PACKET_OK(cmd, expect2, 14 );
   542     IDE_TEST_PACKET_OK(read3cmd, NULL, 2048);
   543     IDE_TEST_PACKET_OK(cmd, expect3, 14 );
   544     IDE_TEST_PACKET_OK(read2cmd, NULL, 2048);
   545     IDE_TEST_PACKET_OK(cmd, expect4, 14 );
   546     IDE_TEST_PACKET_OK(read5cmd, NULL, 2048);
   547     IDE_TEST_PACKET_OK(cmd, expect5, 14 );
   548     IDE_TEST_PACKET_OK(read6cmd, NULL, 2048);
   549     IDE_TEST_PACKET_OK(cmd, expect6, 14 );
   551     return 0;
   552 }
   554 /********************************* Main **************************************/
   556 test_func_t test_fns[] = { test_enable, test_reset, test_packet,
   557 			   test_dma, test_dma_abort, test_read_pio,
   558 			   test_read_toc,
   559 			   test_status1, NULL };
   561 int main() 
   562 {
   563     int i;
   564     ide_init();
   565     return run_tests( test_fns );
   566 }
.