Line 17... |
Line 17... |
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
*/
|
*/
|
|
|
|
|
#include "support.h"
|
#include "support.h"
|
#include "common.h"
|
#include "common.h"
|
#include "atabug.h"
|
#include "atabug.h"
|
#include "ata.h"
|
#include "ata.h"
|
|
|
Line 39... |
Line 38... |
static struct file *filp = &_filp;
|
static struct file *filp = &_filp;
|
|
|
/* buffer for ata-data */
|
/* buffer for ata-data */
|
static unsigned char buf[512];
|
static unsigned char buf[512];
|
|
|
|
|
/**********************************************************************/
|
/**********************************************************************/
|
/* */
|
/* */
|
/* A T A B U G */
|
/* A T A B U G */
|
/* */
|
/* */
|
/**********************************************************************/
|
/**********************************************************************/
|
Line 54... |
Line 52... |
*/
|
*/
|
void module_ata_init (void)
|
void module_ata_init (void)
|
{
|
{
|
ata_num_commands = 0;
|
ata_num_commands = 0;
|
|
|
register_command ("atabug", "", "ATA debugger. Type 'atabug help' for help", atabug);
|
register_command("atabug", "",
|
|
"ATA debugger. Type 'atabug help' for help", atabug);
|
|
|
register_ata_command ("help", "", "Display this help message", atabug_help);
|
register_ata_command("help", "", "Display this help message",
|
register_ata_command ("exit", "", "Exit atabug and return to ORPmon", atabug_exit);
|
atabug_help);
|
register_ata_command ("open", "<device> [<mode>]", "Opens the requested device. Device=<0|1>, Mode=<r>eadonly|read<w>rite.", ata_open_cmd);
|
register_ata_command("exit", "", "Exit atabug and return to ORPmon",
|
|
atabug_exit);
|
|
register_ata_command("open", "<device> [<mode>]",
|
|
"Opens the requested device. Device=<0|1>, Mode=<r>eadonly|read<w>rite.",
|
|
ata_open_cmd);
|
register_ata_command ("close", "", "Closes the device.", ata_close_cmd);
|
register_ata_command ("close", "", "Closes the device.", ata_close_cmd);
|
register_ata_command ("reset", "<mode>", "Reset ata device(s).", ata_reset_cmd);
|
register_ata_command("reset", "<mode>", "Reset ata device(s).",
|
register_ata_command ("enable", "", "Enables ATA host controller, clears all resets", ata_enable_cmd);
|
ata_reset_cmd);
|
register_ata_command ("dump_dev_regs", "", "Dump the (readable) ata device registers.", ata_dump_device_regs_cmd);
|
register_ata_command("enable", "",
|
register_ata_command ("dump_host_regs", "", "Dump the ata host registers.", ata_dump_host_regs_cmd);
|
"Enables ATA host controller, clears all resets",
|
register_ata_command ("exec_cmd", "<cmd>", "Execute ata command <cmd> (hex)", ata_exec_cmd_cmd);
|
ata_enable_cmd);
|
register_ata_command ("identify_device", "", "Dumps device's IDENTIFY DEVICE block.", ata_identify_device_cmd);
|
register_ata_command("dump_dev_regs", "",
|
register_ata_command ("program_timing", "<PIO mode>", "Programs the device to the selected PIO mode.", ata_set_piomode_cmd);
|
"Dump the (readable) ata device registers.",
|
register_ata_command ("read_sectors", "<startsector> [<sectorcount>]", "Reads sector", ata_read_sectors_cmd);
|
ata_dump_device_regs_cmd);
|
register_ata_command ("read_mbr", "<partition>", "Reads the Master Boot Record.", ata_read_mbr_cmd);
|
register_ata_command("dump_host_regs", "",
|
register_ata_command ("read_dosboot", "<sector>", "Reads the device's bootsector (FAT).", ata_read_dosboot_cmd);
|
"Dump the ata host registers.",
|
register_ata_command ("select_device", "<device_no>", "Select ata device. device_no=<0|1>", ata_select_device_cmd);
|
ata_dump_host_regs_cmd);
|
|
register_ata_command("exec_cmd", "<cmd>",
|
|
"Execute ata command <cmd> (hex)",
|
|
ata_exec_cmd_cmd);
|
|
register_ata_command("identify_device", "",
|
|
"Dumps device's IDENTIFY DEVICE block.",
|
|
ata_identify_device_cmd);
|
|
register_ata_command("program_timing", "<PIO mode>",
|
|
"Programs the device to the selected PIO mode.",
|
|
ata_set_piomode_cmd);
|
|
register_ata_command("read_sectors", "<startsector> [<sectorcount>]",
|
|
"Reads sector", ata_read_sectors_cmd);
|
|
register_ata_command("read_mbr", "<partition>",
|
|
"Reads the Master Boot Record.", ata_read_mbr_cmd);
|
|
register_ata_command("read_dosboot", "<sector>",
|
|
"Reads the device's bootsector (FAT).",
|
|
ata_read_dosboot_cmd);
|
|
register_ata_command("select_device", "<device_no>",
|
|
"Select ata device. device_no=<0|1>",
|
|
ata_select_device_cmd);
|
}
|
}
|
|
|
|
|
int atabug(int argc, char **argv)
|
int atabug(int argc, char **argv)
|
{
|
{
|
|
|
/* take care of commandline options */
|
/* take care of commandline options */
|
if (argc == 0)
|
if (argc == 0) {
|
{
|
|
/* start atabug */
|
/* start atabug */
|
while ( !ata_mon_command() );
|
while ( !ata_mon_command() );
|
}
|
} else
|
else
|
|
return execute_ata_command(argv[0], argc -1, &argv[1]);
|
return execute_ata_command(argv[0], argc -1, &argv[1]);
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
Line 113... |
Line 132... |
char *pstr = str;
|
char *pstr = str;
|
char *command_str;
|
char *command_str;
|
char *argv[20];
|
char *argv[20];
|
int argc = 0;
|
int argc = 0;
|
|
|
|
|
/* Show prompt */
|
/* Show prompt */
|
printf ("\natabug> ");
|
printf ("\natabug> ");
|
|
|
|
|
/* Get characters from UART */
|
/* Get characters from UART */
|
c = getc();
|
c = getc();
|
while (c != '\r' && c != '\f' && c != '\n')
|
while (c != '\r' && c != '\f' && c != '\n') {
|
{
|
|
if (c == '\b')
|
if (c == '\b')
|
pstr--;
|
pstr--;
|
else
|
else
|
*pstr++ = c;
|
*pstr++ = c;
|
putc(c);
|
putc(c);
|
Line 134... |
Line 150... |
*pstr = '\0';
|
*pstr = '\0';
|
printf ("\n");
|
printf ("\n");
|
|
|
/* Skip leading blanks */
|
/* Skip leading blanks */
|
pstr = str;
|
pstr = str;
|
while ( isspace(*pstr) ) pstr++;
|
while (isspace(*pstr))
|
|
pstr++;
|
|
|
/* Get command from the string */
|
/* Get command from the string */
|
command_str = pstr;
|
command_str = pstr;
|
|
|
while (1) {
|
while (1) {
|
/* Go to next argument */
|
/* Go to next argument */
|
while ( isgraph(*pstr) ) pstr++;
|
while (isgraph(*pstr))
|
|
pstr++;
|
if (*pstr) {
|
if (*pstr) {
|
*pstr++ = '\0';
|
*pstr++ = '\0';
|
while ( isspace(*pstr) ) pstr++;
|
while (isspace(*pstr))
|
|
pstr++;
|
argv[argc++] = pstr;
|
argv[argc++] = pstr;
|
}
|
} else
|
else
|
|
break;
|
break;
|
}
|
}
|
|
|
return execute_ata_command(command_str, argc, argv);
|
return execute_ata_command(command_str, argc, argv);
|
}
|
}
|
|
|
|
|
int execute_ata_command(char *command_str, int argc, char **argv)
|
int execute_ata_command(char *command_str, int argc, char **argv)
|
{
|
{
|
int i, found = 0;
|
int i, found = 0;
|
|
|
for (i = 0; i < ata_num_commands; i++)
|
for (i = 0; i < ata_num_commands; i++)
|
if ( !strcmp(command_str, ata_command[i].name) )
|
if (!strcmp(command_str, ata_command[i].name)) {
|
{
|
switch (ata_command[i].func(argc, argv)) {
|
switch ( ata_command[i].func(argc, argv) )
|
|
{
|
|
case -1:
|
case -1:
|
printf ("Missing/wrong parameters, usage: %s %s\n", ata_command[i].name, ata_command[i].params);
|
printf
|
|
("Missing/wrong parameters, usage: %s %s\n",
|
|
ata_command[i].name,
|
|
ata_command[i].params);
|
break;
|
break;
|
|
|
case -2:
|
case -2:
|
return -1;
|
return -1;
|
}
|
}
|
Line 182... |
Line 200... |
printf ("Unknown command. Type 'ata help' for help.\n");
|
printf ("Unknown command. Type 'ata help' for help.\n");
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
void register_ata_command(const char *name, const char *params,
|
void register_ata_command (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]) )
|
const char *help, int (*func) (int argc,
|
{
|
char *argv[]))
|
if (ata_num_commands < MAX_ATA_COMMANDS)
|
|
{
|
{
|
|
if (ata_num_commands < MAX_ATA_COMMANDS) {
|
ata_command[ata_num_commands].name = name;
|
ata_command[ata_num_commands].name = name;
|
ata_command[ata_num_commands].params = params;
|
ata_command[ata_num_commands].params = params;
|
ata_command[ata_num_commands].help = help;
|
ata_command[ata_num_commands].help = help;
|
ata_command[ata_num_commands].func = func;
|
ata_command[ata_num_commands].func = func;
|
ata_num_commands++;
|
ata_num_commands++;
|
}
|
} else
|
else
|
printf("ata-command '%s' ignored; MAX_COMMANDS limit reached\n",
|
printf ("ata-command '%s' ignored; MAX_COMMANDS limit reached\n", name);
|
name);
|
}
|
}
|
|
|
int atabug_help(int argc, char **argv)
|
int atabug_help(int argc, char **argv)
|
{
|
{
|
int i;
|
int i;
|
|
|
for (i = 0; i < ata_num_commands; i++)
|
for (i = 0; i < ata_num_commands; i++)
|
printf ("%-15s %-17s -%s\n", ata_command[i].name, ata_command[i].params, ata_command[i].help);
|
printf("%-15s %-17s -%s\n", ata_command[i].name,
|
|
ata_command[i].params, ata_command[i].help);
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
|
|
|
|
/**********************************************************************/
|
/**********************************************************************/
|
/* */
|
/* */
|
/* A T A B U G C O M M A N D S E T */
|
/* A T A B U G C O M M A N D S E T */
|
/* */
|
/* */
|
/**********************************************************************/
|
/**********************************************************************/
|
Line 228... |
Line 244... |
inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
|
inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
|
|
|
return ata_release(inode, filp);
|
return ata_release(inode, filp);
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ D U M P _ D E V I C E _ R E G S
|
A T A _ D U M P _ D E V I C E _ R E G S
|
|
|
Dumps the (readable) ata-registers.
|
Dumps the (readable) ata-registers.
|
Exception: status register is not read, this could mask an interrupt
|
Exception: status register is not read, this could mask an interrupt
|
Line 240... |
Line 255... |
int ata_dump_device_regs_cmd(int argc, char **argv)
|
int ata_dump_device_regs_cmd(int argc, char **argv)
|
{
|
{
|
if (argc)
|
if (argc)
|
printf("\nWARNING: Ignoring invalid argument(s)\n\n");
|
printf("\nWARNING: Ignoring invalid argument(s)\n\n");
|
|
|
|
printf("Alternate status register : 0x%02lX\n",
|
printf("Alternate status register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_ASR) );
|
REG32(ATA_BASE_ADDR + ATA_ASR));
|
printf("Cylinder high register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_CHR) );
|
printf("Cylinder high register : 0x%02lX\n",
|
printf("Cylinder low register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_CLR) );
|
REG32(ATA_BASE_ADDR + ATA_CHR));
|
printf("Device head register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_DHR) );
|
printf("Cylinder low register : 0x%02lX\n",
|
printf("Error register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_ERR) );
|
REG32(ATA_BASE_ADDR + ATA_CLR));
|
printf("Sector count register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_SCR) );
|
printf("Device head register : 0x%02lX\n",
|
printf("Sector number register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_SNR) );
|
REG32(ATA_BASE_ADDR + ATA_DHR));
|
|
printf("Error register : 0x%02lX\n",
|
|
REG32(ATA_BASE_ADDR + ATA_ERR));
|
|
printf("Sector count register : 0x%02lX\n",
|
|
REG32(ATA_BASE_ADDR + ATA_SCR));
|
|
printf("Sector number register : 0x%02lX\n",
|
|
REG32(ATA_BASE_ADDR + ATA_SNR));
|
printf("Status register (see alternate status register)\n" );
|
printf("Status register (see alternate status register)\n" );
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ D U M P _ H O S T _ R E G S
|
A T A _ D U M P _ H O S T _ R E G S
|
|
|
Dumps the ata-host registers
|
Dumps the ata-host registers
|
*/
|
*/
|
int ata_dump_host_regs_cmd(int argc, char **argv)
|
int ata_dump_host_regs_cmd(int argc, char **argv)
|
{
|
{
|
if (argc)
|
if (argc)
|
printf("\nWARNING: Ignoring invalid argument(s)\n\n");
|
printf("\nWARNING: Ignoring invalid argument(s)\n\n");
|
|
|
|
printf("Control register CTRL : 0x%08lX\n",
|
printf("Control register CTRL : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_CTRL) );
|
REG32(ATA_BASE_ADDR + ATA_CTRL));
|
printf("Status register STAT : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_STAT) );
|
printf("Status register STAT : 0x%08lX\n",
|
printf("Pio command timing register PCTR : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PCTR) );
|
REG32(ATA_BASE_ADDR + ATA_STAT));
|
printf("Pio fast timing register (device0) PFTR0: 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PFTR0) );
|
printf("Pio command timing register PCTR : 0x%08lX\n",
|
printf("Pio fast timing register (device1) PFTR1: 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PFTR1) );
|
REG32(ATA_BASE_ADDR + ATA_PCTR));
|
printf("Dma timing register (device0) DTR0 : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_DTR0) );
|
printf("Pio fast timing register (device0) PFTR0: 0x%08lX\n",
|
printf("Dma timing register (device1) DTR1 : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_DTR1) );
|
REG32(ATA_BASE_ADDR + ATA_PFTR0));
|
|
printf("Pio fast timing register (device1) PFTR1: 0x%08lX\n",
|
|
REG32(ATA_BASE_ADDR + ATA_PFTR1));
|
|
printf("Dma timing register (device0) DTR0 : 0x%08lX\n",
|
|
REG32(ATA_BASE_ADDR + ATA_DTR0));
|
|
printf("Dma timing register (device1) DTR1 : 0x%08lX\n",
|
|
REG32(ATA_BASE_ADDR + ATA_DTR1));
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ E N A B L E
|
A T A _ E N A B L E
|
|
|
clears reset bits
|
clears reset bits
|
*/
|
*/
|
Line 306... |
Line 331... |
printf("ATA host controller enabled\n");
|
printf("ATA host controller enabled\n");
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ E X E C _ C M D
|
A T A _ E X E C _ C M D
|
|
|
Executes the command; writes the command number in the command register
|
Executes the command; writes the command number in the command register
|
*/
|
*/
|
Line 323... |
Line 347... |
|
|
ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, strtoul(*argv, argv, 16) );
|
ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, strtoul(*argv, argv, 16) );
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ I D E N T I F Y _ D E V I C E
|
A T A _ I D E N T I F Y _ D E V I C E
|
|
|
Reads the identify_device block and dumps it to the screen
|
Reads the identify_device block and dumps it to the screen
|
*/
|
*/
|
Line 336... |
Line 359... |
unsigned char checksum;
|
unsigned char checksum;
|
|
|
if (argc != 0)
|
if (argc != 0)
|
printf("Ignoring invalid parameters\n");
|
printf("Ignoring invalid parameters\n");
|
|
|
|
|
/* check for busy flag */
|
/* check for busy flag */
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
printf("Selected ata device busy, ignoring command\n");
|
printf("Selected ata device busy, ignoring command\n");
|
else
|
else {
|
{
|
|
/* execute identify device */
|
/* execute identify device */
|
ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
|
ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
|
|
|
/* read block from ata-device */
|
/* read block from ata-device */
|
buf[0] = 0;
|
buf[0] = 0;
|
Line 354... |
Line 375... |
|
|
/* dump data to the screen */
|
/* dump data to the screen */
|
checksum = atabug_dump_data(buf, 512);
|
checksum = atabug_dump_data(buf, 512);
|
|
|
if (buf[512] == 0xa5)
|
if (buf[512] == 0xa5)
|
printf("Checksum = 0x%02X (%s)\n", checksum, checksum ? "error" : "OK");
|
printf("Checksum = 0x%02X (%s)\n", checksum,
|
|
checksum ? "error" : "OK");
|
else
|
else
|
printf("No checksum supported\n");
|
printf("No checksum supported\n");
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ O P E N
|
A T A _ O P E N
|
|
|
opens the ata_device
|
opens the ata_device
|
*/
|
*/
|
Line 378... |
Line 399... |
if (*argv[1] == 'w')
|
if (*argv[1] == 'w')
|
filp->f_mode |= FMODE_WRITE;
|
filp->f_mode |= FMODE_WRITE;
|
|
|
switch( ata_open(inode, filp) ) {
|
switch( ata_open(inode, filp) ) {
|
case EOPENIDEV:
|
case EOPENIDEV:
|
printf( "Error: Invalid device (invalid MINOR %02X)\n", MINOR(inode->i_rdev) );
|
printf("Error: Invalid device (invalid MINOR %02X)\n",
|
|
MINOR(inode->i_rdev));
|
break;
|
break;
|
|
|
case EOPENNODEV:
|
case EOPENNODEV:
|
printf( "Error: Requested device not found\n" );
|
printf( "Error: Requested device not found\n" );
|
break;
|
break;
|
|
|
case EOPENIHOST:
|
case EOPENIHOST:
|
printf( "Error: Invalid host (invalid MAJOR %02X)\n", MAJOR(inode->i_rdev) );
|
printf("Error: Invalid host (invalid MAJOR %02X)\n",
|
|
MAJOR(inode->i_rdev));
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ S E T _ P I O M O D E
|
A T A _ S E T _ P I O M O D E
|
|
|
Sets the device to the requested PIO mode
|
Sets the device to the requested PIO mode
|
*/
|
*/
|
int ata_set_piomode_cmd(int argc, char **argv)
|
int ata_set_piomode_cmd(int argc, char **argv)
|
{
|
{
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ R E A D _ S E C T O R S
|
A T A _ R E A D _ S E C T O R S
|
|
|
Reads 1 sector from the device and dumps it to the screen
|
Reads 1 sector from the device and dumps it to the screen
|
*/
|
*/
|
Line 431... |
Line 452... |
|
|
default:
|
default:
|
return -1;
|
return -1;
|
}
|
}
|
|
|
if ( !sector_cnt )
|
if (!sector_cnt) {
|
{
|
|
printf( "Invalid number of sectors.\n" );
|
printf( "Invalid number of sectors.\n" );
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* check for busy flag */
|
/* check for busy flag */
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
printf("Selected ata device busy, ignoring command\n");
|
printf("Selected ata device busy, ignoring command\n");
|
else
|
else {
|
{
|
|
/* fill the request structure */
|
/* fill the request structure */
|
request.cmd = READ;
|
request.cmd = READ;
|
request.sector = sector;
|
request.sector = sector;
|
request.nr_sectors = sector_cnt;
|
request.nr_sectors = sector_cnt;
|
request.buffer = buf;
|
request.buffer = buf;
|
|
|
if ( ata_request(inode, filp, &request) )
|
if (ata_request(inode, filp, &request)) {
|
{
|
printf
|
printf("Error while executing READ_SECTOR(S) command\n");
|
("Error while executing READ_SECTOR(S) command\n");
|
printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
|
printf
|
}
|
("Status register = 0x%02lX, error register = 0x%02lX\n",
|
else
|
ata_astatus(ATA_BASE_ADDR),
|
{
|
ata_error(ATA_BASE_ADDR));
|
|
} else {
|
/* dump data to the screen */
|
/* dump data to the screen */
|
atabug_dump_data(buf, 512 * sector_cnt);
|
atabug_dump_data(buf, 512 * sector_cnt);
|
}
|
}
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ R E A D _ M B R
|
A T A _ R E A D _ M B R
|
|
|
Reads master boot record from the device and dumps it's contents to the screen
|
Reads master boot record from the device and dumps it's contents to the screen
|
*/
|
*/
|
Line 481... |
Line 500... |
partition = strtoul(*argv, argv, 10);
|
partition = strtoul(*argv, argv, 10);
|
|
|
/* check for busy flag */
|
/* check for busy flag */
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
printf("Selected ata device busy, ignoring command\n");
|
printf("Selected ata device busy, ignoring command\n");
|
else
|
else {
|
{
|
|
/* fill the request structure */
|
/* fill the request structure */
|
request.cmd = READ;
|
request.cmd = READ;
|
request.sector = 0;
|
request.sector = 0;
|
request.nr_sectors = 1;
|
request.nr_sectors = 1;
|
request.buffer = buf;
|
request.buffer = buf;
|
|
|
if ( ata_request(inode, filp, &request) )
|
if (ata_request(inode, filp, &request)) {
|
{
|
|
printf("Error while reading master boot sector.\n");
|
printf("Error while reading master boot sector.\n");
|
printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
|
printf
|
}
|
("Status register = 0x%02lX, error register = 0x%02lX\n",
|
else
|
ata_astatus(ATA_BASE_ADDR),
|
{
|
ata_error(ATA_BASE_ADDR));
|
|
} else {
|
printf( "Skipping bootloader (446bytes)\n" );
|
printf( "Skipping bootloader (446bytes)\n" );
|
printf( "Partition %1d:\n", partition);
|
printf( "Partition %1d:\n", partition);
|
|
|
// abuse partitionnumber to get offset in MBR record
|
// abuse partitionnumber to get offset in MBR record
|
partition *= 16;
|
partition *= 16;
|
partition += 446;
|
partition += 446;
|
|
|
printf( "Bootindicator: 0x%2X (%s)\n", buf[partition], buf[partition] ? "bootable" : "non-bootable");
|
printf("Bootindicator: 0x%2X (%s)\n", buf[partition],
|
printf( "Partition start (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
|
buf[partition] ? "bootable" : "non-bootable");
|
buf[partition +1], (buf[partition +2] & 0xc0) << 2 | buf[partition +3] ,buf[partition +2] & 0x3f );
|
printf
|
|
("Partition start (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
|
|
buf[partition + 1],
|
|
(buf[partition + 2] & 0xc0) << 2 | buf[partition +
|
|
3],
|
|
buf[partition + 2] & 0x3f);
|
printf( "Systemindicator: 0x%02X (", buf[partition +4]);
|
printf( "Systemindicator: 0x%02X (", buf[partition +4]);
|
|
|
switch (buf[partition +4])
|
switch (buf[partition + 4]) {
|
{
|
case 0:
|
case 0: printf ("Non DOS"); break;
|
printf("Non DOS");
|
case 1: printf ("DOS FAT12"); break;
|
break;
|
case 4: printf ("DOS FAT16"); break;
|
case 1:
|
case 5: printf ("DOS extended"); break;
|
printf("DOS FAT12");
|
case 6: printf ("DOS >32MByte"); break;
|
break;
|
|
case 4:
|
|
printf("DOS FAT16");
|
|
break;
|
|
case 5:
|
|
printf("DOS extended");
|
|
break;
|
|
case 6:
|
|
printf("DOS >32MByte");
|
|
break;
|
|
|
default : printf ("unkown");
|
default:
|
|
printf("unkown");
|
};
|
};
|
printf (")\n");
|
printf (")\n");
|
printf( "Partition end (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
|
printf
|
buf[partition +5], (buf[partition +6] & 0xc0) << 2 | buf[partition +7] ,buf[partition +6] & 0x3f );
|
("Partition end (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
|
printf( "Physical Startsector: 0x%08X\n", buf[partition +11] << 24 |
|
buf[partition + 5],
|
buf[partition +10] << 16 |
|
(buf[partition + 6] & 0xc0) << 2 | buf[partition +
|
buf[partition +9] << 8 |
|
7],
|
buf[partition +8]);
|
buf[partition + 6] & 0x3f);
|
printf( "Sector count: 0x%08X\n", buf[partition +15] << 24 |
|
printf("Physical Startsector: 0x%08X\n",
|
buf[partition +14] << 16 |
|
buf[partition + 11] << 24 | buf[partition +
|
buf[partition +13] << 8 |
|
10] << 16 |
|
buf[partition +12]);
|
buf[partition + 9] << 8 | buf[partition + 8]);
|
|
printf("Sector count: 0x%08X\n",
|
|
buf[partition + 15] << 24 | buf[partition +
|
|
14] << 16 |
|
|
buf[partition + 13] << 8 | buf[partition + 12]);
|
}
|
}
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ R E A D _ D O S B O O T
|
A T A _ R E A D _ D O S B O O T
|
|
|
Reads boot sector from the device and dumps it's contents to the screen
|
Reads boot sector from the device and dumps it's contents to the screen
|
*/
|
*/
|
Line 553... |
Line 589... |
sector = strtoul(*argv, argv, 0);
|
sector = strtoul(*argv, argv, 0);
|
|
|
/* check for busy flag */
|
/* check for busy flag */
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
if ( ata_dev_busy(ATA_BASE_ADDR) )
|
printf("Selected ata device busy, ignoring command\n");
|
printf("Selected ata device busy, ignoring command\n");
|
else
|
else {
|
{
|
|
/* fill the request structure */
|
/* fill the request structure */
|
request.cmd = READ;
|
request.cmd = READ;
|
request.sector = sector;
|
request.sector = sector;
|
request.nr_sectors = 1;
|
request.nr_sectors = 1;
|
request.buffer = buf;
|
request.buffer = buf;
|
|
|
if ( ata_request(inode, filp, &request) )
|
if (ata_request(inode, filp, &request)) {
|
{
|
printf("Error whilereading boot sector 0x%02X.\n",
|
printf("Error whilereading boot sector 0x%02X.\n", sector);
|
sector);
|
printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
|
printf
|
}
|
("Status register = 0x%02lX, error register = 0x%02lX\n",
|
else
|
ata_astatus(ATA_BASE_ADDR),
|
{
|
ata_error(ATA_BASE_ADDR));
|
|
} else {
|
printf( "Reading boot sector 0x%02X\n", sector );
|
printf( "Reading boot sector 0x%02X\n", sector );
|
printf( "ID number: 0x%2X%2X%2X\n", buf[0], buf[1], buf[2] );
|
printf("ID number: 0x%2X%2X%2X\n", buf[0], buf[1],
|
|
buf[2]);
|
|
|
printf( "OEM-name and number: " );
|
printf( "OEM-name and number: " );
|
memcpy(txt, &buf[3], 8);
|
memcpy(txt, &buf[3], 8);
|
txt[8] = '\0';
|
txt[8] = '\0';
|
printf( "%s\n", txt );
|
printf( "%s\n", txt );
|
|
|
printf( "Bytes per sector: %5d\n", (buf[12]<<8) | buf[11] );
|
printf("Bytes per sector: %5d\n",
|
|
(buf[12] << 8) | buf[11]);
|
printf( "Sectors per cluster: %3d\n", buf[13] );
|
printf( "Sectors per cluster: %3d\n", buf[13] );
|
printf( "Reserved IM-sectors: %5d\n", (buf[15]<<8) | buf[14] );
|
printf("Reserved IM-sectors: %5d\n",
|
|
(buf[15] << 8) | buf[14]);
|
printf( "Number of FATs: %3d\n", buf[16] );
|
printf( "Number of FATs: %3d\n", buf[16] );
|
printf( "Number of entries in the root-directory: %5d\n", (buf[18]<<8) | buf[17] );
|
printf("Number of entries in the root-directory: %5d\n",
|
printf( "Number of logical sectors: %5d\n", (buf[20]<<8) | buf[19] );
|
(buf[18] << 8) | buf[17]);
|
|
printf("Number of logical sectors: %5d\n",
|
|
(buf[20] << 8) | buf[19]);
|
printf( "Medium descriptor byte: %02X\n", buf[21] );
|
printf( "Medium descriptor byte: %02X\n", buf[21] );
|
printf( "Sectors per FAT: %5d\n", (buf[23]<<8) | buf[22] );
|
printf("Sectors per FAT: %5d\n",
|
printf( "Sectors per track: %5d\n", (buf[25]<<8) | buf[24] );
|
(buf[23] << 8) | buf[22]);
|
printf( "Number of heads: %5d\n", (buf[27]<<8) | buf[26] );
|
printf("Sectors per track: %5d\n",
|
printf( "Number of hidden sectors: %5d\n", (buf[29]<<8) | buf[28] );
|
(buf[25] << 8) | buf[24]);
|
|
printf("Number of heads: %5d\n",
|
|
(buf[27] << 8) | buf[26]);
|
|
printf("Number of hidden sectors: %5d\n",
|
|
(buf[29] << 8) | buf[28]);
|
}
|
}
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ R E S E T
|
A T A _ R E S E T
|
|
|
resets the ATA device, using the select method
|
resets the ATA device, using the select method
|
*/
|
*/
|
Line 606... |
Line 650... |
return -1;
|
return -1;
|
|
|
return ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, SET | (**argv - '0') );
|
return ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, SET | (**argv - '0') );
|
}
|
}
|
|
|
|
|
/*
|
/*
|
A T A _ S E L E C T _ D E V I C E
|
A T A _ S E L E C T _ D E V I C E
|
|
|
selects the ATA device; sets the DEV bit in the device/head register
|
selects the ATA device; sets the DEV bit in the device/head register
|
*/
|
*/
|
Line 621... |
Line 664... |
|
|
inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
|
inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
|
|
|
ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, **argv - '0');
|
ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, **argv - '0');
|
|
|
printf("Ata device %1d selected.\n", REG32(ATA_BASE_ADDR + ATA_DHR) & ATA_DHR_DEV ? 1 : 0);
|
printf("Ata device %1d selected.\n",
|
|
REG32(ATA_BASE_ADDR + ATA_DHR) & ATA_DHR_DEV ? 1 : 0);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
|
|
|
|
/**********************************************************************/
|
/**********************************************************************/
|
/* */
|
/* */
|
/* A T A B U G T O O L S */
|
/* A T A B U G T O O L S */
|
/* */
|
/* */
|
/**********************************************************************/
|
/**********************************************************************/
|
Line 654... |
Line 695... |
/* prepare stored data for display & calculate checksum */
|
/* prepare stored data for display & calculate checksum */
|
checksum = 0;
|
checksum = 0;
|
buf_ptr = buffer;
|
buf_ptr = buffer;
|
|
|
/* display data */
|
/* display data */
|
for (i=0; i < cnt; i += bytes_per_line)
|
for (i = 0; i < cnt; i += bytes_per_line) {
|
{
|
|
printf("%3X ", i);
|
printf("%3X ", i);
|
|
|
/* print hexadecimal notation */
|
/* print hexadecimal notation */
|
for (n=0; n < bytes_per_line; n++)
|
for (n=0; n < bytes_per_line; n++)
|
printf("%02X ", *buf_ptr++);
|
printf("%02X ", *buf_ptr++);
|
|
|
buf_ptr -= bytes_per_line; /* back to the start (of this block) */
|
buf_ptr -= bytes_per_line; /* back to the start (of this block) */
|
|
|
/* print ASCII notation & calculate checksum */
|
/* print ASCII notation & calculate checksum */
|
for (n=0; n < bytes_per_line; n++)
|
for (n = 0; n < bytes_per_line; n++) {
|
{
|
|
c = *buf_ptr++;
|
c = *buf_ptr++;
|
printf("%c", isprint(c) ? c : '.');
|
printf("%c", isprint(c) ? c : '.');
|
checksum += c;
|
checksum += c;
|
}
|
}
|
printf("\n");
|
printf("\n");
|
}
|
}
|
|
|
return checksum;
|
return checksum;
|
}
|
}
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|