aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/ide/core.c734
1 files changed, 367 insertions, 367 deletions
diff --git a/hw/ide/core.c b/hw/ide/core.c
index ac4ee7162d..ed6854dab5 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1864,423 +1864,423 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
int lba48 = 0;
#if defined(DEBUG_IDE)
- printf("ide: CMD=%02x\n", val);
+ printf("ide: CMD=%02x\n", val);
#endif
- s = idebus_active_if(bus);
- /* ignore commands to non existant slave */
- if (s != bus->ifs && !s->bs)
- return;
+ s = idebus_active_if(bus);
+ /* ignore commands to non existant slave */
+ if (s != bus->ifs && !s->bs)
+ return;
- /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
- if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
- return;
+ /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
+ if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
+ return;
- switch(val) {
- case WIN_IDENTIFY:
- if (s->bs && s->drive_kind != IDE_CD) {
- if (s->drive_kind != IDE_CFATA)
- ide_identify(s);
- else
- ide_cfata_identify(s);
- s->status = READY_STAT | SEEK_STAT;
- ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
- } else {
- if (s->drive_kind == IDE_CD) {
- ide_set_signature(s);
- }
- ide_abort_command(s);
- }
- ide_set_irq(s->bus);
- break;
- case WIN_SPECIFY:
- case WIN_RECAL:
- s->error = 0;
+ switch(val) {
+ case WIN_IDENTIFY:
+ if (s->bs && s->drive_kind != IDE_CD) {
+ if (s->drive_kind != IDE_CFATA)
+ ide_identify(s);
+ else
+ ide_cfata_identify(s);
s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
- break;
- case WIN_SETMULT:
- if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
- /* Disable Read and Write Multiple */
- s->mult_sectors = 0;
- s->status = READY_STAT | SEEK_STAT;
- } else if ((s->nsector & 0xff) != 0 &&
- ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
- (s->nsector & (s->nsector - 1)) != 0)) {
- ide_abort_command(s);
- } else {
- s->mult_sectors = s->nsector & 0xff;
- s->status = READY_STAT | SEEK_STAT;
+ ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
+ } else {
+ if (s->drive_kind == IDE_CD) {
+ ide_set_signature(s);
}
- ide_set_irq(s->bus);
- break;
- case WIN_VERIFY_EXT:
- lba48 = 1;
- case WIN_VERIFY:
- case WIN_VERIFY_ONCE:
- /* do sector number check ? */
- ide_cmd_lba48_transform(s, lba48);
+ ide_abort_command(s);
+ }
+ ide_set_irq(s->bus);
+ break;
+ case WIN_SPECIFY:
+ case WIN_RECAL:
+ s->error = 0;
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
+ case WIN_SETMULT:
+ if (s->drive_kind == IDE_CFATA && s->nsector == 0) {
+ /* Disable Read and Write Multiple */
+ s->mult_sectors = 0;
s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
- break;
+ } else if ((s->nsector & 0xff) != 0 &&
+ ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
+ (s->nsector & (s->nsector - 1)) != 0)) {
+ ide_abort_command(s);
+ } else {
+ s->mult_sectors = s->nsector & 0xff;
+ s->status = READY_STAT | SEEK_STAT;
+ }
+ ide_set_irq(s->bus);
+ break;
+ case WIN_VERIFY_EXT:
+ lba48 = 1;
+ case WIN_VERIFY:
+ case WIN_VERIFY_ONCE:
+ /* do sector number check ? */
+ ide_cmd_lba48_transform(s, lba48);
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
case WIN_READ_EXT:
- lba48 = 1;
- case WIN_READ:
- case WIN_READ_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- s->req_nb_sectors = 1;
- ide_sector_read(s);
- break;
+ lba48 = 1;
+ case WIN_READ:
+ case WIN_READ_ONCE:
+ if (!s->bs)
+ goto abort_cmd;
+ ide_cmd_lba48_transform(s, lba48);
+ s->req_nb_sectors = 1;
+ ide_sector_read(s);
+ break;
case WIN_WRITE_EXT:
- lba48 = 1;
- case WIN_WRITE:
- case WIN_WRITE_ONCE:
- case CFA_WRITE_SECT_WO_ERASE:
- case WIN_WRITE_VERIFY:
- ide_cmd_lba48_transform(s, lba48);
- s->error = 0;
- s->status = SEEK_STAT | READY_STAT;
- s->req_nb_sectors = 1;
- ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
- s->media_changed = 1;
- break;
+ lba48 = 1;
+ case WIN_WRITE:
+ case WIN_WRITE_ONCE:
+ case CFA_WRITE_SECT_WO_ERASE:
+ case WIN_WRITE_VERIFY:
+ ide_cmd_lba48_transform(s, lba48);
+ s->error = 0;
+ s->status = SEEK_STAT | READY_STAT;
+ s->req_nb_sectors = 1;
+ ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
+ s->media_changed = 1;
+ break;
case WIN_MULTREAD_EXT:
- lba48 = 1;
- case WIN_MULTREAD:
- if (!s->mult_sectors)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- s->req_nb_sectors = s->mult_sectors;
- ide_sector_read(s);
- break;
- case WIN_MULTWRITE_EXT:
- lba48 = 1;
- case WIN_MULTWRITE:
- case CFA_WRITE_MULTI_WO_ERASE:
- if (!s->mult_sectors)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- s->error = 0;
- s->status = SEEK_STAT | READY_STAT;
- s->req_nb_sectors = s->mult_sectors;
- n = s->nsector;
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
- s->media_changed = 1;
- break;
+ lba48 = 1;
+ case WIN_MULTREAD:
+ if (!s->mult_sectors)
+ goto abort_cmd;
+ ide_cmd_lba48_transform(s, lba48);
+ s->req_nb_sectors = s->mult_sectors;
+ ide_sector_read(s);
+ break;
+ case WIN_MULTWRITE_EXT:
+ lba48 = 1;
+ case WIN_MULTWRITE:
+ case CFA_WRITE_MULTI_WO_ERASE:
+ if (!s->mult_sectors)
+ goto abort_cmd;
+ ide_cmd_lba48_transform(s, lba48);
+ s->error = 0;
+ s->status = SEEK_STAT | READY_STAT;
+ s->req_nb_sectors = s->mult_sectors;
+ n = s->nsector;
+ if (n > s->req_nb_sectors)
+ n = s->req_nb_sectors;
+ ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
+ s->media_changed = 1;
+ break;
case WIN_READDMA_EXT:
- lba48 = 1;
- case WIN_READDMA:
- case WIN_READDMA_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- ide_sector_read_dma(s);
- break;
+ lba48 = 1;
+ case WIN_READDMA:
+ case WIN_READDMA_ONCE:
+ if (!s->bs)
+ goto abort_cmd;
+ ide_cmd_lba48_transform(s, lba48);
+ ide_sector_read_dma(s);
+ break;
case WIN_WRITEDMA_EXT:
- lba48 = 1;
- case WIN_WRITEDMA:
- case WIN_WRITEDMA_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_cmd_lba48_transform(s, lba48);
- ide_sector_write_dma(s);
- s->media_changed = 1;
- break;
- case WIN_READ_NATIVE_MAX_EXT:
- lba48 = 1;
- case WIN_READ_NATIVE_MAX:
- ide_cmd_lba48_transform(s, lba48);
- ide_set_sector(s, s->nb_sectors - 1);
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
- break;
- case WIN_CHECKPOWERMODE1:
- case WIN_CHECKPOWERMODE2:
- s->nsector = 0xff; /* device active or idle */
+ lba48 = 1;
+ case WIN_WRITEDMA:
+ case WIN_WRITEDMA_ONCE:
+ if (!s->bs)
+ goto abort_cmd;
+ ide_cmd_lba48_transform(s, lba48);
+ ide_sector_write_dma(s);
+ s->media_changed = 1;
+ break;
+ case WIN_READ_NATIVE_MAX_EXT:
+ lba48 = 1;
+ case WIN_READ_NATIVE_MAX:
+ ide_cmd_lba48_transform(s, lba48);
+ ide_set_sector(s, s->nb_sectors - 1);
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
+ case WIN_CHECKPOWERMODE1:
+ case WIN_CHECKPOWERMODE2:
+ s->nsector = 0xff; /* device active or idle */
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
+ case WIN_SETFEATURES:
+ if (!s->bs)
+ goto abort_cmd;
+ /* XXX: valid for CDROM ? */
+ switch(s->feature) {
+ case 0xcc: /* reverting to power-on defaults enable */
+ case 0x66: /* reverting to power-on defaults disable */
+ case 0x02: /* write cache enable */
+ case 0x82: /* write cache disable */
+ case 0xaa: /* read look-ahead enable */
+ case 0x55: /* read look-ahead disable */
+ case 0x05: /* set advanced power management mode */
+ case 0x85: /* disable advanced power management mode */
+ case 0x69: /* NOP */
+ case 0x67: /* NOP */
+ case 0x96: /* NOP */
+ case 0x9a: /* NOP */
+ case 0x42: /* enable Automatic Acoustic Mode */
+ case 0xc2: /* disable Automatic Acoustic Mode */
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
break;
- case WIN_SETFEATURES:
- if (!s->bs)
- goto abort_cmd;
- /* XXX: valid for CDROM ? */
- switch(s->feature) {
- case 0xcc: /* reverting to power-on defaults enable */
- case 0x66: /* reverting to power-on defaults disable */
- case 0x02: /* write cache enable */
- case 0x82: /* write cache disable */
- case 0xaa: /* read look-ahead enable */
- case 0x55: /* read look-ahead disable */
- case 0x05: /* set advanced power management mode */
- case 0x85: /* disable advanced power management mode */
- case 0x69: /* NOP */
- case 0x67: /* NOP */
- case 0x96: /* NOP */
- case 0x9a: /* NOP */
- case 0x42: /* enable Automatic Acoustic Mode */
- case 0xc2: /* disable Automatic Acoustic Mode */
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
- break;
- case 0x03: { /* set transfer mode */
+ case 0x03: { /* set transfer mode */
uint8_t val = s->nsector & 0x07;
- uint16_t *identify_data = (uint16_t *)s->identify_data;
+ uint16_t *identify_data = (uint16_t *)s->identify_data;
switch (s->nsector >> 3) {
- case 0x00: /* pio default */
- case 0x01: /* pio mode */
+ case 0x00: /* pio default */
+ case 0x01: /* pio mode */
put_le16(identify_data + 62,0x07);
put_le16(identify_data + 63,0x07);
put_le16(identify_data + 88,0x3f);
break;
- case 0x02: /* sigle word dma mode*/
+ case 0x02: /* sigle word dma mode*/
put_le16(identify_data + 62,0x07 | (1 << (val + 8)));
put_le16(identify_data + 63,0x07);
put_le16(identify_data + 88,0x3f);
break;
- case 0x04: /* mdma mode */
+ case 0x04: /* mdma mode */
put_le16(identify_data + 62,0x07);
put_le16(identify_data + 63,0x07 | (1 << (val + 8)));
put_le16(identify_data + 88,0x3f);
break;
- case 0x08: /* udma mode */
+ case 0x08: /* udma mode */
put_le16(identify_data + 62,0x07);
put_le16(identify_data + 63,0x07);
put_le16(identify_data + 88,0x3f | (1 << (val + 8)));
break;
- default:
+ default:
goto abort_cmd;
}
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
- break;
- }
- default:
- goto abort_cmd;
- }
- break;
- case WIN_FLUSH_CACHE:
- case WIN_FLUSH_CACHE_EXT:
- ide_flush_cache(s);
- break;
- case WIN_STANDBY:
- case WIN_STANDBY2:
- case WIN_STANDBYNOW1:
- case WIN_STANDBYNOW2:
- case WIN_IDLEIMMEDIATE:
- case CFA_IDLEIMMEDIATE:
- case WIN_SETIDLE1:
- case WIN_SETIDLE2:
- case WIN_SLEEPNOW1:
- case WIN_SLEEPNOW2:
- s->status = READY_STAT;
- ide_set_irq(s->bus);
- break;
- case WIN_SEEK:
- if(s->drive_kind == IDE_CD)
- goto abort_cmd;
- /* XXX: Check that seek is within bounds */
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
break;
- /* ATAPI commands */
- case WIN_PIDENTIFY:
- if (s->drive_kind == IDE_CD) {
- ide_atapi_identify(s);
- s->status = READY_STAT | SEEK_STAT;
- ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
- } else {
- ide_abort_command(s);
- }
- ide_set_irq(s->bus);
- break;
- case WIN_DIAGNOSE:
- ide_set_signature(s);
- if (s->drive_kind == IDE_CD)
- s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet
- * devices to return a clear status register
- * with READY_STAT *not* set. */
- else
- s->status = READY_STAT | SEEK_STAT;
- s->error = 0x01; /* Device 0 passed, Device 1 passed or not
- * present.
- */
- ide_set_irq(s->bus);
- break;
- case WIN_SRST:
- if (s->drive_kind != IDE_CD)
- goto abort_cmd;
- ide_set_signature(s);
- s->status = 0x00; /* NOTE: READY is _not_ set */
- s->error = 0x01;
- break;
- case WIN_PACKETCMD:
- if (s->drive_kind != IDE_CD)
- goto abort_cmd;
- /* overlapping commands not supported */
- if (s->feature & 0x02)
- goto abort_cmd;
+ }
+ default:
+ goto abort_cmd;
+ }
+ break;
+ case WIN_FLUSH_CACHE:
+ case WIN_FLUSH_CACHE_EXT:
+ ide_flush_cache(s);
+ break;
+ case WIN_STANDBY:
+ case WIN_STANDBY2:
+ case WIN_STANDBYNOW1:
+ case WIN_STANDBYNOW2:
+ case WIN_IDLEIMMEDIATE:
+ case CFA_IDLEIMMEDIATE:
+ case WIN_SETIDLE1:
+ case WIN_SETIDLE2:
+ case WIN_SLEEPNOW1:
+ case WIN_SLEEPNOW2:
+ s->status = READY_STAT;
+ ide_set_irq(s->bus);
+ break;
+ case WIN_SEEK:
+ if(s->drive_kind == IDE_CD)
+ goto abort_cmd;
+ /* XXX: Check that seek is within bounds */
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
+ /* ATAPI commands */
+ case WIN_PIDENTIFY:
+ if (s->drive_kind == IDE_CD) {
+ ide_atapi_identify(s);
s->status = READY_STAT | SEEK_STAT;
- s->atapi_dma = s->feature & 1;
- s->nsector = 1;
- ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
- ide_atapi_cmd);
- break;
- /* CF-ATA commands */
- case CFA_REQ_EXT_ERROR_CODE:
- if (s->drive_kind != IDE_CFATA)
- goto abort_cmd;
- s->error = 0x09; /* miscellaneous error */
+ ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
+ } else {
+ ide_abort_command(s);
+ }
+ ide_set_irq(s->bus);
+ break;
+ case WIN_DIAGNOSE:
+ ide_set_signature(s);
+ if (s->drive_kind == IDE_CD)
+ s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet
+ * devices to return a clear status register
+ * with READY_STAT *not* set. */
+ else
s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
+ s->error = 0x01; /* Device 0 passed, Device 1 passed or not
+ * present.
+ */
+ ide_set_irq(s->bus);
+ break;
+ case WIN_SRST:
+ if (s->drive_kind != IDE_CD)
+ goto abort_cmd;
+ ide_set_signature(s);
+ s->status = 0x00; /* NOTE: READY is _not_ set */
+ s->error = 0x01;
+ break;
+ case WIN_PACKETCMD:
+ if (s->drive_kind != IDE_CD)
+ goto abort_cmd;
+ /* overlapping commands not supported */
+ if (s->feature & 0x02)
+ goto abort_cmd;
+ s->status = READY_STAT | SEEK_STAT;
+ s->atapi_dma = s->feature & 1;
+ s->nsector = 1;
+ ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
+ ide_atapi_cmd);
+ break;
+ /* CF-ATA commands */
+ case CFA_REQ_EXT_ERROR_CODE:
+ if (s->drive_kind != IDE_CFATA)
+ goto abort_cmd;
+ s->error = 0x09; /* miscellaneous error */
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
+ case CFA_ERASE_SECTORS:
+ case CFA_WEAR_LEVEL:
+ if (s->drive_kind != IDE_CFATA)
+ goto abort_cmd;
+ if (val == CFA_WEAR_LEVEL)
+ s->nsector = 0;
+ if (val == CFA_ERASE_SECTORS)
+ s->media_changed = 1;
+ s->error = 0x00;
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
+ case CFA_TRANSLATE_SECTOR:
+ if (s->drive_kind != IDE_CFATA)
+ goto abort_cmd;
+ s->error = 0x00;
+ s->status = READY_STAT | SEEK_STAT;
+ memset(s->io_buffer, 0, 0x200);
+ s->io_buffer[0x00] = s->hcyl; /* Cyl MSB */
+ s->io_buffer[0x01] = s->lcyl; /* Cyl LSB */
+ s->io_buffer[0x02] = s->select; /* Head */
+ s->io_buffer[0x03] = s->sector; /* Sector */
+ s->io_buffer[0x04] = ide_get_sector(s) >> 16; /* LBA MSB */
+ s->io_buffer[0x05] = ide_get_sector(s) >> 8; /* LBA */
+ s->io_buffer[0x06] = ide_get_sector(s) >> 0; /* LBA LSB */
+ s->io_buffer[0x13] = 0x00; /* Erase flag */
+ s->io_buffer[0x18] = 0x00; /* Hot count */
+ s->io_buffer[0x19] = 0x00; /* Hot count */
+ s->io_buffer[0x1a] = 0x01; /* Hot count */
+ ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
+ ide_set_irq(s->bus);
+ break;
+ case CFA_ACCESS_METADATA_STORAGE:
+ if (s->drive_kind != IDE_CFATA)
+ goto abort_cmd;
+ switch (s->feature) {
+ case 0x02: /* Inquiry Metadata Storage */
+ ide_cfata_metadata_inquiry(s);
break;
- case CFA_ERASE_SECTORS:
- case CFA_WEAR_LEVEL:
- if (s->drive_kind != IDE_CFATA)
- goto abort_cmd;
- if (val == CFA_WEAR_LEVEL)
- s->nsector = 0;
- if (val == CFA_ERASE_SECTORS)
- s->media_changed = 1;
- s->error = 0x00;
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
+ case 0x03: /* Read Metadata Storage */
+ ide_cfata_metadata_read(s);
break;
- case CFA_TRANSLATE_SECTOR:
- if (s->drive_kind != IDE_CFATA)
- goto abort_cmd;
- s->error = 0x00;
- s->status = READY_STAT | SEEK_STAT;
- memset(s->io_buffer, 0, 0x200);
- s->io_buffer[0x00] = s->hcyl; /* Cyl MSB */
- s->io_buffer[0x01] = s->lcyl; /* Cyl LSB */
- s->io_buffer[0x02] = s->select; /* Head */
- s->io_buffer[0x03] = s->sector; /* Sector */
- s->io_buffer[0x04] = ide_get_sector(s) >> 16; /* LBA MSB */
- s->io_buffer[0x05] = ide_get_sector(s) >> 8; /* LBA */
- s->io_buffer[0x06] = ide_get_sector(s) >> 0; /* LBA LSB */
- s->io_buffer[0x13] = 0x00; /* Erase flag */
- s->io_buffer[0x18] = 0x00; /* Hot count */
- s->io_buffer[0x19] = 0x00; /* Hot count */
- s->io_buffer[0x1a] = 0x01; /* Hot count */
- ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
- ide_set_irq(s->bus);
+ case 0x04: /* Write Metadata Storage */
+ ide_cfata_metadata_write(s);
break;
- case CFA_ACCESS_METADATA_STORAGE:
- if (s->drive_kind != IDE_CFATA)
- goto abort_cmd;
- switch (s->feature) {
- case 0x02: /* Inquiry Metadata Storage */
- ide_cfata_metadata_inquiry(s);
- break;
- case 0x03: /* Read Metadata Storage */
- ide_cfata_metadata_read(s);
- break;
- case 0x04: /* Write Metadata Storage */
- ide_cfata_metadata_write(s);
- break;
- default:
- goto abort_cmd;
- }
- ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
- s->status = 0x00; /* NOTE: READY is _not_ set */
- ide_set_irq(s->bus);
- break;
- case IBM_SENSE_CONDITION:
- if (s->drive_kind != IDE_CFATA)
- goto abort_cmd;
- switch (s->feature) {
- case 0x01: /* sense temperature in device */
- s->nsector = 0x50; /* +20 C */
- break;
- default:
- goto abort_cmd;
- }
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
+ default:
+ goto abort_cmd;
+ }
+ ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
+ s->status = 0x00; /* NOTE: READY is _not_ set */
+ ide_set_irq(s->bus);
+ break;
+ case IBM_SENSE_CONDITION:
+ if (s->drive_kind != IDE_CFATA)
+ goto abort_cmd;
+ switch (s->feature) {
+ case 0x01: /* sense temperature in device */
+ s->nsector = 0x50; /* +20 C */
break;
+ default:
+ goto abort_cmd;
+ }
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
case WIN_SMART:
- if (s->drive_kind == IDE_CD)
+ if (s->drive_kind == IDE_CD)
goto abort_cmd;
- if (s->hcyl != 0xc2 || s->lcyl != 0x4f)
+ if (s->hcyl != 0xc2 || s->lcyl != 0x4f)
goto abort_cmd;
- if (!s->smart_enabled && s->feature != SMART_ENABLE)
+ if (!s->smart_enabled && s->feature != SMART_ENABLE)
goto abort_cmd;
- switch (s->feature) {
- case SMART_DISABLE:
+ switch (s->feature) {
+ case SMART_DISABLE:
s->smart_enabled = 0;
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
break;
- case SMART_ENABLE:
+ case SMART_ENABLE:
s->smart_enabled = 1;
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
break;
- case SMART_ATTR_AUTOSAVE:
+ case SMART_ATTR_AUTOSAVE:
switch (s->sector) {
case 0x00:
- s->smart_autosave = 0;
- break;
+ s->smart_autosave = 0;
+ break;
case 0xf1:
- s->smart_autosave = 1;
- break;
+ s->smart_autosave = 1;
+ break;
default:
- goto abort_cmd;
+ goto abort_cmd;
}
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
break;
- case SMART_STATUS:
+ case SMART_STATUS:
if (!s->smart_errors) {
- s->hcyl = 0xc2;
- s->lcyl = 0x4f;
+ s->hcyl = 0xc2;
+ s->lcyl = 0x4f;
} else {
- s->hcyl = 0x2c;
- s->lcyl = 0xf4;
+ s->hcyl = 0x2c;
+ s->lcyl = 0xf4;
}
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
break;
- case SMART_READ_THRESH:
+ case SMART_READ_THRESH:
memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; /* smart struct version */
for (n=0; n<30; n++) {
- if (smart_attributes[n][0] == 0)
+ if (smart_attributes[n][0] == 0)
break;
- s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
- s->io_buffer[2+1+(n*12)] = smart_attributes[n][4];
+ s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
+ s->io_buffer[2+1+(n*12)] = smart_attributes[n][4];
}
for (n=0; n<511; n++) /* checksum */
- s->io_buffer[511] += s->io_buffer[n];
+ s->io_buffer[511] += s->io_buffer[n];
s->io_buffer[511] = 0x100 - s->io_buffer[511];
s->status = READY_STAT | SEEK_STAT;
ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
ide_set_irq(s->bus);
break;
- case SMART_READ_DATA:
+ case SMART_READ_DATA:
memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; /* smart struct version */
for (n=0; n<30; n++) {
- if (smart_attributes[n][0] == 0)
+ if (smart_attributes[n][0] == 0)
break;
- s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
- s->io_buffer[2+1+(n*12)] = smart_attributes[n][1];
- s->io_buffer[2+3+(n*12)] = smart_attributes[n][2];
- s->io_buffer[2+4+(n*12)] = smart_attributes[n][3];
+ s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
+ s->io_buffer[2+1+(n*12)] = smart_attributes[n][1];
+ s->io_buffer[2+3+(n*12)] = smart_attributes[n][2];
+ s->io_buffer[2+4+(n*12)] = smart_attributes[n][3];
}
s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00);
if (s->smart_selftest_count == 0) {
- s->io_buffer[363] = 0;
+ s->io_buffer[363] = 0;
} else {
- s->io_buffer[363] =
+ s->io_buffer[363] =
s->smart_selftest_data[3 +
- (s->smart_selftest_count - 1) *
- 24];
+ (s->smart_selftest_count - 1) *
+ 24];
}
s->io_buffer[364] = 0x20;
s->io_buffer[365] = 0x01;
@@ -2294,76 +2294,76 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
s->io_buffer[374] = 0x01; /* minutes for poll conveyance */
for (n=0; n<511; n++)
- s->io_buffer[511] += s->io_buffer[n];
+ s->io_buffer[511] += s->io_buffer[n];
s->io_buffer[511] = 0x100 - s->io_buffer[511];
s->status = READY_STAT | SEEK_STAT;
ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
ide_set_irq(s->bus);
break;
- case SMART_READ_LOG:
+ case SMART_READ_LOG:
switch (s->sector) {
case 0x01: /* summary smart error log */
- memset(s->io_buffer, 0, 0x200);
- s->io_buffer[0] = 0x01;
- s->io_buffer[1] = 0x00; /* no error entries */
- s->io_buffer[452] = s->smart_errors & 0xff;
- s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
+ memset(s->io_buffer, 0, 0x200);
+ s->io_buffer[0] = 0x01;
+ s->io_buffer[1] = 0x00; /* no error entries */
+ s->io_buffer[452] = s->smart_errors & 0xff;
+ s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;
- for (n=0; n<511; n++)
+ for (n=0; n<511; n++)
s->io_buffer[511] += s->io_buffer[n];
- s->io_buffer[511] = 0x100 - s->io_buffer[511];
- break;
+ s->io_buffer[511] = 0x100 - s->io_buffer[511];
+ break;
case 0x06: /* smart self test log */
- memset(s->io_buffer, 0, 0x200);
- s->io_buffer[0] = 0x01;
- if (s->smart_selftest_count == 0) {
+ memset(s->io_buffer, 0, 0x200);
+ s->io_buffer[0] = 0x01;
+ if (s->smart_selftest_count == 0) {
s->io_buffer[508] = 0;
- } else {
+ } else {
s->io_buffer[508] = s->smart_selftest_count;
for (n=2; n<506; n++)
- s->io_buffer[n] = s->smart_selftest_data[n];
- }
- for (n=0; n<511; n++)
+ s->io_buffer[n] = s->smart_selftest_data[n];
+ }
+ for (n=0; n<511; n++)
s->io_buffer[511] += s->io_buffer[n];
- s->io_buffer[511] = 0x100 - s->io_buffer[511];
- break;
+ s->io_buffer[511] = 0x100 - s->io_buffer[511];
+ break;
default:
- goto abort_cmd;
+ goto abort_cmd;
}
s->status = READY_STAT | SEEK_STAT;
ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
ide_set_irq(s->bus);
break;
- case SMART_EXECUTE_OFFLINE:
+ case SMART_EXECUTE_OFFLINE:
switch (s->sector) {
case 0: /* off-line routine */
case 1: /* short self test */
case 2: /* extended self test */
- s->smart_selftest_count++;
- if(s->smart_selftest_count > 21)
+ s->smart_selftest_count++;
+ if(s->smart_selftest_count > 21)
s->smart_selftest_count = 0;
- n = 2 + (s->smart_selftest_count - 1) * 24;
- s->smart_selftest_data[n] = s->sector;
- s->smart_selftest_data[n+1] = 0x00; /* OK and finished */
- s->smart_selftest_data[n+2] = 0x34; /* hour count lsb */
- s->smart_selftest_data[n+3] = 0x12; /* hour count msb */
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s->bus);
- break;
+ n = 2 + (s->smart_selftest_count - 1) * 24;
+ s->smart_selftest_data[n] = s->sector;
+ s->smart_selftest_data[n+1] = 0x00; /* OK and finished */
+ s->smart_selftest_data[n+2] = 0x34; /* hour count lsb */
+ s->smart_selftest_data[n+3] = 0x12; /* hour count msb */
+ s->status = READY_STAT | SEEK_STAT;
+ ide_set_irq(s->bus);
+ break;
default:
- goto abort_cmd;
+ goto abort_cmd;
}
break;
- default:
+ default:
goto abort_cmd;
- }
- break;
- default:
- abort_cmd:
- ide_abort_command(s);
- ide_set_irq(s->bus);
- break;
- }
+ }
+ break;
+ default:
+ abort_cmd:
+ ide_abort_command(s);
+ ide_set_irq(s->bus);
+ break;
+ }
}
uint32_t ide_ioport_read(void *opaque, uint32_t addr1)