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

📄 ide.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
    s->lba = -1; /* no sector read */    s->packet_transfer_size = size;    s->io_buffer_size = size;    /* dma: send the reply data as one chunk */    s->elementary_transfer_size = 0;    s->io_buffer_index = 0;    if (s->atapi_dma) {    	s->status = READY_STAT | DRQ_STAT;	ide_dma_start(s, ide_atapi_cmd_read_dma_cb);    } else {    	s->status = READY_STAT;    	ide_atapi_cmd_reply_end(s);    }}/* start a CD-CDROM read command */static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,                                   int sector_size){    s->lba = lba;    s->packet_transfer_size = nb_sectors * sector_size;    s->elementary_transfer_size = 0;    s->io_buffer_index = sector_size;    s->cd_sector_size = sector_size;    s->status = READY_STAT;    ide_atapi_cmd_reply_end(s);}/* ATAPI DMA support *//* XXX: handle read errors */static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret){    BMDMAState *bm = opaque;    IDEState *s = bm->ide_if;    int data_offset, n;    if (!s->bs) return; /* yikes */    if (ret < 0) {        ide_atapi_io_error(s, ret);        goto eot;    }    if (s->io_buffer_size > 0) {	/*	 * For a cdrom read sector command (s->lba != -1),	 * adjust the lba for the next s->io_buffer_size chunk	 * and dma the current chunk.	 * For a command != read (s->lba == -1), just transfer	 * the reply data.	 */	if (s->lba != -1) {	    if (s->cd_sector_size == 2352) {		n = 1;		cd_data_to_raw(s->io_buffer, s->lba);	    } else {		n = s->io_buffer_size >> 11;	    }	    s->lba += n;	}        s->packet_transfer_size -= s->io_buffer_size;        if (dma_buf_rw(bm, 1) == 0)            goto eot;    }    if (s->packet_transfer_size <= 0) {        s->status = READY_STAT;        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;        ide_set_irq(s);    eot:        bm->status &= ~BM_STATUS_DMAING;        bm->status |= BM_STATUS_INT;        bm->dma_cb = NULL;        bm->ide_if = NULL;        bm->aiocb = NULL;        return;    }        s->io_buffer_index = 0;    if (s->cd_sector_size == 2352) {        n = 1;        s->io_buffer_size = s->cd_sector_size;        data_offset = 16;    } else {        n = s->packet_transfer_size >> 11;        if (n > (IDE_DMA_BUF_SIZE / 2048))            n = (IDE_DMA_BUF_SIZE / 2048);        s->io_buffer_size = n * 2048;        data_offset = 0;    }#ifdef DEBUG_AIO    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);#endif    bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,                               s->io_buffer + data_offset, n * 4,                               ide_atapi_cmd_read_dma_cb, bm);    if (!bm->aiocb) {        /* Note: media not present is the most likely case */        ide_atapi_cmd_error(s, SENSE_NOT_READY,                             ASC_MEDIUM_NOT_PRESENT);        goto eot;    }}/* start a CD-CDROM read command with DMA *//* XXX: test if DMA is available */static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,                                   int sector_size){    s->lba = lba;    s->packet_transfer_size = nb_sectors * sector_size;    s->io_buffer_index = 0;    s->io_buffer_size = 0;    s->cd_sector_size = sector_size;    /* XXX: check if BUSY_STAT should be set */    s->status = READY_STAT | DRQ_STAT | BUSY_STAT;    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);}static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,                                int sector_size){#ifdef DEBUG_IDE_ATAPI    printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",	lba, nb_sectors);#endif    if (s->atapi_dma) {        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);    } else {        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);    }}static void ide_atapi_cmd(IDEState *s){    const uint8_t *packet;    uint8_t *buf;    int max_len;    packet = s->io_buffer;    buf = s->io_buffer;#ifdef DEBUG_IDE_ATAPI    {        int i;        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {            printf(" %02x", packet[i]);        }        printf("\n");    }#endif    switch(s->io_buffer[0]) {    case GPCMD_TEST_UNIT_READY:        if (bdrv_is_inserted(s->bs)) {            if (s->is_cdrom && s->sense_key == SENSE_NOT_READY) {                ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION,                                     ASC_MEDIUM_MAY_HAVE_CHANGED);                break;            }            ide_atapi_cmd_ok(s);        } else {            ide_atapi_cmd_error(s, SENSE_NOT_READY,                                 ASC_MEDIUM_NOT_PRESENT);            xenstore_check_new_media_present(1000);        }        break;    case GPCMD_MODE_SENSE_10:        {            int action, code;            max_len = ube16_to_cpu(packet + 7);            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:        {            int lba;            int64_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;            int64_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:        {            int64_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_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; /* additionnal length */        buf[5] = 0; /* reserved */        buf[6] = 0; /* reserved */        buf[7] = 0; /* reserved */        padstr8(buf + 8, 8, "QEMU");        padstr8(buf + 16, 16, "QEMU CD-ROM");

⌨️ 快捷键说明

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