Annotation of qemu/hw/ide/pci.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * QEMU IDE Emulation: PCI Bus support.
                      3:  *
                      4:  * Copyright (c) 2003 Fabrice Bellard
                      5:  * Copyright (c) 2006 Openedhand Ltd.
                      6:  *
                      7:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      8:  * of this software and associated documentation files (the "Software"), to deal
                      9:  * in the Software without restriction, including without limitation the rights
                     10:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     11:  * copies of the Software, and to permit persons to whom the Software is
                     12:  * furnished to do so, subject to the following conditions:
                     13:  *
                     14:  * The above copyright notice and this permission notice shall be included in
                     15:  * all copies or substantial portions of the Software.
                     16:  *
                     17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     18:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     22:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     23:  * THE SOFTWARE.
                     24:  */
                     25: #include <hw/hw.h>
                     26: #include <hw/pc.h>
                     27: #include <hw/pci.h>
                     28: #include <hw/isa.h>
                     29: #include "block.h"
                     30: #include "block_int.h"
                     31: #include "sysemu.h"
                     32: #include "dma.h"
                     33: 
                     34: #include <hw/ide/pci.h>
                     35: 
                     36: void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
                     37: {
                     38:     BMDMAState *bm = opaque;
                     39: #ifdef DEBUG_IDE
                     40:     printf("%s: 0x%08x\n", __func__, val);
                     41: #endif
                     42:     if (!(val & BM_CMD_START)) {
1.1.1.2 ! root       43:         /*
        !            44:          * We can't cancel Scatter Gather DMA in the middle of the
        !            45:          * operation or a partial (not full) DMA transfer would reach
        !            46:          * the storage so we wait for completion instead (we beahve
        !            47:          * like if the DMA was completed by the time the guest trying
        !            48:          * to cancel dma with bmdma_cmd_writeb with BM_CMD_START not
        !            49:          * set).
        !            50:          *
        !            51:          * In the future we'll be able to safely cancel the I/O if the
        !            52:          * whole DMA operation will be submitted to disk with a single
        !            53:          * aio operation with preadv/pwritev.
        !            54:          */
        !            55:         if (bm->aiocb) {
        !            56:             qemu_aio_flush();
        !            57: #ifdef DEBUG_IDE
        !            58:             if (bm->aiocb)
        !            59:                 printf("ide_dma_cancel: aiocb still pending");
        !            60:             if (bm->status & BM_STATUS_DMAING)
        !            61:                 printf("ide_dma_cancel: BM_STATUS_DMAING still pending");
        !            62: #endif
        !            63:         }
1.1       root       64:         bm->cmd = val & 0x09;
                     65:     } else {
                     66:         if (!(bm->status & BM_STATUS_DMAING)) {
                     67:             bm->status |= BM_STATUS_DMAING;
                     68:             /* start dma transfer if possible */
                     69:             if (bm->dma_cb)
                     70:                 bm->dma_cb(bm, 0);
                     71:         }
                     72:         bm->cmd = val & 0x09;
                     73:     }
                     74: }
                     75: 
                     76: uint32_t bmdma_addr_readb(void *opaque, uint32_t addr)
                     77: {
                     78:     BMDMAState *bm = opaque;
                     79:     uint32_t val;
                     80:     val = (bm->addr >> ((addr & 3) * 8)) & 0xff;
                     81: #ifdef DEBUG_IDE
                     82:     printf("%s: 0x%08x\n", __func__, val);
                     83: #endif
                     84:     return val;
                     85: }
                     86: 
                     87: void bmdma_addr_writeb(void *opaque, uint32_t addr, uint32_t val)
                     88: {
                     89:     BMDMAState *bm = opaque;
                     90:     int shift = (addr & 3) * 8;
                     91: #ifdef DEBUG_IDE
                     92:     printf("%s: 0x%08x\n", __func__, val);
                     93: #endif
                     94:     bm->addr &= ~(0xFF << shift);
                     95:     bm->addr |= ((val & 0xFF) << shift) & ~3;
                     96:     bm->cur_addr = bm->addr;
                     97: }
                     98: 
                     99: uint32_t bmdma_addr_readw(void *opaque, uint32_t addr)
                    100: {
                    101:     BMDMAState *bm = opaque;
                    102:     uint32_t val;
                    103:     val = (bm->addr >> ((addr & 3) * 8)) & 0xffff;
                    104: #ifdef DEBUG_IDE
                    105:     printf("%s: 0x%08x\n", __func__, val);
                    106: #endif
                    107:     return val;
                    108: }
                    109: 
                    110: void bmdma_addr_writew(void *opaque, uint32_t addr, uint32_t val)
                    111: {
                    112:     BMDMAState *bm = opaque;
                    113:     int shift = (addr & 3) * 8;
                    114: #ifdef DEBUG_IDE
                    115:     printf("%s: 0x%08x\n", __func__, val);
                    116: #endif
                    117:     bm->addr &= ~(0xFFFF << shift);
                    118:     bm->addr |= ((val & 0xFFFF) << shift) & ~3;
                    119:     bm->cur_addr = bm->addr;
                    120: }
                    121: 
                    122: uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
                    123: {
                    124:     BMDMAState *bm = opaque;
                    125:     uint32_t val;
                    126:     val = bm->addr;
                    127: #ifdef DEBUG_IDE
                    128:     printf("%s: 0x%08x\n", __func__, val);
                    129: #endif
                    130:     return val;
                    131: }
                    132: 
                    133: void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
                    134: {
                    135:     BMDMAState *bm = opaque;
                    136: #ifdef DEBUG_IDE
                    137:     printf("%s: 0x%08x\n", __func__, val);
                    138: #endif
                    139:     bm->addr = val & ~3;
                    140:     bm->cur_addr = bm->addr;
                    141: }
                    142: 
1.1.1.2 ! root      143: static bool ide_bmdma_current_needed(void *opaque)
        !           144: {
        !           145:     BMDMAState *bm = opaque;
        !           146: 
        !           147:     return (bm->cur_prd_len != 0);
        !           148: }
        !           149: 
        !           150: static const VMStateDescription vmstate_bmdma_current = {
        !           151:     .name = "ide bmdma_current",
        !           152:     .version_id = 1,
        !           153:     .minimum_version_id = 1,
        !           154:     .minimum_version_id_old = 1,
        !           155:     .fields      = (VMStateField []) {
        !           156:         VMSTATE_UINT32(cur_addr, BMDMAState),
        !           157:         VMSTATE_UINT32(cur_prd_last, BMDMAState),
        !           158:         VMSTATE_UINT32(cur_prd_addr, BMDMAState),
        !           159:         VMSTATE_UINT32(cur_prd_len, BMDMAState),
        !           160:         VMSTATE_END_OF_LIST()
        !           161:     }
        !           162: };
        !           163: 
        !           164: 
1.1       root      165: static const VMStateDescription vmstate_bmdma = {
                    166:     .name = "ide bmdma",
                    167:     .version_id = 3,
                    168:     .minimum_version_id = 0,
                    169:     .minimum_version_id_old = 0,
                    170:     .fields      = (VMStateField []) {
                    171:         VMSTATE_UINT8(cmd, BMDMAState),
                    172:         VMSTATE_UINT8(status, BMDMAState),
                    173:         VMSTATE_UINT32(addr, BMDMAState),
                    174:         VMSTATE_INT64(sector_num, BMDMAState),
                    175:         VMSTATE_UINT32(nsector, BMDMAState),
                    176:         VMSTATE_UINT8(unit, BMDMAState),
                    177:         VMSTATE_END_OF_LIST()
1.1.1.2 ! root      178:     },
        !           179:     .subsections = (VMStateSubsection []) {
        !           180:         {
        !           181:             .vmsd = &vmstate_bmdma_current,
        !           182:             .needed = ide_bmdma_current_needed,
        !           183:         }, {
        !           184:             /* empty */
        !           185:         }
1.1       root      186:     }
                    187: };
                    188: 
                    189: static int ide_pci_post_load(void *opaque, int version_id)
                    190: {
                    191:     PCIIDEState *d = opaque;
                    192:     int i;
                    193: 
                    194:     for(i = 0; i < 2; i++) {
                    195:         /* current versions always store 0/1, but older version
                    196:            stored bigger values. We only need last bit */
                    197:         d->bmdma[i].unit &= 1;
                    198:     }
                    199:     return 0;
                    200: }
                    201: 
                    202: const VMStateDescription vmstate_ide_pci = {
                    203:     .name = "ide",
                    204:     .version_id = 3,
                    205:     .minimum_version_id = 0,
                    206:     .minimum_version_id_old = 0,
                    207:     .post_load = ide_pci_post_load,
                    208:     .fields      = (VMStateField []) {
                    209:         VMSTATE_PCI_DEVICE(dev, PCIIDEState),
                    210:         VMSTATE_STRUCT_ARRAY(bmdma, PCIIDEState, 2, 0,
                    211:                              vmstate_bmdma, BMDMAState),
                    212:         VMSTATE_IDE_BUS_ARRAY(bus, PCIIDEState, 2),
                    213:         VMSTATE_IDE_DRIVES(bus[0].ifs, PCIIDEState),
                    214:         VMSTATE_IDE_DRIVES(bus[1].ifs, PCIIDEState),
                    215:         VMSTATE_END_OF_LIST()
                    216:     }
                    217: };
                    218: 
                    219: void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
                    220: {
                    221:     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
                    222:     static const int bus[4]  = { 0, 0, 1, 1 };
                    223:     static const int unit[4] = { 0, 1, 0, 1 };
                    224:     int i;
                    225: 
                    226:     for (i = 0; i < 4; i++) {
                    227:         if (hd_table[i] == NULL)
                    228:             continue;
                    229:         ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]);
                    230:     }
                    231: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.