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

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 "dma.h"
                     31: 
                     32: #include <hw/ide/pci.h>
                     33: 
1.1.1.3   root       34: #define BMDMA_PAGE_SIZE 4096
                     35: 
                     36: static void bmdma_start_dma(IDEDMA *dma, IDEState *s,
                     37:                             BlockDriverCompletionFunc *dma_cb)
1.1       root       38: {
1.1.1.3   root       39:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                     40: 
                     41:     bm->unit = s->unit;
                     42:     bm->dma_cb = dma_cb;
                     43:     bm->cur_prd_last = 0;
                     44:     bm->cur_prd_addr = 0;
                     45:     bm->cur_prd_len = 0;
                     46:     bm->sector_num = ide_get_sector(s);
                     47:     bm->nsector = s->nsector;
                     48: 
                     49:     if (bm->status & BM_STATUS_DMAING) {
                     50:         bm->dma_cb(bmdma_active_if(bm), 0);
                     51:     }
                     52: }
                     53: 
                     54: /* return 0 if buffer completed */
                     55: static int bmdma_prepare_buf(IDEDMA *dma, int is_write)
                     56: {
                     57:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                     58:     IDEState *s = bmdma_active_if(bm);
                     59:     struct {
                     60:         uint32_t addr;
                     61:         uint32_t size;
                     62:     } prd;
                     63:     int l, len;
                     64: 
1.1.1.5   root       65:     pci_dma_sglist_init(&s->sg, &bm->pci_dev->dev,
                     66:                         s->nsector / (BMDMA_PAGE_SIZE / 512) + 1);
1.1.1.3   root       67:     s->io_buffer_size = 0;
                     68:     for(;;) {
                     69:         if (bm->cur_prd_len == 0) {
                     70:             /* end of table (with a fail safe of one page) */
                     71:             if (bm->cur_prd_last ||
                     72:                 (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE)
                     73:                 return s->io_buffer_size != 0;
1.1.1.6 ! root       74:             pci_dma_read(&bm->pci_dev->dev, bm->cur_addr, &prd, 8);
1.1.1.3   root       75:             bm->cur_addr += 8;
                     76:             prd.addr = le32_to_cpu(prd.addr);
                     77:             prd.size = le32_to_cpu(prd.size);
                     78:             len = prd.size & 0xfffe;
                     79:             if (len == 0)
                     80:                 len = 0x10000;
                     81:             bm->cur_prd_len = len;
                     82:             bm->cur_prd_addr = prd.addr;
                     83:             bm->cur_prd_last = (prd.size & 0x80000000);
1.1.1.2   root       84:         }
1.1.1.3   root       85:         l = bm->cur_prd_len;
                     86:         if (l > 0) {
                     87:             qemu_sglist_add(&s->sg, bm->cur_prd_addr, l);
                     88:             bm->cur_prd_addr += l;
                     89:             bm->cur_prd_len -= l;
                     90:             s->io_buffer_size += l;
1.1       root       91:         }
                     92:     }
1.1.1.3   root       93:     return 1;
1.1       root       94: }
                     95: 
1.1.1.3   root       96: /* return 0 if buffer completed */
                     97: static int bmdma_rw_buf(IDEDMA *dma, int is_write)
1.1       root       98: {
1.1.1.3   root       99:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                    100:     IDEState *s = bmdma_active_if(bm);
                    101:     struct {
                    102:         uint32_t addr;
                    103:         uint32_t size;
                    104:     } prd;
                    105:     int l, len;
                    106: 
                    107:     for(;;) {
                    108:         l = s->io_buffer_size - s->io_buffer_index;
                    109:         if (l <= 0)
                    110:             break;
                    111:         if (bm->cur_prd_len == 0) {
                    112:             /* end of table (with a fail safe of one page) */
                    113:             if (bm->cur_prd_last ||
                    114:                 (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE)
                    115:                 return 0;
1.1.1.6 ! root      116:             pci_dma_read(&bm->pci_dev->dev, bm->cur_addr, &prd, 8);
1.1.1.3   root      117:             bm->cur_addr += 8;
                    118:             prd.addr = le32_to_cpu(prd.addr);
                    119:             prd.size = le32_to_cpu(prd.size);
                    120:             len = prd.size & 0xfffe;
                    121:             if (len == 0)
                    122:                 len = 0x10000;
                    123:             bm->cur_prd_len = len;
                    124:             bm->cur_prd_addr = prd.addr;
                    125:             bm->cur_prd_last = (prd.size & 0x80000000);
                    126:         }
                    127:         if (l > bm->cur_prd_len)
                    128:             l = bm->cur_prd_len;
                    129:         if (l > 0) {
                    130:             if (is_write) {
1.1.1.5   root      131:                 pci_dma_write(&bm->pci_dev->dev, bm->cur_prd_addr,
                    132:                               s->io_buffer + s->io_buffer_index, l);
1.1.1.3   root      133:             } else {
1.1.1.5   root      134:                 pci_dma_read(&bm->pci_dev->dev, bm->cur_prd_addr,
                    135:                              s->io_buffer + s->io_buffer_index, l);
1.1.1.3   root      136:             }
                    137:             bm->cur_prd_addr += l;
                    138:             bm->cur_prd_len -= l;
                    139:             s->io_buffer_index += l;
                    140:         }
                    141:     }
                    142:     return 1;
1.1       root      143: }
                    144: 
1.1.1.3   root      145: static int bmdma_set_unit(IDEDMA *dma, int unit)
1.1       root      146: {
1.1.1.3   root      147:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                    148:     bm->unit = unit;
                    149: 
                    150:     return 0;
                    151: }
                    152: 
                    153: static int bmdma_add_status(IDEDMA *dma, int status)
                    154: {
                    155:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                    156:     bm->status |= status;
                    157: 
                    158:     return 0;
                    159: }
                    160: 
                    161: static int bmdma_set_inactive(IDEDMA *dma)
                    162: {
                    163:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                    164: 
                    165:     bm->status &= ~BM_STATUS_DMAING;
                    166:     bm->dma_cb = NULL;
                    167:     bm->unit = -1;
                    168: 
                    169:     return 0;
                    170: }
                    171: 
1.1.1.4   root      172: static void bmdma_restart_dma(BMDMAState *bm, enum ide_dma_cmd dma_cmd)
1.1.1.3   root      173: {
                    174:     IDEState *s = bmdma_active_if(bm);
                    175: 
                    176:     ide_set_sector(s, bm->sector_num);
                    177:     s->io_buffer_index = 0;
                    178:     s->io_buffer_size = 0;
                    179:     s->nsector = bm->nsector;
1.1.1.4   root      180:     s->dma_cmd = dma_cmd;
1.1       root      181:     bm->cur_addr = bm->addr;
1.1.1.3   root      182:     bm->dma_cb = ide_dma_cb;
                    183:     bmdma_start_dma(&bm->dma, s, bm->dma_cb);
1.1       root      184: }
                    185: 
1.1.1.4   root      186: /* TODO This should be common IDE code */
1.1.1.3   root      187: static void bmdma_restart_bh(void *opaque)
1.1       root      188: {
                    189:     BMDMAState *bm = opaque;
1.1.1.4   root      190:     IDEBus *bus = bm->bus;
1.1.1.3   root      191:     int is_read;
1.1.1.4   root      192:     int error_status;
1.1.1.3   root      193: 
                    194:     qemu_bh_delete(bm->bh);
                    195:     bm->bh = NULL;
                    196: 
1.1.1.4   root      197:     if (bm->unit == (uint8_t) -1) {
                    198:         return;
                    199:     }
                    200: 
                    201:     is_read = !!(bus->error_status & BM_STATUS_RETRY_READ);
1.1.1.3   root      202: 
1.1.1.4   root      203:     /* The error status must be cleared before resubmitting the request: The
                    204:      * request may fail again, and this case can only be distinguished if the
                    205:      * called function can set a new error status. */
                    206:     error_status = bus->error_status;
                    207:     bus->error_status = 0;
                    208: 
                    209:     if (error_status & BM_STATUS_DMA_RETRY) {
                    210:         if (error_status & BM_STATUS_RETRY_TRIM) {
                    211:             bmdma_restart_dma(bm, IDE_DMA_TRIM);
                    212:         } else {
                    213:             bmdma_restart_dma(bm, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
                    214:         }
                    215:     } else if (error_status & BM_STATUS_PIO_RETRY) {
1.1.1.3   root      216:         if (is_read) {
                    217:             ide_sector_read(bmdma_active_if(bm));
                    218:         } else {
                    219:             ide_sector_write(bmdma_active_if(bm));
                    220:         }
1.1.1.4   root      221:     } else if (error_status & BM_STATUS_RETRY_FLUSH) {
1.1.1.3   root      222:         ide_flush_cache(bmdma_active_if(bm));
                    223:     }
                    224: }
                    225: 
1.1.1.5   root      226: static void bmdma_restart_cb(void *opaque, int running, RunState state)
1.1.1.3   root      227: {
                    228:     IDEDMA *dma = opaque;
                    229:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                    230: 
                    231:     if (!running)
                    232:         return;
                    233: 
                    234:     if (!bm->bh) {
                    235:         bm->bh = qemu_bh_new(bmdma_restart_bh, &bm->dma);
                    236:         qemu_bh_schedule(bm->bh);
                    237:     }
                    238: }
                    239: 
                    240: static void bmdma_cancel(BMDMAState *bm)
                    241: {
                    242:     if (bm->status & BM_STATUS_DMAING) {
                    243:         /* cancel DMA request */
                    244:         bmdma_set_inactive(&bm->dma);
                    245:     }
                    246: }
                    247: 
                    248: static int bmdma_reset(IDEDMA *dma)
                    249: {
                    250:     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
                    251: 
1.1       root      252: #ifdef DEBUG_IDE
1.1.1.3   root      253:     printf("ide: dma_reset\n");
1.1       root      254: #endif
1.1.1.3   root      255:     bmdma_cancel(bm);
                    256:     bm->cmd = 0;
                    257:     bm->status = 0;
                    258:     bm->addr = 0;
                    259:     bm->cur_addr = 0;
                    260:     bm->cur_prd_last = 0;
                    261:     bm->cur_prd_addr = 0;
                    262:     bm->cur_prd_len = 0;
                    263:     bm->sector_num = 0;
                    264:     bm->nsector = 0;
                    265: 
                    266:     return 0;
                    267: }
                    268: 
                    269: static int bmdma_start_transfer(IDEDMA *dma)
                    270: {
                    271:     return 0;
                    272: }
                    273: 
                    274: static void bmdma_irq(void *opaque, int n, int level)
                    275: {
                    276:     BMDMAState *bm = opaque;
                    277: 
                    278:     if (!level) {
                    279:         /* pass through lower */
                    280:         qemu_set_irq(bm->irq, level);
                    281:         return;
                    282:     }
                    283: 
                    284:     bm->status |= BM_STATUS_INT;
                    285: 
                    286:     /* trigger the real irq */
                    287:     qemu_set_irq(bm->irq, level);
1.1       root      288: }
                    289: 
1.1.1.5   root      290: void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
1.1       root      291: {
                    292: #ifdef DEBUG_IDE
                    293:     printf("%s: 0x%08x\n", __func__, val);
                    294: #endif
1.1.1.3   root      295: 
                    296:     /* Ignore writes to SSBM if it keeps the old value */
                    297:     if ((val & BM_CMD_START) != (bm->cmd & BM_CMD_START)) {
                    298:         if (!(val & BM_CMD_START)) {
                    299:             /*
                    300:              * We can't cancel Scatter Gather DMA in the middle of the
                    301:              * operation or a partial (not full) DMA transfer would reach
                    302:              * the storage so we wait for completion instead (we beahve
                    303:              * like if the DMA was completed by the time the guest trying
                    304:              * to cancel dma with bmdma_cmd_writeb with BM_CMD_START not
                    305:              * set).
                    306:              *
                    307:              * In the future we'll be able to safely cancel the I/O if the
                    308:              * whole DMA operation will be submitted to disk with a single
                    309:              * aio operation with preadv/pwritev.
                    310:              */
                    311:             if (bm->bus->dma->aiocb) {
1.1.1.6 ! root      312:                 bdrv_drain_all();
1.1.1.4   root      313:                 assert(bm->bus->dma->aiocb == NULL);
                    314:                 assert((bm->status & BM_STATUS_DMAING) == 0);
1.1.1.3   root      315:             }
                    316:         } else {
                    317:             bm->cur_addr = bm->addr;
                    318:             if (!(bm->status & BM_STATUS_DMAING)) {
                    319:                 bm->status |= BM_STATUS_DMAING;
                    320:                 /* start dma transfer if possible */
                    321:                 if (bm->dma_cb)
                    322:                     bm->dma_cb(bmdma_active_if(bm), 0);
                    323:             }
                    324:         }
                    325:     }
                    326: 
                    327:     bm->cmd = val & 0x09;
1.1       root      328: }
                    329: 
1.1.1.6 ! root      330: static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr,
1.1.1.5   root      331:                                 unsigned width)
1.1       root      332: {
1.1.1.5   root      333:     BMDMAState *bm = opaque;
1.1.1.3   root      334:     uint32_t mask = (1ULL << (width * 8)) - 1;
1.1.1.5   root      335:     uint64_t data;
1.1.1.3   root      336: 
1.1.1.5   root      337:     data = (bm->addr >> (addr * 8)) & mask;
1.1       root      338: #ifdef DEBUG_IDE
1.1.1.6 ! root      339:     printf("%s: 0x%08x\n", __func__, (unsigned)data);
1.1       root      340: #endif
1.1.1.5   root      341:     return data;
1.1       root      342: }
                    343: 
1.1.1.6 ! root      344: static void bmdma_addr_write(void *opaque, target_phys_addr_t addr,
1.1.1.5   root      345:                              uint64_t data, unsigned width)
1.1       root      346: {
1.1.1.5   root      347:     BMDMAState *bm = opaque;
1.1.1.3   root      348:     int shift = addr * 8;
                    349:     uint32_t mask = (1ULL << (width * 8)) - 1;
                    350: 
1.1       root      351: #ifdef DEBUG_IDE
1.1.1.3   root      352:     printf("%s: 0x%08x\n", __func__, (unsigned)data);
1.1       root      353: #endif
1.1.1.3   root      354:     bm->addr &= ~(mask << shift);
                    355:     bm->addr |= ((data & mask) << shift) & ~3;
1.1       root      356: }
                    357: 
1.1.1.5   root      358: MemoryRegionOps bmdma_addr_ioport_ops = {
1.1.1.3   root      359:     .read = bmdma_addr_read,
                    360:     .write = bmdma_addr_write,
1.1.1.5   root      361:     .endianness = DEVICE_LITTLE_ENDIAN,
1.1.1.3   root      362: };
                    363: 
1.1.1.2   root      364: static bool ide_bmdma_current_needed(void *opaque)
                    365: {
                    366:     BMDMAState *bm = opaque;
                    367: 
                    368:     return (bm->cur_prd_len != 0);
                    369: }
                    370: 
1.1.1.4   root      371: static bool ide_bmdma_status_needed(void *opaque)
                    372: {
                    373:     BMDMAState *bm = opaque;
                    374: 
                    375:     /* Older versions abused some bits in the status register for internal
                    376:      * error state. If any of these bits are set, we must add a subsection to
                    377:      * transfer the real status register */
                    378:     uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS;
                    379: 
                    380:     return ((bm->status & abused_bits) != 0);
                    381: }
                    382: 
                    383: static void ide_bmdma_pre_save(void *opaque)
                    384: {
                    385:     BMDMAState *bm = opaque;
                    386:     uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS;
                    387: 
                    388:     bm->migration_compat_status =
                    389:         (bm->status & ~abused_bits) | (bm->bus->error_status & abused_bits);
                    390: }
                    391: 
                    392: /* This function accesses bm->bus->error_status which is loaded only after
                    393:  * BMDMA itself. This is why the function is called from ide_pci_post_load
                    394:  * instead of being registered with VMState where it would run too early. */
                    395: static int ide_bmdma_post_load(void *opaque, int version_id)
                    396: {
                    397:     BMDMAState *bm = opaque;
                    398:     uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS;
                    399: 
                    400:     if (bm->status == 0) {
                    401:         bm->status = bm->migration_compat_status & ~abused_bits;
                    402:         bm->bus->error_status |= bm->migration_compat_status & abused_bits;
                    403:     }
                    404: 
                    405:     return 0;
                    406: }
                    407: 
1.1.1.2   root      408: static const VMStateDescription vmstate_bmdma_current = {
                    409:     .name = "ide bmdma_current",
                    410:     .version_id = 1,
                    411:     .minimum_version_id = 1,
                    412:     .minimum_version_id_old = 1,
                    413:     .fields      = (VMStateField []) {
                    414:         VMSTATE_UINT32(cur_addr, BMDMAState),
                    415:         VMSTATE_UINT32(cur_prd_last, BMDMAState),
                    416:         VMSTATE_UINT32(cur_prd_addr, BMDMAState),
                    417:         VMSTATE_UINT32(cur_prd_len, BMDMAState),
                    418:         VMSTATE_END_OF_LIST()
                    419:     }
                    420: };
                    421: 
1.1.1.4   root      422: const VMStateDescription vmstate_bmdma_status = {
                    423:     .name ="ide bmdma/status",
                    424:     .version_id = 1,
                    425:     .minimum_version_id = 1,
                    426:     .minimum_version_id_old = 1,
                    427:     .fields = (VMStateField []) {
                    428:         VMSTATE_UINT8(status, BMDMAState),
                    429:         VMSTATE_END_OF_LIST()
                    430:     }
                    431: };
1.1.1.2   root      432: 
1.1       root      433: static const VMStateDescription vmstate_bmdma = {
                    434:     .name = "ide bmdma",
                    435:     .version_id = 3,
                    436:     .minimum_version_id = 0,
                    437:     .minimum_version_id_old = 0,
1.1.1.4   root      438:     .pre_save  = ide_bmdma_pre_save,
1.1       root      439:     .fields      = (VMStateField []) {
                    440:         VMSTATE_UINT8(cmd, BMDMAState),
1.1.1.4   root      441:         VMSTATE_UINT8(migration_compat_status, BMDMAState),
1.1       root      442:         VMSTATE_UINT32(addr, BMDMAState),
                    443:         VMSTATE_INT64(sector_num, BMDMAState),
                    444:         VMSTATE_UINT32(nsector, BMDMAState),
                    445:         VMSTATE_UINT8(unit, BMDMAState),
                    446:         VMSTATE_END_OF_LIST()
1.1.1.2   root      447:     },
                    448:     .subsections = (VMStateSubsection []) {
                    449:         {
                    450:             .vmsd = &vmstate_bmdma_current,
                    451:             .needed = ide_bmdma_current_needed,
                    452:         }, {
1.1.1.4   root      453:             .vmsd = &vmstate_bmdma_status,
                    454:             .needed = ide_bmdma_status_needed,
                    455:         }, {
1.1.1.2   root      456:             /* empty */
                    457:         }
1.1       root      458:     }
                    459: };
                    460: 
                    461: static int ide_pci_post_load(void *opaque, int version_id)
                    462: {
                    463:     PCIIDEState *d = opaque;
                    464:     int i;
                    465: 
                    466:     for(i = 0; i < 2; i++) {
                    467:         /* current versions always store 0/1, but older version
                    468:            stored bigger values. We only need last bit */
                    469:         d->bmdma[i].unit &= 1;
1.1.1.4   root      470:         ide_bmdma_post_load(&d->bmdma[i], -1);
1.1       root      471:     }
1.1.1.4   root      472: 
1.1       root      473:     return 0;
                    474: }
                    475: 
                    476: const VMStateDescription vmstate_ide_pci = {
                    477:     .name = "ide",
                    478:     .version_id = 3,
                    479:     .minimum_version_id = 0,
                    480:     .minimum_version_id_old = 0,
                    481:     .post_load = ide_pci_post_load,
                    482:     .fields      = (VMStateField []) {
                    483:         VMSTATE_PCI_DEVICE(dev, PCIIDEState),
                    484:         VMSTATE_STRUCT_ARRAY(bmdma, PCIIDEState, 2, 0,
                    485:                              vmstate_bmdma, BMDMAState),
                    486:         VMSTATE_IDE_BUS_ARRAY(bus, PCIIDEState, 2),
                    487:         VMSTATE_IDE_DRIVES(bus[0].ifs, PCIIDEState),
                    488:         VMSTATE_IDE_DRIVES(bus[1].ifs, PCIIDEState),
                    489:         VMSTATE_END_OF_LIST()
                    490:     }
                    491: };
                    492: 
                    493: void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
                    494: {
                    495:     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
                    496:     static const int bus[4]  = { 0, 0, 1, 1 };
                    497:     static const int unit[4] = { 0, 1, 0, 1 };
                    498:     int i;
                    499: 
                    500:     for (i = 0; i < 4; i++) {
                    501:         if (hd_table[i] == NULL)
                    502:             continue;
                    503:         ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]);
                    504:     }
                    505: }
1.1.1.3   root      506: 
                    507: static const struct IDEDMAOps bmdma_ops = {
                    508:     .start_dma = bmdma_start_dma,
                    509:     .start_transfer = bmdma_start_transfer,
                    510:     .prepare_buf = bmdma_prepare_buf,
                    511:     .rw_buf = bmdma_rw_buf,
                    512:     .set_unit = bmdma_set_unit,
                    513:     .add_status = bmdma_add_status,
                    514:     .set_inactive = bmdma_set_inactive,
                    515:     .restart_cb = bmdma_restart_cb,
                    516:     .reset = bmdma_reset,
                    517: };
                    518: 
1.1.1.5   root      519: void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
1.1.1.3   root      520: {
                    521:     qemu_irq *irq;
                    522: 
                    523:     if (bus->dma == &bm->dma) {
                    524:         return;
                    525:     }
                    526: 
                    527:     bm->dma.ops = &bmdma_ops;
                    528:     bus->dma = &bm->dma;
                    529:     bm->irq = bus->irq;
                    530:     irq = qemu_allocate_irqs(bmdma_irq, bm, 1);
                    531:     bus->irq = *irq;
1.1.1.5   root      532:     bm->pci_dev = d;
1.1.1.3   root      533: }

unix.superglobalmegacorp.com

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