static bool cmd_smart(IDEState *s, uint8_t cmd)

{

    int n;



    if (s->hcyl != 0xc2 || s->lcyl != 0x4f) {

        goto abort_cmd;

    }



    if (!s->smart_enabled && s->feature != SMART_ENABLE) {

        goto abort_cmd;

    }



    switch (s->feature) {

    case SMART_DISABLE:

        s->smart_enabled = 0;

        return true;



    case SMART_ENABLE:

        s->smart_enabled = 1;

        return true;



    case SMART_ATTR_AUTOSAVE:

        switch (s->sector) {

        case 0x00:

            s->smart_autosave = 0;

            break;

        case 0xf1:

            s->smart_autosave = 1;

            break;

        default:

            goto abort_cmd;

        }

        return true;



    case SMART_STATUS:

        if (!s->smart_errors) {

            s->hcyl = 0xc2;

            s->lcyl = 0x4f;

        } else {

            s->hcyl = 0x2c;

            s->lcyl = 0xf4;

        }

        return true;



    case SMART_READ_THRESH:

        memset(s->io_buffer, 0, 0x200);

        s->io_buffer[0] = 0x01; /* smart struct version */



        for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {

            s->io_buffer[2 + 0 + (n * 12)] = smart_attributes[n][0];

            s->io_buffer[2 + 1 + (n * 12)] = smart_attributes[n][11];

        }



        /* checksum */

        for (n = 0; n < 511; 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);

        return false;



    case SMART_READ_DATA:

        memset(s->io_buffer, 0, 0x200);

        s->io_buffer[0] = 0x01; /* smart struct version */



        for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {

            int i;

            for (i = 0; i < 11; i++) {

                s->io_buffer[2 + i + (n * 12)] = smart_attributes[n][i];

            }

        }



        s->io_buffer[362] = 0x02 | (s->smart_autosave ? 0x80 : 0x00);

        if (s->smart_selftest_count == 0) {

            s->io_buffer[363] = 0;

        } else {

            s->io_buffer[363] =

                s->smart_selftest_data[3 +

                           (s->smart_selftest_count - 1) *

                           24];

        }

        s->io_buffer[364] = 0x20;

        s->io_buffer[365] = 0x01;

        /* offline data collection capacity: execute + self-test*/

        s->io_buffer[367] = (1 << 4 | 1 << 3 | 1);

        s->io_buffer[368] = 0x03; /* smart capability (1) */

        s->io_buffer[369] = 0x00; /* smart capability (2) */

        s->io_buffer[370] = 0x01; /* error logging supported */

        s->io_buffer[372] = 0x02; /* minutes for poll short test */

        s->io_buffer[373] = 0x36; /* minutes for poll ext test */

        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] = 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);

        return false;



    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;



            for (n = 0; n < 511; n++) {

                s->io_buffer[511] += s->io_buffer[n];

            }

            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) {

                s->io_buffer[508] = 0;

            } 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[511] += s->io_buffer[n];

            }

            s->io_buffer[511] = 0x100 - s->io_buffer[511];

            break;

        default:

            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);

        return false;



    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 = 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 */

            break;

        default:

            goto abort_cmd;

        }

        return true;

    }



abort_cmd:

    ide_abort_command(s);

    return true;

}

static bool cmd_smart(IDEState *s, uint8_t cmd)

{

    int n;



    if (s->hcyl != 0xc2 || s->lcyl != 0x4f) {

        goto abort_cmd;

    }



    if (!s->smart_enabled && s->feature != SMART_ENABLE) {

        goto abort_cmd;

    }



    switch (s->feature) {

    case SMART_DISABLE:

        s->smart_enabled = 0;

        return true;



    case SMART_ENABLE:

        s->smart_enabled = 1;

        return true;



    case SMART_ATTR_AUTOSAVE:

        switch (s->sector) {

        case 0x00:

            s->smart_autosave = 0;

            break;

        case 0xf1:

            s->smart_autosave = 1;

            break;

        default:

            goto abort_cmd;

        }

        return true;



    case SMART_STATUS:

        if (!s->smart_errors) {

            s->hcyl = 0xc2;

            s->lcyl = 0x4f;

        } else {

            s->hcyl = 0x2c;

            s->lcyl = 0xf4;

        }

        return true;



    case SMART_READ_THRESH:

        memset(s->io_buffer, 0, 0x200);

        s->io_buffer[0] = 0x01; 



        for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {

            s->io_buffer[2 + 0 + (n * 12)] = smart_attributes[n][0];

            s->io_buffer[2 + 1 + (n * 12)] = smart_attributes[n][11];

        }



        

        for (n = 0; n < 511; 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);

        return false;



    case SMART_READ_DATA:

        memset(s->io_buffer, 0, 0x200);

        s->io_buffer[0] = 0x01; 



        for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {

            int i;

            for (i = 0; i < 11; i++) {

                s->io_buffer[2 + i + (n * 12)] = smart_attributes[n][i];

            }

        }



        s->io_buffer[362] = 0x02 | (s->smart_autosave ? 0x80 : 0x00);

        if (s->smart_selftest_count == 0) {

            s->io_buffer[363] = 0;

        } else {

            s->io_buffer[363] =

                s->smart_selftest_data[3 +

                           (s->smart_selftest_count - 1) *

                           24];

        }

        s->io_buffer[364] = 0x20;

        s->io_buffer[365] = 0x01;

        

        s->io_buffer[367] = (1 << 4 | 1 << 3 | 1);

        s->io_buffer[368] = 0x03; 

        s->io_buffer[369] = 0x00; 

        s->io_buffer[370] = 0x01; 

        s->io_buffer[372] = 0x02; 

        s->io_buffer[373] = 0x36; 

        s->io_buffer[374] = 0x01; 



        for (n = 0; n < 511; 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);

        return false;



    case SMART_READ_LOG:

        switch (s->sector) {

        case 0x01: 

            memset(s->io_buffer, 0, 0x200);

            s->io_buffer[0] = 0x01;

            s->io_buffer[1] = 0x00; 

            s->io_buffer[452] = s->smart_errors & 0xff;

            s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;



            for (n = 0; n < 511; n++) {

                s->io_buffer[511] += s->io_buffer[n];

            }

            s->io_buffer[511] = 0x100 - s->io_buffer[511];

            break;

        case 0x06: 

            memset(s->io_buffer, 0, 0x200);

            s->io_buffer[0] = 0x01;

            if (s->smart_selftest_count == 0) {

                s->io_buffer[508] = 0;

            } 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[511] += s->io_buffer[n];

            }

            s->io_buffer[511] = 0x100 - s->io_buffer[511];

            break;

        default:

            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);

        return false;



    case SMART_EXECUTE_OFFLINE:

        switch (s->sector) {

        case 0: 

        case 1: 

        case 2: 

            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; 

            s->smart_selftest_data[n + 2] = 0x34; 

            s->smart_selftest_data[n + 3] = 0x12; 

            break;

        default:

            goto abort_cmd;

        }

        return true;

    }



abort_cmd:

    ide_abort_command(s);

    return true;

}

                s->smart_selftest_count = 0;
static bool FUNC_0(IDEState *s, uint8_t cmd)

{

    int VAR_0;



    if (s->hcyl != 0xc2 || s->lcyl != 0x4f) {

        goto abort_cmd;

    }



    if (!s->smart_enabled && s->feature != SMART_ENABLE) {

        goto abort_cmd;

    }



    switch (s->feature) {

    case SMART_DISABLE:

        s->smart_enabled = 0;

        return true;



    case SMART_ENABLE:

        s->smart_enabled = 1;

        return true;



    case SMART_ATTR_AUTOSAVE:

        switch (s->sector) {

        case 0x00:

            s->smart_autosave = 0;

            break;

        case 0xf1:

            s->smart_autosave = 1;

            break;

        default:

            goto abort_cmd;

        }

        return true;



    case SMART_STATUS:

        if (!s->smart_errors) {

            s->hcyl = 0xc2;

            s->lcyl = 0x4f;

        } else {

            s->hcyl = 0x2c;

            s->lcyl = 0xf4;

        }

        return true;



    case SMART_READ_THRESH:

        memset(s->io_buffer, 0, 0x200);

        s->io_buffer[0] = 0x01; 



        for (VAR_0 = 0; VAR_0 < ARRAY_SIZE(smart_attributes); VAR_0++) {

            s->io_buffer[2 + 0 + (VAR_0 * 12)] = smart_attributes[VAR_0][0];

            s->io_buffer[2 + 1 + (VAR_0 * 12)] = smart_attributes[VAR_0][11];

        }



        

        for (VAR_0 = 0; VAR_0 < 511; VAR_0++) {

            s->io_buffer[511] += s->io_buffer[VAR_0];

        }

        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);

        return false;



    case SMART_READ_DATA:

        memset(s->io_buffer, 0, 0x200);

        s->io_buffer[0] = 0x01; 



        for (VAR_0 = 0; VAR_0 < ARRAY_SIZE(smart_attributes); VAR_0++) {

            int i;

            for (i = 0; i < 11; i++) {

                s->io_buffer[2 + i + (VAR_0 * 12)] = smart_attributes[VAR_0][i];

            }

        }



        s->io_buffer[362] = 0x02 | (s->smart_autosave ? 0x80 : 0x00);

        if (s->smart_selftest_count == 0) {

            s->io_buffer[363] = 0;

        } else {

            s->io_buffer[363] =

                s->smart_selftest_data[3 +

                           (s->smart_selftest_count - 1) *

                           24];

        }

        s->io_buffer[364] = 0x20;

        s->io_buffer[365] = 0x01;

        

        s->io_buffer[367] = (1 << 4 | 1 << 3 | 1);

        s->io_buffer[368] = 0x03; 

        s->io_buffer[369] = 0x00; 

        s->io_buffer[370] = 0x01; 

        s->io_buffer[372] = 0x02; 

        s->io_buffer[373] = 0x36; 

        s->io_buffer[374] = 0x01; 



        for (VAR_0 = 0; VAR_0 < 511; VAR_0++) {

            s->io_buffer[511] += s->io_buffer[VAR_0];

        }

        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);

        return false;



    case SMART_READ_LOG:

        switch (s->sector) {

        case 0x01: 

            memset(s->io_buffer, 0, 0x200);

            s->io_buffer[0] = 0x01;

            s->io_buffer[1] = 0x00; 

            s->io_buffer[452] = s->smart_errors & 0xff;

            s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8;



            for (VAR_0 = 0; VAR_0 < 511; VAR_0++) {

                s->io_buffer[511] += s->io_buffer[VAR_0];

            }

            s->io_buffer[511] = 0x100 - s->io_buffer[511];

            break;

        case 0x06: 

            memset(s->io_buffer, 0, 0x200);

            s->io_buffer[0] = 0x01;

            if (s->smart_selftest_count == 0) {

                s->io_buffer[508] = 0;

            } else {

                s->io_buffer[508] = s->smart_selftest_count;

                for (VAR_0 = 2; VAR_0 < 506; VAR_0++)  {

                    s->io_buffer[VAR_0] = s->smart_selftest_data[VAR_0];

                }

            }



            for (VAR_0 = 0; VAR_0 < 511; VAR_0++) {

                s->io_buffer[511] += s->io_buffer[VAR_0];

            }

            s->io_buffer[511] = 0x100 - s->io_buffer[511];

            break;

        default:

            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);

        return false;



    case SMART_EXECUTE_OFFLINE:

        switch (s->sector) {

        case 0: 

        case 1: 

        case 2: 

            s->smart_selftest_count++;

            if (s->smart_selftest_count > 21) {

                s->smart_selftest_count = 0;

            }

            VAR_0 = 2 + (s->smart_selftest_count - 1) * 24;

            s->smart_selftest_data[VAR_0] = s->sector;

            s->smart_selftest_data[VAR_0 + 1] = 0x00; 

            s->smart_selftest_data[VAR_0 + 2] = 0x34; 

            s->smart_selftest_data[VAR_0 + 3] = 0x12; 

            break;

        default:

            goto abort_cmd;

        }

        return true;

    }



abort_cmd:

    ide_abort_command(s);

    return true;

}

static bool FUNC_0(IDEState *s, uint8_t cmd)
{ int VAR_0; if (s->hcyl != 0xc2 || s->lcyl != 0x4f) { goto abort_cmd; } if (!s->smart_enabled && s->feature != SMART_ENABLE) { goto abort_cmd; } switch (s->feature) { case SMART_DISABLE:
s->smart_enabled = 0; return true; case SMART_ENABLE:
s->smart_enabled = 1; return true; case SMART_ATTR_AUTOSAVE:
switch (s->sector) { case 0x00:
s->smart_autosave = 0; break; case 0xf1:
s->smart_autosave = 1; break; default:
goto abort_cmd; } return true; case SMART_STATUS:
if (!s->smart_errors) { s->hcyl = 0xc2; s->lcyl = 0x4f; } else { s->hcyl = 0x2c; s->lcyl = 0xf4; } return true; case SMART_READ_THRESH:
memset(s->io_buffer, 0, 0x200); s->io_buffer[0] = 0x01; for (VAR_0 = 0; VAR_0 < ARRAY_SIZE(smart_attributes); VAR_0++) { s->io_buffer[2 + 0 + (VAR_0 * 12)] = smart_attributes[VAR_0][0]; s->io_buffer[2 + 1 + (VAR_0 * 12)] = smart_attributes[VAR_0][11]; } for (VAR_0 = 0; VAR_0 < 511; VAR_0++) { s->io_buffer[511] += s->io_buffer[VAR_0]; } 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); return false; case SMART_READ_DATA:
memset(s->io_buffer, 0, 0x200); s->io_buffer[0] = 0x01; for (VAR_0 = 0; VAR_0 < ARRAY_SIZE(smart_attributes); VAR_0++) { int i; for (i = 0; i < 11; i++) { s->io_buffer[2 + i + (VAR_0 * 12)] = smart_attributes[VAR_0][i]; } } s->io_buffer[362] = 0x02 | (s->smart_autosave ? 0x80 : 0x00); if (s->smart_selftest_count == 0) { s->io_buffer[363] = 0; } else { s->io_buffer[363] =
s->smart_selftest_data[3 +
(s->smart_selftest_count - 1) *
24]; } s->io_buffer[364] = 0x20; s->io_buffer[365] = 0x01; s->io_buffer[367] = (1 << 4 | 1 << 3 | 1); s->io_buffer[368] = 0x03; s->io_buffer[369] = 0x00; s->io_buffer[370] = 0x01; s->io_buffer[372] = 0x02; s->io_buffer[373] = 0x36; s->io_buffer[374] = 0x01; for (VAR_0 = 0; VAR_0 < 511; VAR_0++) { s->io_buffer[511] += s->io_buffer[VAR_0]; } 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); return false; case SMART_READ_LOG:
switch (s->sector) { case 0x01:
memset(s->io_buffer, 0, 0x200); s->io_buffer[0] = 0x01; s->io_buffer[1] = 0x00; s->io_buffer[452] = s->smart_errors & 0xff; s->io_buffer[453] = (s->smart_errors & 0xff00) >> 8; for (VAR_0 = 0; VAR_0 < 511; VAR_0++) { s->io_buffer[511] += s->io_buffer[VAR_0]; } s->io_buffer[511] = 0x100 - s->io_buffer[511]; break; case 0x06:
memset(s->io_buffer, 0, 0x200); s->io_buffer[0] = 0x01; if (s->smart_selftest_count == 0) { s->io_buffer[508] = 0; } else { s->io_buffer[508] = s->smart_selftest_count; for (VAR_0 = 2; VAR_0 < 506; VAR_0++)  { s->io_buffer[VAR_0] = s->smart_selftest_data[VAR_0]; } } for (VAR_0 = 0; VAR_0 < 511; VAR_0++) { s->io_buffer[511] += s->io_buffer[VAR_0]; } s->io_buffer[511] = 0x100 - s->io_buffer[511]; break; default:
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); return false; case SMART_EXECUTE_OFFLINE:
switch (s->sector) { case 0:
case 1:
case 2:
s->smart_selftest_count++; if (s->smart_selftest_count > 21) { s->smart_selftest_count = 0; } VAR_0 = 2 + (s->smart_selftest_count - 1) * 24; s->smart_selftest_data[VAR_0] = s->sector; s->smart_selftest_data[VAR_0 + 1] = 0x00; s->smart_selftest_data[VAR_0 + 2] = 0x34; s->smart_selftest_data[VAR_0 + 3] = 0x12; break; default:
goto abort_cmd; } return true; } abort_cmd:
ide_abort_command(s); return true; }