⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
            ide_atapi_cmd_ok(s);        } else {            ide_atapi_cmd_error(s, SENSE_NOT_READY,                                ASC_MEDIUM_NOT_PRESENT);        }        break;    case GPCMD_MODE_SENSE_6:    case GPCMD_MODE_SENSE_10:        {            int action, code;            if (packet[0] == GPCMD_MODE_SENSE_10)                max_len = ube16_to_cpu(packet + 7);            else                max_len = packet[4];            action = packet[2] >> 6;            code = packet[2] & 0x3f;            switch(action) {            case 0: /* current values */                switch(code) {                case 0x01: /* error recovery */                    cpu_to_ube16(&buf[0], 16 + 6);                    buf[2] = 0x70;                    buf[3] = 0;                    buf[4] = 0;                    buf[5] = 0;                    buf[6] = 0;                    buf[7] = 0;                    buf[8] = 0x01;                    buf[9] = 0x06;                    buf[10] = 0x00;                    buf[11] = 0x05;                    buf[12] = 0x00;                    buf[13] = 0x00;                    buf[14] = 0x00;                    buf[15] = 0x00;                    ide_atapi_cmd_reply(s, 16, max_len);                    break;                case 0x2a:                    cpu_to_ube16(&buf[0], 28 + 6);                    buf[2] = 0x70;                    buf[3] = 0;                    buf[4] = 0;                    buf[5] = 0;                    buf[6] = 0;                    buf[7] = 0;                    buf[8] = 0x2a;                    buf[9] = 0x12;                    buf[10] = 0x00;                    buf[11] = 0x00;                    buf[12] = 0x70;                    buf[13] = 3 << 5;                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);                    if (bdrv_is_locked(s->bs))                        buf[6] |= 1 << 1;                    buf[15] = 0x00;                    cpu_to_ube16(&buf[16], 706);                    buf[18] = 0;                    buf[19] = 2;                    cpu_to_ube16(&buf[20], 512);                    cpu_to_ube16(&buf[22], 706);                    buf[24] = 0;                    buf[25] = 0;                    buf[26] = 0;                    buf[27] = 0;                    ide_atapi_cmd_reply(s, 28, max_len);                    break;                default:                    goto error_cmd;                }                break;            case 1: /* changeable values */                goto error_cmd;            case 2: /* default values */                goto error_cmd;            default:            case 3: /* saved values */                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);                break;            }        }        break;    case GPCMD_REQUEST_SENSE:        max_len = packet[4];        memset(buf, 0, 18);        buf[0] = 0x70 | (1 << 7);        buf[2] = s->sense_key;        buf[7] = 10;        buf[12] = s->asc;        ide_atapi_cmd_reply(s, 18, max_len);        break;    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:        if (bdrv_is_inserted(s->bs)) {            bdrv_set_locked(s->bs, packet[4] & 1);            ide_atapi_cmd_ok(s);        } else {            ide_atapi_cmd_error(s, SENSE_NOT_READY,                                ASC_MEDIUM_NOT_PRESENT);        }        break;    case GPCMD_READ_10:    case GPCMD_READ_12:        {            int nb_sectors, lba;            if (packet[0] == GPCMD_READ_10)                nb_sectors = ube16_to_cpu(packet + 7);            else                nb_sectors = ube32_to_cpu(packet + 6);            lba = ube32_to_cpu(packet + 2);            if (nb_sectors == 0) {                ide_atapi_cmd_ok(s);                break;            }            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);        }        break;    case GPCMD_READ_CD:        {            int nb_sectors, lba, transfer_request;            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];            lba = ube32_to_cpu(packet + 2);            if (nb_sectors == 0) {                ide_atapi_cmd_ok(s);                break;            }            transfer_request = packet[9];            switch(transfer_request & 0xf8) {            case 0x00:                /* nothing */                ide_atapi_cmd_ok(s);                break;            case 0x10:                /* normal read */                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);                break;            case 0xf8:                /* read all data */                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);                break;            default:                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                    ASC_INV_FIELD_IN_CMD_PACKET);                break;            }        }        break;    case GPCMD_SEEK:        {            unsigned int lba;            uint64_t total_sectors;            bdrv_get_geometry(s->bs, &total_sectors);            total_sectors >>= 2;            if (total_sectors == 0) {                ide_atapi_cmd_error(s, SENSE_NOT_READY,                                    ASC_MEDIUM_NOT_PRESENT);                break;            }            lba = ube32_to_cpu(packet + 2);            if (lba >= total_sectors) {                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                    ASC_LOGICAL_BLOCK_OOR);                break;            }            ide_atapi_cmd_ok(s);        }        break;    case GPCMD_START_STOP_UNIT:        {            int start, eject;            start = packet[4] & 1;            eject = (packet[4] >> 1) & 1;            if (eject && !start) {                /* eject the disk */                bdrv_eject(s->bs, 1);            } else if (eject && start) {                /* close the tray */                bdrv_eject(s->bs, 0);            }            ide_atapi_cmd_ok(s);        }        break;    case GPCMD_MECHANISM_STATUS:        {            max_len = ube16_to_cpu(packet + 8);            cpu_to_ube16(buf, 0);            /* no current LBA */            buf[2] = 0;            buf[3] = 0;            buf[4] = 0;            buf[5] = 1;            cpu_to_ube16(buf + 6, 0);            ide_atapi_cmd_reply(s, 8, max_len);        }        break;    case GPCMD_READ_TOC_PMA_ATIP:        {            int format, msf, start_track, len;            uint64_t total_sectors;            bdrv_get_geometry(s->bs, &total_sectors);            total_sectors >>= 2;            if (total_sectors == 0) {                ide_atapi_cmd_error(s, SENSE_NOT_READY,                                    ASC_MEDIUM_NOT_PRESENT);                break;            }            max_len = ube16_to_cpu(packet + 7);            format = packet[9] >> 6;            msf = (packet[1] >> 1) & 1;            start_track = packet[6];            switch(format) {            case 0:                len = cdrom_read_toc(total_sectors, buf, msf, start_track);                if (len < 0)                    goto error_cmd;                ide_atapi_cmd_reply(s, len, max_len);                break;            case 1:                /* multi session : only a single session defined */                memset(buf, 0, 12);                buf[1] = 0x0a;                buf[2] = 0x01;                buf[3] = 0x01;                ide_atapi_cmd_reply(s, 12, max_len);                break;            case 2:                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);                if (len < 0)                    goto error_cmd;                ide_atapi_cmd_reply(s, len, max_len);                break;            default:            error_cmd:                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                    ASC_INV_FIELD_IN_CMD_PACKET);                break;            }        }        break;    case GPCMD_READ_CDVD_CAPACITY:        {            uint64_t total_sectors;            bdrv_get_geometry(s->bs, &total_sectors);            total_sectors >>= 2;            if (total_sectors == 0) {                ide_atapi_cmd_error(s, SENSE_NOT_READY,                                    ASC_MEDIUM_NOT_PRESENT);                break;            }            /* NOTE: it is really the number of sectors minus 1 */            cpu_to_ube32(buf, total_sectors - 1);            cpu_to_ube32(buf + 4, 2048);            ide_atapi_cmd_reply(s, 8, 8);        }        break;    case GPCMD_READ_DVD_STRUCTURE:        {            int media = packet[1];            int layer = packet[6];            int format = packet[2];            uint64_t total_sectors;            if (media != 0 || layer != 0)            {                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                    ASC_INV_FIELD_IN_CMD_PACKET);            }            switch (format) {                case 0:                    bdrv_get_geometry(s->bs, &total_sectors);                    total_sectors >>= 2;                    if (total_sectors == 0) {                        ide_atapi_cmd_error(s, SENSE_NOT_READY,                                            ASC_MEDIUM_NOT_PRESENT);                        break;                    }                    memset(buf, 0, 2052);                    buf[4] = 1;   // DVD-ROM, part version 1                    buf[5] = 0xf; // 120mm disc, maximum rate unspecified                    buf[6] = 0;   // one layer, embossed data                    buf[7] = 0;                    cpu_to_ube32(buf + 8, 0);                    cpu_to_ube32(buf + 12, total_sectors - 1);                    cpu_to_ube32(buf + 16, total_sectors - 1);                    cpu_to_be16wu((uint16_t *)buf, 2048 + 4);                    ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4);                    break;                default:                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                        ASC_INV_FIELD_IN_CMD_PACKET);                    break;            }        }        break;    case GPCMD_SET_SPEED:        ide_atapi_cmd_ok(s);        break;    case GPCMD_INQUIRY:        max_len = packet[4];        buf[0] = 0x05; /* CD-ROM */        buf[1] = 0x80; /* removable */        buf[2] = 0x00; /* ISO */        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */        buf[4] = 31; /* additional length */        buf[5] = 0; /* reserved */        buf[6] = 0; /* reserved */        buf[7] = 0; /* reserved */        padstr8(buf + 8, 8, "QEMU");        padstr8(buf + 16, 16, "QEMU DVD-ROM");        padstr8(buf + 32, 4, QEMU_VERSION);        ide_atapi_cmd_reply(s, 36, max_len);        break;    case GPCMD_GET_CONFIGURATION:        {            uint32_t len;            /* only feature 0 is supported */            if (packet[2] != 0 || packet[3] != 0) {                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                    ASC_INV_FIELD_IN_CMD_PACKET);                break;            }            /* XXX: could result in alignment problems in some architectures */            max_len = ube16_to_cpu(packet + 7);            /*             * XXX: avoid overflow for io_buffer if max_len is bigger than the             *      size of that buffer (dimensioned to max number of sectors             *      to transfer at once)             *             *      Only a problem if the feature/profiles grow exponentially.             */            if (max_len > 512) /* XXX: assume 1 sector */                max_len = 512;            memset(buf, 0, max_len);            /*              * the number of sectors from the media tells us which profile             * to use as current.  0 means there is no media             *             * XXX: fails to detect correctly DVDs with less data burned             *      than what a CD can hold             */            if ((s -> nb_sectors)) {                if ((s -> nb_sectors > CD_MAX_SECTORS))                    cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);                else                    cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);            }            len = 8; /* header completed */            if (max_len > len) {                uint8_t index = 0;                buf[10] = 0x02 | 0x01; /* persistent and current */                len += 4; /* header */                len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);                len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);            }            cpu_to_ube32(buf, len - 4); /* data length */            ide_atapi_cmd_reply(s, len, max_len);            break;        }    default:        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                            ASC_ILLEGAL_OPCODE);        break;    }}static void ide_cfata_metadata_inquiry(IDEState *s){    uint16_t *p;    uint32_t spd;    p = (uint16_t *) s->io_buffer;    memset(p, 0, 0x200);    spd = ((s->mdata_size - 1) >> 9) + 1;    put_le16(p + 0, 0x0001);			/* Data format revision */    put_le16(p + 1, 0x0000);			/* Media property: silicon */    put_le16(p + 2, s->media_changed);		/* Media status */    put_le16(p + 3, s->mdata_size & 0xffff);	/* Capacity in bytes (low) */    put_le16(p + 4, s->mdata_size >> 16);	/* Capacity in bytes (high) */    put_le16(p + 5, spd & 0xffff);		/* Sectors per device (low) */    put_le16(p + 6, spd >> 16);			/* Sectors per device (high) */}static void ide_cfata_metadata_read(IDEState *s){    uint16_t *p;    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {        s->status = ERR_STAT;        s->error = ABRT_ERR;        return;    }    p = (uint16_t *) s->io_buffer;    memset(p, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -