ide: fix whitespace gap in ide_exec_cmd

Now that we have the function split out, we have to reindent it.
In order to increase the readability of the actual functional change,
this is split out.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Alexander Graf 2010-12-14 01:34:34 +01:00 committed by Kevin Wolf
parent 7cff87ff6a
commit 6ef2ba5ea6
1 changed files with 367 additions and 367 deletions

View File

@ -1864,423 +1864,423 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
int lba48 = 0; int lba48 = 0;
#if defined(DEBUG_IDE) #if defined(DEBUG_IDE)
printf("ide: CMD=%02x\n", val); printf("ide: CMD=%02x\n", val);
#endif #endif
s = idebus_active_if(bus); s = idebus_active_if(bus);
/* ignore commands to non existant slave */ /* ignore commands to non existant slave */
if (s != bus->ifs && !s->bs) if (s != bus->ifs && !s->bs)
return; return;
/* Only DEVICE RESET is allowed while BSY or/and DRQ are set */ /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET) if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
return; return;
switch(val) { switch(val) {
case WIN_IDENTIFY: case WIN_IDENTIFY:
if (s->bs && s->drive_kind != IDE_CD) { if (s->bs && s->drive_kind != IDE_CD) {
if (s->drive_kind != IDE_CFATA) if (s->drive_kind != IDE_CFATA)
ide_identify(s); ide_identify(s);
else else
ide_cfata_identify(s); 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;
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
break; } else {
case WIN_SETMULT: if (s->drive_kind == IDE_CD) {
if (s->drive_kind == IDE_CFATA && s->nsector == 0) { ide_set_signature(s);
/* 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_set_irq(s->bus); ide_abort_command(s);
break; }
case WIN_VERIFY_EXT: ide_set_irq(s->bus);
lba48 = 1; break;
case WIN_VERIFY: case WIN_SPECIFY:
case WIN_VERIFY_ONCE: case WIN_RECAL:
/* do sector number check ? */ s->error = 0;
ide_cmd_lba48_transform(s, lba48); 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; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); } else if ((s->nsector & 0xff) != 0 &&
break; ((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: case WIN_READ_EXT:
lba48 = 1; lba48 = 1;
case WIN_READ: case WIN_READ:
case WIN_READ_ONCE: case WIN_READ_ONCE:
if (!s->bs) if (!s->bs)
goto abort_cmd; goto abort_cmd;
ide_cmd_lba48_transform(s, lba48); ide_cmd_lba48_transform(s, lba48);
s->req_nb_sectors = 1; s->req_nb_sectors = 1;
ide_sector_read(s); ide_sector_read(s);
break; break;
case WIN_WRITE_EXT: case WIN_WRITE_EXT:
lba48 = 1; lba48 = 1;
case WIN_WRITE: case WIN_WRITE:
case WIN_WRITE_ONCE: case WIN_WRITE_ONCE:
case CFA_WRITE_SECT_WO_ERASE: case CFA_WRITE_SECT_WO_ERASE:
case WIN_WRITE_VERIFY: case WIN_WRITE_VERIFY:
ide_cmd_lba48_transform(s, lba48); ide_cmd_lba48_transform(s, lba48);
s->error = 0; s->error = 0;
s->status = SEEK_STAT | READY_STAT; s->status = SEEK_STAT | READY_STAT;
s->req_nb_sectors = 1; s->req_nb_sectors = 1;
ide_transfer_start(s, s->io_buffer, 512, ide_sector_write); ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
s->media_changed = 1; s->media_changed = 1;
break; break;
case WIN_MULTREAD_EXT: case WIN_MULTREAD_EXT:
lba48 = 1; lba48 = 1;
case WIN_MULTREAD: case WIN_MULTREAD:
if (!s->mult_sectors) if (!s->mult_sectors)
goto abort_cmd; goto abort_cmd;
ide_cmd_lba48_transform(s, lba48); ide_cmd_lba48_transform(s, lba48);
s->req_nb_sectors = s->mult_sectors; s->req_nb_sectors = s->mult_sectors;
ide_sector_read(s); ide_sector_read(s);
break; break;
case WIN_MULTWRITE_EXT: case WIN_MULTWRITE_EXT:
lba48 = 1; lba48 = 1;
case WIN_MULTWRITE: case WIN_MULTWRITE:
case CFA_WRITE_MULTI_WO_ERASE: case CFA_WRITE_MULTI_WO_ERASE:
if (!s->mult_sectors) if (!s->mult_sectors)
goto abort_cmd; goto abort_cmd;
ide_cmd_lba48_transform(s, lba48); ide_cmd_lba48_transform(s, lba48);
s->error = 0; s->error = 0;
s->status = SEEK_STAT | READY_STAT; s->status = SEEK_STAT | READY_STAT;
s->req_nb_sectors = s->mult_sectors; s->req_nb_sectors = s->mult_sectors;
n = s->nsector; n = s->nsector;
if (n > s->req_nb_sectors) if (n > s->req_nb_sectors)
n = s->req_nb_sectors; n = s->req_nb_sectors;
ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write); ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
s->media_changed = 1; s->media_changed = 1;
break; break;
case WIN_READDMA_EXT: case WIN_READDMA_EXT:
lba48 = 1; lba48 = 1;
case WIN_READDMA: case WIN_READDMA:
case WIN_READDMA_ONCE: case WIN_READDMA_ONCE:
if (!s->bs) if (!s->bs)
goto abort_cmd; goto abort_cmd;
ide_cmd_lba48_transform(s, lba48); ide_cmd_lba48_transform(s, lba48);
ide_sector_read_dma(s); ide_sector_read_dma(s);
break; break;
case WIN_WRITEDMA_EXT: case WIN_WRITEDMA_EXT:
lba48 = 1; lba48 = 1;
case WIN_WRITEDMA: case WIN_WRITEDMA:
case WIN_WRITEDMA_ONCE: case WIN_WRITEDMA_ONCE:
if (!s->bs) if (!s->bs)
goto abort_cmd; goto abort_cmd;
ide_cmd_lba48_transform(s, lba48); ide_cmd_lba48_transform(s, lba48);
ide_sector_write_dma(s); ide_sector_write_dma(s);
s->media_changed = 1; s->media_changed = 1;
break; break;
case WIN_READ_NATIVE_MAX_EXT: case WIN_READ_NATIVE_MAX_EXT:
lba48 = 1; lba48 = 1;
case WIN_READ_NATIVE_MAX: case WIN_READ_NATIVE_MAX:
ide_cmd_lba48_transform(s, lba48); ide_cmd_lba48_transform(s, lba48);
ide_set_sector(s, s->nb_sectors - 1); 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; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case WIN_CHECKPOWERMODE1: case 0x03: { /* set transfer mode */
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 0x03: { /* set transfer mode */
uint8_t val = s->nsector & 0x07; 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) { switch (s->nsector >> 3) {
case 0x00: /* pio default */ case 0x00: /* pio default */
case 0x01: /* pio mode */ case 0x01: /* pio mode */
put_le16(identify_data + 62,0x07); put_le16(identify_data + 62,0x07);
put_le16(identify_data + 63,0x07); put_le16(identify_data + 63,0x07);
put_le16(identify_data + 88,0x3f); put_le16(identify_data + 88,0x3f);
break; 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 + 62,0x07 | (1 << (val + 8)));
put_le16(identify_data + 63,0x07); put_le16(identify_data + 63,0x07);
put_le16(identify_data + 88,0x3f); put_le16(identify_data + 88,0x3f);
break; break;
case 0x04: /* mdma mode */ case 0x04: /* mdma mode */
put_le16(identify_data + 62,0x07); put_le16(identify_data + 62,0x07);
put_le16(identify_data + 63,0x07 | (1 << (val + 8))); put_le16(identify_data + 63,0x07 | (1 << (val + 8)));
put_le16(identify_data + 88,0x3f); put_le16(identify_data + 88,0x3f);
break; break;
case 0x08: /* udma mode */ case 0x08: /* udma mode */
put_le16(identify_data + 62,0x07); put_le16(identify_data + 62,0x07);
put_le16(identify_data + 63,0x07); put_le16(identify_data + 63,0x07);
put_le16(identify_data + 88,0x3f | (1 << (val + 8))); put_le16(identify_data + 88,0x3f | (1 << (val + 8)));
break; break;
default: default:
goto abort_cmd; 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; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
/* ATAPI commands */ }
case WIN_PIDENTIFY: default:
if (s->drive_kind == IDE_CD) { goto abort_cmd;
ide_atapi_identify(s); }
s->status = READY_STAT | SEEK_STAT; break;
ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop); case WIN_FLUSH_CACHE:
} else { case WIN_FLUSH_CACHE_EXT:
ide_abort_command(s); ide_flush_cache(s);
} break;
ide_set_irq(s->bus); case WIN_STANDBY:
break; case WIN_STANDBY2:
case WIN_DIAGNOSE: case WIN_STANDBYNOW1:
ide_set_signature(s); case WIN_STANDBYNOW2:
if (s->drive_kind == IDE_CD) case WIN_IDLEIMMEDIATE:
s->status = 0; /* ATAPI spec (v6) section 9.10 defines packet case CFA_IDLEIMMEDIATE:
* devices to return a clear status register case WIN_SETIDLE1:
* with READY_STAT *not* set. */ case WIN_SETIDLE2:
else case WIN_SLEEPNOW1:
s->status = READY_STAT | SEEK_STAT; case WIN_SLEEPNOW2:
s->error = 0x01; /* Device 0 passed, Device 1 passed or not s->status = READY_STAT;
* present. ide_set_irq(s->bus);
*/ break;
ide_set_irq(s->bus); case WIN_SEEK:
break; if(s->drive_kind == IDE_CD)
case WIN_SRST: goto abort_cmd;
if (s->drive_kind != IDE_CD) /* XXX: Check that seek is within bounds */
goto abort_cmd; s->status = READY_STAT | SEEK_STAT;
ide_set_signature(s); ide_set_irq(s->bus);
s->status = 0x00; /* NOTE: READY is _not_ set */ break;
s->error = 0x01; /* ATAPI commands */
break; case WIN_PIDENTIFY:
case WIN_PACKETCMD: if (s->drive_kind == IDE_CD) {
if (s->drive_kind != IDE_CD) ide_atapi_identify(s);
goto abort_cmd;
/* overlapping commands not supported */
if (s->feature & 0x02)
goto abort_cmd;
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
s->atapi_dma = s->feature & 1; ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
s->nsector = 1; } else {
ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, ide_abort_command(s);
ide_atapi_cmd); }
break; ide_set_irq(s->bus);
/* CF-ATA commands */ break;
case CFA_REQ_EXT_ERROR_CODE: case WIN_DIAGNOSE:
if (s->drive_kind != IDE_CFATA) ide_set_signature(s);
goto abort_cmd; if (s->drive_kind == IDE_CD)
s->error = 0x09; /* miscellaneous error */ 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->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; break;
case CFA_ERASE_SECTORS: case 0x03: /* Read Metadata Storage */
case CFA_WEAR_LEVEL: ide_cfata_metadata_read(s);
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; break;
case CFA_TRANSLATE_SECTOR: case 0x04: /* Write Metadata Storage */
if (s->drive_kind != IDE_CFATA) ide_cfata_metadata_write(s);
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; break;
case CFA_ACCESS_METADATA_STORAGE: default:
if (s->drive_kind != IDE_CFATA) goto abort_cmd;
goto abort_cmd; }
switch (s->feature) { ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
case 0x02: /* Inquiry Metadata Storage */ s->status = 0x00; /* NOTE: READY is _not_ set */
ide_cfata_metadata_inquiry(s); ide_set_irq(s->bus);
break; break;
case 0x03: /* Read Metadata Storage */ case IBM_SENSE_CONDITION:
ide_cfata_metadata_read(s); if (s->drive_kind != IDE_CFATA)
break; goto abort_cmd;
case 0x04: /* Write Metadata Storage */ switch (s->feature) {
ide_cfata_metadata_write(s); case 0x01: /* sense temperature in device */
break; s->nsector = 0x50; /* +20 C */
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; break;
default:
goto abort_cmd;
}
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
break;
case WIN_SMART: case WIN_SMART:
if (s->drive_kind == IDE_CD) if (s->drive_kind == IDE_CD)
goto abort_cmd; goto abort_cmd;
if (s->hcyl != 0xc2 || s->lcyl != 0x4f) if (s->hcyl != 0xc2 || s->lcyl != 0x4f)
goto abort_cmd; goto abort_cmd;
if (!s->smart_enabled && s->feature != SMART_ENABLE) if (!s->smart_enabled && s->feature != SMART_ENABLE)
goto abort_cmd; goto abort_cmd;
switch (s->feature) { switch (s->feature) {
case SMART_DISABLE: case SMART_DISABLE:
s->smart_enabled = 0; s->smart_enabled = 0;
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case SMART_ENABLE: case SMART_ENABLE:
s->smart_enabled = 1; s->smart_enabled = 1;
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case SMART_ATTR_AUTOSAVE: case SMART_ATTR_AUTOSAVE:
switch (s->sector) { switch (s->sector) {
case 0x00: case 0x00:
s->smart_autosave = 0; s->smart_autosave = 0;
break; break;
case 0xf1: case 0xf1:
s->smart_autosave = 1; s->smart_autosave = 1;
break; break;
default: default:
goto abort_cmd; goto abort_cmd;
} }
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case SMART_STATUS: case SMART_STATUS:
if (!s->smart_errors) { if (!s->smart_errors) {
s->hcyl = 0xc2; s->hcyl = 0xc2;
s->lcyl = 0x4f; s->lcyl = 0x4f;
} else { } else {
s->hcyl = 0x2c; s->hcyl = 0x2c;
s->lcyl = 0xf4; s->lcyl = 0xf4;
} }
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case SMART_READ_THRESH: case SMART_READ_THRESH:
memset(s->io_buffer, 0, 0x200); memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; /* smart struct version */ s->io_buffer[0] = 0x01; /* smart struct version */
for (n=0; n<30; n++) { for (n=0; n<30; n++) {
if (smart_attributes[n][0] == 0) if (smart_attributes[n][0] == 0)
break; break;
s->io_buffer[2+0+(n*12)] = smart_attributes[n][0]; 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+1+(n*12)] = smart_attributes[n][4];
} }
for (n=0; n<511; n++) /* checksum */ 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->io_buffer[511] = 0x100 - s->io_buffer[511];
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop); ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case SMART_READ_DATA: case SMART_READ_DATA:
memset(s->io_buffer, 0, 0x200); memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; /* smart struct version */ s->io_buffer[0] = 0x01; /* smart struct version */
for (n=0; n<30; n++) { for (n=0; n<30; n++) {
if (smart_attributes[n][0] == 0) if (smart_attributes[n][0] == 0)
break; break;
s->io_buffer[2+0+(n*12)] = smart_attributes[n][0]; 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+1+(n*12)] = smart_attributes[n][1];
s->io_buffer[2+3+(n*12)] = smart_attributes[n][2]; 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+4+(n*12)] = smart_attributes[n][3];
} }
s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00); s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00);
if (s->smart_selftest_count == 0) { if (s->smart_selftest_count == 0) {
s->io_buffer[363] = 0; s->io_buffer[363] = 0;
} else { } else {
s->io_buffer[363] = s->io_buffer[363] =
s->smart_selftest_data[3 + s->smart_selftest_data[3 +
(s->smart_selftest_count - 1) * (s->smart_selftest_count - 1) *
24]; 24];
} }
s->io_buffer[364] = 0x20; s->io_buffer[364] = 0x20;
s->io_buffer[365] = 0x01; 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 */ s->io_buffer[374] = 0x01; /* minutes for poll conveyance */
for (n=0; n<511; n++) 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->io_buffer[511] = 0x100 - s->io_buffer[511];
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop); ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case SMART_READ_LOG: case SMART_READ_LOG:
switch (s->sector) { switch (s->sector) {
case 0x01: /* summary smart error log */ case 0x01: /* summary smart error log */
memset(s->io_buffer, 0, 0x200); memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; s->io_buffer[0] = 0x01;
s->io_buffer[1] = 0x00; /* no error entries */ s->io_buffer[1] = 0x00; /* no error entries */
s->io_buffer[452] = s->smart_errors & 0xff; s->io_buffer[452] = s->smart_errors & 0xff;
s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8; 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] += s->io_buffer[n];
s->io_buffer[511] = 0x100 - s->io_buffer[511]; s->io_buffer[511] = 0x100 - s->io_buffer[511];
break; break;
case 0x06: /* smart self test log */ case 0x06: /* smart self test log */
memset(s->io_buffer, 0, 0x200); memset(s->io_buffer, 0, 0x200);
s->io_buffer[0] = 0x01; s->io_buffer[0] = 0x01;
if (s->smart_selftest_count == 0) { if (s->smart_selftest_count == 0) {
s->io_buffer[508] = 0; s->io_buffer[508] = 0;
} else { } else {
s->io_buffer[508] = s->smart_selftest_count; s->io_buffer[508] = s->smart_selftest_count;
for (n=2; n<506; n++) for (n=2; n<506; n++)
s->io_buffer[n] = s->smart_selftest_data[n]; s->io_buffer[n] = s->smart_selftest_data[n];
} }
for (n=0; n<511; n++) 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->io_buffer[511] = 0x100 - s->io_buffer[511];
break; break;
default: default:
goto abort_cmd; goto abort_cmd;
} }
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop); ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
case SMART_EXECUTE_OFFLINE: case SMART_EXECUTE_OFFLINE:
switch (s->sector) { switch (s->sector) {
case 0: /* off-line routine */ case 0: /* off-line routine */
case 1: /* short self test */ case 1: /* short self test */
case 2: /* extended self test */ case 2: /* extended self test */
s->smart_selftest_count++; s->smart_selftest_count++;
if(s->smart_selftest_count > 21) if(s->smart_selftest_count > 21)
s->smart_selftest_count = 0; s->smart_selftest_count = 0;
n = 2 + (s->smart_selftest_count - 1) * 24; n = 2 + (s->smart_selftest_count - 1) * 24;
s->smart_selftest_data[n] = s->sector; s->smart_selftest_data[n] = s->sector;
s->smart_selftest_data[n+1] = 0x00; /* OK and finished */ 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+2] = 0x34; /* hour count lsb */
s->smart_selftest_data[n+3] = 0x12; /* hour count msb */ s->smart_selftest_data[n+3] = 0x12; /* hour count msb */
s->status = READY_STAT | SEEK_STAT; s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
default: default:
goto abort_cmd; goto abort_cmd;
} }
break; break;
default: default:
goto abort_cmd; goto abort_cmd;
} }
break; break;
default: default:
abort_cmd: abort_cmd:
ide_abort_command(s); ide_abort_command(s);
ide_set_irq(s->bus); ide_set_irq(s->bus);
break; break;
} }
} }
uint32_t ide_ioport_read(void *opaque, uint32_t addr1) uint32_t ide_ioport_read(void *opaque, uint32_t addr1)