struct vm_device * pci_bus;
struct pci_device * ide_pci;
+
+ struct v3_vm_info * vm;
};
/* Drive Commands */
-static void ide_raise_irq(struct vm_device * dev, struct ide_channel * channel) {
+static void ide_raise_irq(struct ide_internal * ide, struct ide_channel * channel) {
if (channel->ctrl_reg.irq_disable == 0) {
// PrintError("Raising IDE Interrupt %d\n", channel->irq);
channel->dma_status.int_gen = 1;
- v3_raise_irq(dev->vm, channel->irq);
+ v3_raise_irq(ide->vm, channel->irq);
}
}
}
-static void ide_abort_command(struct vm_device * dev, struct ide_channel * channel) {
+static void ide_abort_command(struct ide_internal * ide, struct ide_channel * channel) {
channel->status.val = 0x41; // Error + ready
channel->error_reg.val = 0x04; // No idea...
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
-static int dma_read(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel);
-static int dma_write(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel);
+static int dma_read(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel);
+static int dma_write(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel);
/* ATAPI functions */
#endif
/* IO Operations */
-static int dma_read(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
+static int dma_read(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
// This is at top level scope to do the EOT test at the end
struct ide_dma_prd prd_entry = {};
// Read a sector/block at a time until the prd entry is full.
#ifdef CONFIG_DEBUG_IDE
- print_prd_table(dev, channel);
+ print_prd_table(ide, channel);
#endif
PrintDebug("DMA read for %d bytes\n", bytes_left);
bytes_to_write = (prd_bytes_left > HD_SECTOR_SIZE) ? HD_SECTOR_SIZE : prd_bytes_left;
- if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
+ if (ata_read(ide, channel, drive->data_buf, 1) == -1) {
PrintError("Failed to read next disk sector\n");
return -1;
}
if (atapi_cmd_is_data_op(drive->cd_state.atapi_cmd)) {
bytes_to_write = (prd_bytes_left > ATAPI_BLOCK_SIZE) ? ATAPI_BLOCK_SIZE : prd_bytes_left;
- if (atapi_read_chunk(dev, channel) == -1) {
+ if (atapi_read_chunk(ide, channel) == -1) {
PrintError("Failed to read next disk sector\n");
return -1;
}
channel->dma_status.err = 0;
}
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
return 0;
}
-static int dma_write(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
+static int dma_write(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
// This is at top level scope to do the EOT test at the end
struct ide_dma_prd prd_entry = {};
PrintDebug("\t DMA ret=%d (prd_bytes_left=%d) (bytes_left=%d)\n", ret, prd_bytes_left, bytes_left);
- if (ata_write(dev, channel, drive->data_buf, 1) == -1) {
+ if (ata_write(ide, channel, drive->data_buf, 1) == -1) {
PrintError("Failed to write data to disk\n");
return -1;
}
channel->dma_status.err = 0;
}
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
return 0;
}
#define DMA_CHANNEL_FLAG 0x08
static int write_dma_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+ struct ide_internal * ide = (struct ide_internal *)private_data;
uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3;
struct ide_channel * channel = &(ide->channels[channel_flag]);
if (channel->dma_cmd.read == 1) {
// DMA Read
- if (dma_read(core, dev, channel) == -1) {
+ if (dma_read(core, ide, channel) == -1) {
PrintError("Failed DMA Read\n");
return -1;
}
} else {
// DMA write
- if (dma_write(core, dev, channel) == -1) {
+ if (dma_write(core, ide, channel) == -1) {
PrintError("Failed DMA Write\n");
return -1;
}
static int read_dma_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+ struct ide_internal * ide = (struct ide_internal *)private_data;
uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3;
struct ide_channel * channel = &(ide->channels[channel_flag]);
-static int write_cmd_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int write_cmd_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
drive_reset(drive);
// JRL: Should we abort here?
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
} else {
atapi_identify_device(drive);
channel->error_reg.val = 0;
channel->status.val = 0x58; // ready, data_req, seek_complete
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
break;
case 0xec: // Identify Device
drive_reset(drive);
// JRL: Should we abort here?
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
} else {
ata_identify_device(drive);
channel->error_reg.val = 0;
channel->status.val = 0x58;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
break;
case 0xa0: // ATAPI Command Packet
if (drive->drive_type != BLOCK_CDROM) {
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
}
drive->sector_count = 1;
case 0x21: // Read Sectors without Retry
drive->hd_state.cur_sector_num = 1;
- if (ata_read_sectors(dev, channel) == -1) {
+ if (ata_read_sectors(ide, channel) == -1) {
PrintError("Error reading sectors\n");
return -1;
}
case 0x24: // Read Sectors Extended
drive->hd_state.cur_sector_num = 1;
- if (ata_read_sectors_ext(dev, channel) == -1) {
+ if (ata_read_sectors_ext(ide, channel) == -1) {
PrintError("Error reading extended sectors\n");
return -1;
}
case 0xc9: { // Read DMA
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);
+ if (ata_get_lba(ide, channel, &(drive->current_lba)) == -1) {
+ ide_abort_command(ide, channel);
return 0;
}
if (channel->dma_status.active == 1) {
// DMA Read
- if (dma_read(core, dev, channel) == -1) {
+ if (dma_read(core, ide, channel) == -1) {
PrintError("Failed DMA Read\n");
return -1;
}
case 0xca: { // Write DMA
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);
+ if (ata_get_lba(ide, channel, &(drive->current_lba)) == -1) {
+ ide_abort_command(ide, channel);
return 0;
}
if (channel->dma_status.active == 1) {
// DMA Write
- if (dma_write(core, dev, channel) == -1) {
+ if (dma_write(core, ide, channel) == -1) {
PrintError("Failed DMA Write\n");
return -1;
}
case 0x99: // Sleep Now 2
channel->status.val = 0;
channel->status.ready = 1;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
case 0xef: // Set Features
channel->status.ready = 1;
channel->status.seek_complete = 1;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
case 0x91: // Initialize Drive Parameters
channel->status.error = 0;
channel->status.ready = 1;
channel->status.seek_complete = 1;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
case 0xc6: { // Set multiple mode (IDE Block mode)
// This makes the drive transfer multiple sectors before generating an interrupt
uint32_t tmp_sect_num = drive->sector_num; // GCC SUCKS
if (tmp_sect_num > MAX_MULT_SECTORS) {
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
break;
}
channel->status.ready = 1;
channel->status.error = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
}
}
-static int write_data_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int write_data_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
return -1;
case 0xa0: // ATAPI packet command
- if (atapi_handle_packet(core, dev, channel) == -1) {
+ if (atapi_handle_packet(core, ide, channel) == -1) {
PrintError("Error handling ATAPI packet\n");
return -1;
}
}
-static int read_hd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
+static int read_hd_data(uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
int data_offset = drive->transfer_index % HD_SECTOR_SIZE;
if ((data_offset == 0) && (drive->transfer_index > 0)) {
drive->current_lba++;
- if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
+ if (ata_read(ide, channel, drive->data_buf, 1) == -1) {
PrintError("Could not read next disk sector\n");
return -1;
}
drive->irq_flags.io_dir = 1;
channel->status.busy = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
-static int read_cd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
+static int read_cd_data(uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
int data_offset = drive->transfer_index % ATAPI_BLOCK_SIZE;
int req_offset = drive->transfer_index % drive->req_len;
if ((data_offset == 0) && (drive->transfer_index > 0)) {
- if (atapi_update_data_buf(dev, channel) == -1) {
+ if (atapi_update_data_buf(ide, channel) == -1) {
PrintError("Could not update CDROM data buffer\n");
return -1;
}
drive->irq_flags.c_d = 0;
// Update the request length in the cylinder regs
- if (atapi_update_req_len(dev, channel, drive->transfer_length - drive->transfer_index) == -1) {
+ if (atapi_update_req_len(ide, channel, drive->transfer_length - drive->transfer_index) == -1) {
PrintError("Could not update request length after completed increment\n");
return -1;
}
drive->irq_flags.io_dir = 1;
channel->status.busy = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
return length;
}
-static int read_drive_id( uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
+static int read_drive_id( uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
channel->status.busy = 0;
}
-static int ide_read_data_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int ide_read_data_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
if ((channel->cmd_reg == 0xec) ||
(channel->cmd_reg == 0xa1)) {
- return read_drive_id((uint8_t *)dst, length, dev, channel);
+ return read_drive_id((uint8_t *)dst, length, ide, channel);
}
if (drive->drive_type == BLOCK_CDROM) {
- if (read_cd_data((uint8_t *)dst, length, dev, channel) == -1) {
+ if (read_cd_data((uint8_t *)dst, length, ide, channel) == -1) {
PrintError("IDE: Could not read CD Data\n");
return -1;
}
} else if (drive->drive_type == BLOCK_DISK) {
- if (read_hd_data((uint8_t *)dst, length, dev, channel) == -1) {
+ if (read_hd_data((uint8_t *)dst, length, ide, channel) == -1) {
PrintError("IDE: Could not read HD Data\n");
return -1;
}
return length;
}
-static int write_port_std(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int write_port_std(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
}
-static int read_port_std(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int read_port_std(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
return 0;
}
-static int init_ide_state(struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int init_ide_state(struct ide_internal * ide) {
int i;
/*
memset(ide, 0, sizeof(struct ide_internal));
+ ide->vm = vm;
ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
return -1;
}
- if (init_ide_state(dev) == -1) {
+ if (init_ide_state(ide) == -1) {
PrintError("Failed to initialize IDE state\n");
v3_detach_device(dev);
return -1;