From 3bac6bf02c3685ebc6726eedd6bb255c35c716a9 Mon Sep 17 00:00:00 2001 From: Steven James Date: Mon, 11 Nov 2002 21:30:45 +0000 Subject: [PATCH] dd write functionality if DANGER_IDE_WRITE defined --- src/include/pc80/ide.h | 10 ++++++ src/pc80/ide/ide.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/src/include/pc80/ide.h b/src/include/pc80/ide.h index cf330be0b5..715aba9d3f 100644 --- a/src/include/pc80/ide.h +++ b/src/include/pc80/ide.h @@ -54,6 +54,11 @@ extern harddisk_info_t harddisk_info[NUM_HD]; extern int ide_init(void); extern int ide_read_sector(int driveno, void * buf, unsigned int sector, int byte_offset, int n_bytes); + +#ifdef DANGER_IDE_WRITE +extern int ide_write_sector(int driveno, void * buf, unsigned int sector); +#endif + extern int ide_read_data(unsigned base, void * buf, size_t size); extern int ide_write_data(unsigned base, void * buf, size_t size); extern int ide_shutdown(void); @@ -111,6 +116,11 @@ typedef enum { IDE_CMD_NOOP = 0, IDE_CMD_RECALIBRATE = 0x10, IDE_CMD_READ_MULTI_RETRY = 0x20, + +#ifdef DANGER_IDE_WRITE + IDE_CMD_WRITE_MULTI_RETRY = 0x30, +#endif + IDE_CMD_READ_MULTI = IDE_CMD_READ_MULTI_RETRY, IDE_CMD_READ_MULTI_NORETRY = 0x21, diff --git a/src/pc80/ide/ide.c b/src/pc80/ide/ide.c index 913f8455fb..fa34568e0d 100644 --- a/src/pc80/ide/ide.c +++ b/src/pc80/ide/ide.c @@ -401,6 +401,82 @@ int ide_read_sector(int drive, void * buffer, unsigned int block, int byte_offse return status; } +#ifdef DANGER_IDE_WRITE +/* write a sector or a partial sector */ +int ide_write_sector(int drive, void * buffer, unsigned int block ) { + ide_cmd_param_t cmd = IDE_DEFAULT_COMMAND; + unsigned base; + unsigned int track; + int status; + int address_mode = harddisk_info[drive].address_mode; + //int i; + + printk_info(__FUNCTION__ " drive[%d], buffer[%08x], block[%08x]\n", + drive, buffer, block); + printk_info(__FUNCTION__ " block(%08x) from addr(%08x)\r", block, (int)buffer); + if ((drive < 0) || (drive >= NUM_HD) || + (harddisk_info[drive].drive_exists == 0)) + { + printk_info("unknown drive\n"); + return 1; + } + base = harddisk_info[drive].controller_port; + + if (harddisk_info[drive].num_heads > 8) { + outb_p(0xA, IDE_REG_CONTROL(base)); + } else { + outb_p(0x2, IDE_REG_CONTROL(base)); + } + + cmd.sector_count = 1; + + if (address_mode == IDE_DH_CHS) { + track = block / harddisk_info[drive].num_sectors_per_track; + + cmd.sector_number = 1+(block % harddisk_info[drive].num_sectors_per_track); + cmd.cylinder = track / harddisk_info[drive].num_heads; + cmd.drivehead = IDE_DH_DEFAULT | + IDE_DH_HEAD(track % harddisk_info[drive].num_heads) | + IDE_DH_DRIVE(drive) | + IDE_DH_CHS; + printk_info(__FUNCTION__ " CHS: track=[%d], sector_number=[%d], cylinder=[%d]\n", track, cmd.sector_number, cmd.cylinder); + /* + */ + } else { +#if 1 + cmd.sector_number = block & 0xff; /* lower byte of block (lba) */ + cmd.cylinder = (block >> 8) & 0xffff; /* middle 2 bytes of block (lba) */ + cmd.drivehead = IDE_DH_DEFAULT | /* set bits that must be on */ + ((block >> 24) & 0x0f) | /* lower nibble of byte 3 of block */ + IDE_DH_DRIVE(drive) | + IDE_DH_LBA; +#else + cmd.sector_number = (block >> 24) & 0xff; /* byte 0 of block (lba) */ + cmd.cylinder = (block >> 8) & 0xffff; /* bytes 1 & 2 of block (lba) */ + cmd.drivehead = IDE_DH_DEFAULT | /* set bits that must be on */ + ((block >> 4) & 0x0f) | /* upper nibble of byte 3 of block */ + IDE_DH_DRIVE(drive) | + IDE_DH_LBA; +#endif + printk_info(__FUNCTION__ " LBA: drivehead[%0x], cylinder[%04x], sector[%0x], block[%8x]\n", + cmd.drivehead, cmd.cylinder, cmd.sector_number, block & 0x0fffffff); + /* + */ + } + + write_command(base, IDE_CMD_WRITE_MULTI_RETRY, &cmd); + if ((inb_p(IDE_REG_STATUS(base)) & 1) != 0) { + printk_info("ide not ready...\n"); + return 1; + } + + status = ide_write_data(base, buffer, IDE_SECTOR_SIZE); + return status; +} + + +#endif + #if 0 /* read a sector or a partial sector */ int ide_read_sector(int drive, void * buffer, unsigned int block, int byte_offset,