#include #include #include #include "harddisk.h" #include struct MsgPort * diskport; struct IOExtHD * diskreq; BYTE sector[ HD_SECTOR ]; struct hd_FirstSector first; extern struct MsgPort * CreatePort (); extern struct IORequest * CreateExtIO (); extern LONG OpenDevice (); extern LONG DoIO (); main() { long error; diskport = CreatePort ( 0L , 0L ); if ( diskport == NULL ) { printf ( "Error in CreatePort ()\n" ); } else { diskreq = (struct IOExtHD *) CreateExtIO ( diskport , (LONG) sizeof ( struct IOExtHD ) ); if ( diskreq == NULL ) { printf ( "CreateExtIO() failed\n" ); } else { error = OpenDevice ( HD_NAME , 0L , diskreq , 0L ); if ( error != 0 ) { printf ( "Error value returned by OpenDevice was %ld\n" , error ); } else { diskreq->iohd_TD.iotd_Req.io_Command = CMD_READ; diskreq->iohd_TD.iotd_Req.io_Data = (APTR) &first; diskreq->iohd_TD.iotd_Req.io_Length = sizeof ( first ); diskreq->iohd_TD.iotd_Req.io_Offset = 0; if ( DoIO ( diskreq ) != 0 ) { printf ( "Error in reading first sector information\n" ); } else { if ( first.magic != HD_MAGIC ) printf ( "Header sector information not found (wrong magic number)\n" ); else do_commands (); } CloseDevice ( diskreq ); } DeleteExtIO ( diskreq , (LONG) sizeof ( struct IOExtHD ) ); } DeletePort ( diskport ); } } do_commands () { long block; int i; char buf[ 80 ]; int retry_limit; while ( 1 ) { printf ( "\nDisk Information:\n\n" ); printf ( "%4ld cylinders\n" , first.cylinders ); printf ( "%4ld park cylinder\n" , first.park_cylinder ); printf ( "%4ld heads\n" , first.heads ); printf ( "%4ld sectors\n" , first.sectors ); printf ( "%4ld map sectors\n" , first.map_sectors ); printf ( "%4ld bad sectors\n" , first.bad_sectors ); printf ( "%4ld write precompensation\n" , first.precomp ); printf ( "\nBad blocks: " ); for ( i = 0; i < first.bad_sectors; i++ ) printf ( "%ld " , (long)first.map[i] ); printf ( "\n\n" ); diskreq->iohd_TD.iotd_Req.io_Command = CMD_FLUSH; DoIO ( diskreq ); diskreq->iohd_TD.iotd_Req.io_Command = CMD_CLEAR; DoIO ( diskreq ); printf ( "Enter block number or (q)uit: " ); if ( gets ( buf ) == NULL ) return; if ( buf[0] == 'q' || buf[0] == 'Q' ) return; if ( sscanf ( buf , "%ld" , &block ) != 1 ) { printf ( "Illegal block number\n" ); } else { printf ( "Reading block %ld\n" , block ); diskreq->iohd_TD.iotd_Req.io_Command = CMD_READ; diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or[0]; diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR; diskreq->iohd_TD.iotd_Req.io_Offset = block * HD_SECTOR; if ( DoIO ( diskreq ) != 0 ) { while ( 1 ) { printf ( "Failed to read sector - enter retry count: " ); if ( gets ( buf ) == NULL ) return; if ( sscanf ( buf , "%d" , &retry_limit ) != 1 ) retry_limit = 1; if ( retry_limit <= 0 ) break; for ( i = 0; i < retry_limit; i++ ) { printf ( "Reading block %ld\n" , block ); diskreq->iohd_TD.iotd_Req.io_Command = CMD_READ; diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or[0]; diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR; diskreq->iohd_TD.iotd_Req.io_Offset = block * HD_SECTOR; if ( DoIO ( diskreq ) == 0 ) break; } if ( i >= retry_limit ) { printf ( "Failed to read sector after %d attempts - setting buffer to 0's\n" , retry_limit ); for ( i = 0; i < HD_SECTOR; i++ ) sector[i] = 0; } else { printf ( "Sector successfully read after %d retries\n" , i ); break; } } } printf ( "(u)nlink the sector or\n(w)rite the sector? " ); if ( gets ( buf ) == NULL ) return; if ( buf[0] == 'u' || buf[0] == 'U' ) { while ( first.bad_sectors < HD_MAP_SIZE && first.map[ first.bad_sectors ] == MAP_MARK_BAD ) first.bad_sectors++; if ( first.bad_sectors >= HD_MAP_SIZE ) { printf ( "Bad sector map table is full!\n" ); } else { /* write out sector at block first.bad_sectors */ printf ( "Writing sector buffer to block %ld\n" , first.bad_sectors + HD_MAP_SECTORS ); diskreq->iohd_TD.iotd_Req.io_Command = CMD_WRITE; diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or[0]; diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR; diskreq->iohd_TD.iotd_Req.io_Offset = ( first.bad_sectors + HD_MAP_SECTORS ) * HD_SECTOR; if ( DoIO ( diskreq ) != 0 ) { printf ( "Failed to write block - bad sector not removed\n" ); } else { /* change map */ first.map[ first.bad_sectors++ ] = block; /* write out sector map */ diskreq->iohd_TD.iotd_Req.io_Command = CMD_WRITE; diskreq->iohd_TD.iotd_Req.io_Data = (APTR) &first; diskreq->iohd_TD.iotd_Req.io_Length = sizeof ( first ); diskreq->iohd_TD.iotd_Req.io_Offset = 0; if ( DoIO ( diskreq ) != 0 ) { printf ( "Failed to write first sectors\n" ); return; } printf ( "\nUnlinked - WARNING: you must reboot for driver to learn of relinking\n\n" ); } } } else if ( buf[0] == 'w' || buf[0] == 'W' ) { printf ( "Writing block %ld\n" , block ); diskreq->iohd_TD.iotd_Req.io_Command = CMD_WRITE; diskreq->iohd_TD.iotd_Req.io_Data = (APTR) §or; diskreq->iohd_TD.iotd_Req.io_Length = HD_SECTOR; diskreq->iohd_TD.iotd_Req.io_Offset = block * HD_SECTOR; if ( DoIO ( diskreq ) != 0 ) { printf ( "Failed to rewrite sector\n" ); } else printf ( "Rewrite successful\n" ); } else { printf ( "Sector not unlinked or rewritten\n" ); } } } }