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

📄 ide.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
        padstr8(buf + 32, 4, QEMU_VERSION);        ide_atapi_cmd_reply(s, 36, max_len);        break;    default:        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                             ASC_ILLEGAL_OPCODE);        break;    }}/* called when the inserted state of the media has changed */static void cdrom_change_cb(void *opaque){    IDEState *s = opaque;    int64_t nb_sectors;    if (!s->bs) return; /* yikes */    /* XXX: send interrupt too */    bdrv_get_geometry(s->bs, &nb_sectors);    s->nb_sectors = nb_sectors;}static void ide_cmd_lba48_transform(IDEState *s, int lba48){    s->lba48 = lba48;    /* handle the 'magic' 0 nsector count conversion here. to avoid     * fiddling with the rest of the read logic, we just store the     * full sector count in ->nsector and ignore ->hob_nsector from now     */    if (!s->lba48) {	if (!s->nsector)	    s->nsector = 256;    } else {	if (!s->nsector && !s->hob_nsector)	    s->nsector = 65536;	else {	    int lo = s->nsector;	    int hi = s->hob_nsector;	    s->nsector = (hi << 8) | lo;	}    }}static void ide_clear_hob(IDEState *ide_if){    /* any write clears HOB high bit of device control register */    ide_if[0].select &= ~(1 << 7);    ide_if[1].select &= ~(1 << 7);}static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val){    IDEState *ide_if = opaque;    IDEState *s;    int unit, n;    int lba48 = 0;    int ret;#ifdef DEBUG_IDE    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);#endif    addr &= 7;    switch(addr) {    case 0:        break;    case 1:	ide_clear_hob(ide_if);        /* NOTE: data is written to the two drives */	ide_if[0].hob_feature = ide_if[0].feature;	ide_if[1].hob_feature = ide_if[1].feature;        ide_if[0].feature = val;        ide_if[1].feature = val;        break;    case 2:	ide_clear_hob(ide_if);	ide_if[0].hob_nsector = ide_if[0].nsector;	ide_if[1].hob_nsector = ide_if[1].nsector;        ide_if[0].nsector = val;        ide_if[1].nsector = val;        break;    case 3:	ide_clear_hob(ide_if);	ide_if[0].hob_sector = ide_if[0].sector;	ide_if[1].hob_sector = ide_if[1].sector;        ide_if[0].sector = val;        ide_if[1].sector = val;        break;    case 4:	ide_clear_hob(ide_if);	ide_if[0].hob_lcyl = ide_if[0].lcyl;	ide_if[1].hob_lcyl = ide_if[1].lcyl;        ide_if[0].lcyl = val;        ide_if[1].lcyl = val;        break;    case 5:	ide_clear_hob(ide_if);	ide_if[0].hob_hcyl = ide_if[0].hcyl;	ide_if[1].hob_hcyl = ide_if[1].hcyl;        ide_if[0].hcyl = val;        ide_if[1].hcyl = val;        break;    case 6:	/* FIXME: HOB readback uses bit 7 */        ide_if[0].select = (val & ~0x10) | 0xa0;        ide_if[1].select = (val | 0x10) | 0xa0;        /* select drive */        buffered_pio_reset(ide_if->cur_drive);        unit = (val >> 4) & 1;        s = ide_if + unit;        ide_if->cur_drive = s;        break;    default:    case 7:        /* command */#if defined(DEBUG_IDE)        printf("ide: CMD=%02x\n", val);#endif        s = ide_if->cur_drive;        /* ignore commands to non existant device */        if (!s->bs)             break;        switch(val) {        case WIN_IDENTIFY:            if (s->bs && !s->is_cdrom) {                ide_identify(s);                s->status = READY_STAT | SEEK_STAT;                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);            } else {                if (s->is_cdrom) {                    ide_set_signature(s);                }                ide_abort_command(s);            }            ide_set_irq(s);            break;        case WIN_SPECIFY:        case WIN_RECAL:            s->error = 0;            s->status = READY_STAT | SEEK_STAT;            ide_set_irq(s);            break;        case WIN_SETMULT:            if (s->nsector > MAX_MULT_SECTORS ||                 (s->nsector & (s->nsector - 1)) != 0) {                ide_abort_command(s);            } else {                s->mult_sectors = s->nsector;                s->status = READY_STAT;            }            ide_set_irq(s);            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;            ide_set_irq(s);            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;	case WIN_WRITE_EXT:	    lba48 = 1;        case WIN_WRITE:        case WIN_WRITE_ONCE:	    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);            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:            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);            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;	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);            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;            ide_set_irq(s);            break;        case WIN_CHECKPOWERMODE1:            s->nsector = 0xff; /* device active or idle */            s->status = READY_STAT;            ide_set_irq(s);            break;        case WIN_SETFEATURES:            if (!s->bs)                goto abort_cmd;            /* XXX: valid for CDROM ? */            switch(s->feature) {            case 0x02: /* write cache enable */                s->write_cache = 1;                s->status = READY_STAT | SEEK_STAT;                ide_set_irq(s);                break;            case 0x82: /* write cache disable */                s->write_cache = 0;                s->status = READY_STAT | SEEK_STAT;                ide_set_irq(s);                break;            case 0xaa: /* read look-ahead enable */            case 0x55: /* read look-ahead disable */            case 0x42: /* EN_AAM: enable Automatic Acoustic Mode */            case 0xc2: /* DIS_AAM: disable Automatic Acoustic Mode */            case 0x85: /* DIS_APM: disable APM */                s->status = READY_STAT | SEEK_STAT;                ide_set_irq(s);                break;            case 0x03: { /* set transfer mode */		uint8_t val = s->nsector & 0x07;		switch (s->nsector >> 3) {		    case 0x00: /* pio default */		    case 0x01: /* pio mode */			put_le16(s->identify_data + 63,0x07);			put_le16(s->identify_data + 88,0x3f);			break;		    case 0x04: /* mdma mode */			put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));			put_le16(s->identify_data + 88,0x3f);			break;		    case 0x08: /* udma mode */			put_le16(s->identify_data + 63,0x07);			put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));			break;		    default:			goto abort_cmd;		}                s->status = READY_STAT | SEEK_STAT;                ide_set_irq(s);                break;	    }            default:                goto abort_cmd;            }            break;        case WIN_FLUSH_CACHE:        case WIN_FLUSH_CACHE_EXT:            s->status = BUSY_STAT;            bdrv_aio_flush(s->bs, ide_flush_cb, s);            break;        case WIN_IDLEIMMEDIATE:        case WIN_STANDBY:        case WIN_SETIDLE1:        case WIN_STANDBYNOW1:        case WIN_SLEEPNOW1:        case WIN_STANDBY2:        case WIN_SETIDLE2:        case WIN_STANDBYNOW2:        case WIN_SLEEPNOW2:	    s->status = READY_STAT;            ide_set_irq(s);            break;            /* ATAPI commands */        case WIN_PIDENTIFY:            if (s->is_cdrom) {                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);            break;        case WIN_DIAGNOSE:            ide_set_signature(s);            s->status = 0x00; /* NOTE: READY is _not_ set */            s->error = 0x01;            break;        case WIN_SRST:            if (!s->is_cdrom)                goto abort_cmd;            ide_set_signature(s);            s->status = 0x00; /* NOTE: READY is _not_ set */            s->error = 0x01;            break;        case WIN_PACKETCMD:            if (!s->is_cdrom)                goto abort_cmd;            /* overlapping commands not supported */            if (s->feature & 0x02)                goto abort_cmd;            s->status = READY_STAT;            s->atapi_dma = s->feature & 1;            s->nsector = 1;            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,                                ide_atapi_cmd);            break;        default:        abort_cmd:            ide_abort_command(s);            ide_set_irq(s);            break;        }    }}static uint32_t ide_ioport_read(void *opaque, uint32_t addr1){    IDEState *ide_if = opaque;    IDEState *s = ide_if->cur_drive;    uint32_t addr;    int ret, hob;    addr = addr1 & 7;    /* FIXME: HOB readback uses bit 7, but it's always set right now */    //hob = s->select & (1 << 7);    hob = 0;    switch(addr) {    case 0:        ret = 0xff;        break;    case 1:        if (!ide_if[0].bs && !ide_if[1].bs)            ret = 0;        else if (!hob)            ret = s->error;	else	    ret = s->hob_feature;        break;    case 2:        if (!ide_if[0].bs && !ide_if[1].bs)            ret = 0;        else if (!hob)            ret = s->nsector & 0xff;	else	    ret = s->hob_nsector;        break;    case 3:        if (!ide_if[0].bs && !ide_if[1].bs)            ret = 0;        else if (!hob)            ret = s->sector;	else	    ret = s->hob_sector;        break;    case 4:        if (!ide_if[0].bs && !ide_if[1].bs)            ret = 0;        else if (!hob)            ret = s->lcyl;	else	    ret = s->hob_lcyl;        break;    case 5:        if (!ide_if[0].bs && !ide_if[1].bs)            ret = 0;        else if (!hob)            ret = s->hcyl;	else	    ret = s->hob_hcyl;        break;    case 6:        if (!ide_if[0].bs && !ide_if[1].bs)            ret = 0;        else            ret = s->select;        break;    default:    case 7:        if ((!ide_if[0].bs && !ide_if[1].bs) ||            (s != ide_if && !s->bs))            ret = 0;        else            ret = s->status;        s->set_irq(s->irq_opaque, s->irq, 0);        break;    }#ifdef DEBUG_IDE    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);#endif    return ret;}static uint32_t ide_status_read(void *opaque, uint32_t addr){ 

⌨️ 快捷键说明

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