drive_id->cdrom_flag = 0;
// Make it the simplest drive possible (1 head, 1 cyl, 1 sect/track)
- drive_id->num_cylinders = 1;
- drive_id->num_heads = 1;
- drive_id->bytes_per_track = IDE_SECTOR_SIZE;
+ drive_id->num_cylinders = drive->num_cylinders;
+ drive_id->num_heads = drive->num_heads;
+ drive_id->bytes_per_track = drive->num_sectors * IDE_SECTOR_SIZE;
drive_id->bytes_per_sector = IDE_SECTOR_SIZE;
- drive_id->sectors_per_track = 1;
+ drive_id->sectors_per_track = drive->num_sectors;
// These buffers do not contain a terminating "\0"
// 32 bits access
drive_id->dword_io = 1;
+
// enable DMA access
drive_id->dma_enable = 1;
// Drive Capacity (48 bit LBA)
drive_id->lba_capacity_2 = drive->hd_ops->get_capacity(drive->private_data);
+
// lower byte is the maximum multiple sector size...
drive_id->rw_multiples = 0x8000 | MAX_MULT_SECTORS;
+
+
// words 64-70, 54-58 valid
drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
+
// copied from CFA540A
- drive_id->buf[63] = 0x0103; // variable (DMA stuff)
+ // drive_id->buf[63] = 0x0103; // variable (DMA stuff)
//drive_id->buf[63] = 0x0000; // variable (DMA stuff)
+ drive_id->buf[63] = 0x0007;
+
// drive_id->buf[64] = 0x0001; // PIO
drive_id->buf[65] = 0x00b4;
// drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
+
drive_id->buf[83] |= 0x0400; // supports 48 bit LBA
drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
+
}
drive->hd_state.accessed = 1;
}
+ PrintDebug("Reading Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt);
+
int ret = drive->hd_ops->read(dst, sect_cnt, drive->current_lba, drive->private_data);
if (ret == -1) {
}
+static int ata_write(struct vm_device * dev, struct ide_channel * channel, uint8_t * src, uint_t sect_cnt) {
+ struct ide_drive * drive = get_selected_drive(channel);
-// 28 bit LBA
-static int ata_read_sectors(struct vm_device * dev, struct ide_channel * channel) {
+ PrintDebug("Writing Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt);
+
+ int ret = drive->hd_ops->write(src, sect_cnt, drive->current_lba, drive->private_data);
+
+ if (ret == -1) {
+ PrintError("IDE: Error writing HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+static int ata_get_lba(struct vm_device * dev, struct ide_channel * channel, uint64_t * lba) {
struct ide_drive * drive = get_selected_drive(channel);
// The if the sector count == 0 then read 256 sectors (cast up to handle that value)
uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
lba_addr.buf[3] = channel->drive_head.lba3;
- if (lba_addr.addr + (sect_cnt * IDE_SECTOR_SIZE) >
+ if ((lba_addr.addr + sect_cnt) >
drive->hd_ops->get_capacity(drive->private_data)) {
PrintError("IDE: request size exceeds disk capacity (lba=%d) (sect_cnt=%d) (ReadEnd=%d) (capacity=%p)\n",
lba_addr.addr, sect_cnt,
lba_addr.addr + (sect_cnt * IDE_SECTOR_SIZE),
(void *)(addr_t)(drive->hd_ops->get_capacity(drive->private_data)));
+ return -1;
+ }
+
+ *lba = lba_addr.addr;
+ return 0;
+}
+
+
+// 28 bit LBA
+static int ata_read_sectors(struct vm_device * dev, struct ide_channel * channel) {
+ struct ide_drive * drive = get_selected_drive(channel);
+ // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
+ uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
+
+ if (ata_get_lba(dev, channel, &(drive->current_lba)) == -1) {
ide_abort_command(dev, channel);
return 0;
}
- drive->current_lba = lba_addr.addr;
if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
PrintError("Could not read disk sector\n");