Commit b42ec42d4306e6da1e72a32167262343025116ed
1 parent
927e3a4e
DB-DMA cleanup
Signed-off-by: Laurent Vivier <Laurent@vivier.eu> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6676 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
133 additions
and
164 deletions
hw/ide.c
... | ... | @@ -3429,71 +3429,69 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, |
3429 | 3429 | |
3430 | 3430 | typedef struct MACIOIDEState { |
3431 | 3431 | IDEState ide_if[2]; |
3432 | - void *dbdma; | |
3433 | 3432 | int stream_index; |
3434 | 3433 | } MACIOIDEState; |
3435 | 3434 | |
3436 | -static int pmac_atapi_read(DBDMA_transfer *info, DBDMA_transfer_cb cb) | |
3435 | +static void pmac_atapi_read(DBDMA_io *io) | |
3437 | 3436 | { |
3438 | - MACIOIDEState *m = info->opaque; | |
3437 | + MACIOIDEState *m = io->opaque; | |
3439 | 3438 | IDEState *s = m->ide_if->cur_drive; |
3440 | - int ret; | |
3441 | - | |
3442 | - if (s->lba == -1) | |
3443 | - return 0; | |
3444 | - | |
3445 | - info->buf_pos = 0; | |
3439 | + int ret, len; | |
3446 | 3440 | |
3447 | - while (info->buf_pos < info->len && s->packet_transfer_size > 0) { | |
3441 | + while (io->len > 0 && | |
3442 | + s->packet_transfer_size > 0) { | |
3448 | 3443 | |
3449 | - ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size); | |
3444 | + len = s->cd_sector_size; | |
3445 | + ret = cd_read_sector(s->bs, s->lba, s->io_buffer, len); | |
3450 | 3446 | if (ret < 0) { |
3447 | + io->dma_end(io); | |
3451 | 3448 | ide_transfer_stop(s); |
3452 | 3449 | ide_atapi_io_error(s, ret); |
3453 | - return info->buf_pos; | |
3450 | + return; | |
3454 | 3451 | } |
3455 | 3452 | |
3456 | - info->buf = s->io_buffer + m->stream_index; | |
3457 | - | |
3458 | - info->buf_len = s->cd_sector_size; | |
3459 | - if (info->buf_pos + info->buf_len > info->len) | |
3460 | - info->buf_len = info->len - info->buf_pos; | |
3453 | + if (len > io->len) | |
3454 | + len = io->len; | |
3461 | 3455 | |
3462 | - cb(info); | |
3456 | + cpu_physical_memory_write(io->addr, | |
3457 | + s->io_buffer + m->stream_index, len); | |
3463 | 3458 | |
3464 | 3459 | /* db-dma can ask for 512 bytes whereas block size is 2048... */ |
3465 | 3460 | |
3466 | - m->stream_index += info->buf_len; | |
3461 | + m->stream_index += len; | |
3467 | 3462 | s->lba += m->stream_index / s->cd_sector_size; |
3468 | 3463 | m->stream_index %= s->cd_sector_size; |
3469 | 3464 | |
3470 | - info->buf_pos += info->buf_len; | |
3471 | - s->packet_transfer_size -= info->buf_len; | |
3465 | + io->len -= len; | |
3466 | + io->addr += len; | |
3467 | + s->packet_transfer_size -= len; | |
3472 | 3468 | } |
3469 | + | |
3470 | + if (io->len <= 0) | |
3471 | + io->dma_end(io); | |
3472 | + | |
3473 | 3473 | if (s->packet_transfer_size <= 0) { |
3474 | 3474 | s->status = READY_STAT | SEEK_STAT; |
3475 | 3475 | s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO |
3476 | 3476 | | ATAPI_INT_REASON_CD; |
3477 | 3477 | ide_set_irq(s); |
3478 | 3478 | } |
3479 | - | |
3480 | - return info->buf_pos; | |
3481 | 3479 | } |
3482 | 3480 | |
3483 | -static int pmac_ide_transfer(DBDMA_transfer *info, | |
3484 | - DBDMA_transfer_cb cb) | |
3481 | +static void pmac_ide_transfer(DBDMA_io *io) | |
3485 | 3482 | { |
3486 | - MACIOIDEState *m = info->opaque; | |
3483 | + MACIOIDEState *m = io->opaque; | |
3487 | 3484 | IDEState *s = m->ide_if->cur_drive; |
3488 | 3485 | int64_t sector_num; |
3489 | 3486 | int ret, n; |
3487 | + int len; | |
3490 | 3488 | |
3491 | - if (s->is_cdrom) | |
3492 | - return pmac_atapi_read(info, cb); | |
3489 | + if (s->is_cdrom) { | |
3490 | + pmac_atapi_read(io); | |
3491 | + return; | |
3492 | + } | |
3493 | 3493 | |
3494 | - info->buf = s->io_buffer; | |
3495 | - info->buf_pos = 0; | |
3496 | - while (info->buf_pos < info->len && s->nsector > 0) { | |
3494 | + while (io->len > 0 && s->nsector > 0) { | |
3497 | 3495 | |
3498 | 3496 | sector_num = ide_get_sector(s); |
3499 | 3497 | |
... | ... | @@ -3501,36 +3499,40 @@ static int pmac_ide_transfer(DBDMA_transfer *info, |
3501 | 3499 | if (n > IDE_DMA_BUF_SECTORS) |
3502 | 3500 | n = IDE_DMA_BUF_SECTORS; |
3503 | 3501 | |
3504 | - info->buf_len = n << 9; | |
3505 | - if (info->buf_pos + info->buf_len > info->len) | |
3506 | - info->buf_len = info->len - info->buf_pos; | |
3507 | - n = info->buf_len >> 9; | |
3502 | + len = n << 9; | |
3503 | + if (len > io->len) | |
3504 | + len = io->len; | |
3505 | + n = (len + 511) >> 9; | |
3508 | 3506 | |
3509 | 3507 | if (s->is_read) { |
3510 | 3508 | ret = bdrv_read(s->bs, sector_num, s->io_buffer, n); |
3511 | - if (ret == 0) | |
3512 | - cb(info); | |
3509 | + cpu_physical_memory_write(io->addr, s->io_buffer, len); | |
3513 | 3510 | } else { |
3514 | - cb(info); | |
3511 | + cpu_physical_memory_read(io->addr, s->io_buffer, len); | |
3515 | 3512 | ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); |
3516 | 3513 | } |
3517 | 3514 | |
3518 | 3515 | if (ret != 0) { |
3516 | + io->dma_end(io); | |
3519 | 3517 | ide_rw_error(s); |
3520 | - return info->buf_pos; | |
3518 | + return; | |
3521 | 3519 | } |
3522 | 3520 | |
3523 | - info->buf_pos += n << 9; | |
3521 | + io->len -= len; | |
3522 | + io->addr += len; | |
3524 | 3523 | ide_set_sector(s, sector_num + n); |
3525 | 3524 | s->nsector -= n; |
3526 | 3525 | } |
3527 | 3526 | |
3527 | + if (io->len <= 0) | |
3528 | + io->dma_end(io); | |
3529 | + | |
3528 | 3530 | if (s->nsector <= 0) { |
3529 | 3531 | s->status = READY_STAT | SEEK_STAT; |
3530 | 3532 | ide_set_irq(s); |
3531 | 3533 | } |
3532 | 3534 | |
3533 | - return info->buf_pos; | |
3535 | + return; | |
3534 | 3536 | } |
3535 | 3537 | |
3536 | 3538 | /* PowerMac IDE memory IO */ |
... | ... | @@ -3709,10 +3711,8 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq, |
3709 | 3711 | d = qemu_mallocz(sizeof(MACIOIDEState)); |
3710 | 3712 | ide_init2(d->ide_if, hd_table[0], hd_table[1], irq); |
3711 | 3713 | |
3712 | - if (dbdma) { | |
3713 | - d->dbdma = dbdma; | |
3714 | + if (dbdma) | |
3714 | 3715 | DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, d); |
3715 | - } | |
3716 | 3716 | |
3717 | 3717 | pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, |
3718 | 3718 | pmac_ide_write, d); | ... | ... |
hw/mac_dbdma.c
... | ... | @@ -158,9 +158,10 @@ typedef struct DBDMA_channel { |
158 | 158 | int channel; |
159 | 159 | uint32_t regs[DBDMA_REGS]; |
160 | 160 | qemu_irq irq; |
161 | - DBDMA_transfer io; | |
162 | - DBDMA_transfer_handler transfer_handler; | |
161 | + DBDMA_io io; | |
162 | + DBDMA_rw rw; | |
163 | 163 | dbdma_cmd current; |
164 | + int processing; | |
164 | 165 | } DBDMA_channel; |
165 | 166 | |
166 | 167 | #ifdef DEBUG_DBDMA |
... | ... | @@ -218,7 +219,7 @@ static void conditional_interrupt(DBDMA_channel *ch) |
218 | 219 | |
219 | 220 | DBDMA_DPRINTF("conditional_interrupt\n"); |
220 | 221 | |
221 | - intr = be16_to_cpu(current->command) & INTR_MASK; | |
222 | + intr = le16_to_cpu(current->command) & INTR_MASK; | |
222 | 223 | |
223 | 224 | switch(intr) { |
224 | 225 | case INTR_NEVER: /* don't interrupt */ |
... | ... | @@ -257,7 +258,7 @@ static int conditional_wait(DBDMA_channel *ch) |
257 | 258 | |
258 | 259 | DBDMA_DPRINTF("conditional_wait\n"); |
259 | 260 | |
260 | - wait = be16_to_cpu(current->command) & WAIT_MASK; | |
261 | + wait = le16_to_cpu(current->command) & WAIT_MASK; | |
261 | 262 | |
262 | 263 | switch(wait) { |
263 | 264 | case WAIT_NEVER: /* don't wait */ |
... | ... | @@ -318,7 +319,7 @@ static void conditional_branch(DBDMA_channel *ch) |
318 | 319 | |
319 | 320 | /* check if we must branch */ |
320 | 321 | |
321 | - br = be16_to_cpu(current->command) & BR_MASK; | |
322 | + br = le16_to_cpu(current->command) & BR_MASK; | |
322 | 323 | |
323 | 324 | switch(br) { |
324 | 325 | case BR_NEVER: /* don't branch */ |
... | ... | @@ -352,38 +353,35 @@ static void conditional_branch(DBDMA_channel *ch) |
352 | 353 | } |
353 | 354 | } |
354 | 355 | |
355 | -static int dbdma_read_memory(DBDMA_transfer *io) | |
356 | -{ | |
357 | - DBDMA_channel *ch = io->channel; | |
358 | - dbdma_cmd *current = &ch->current; | |
359 | - | |
360 | - DBDMA_DPRINTF("DBDMA_read_memory\n"); | |
361 | - | |
362 | - cpu_physical_memory_read(le32_to_cpu(current->phy_addr) + io->buf_pos, | |
363 | - io->buf, io->buf_len); | |
364 | - | |
365 | - return io->buf_len; | |
366 | -} | |
356 | +static QEMUBH *dbdma_bh; | |
357 | +static void channel_run(DBDMA_channel *ch); | |
367 | 358 | |
368 | -static int dbdma_write_memory(DBDMA_transfer *io) | |
359 | +static void dbdma_end(DBDMA_io *io) | |
369 | 360 | { |
370 | 361 | DBDMA_channel *ch = io->channel; |
371 | 362 | dbdma_cmd *current = &ch->current; |
372 | 363 | |
373 | - DBDMA_DPRINTF("DBDMA_write_memory\n"); | |
364 | + if (conditional_wait(ch)) | |
365 | + goto wait; | |
374 | 366 | |
375 | - cpu_physical_memory_write(le32_to_cpu(current->phy_addr) + io->buf_pos, | |
376 | - io->buf, io->buf_len); | |
367 | + current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); | |
368 | + current->res_count = cpu_to_le16(be32_to_cpu(io->len)); | |
369 | + dbdma_cmdptr_save(ch); | |
370 | + ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH); | |
371 | + | |
372 | + conditional_interrupt(ch); | |
373 | + conditional_branch(ch); | |
377 | 374 | |
378 | - return io->buf_len; | |
375 | +wait: | |
376 | + ch->processing = 0; | |
377 | + if ((ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN)) && | |
378 | + (ch->regs[DBDMA_STATUS] & cpu_to_be32(ACTIVE))) | |
379 | + channel_run(ch); | |
379 | 380 | } |
380 | 381 | |
381 | -static int start_output(DBDMA_channel *ch, int key, uint32_t addr, | |
382 | +static void start_output(DBDMA_channel *ch, int key, uint32_t addr, | |
382 | 383 | uint16_t req_count, int is_last) |
383 | 384 | { |
384 | - dbdma_cmd *current = &ch->current; | |
385 | - uint32_t n; | |
386 | - | |
387 | 385 | DBDMA_DPRINTF("start_output\n"); |
388 | 386 | |
389 | 387 | /* KEY_REGS, KEY_DEVICE and KEY_STREAM |
... | ... | @@ -393,35 +391,21 @@ static int start_output(DBDMA_channel *ch, int key, uint32_t addr, |
393 | 391 | DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key); |
394 | 392 | if (!addr || key > KEY_STREAM3) { |
395 | 393 | kill_channel(ch); |
396 | - return 0; | |
394 | + return; | |
397 | 395 | } |
398 | 396 | |
399 | - ch->io.buf = NULL; | |
400 | - ch->io.buf_pos = 0; | |
401 | - ch->io.buf_len = 0; | |
397 | + ch->io.addr = addr; | |
402 | 398 | ch->io.len = req_count; |
403 | 399 | ch->io.is_last = is_last; |
404 | - n = ch->transfer_handler(&ch->io, dbdma_read_memory); | |
405 | - | |
406 | - if (conditional_wait(ch)) | |
407 | - return 1; | |
408 | - | |
409 | - current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); | |
410 | - current->res_count = cpu_to_le16(0); | |
411 | - dbdma_cmdptr_save(ch); | |
412 | - | |
413 | - conditional_interrupt(ch); | |
414 | - conditional_branch(ch); | |
415 | - | |
416 | - return 1; | |
400 | + ch->io.dma_end = dbdma_end; | |
401 | + ch->io.is_dma_out = 1; | |
402 | + ch->processing = 1; | |
403 | + ch->rw(&ch->io); | |
417 | 404 | } |
418 | 405 | |
419 | -static int start_input(DBDMA_channel *ch, int key, uint32_t addr, | |
406 | +static void start_input(DBDMA_channel *ch, int key, uint32_t addr, | |
420 | 407 | uint16_t req_count, int is_last) |
421 | 408 | { |
422 | - dbdma_cmd *current = &ch->current; | |
423 | - uint32_t n; | |
424 | - | |
425 | 409 | DBDMA_DPRINTF("start_input\n"); |
426 | 410 | |
427 | 411 | /* KEY_REGS, KEY_DEVICE and KEY_STREAM |
... | ... | @@ -430,30 +414,19 @@ static int start_input(DBDMA_channel *ch, int key, uint32_t addr, |
430 | 414 | |
431 | 415 | if (!addr || key > KEY_STREAM3) { |
432 | 416 | kill_channel(ch); |
433 | - return 0; | |
417 | + return; | |
434 | 418 | } |
435 | 419 | |
436 | - ch->io.buf = NULL; | |
437 | - ch->io.buf_pos = 0; | |
438 | - ch->io.buf_len = 0; | |
420 | + ch->io.addr = addr; | |
439 | 421 | ch->io.len = req_count; |
440 | 422 | ch->io.is_last = is_last; |
441 | - n = ch->transfer_handler(&ch->io, dbdma_write_memory); | |
442 | - | |
443 | - if (conditional_wait(ch)) | |
444 | - return 1; | |
445 | - | |
446 | - current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); | |
447 | - current->res_count = cpu_to_le16(0); | |
448 | - dbdma_cmdptr_save(ch); | |
449 | - | |
450 | - conditional_interrupt(ch); | |
451 | - conditional_branch(ch); | |
452 | - | |
453 | - return 1; | |
423 | + ch->io.dma_end = dbdma_end; | |
424 | + ch->io.is_dma_out = 0; | |
425 | + ch->processing = 1; | |
426 | + ch->rw(&ch->io); | |
454 | 427 | } |
455 | 428 | |
456 | -static int load_word(DBDMA_channel *ch, int key, uint32_t addr, | |
429 | +static void load_word(DBDMA_channel *ch, int key, uint32_t addr, | |
457 | 430 | uint16_t len) |
458 | 431 | { |
459 | 432 | dbdma_cmd *current = &ch->current; |
... | ... | @@ -466,7 +439,7 @@ static int load_word(DBDMA_channel *ch, int key, uint32_t addr, |
466 | 439 | if (key != KEY_SYSTEM) { |
467 | 440 | printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key); |
468 | 441 | kill_channel(ch); |
469 | - return 0; | |
442 | + return; | |
470 | 443 | } |
471 | 444 | |
472 | 445 | cpu_physical_memory_read(addr, (uint8_t*)&val, len); |
... | ... | @@ -479,18 +452,20 @@ static int load_word(DBDMA_channel *ch, int key, uint32_t addr, |
479 | 452 | current->cmd_dep = val; |
480 | 453 | |
481 | 454 | if (conditional_wait(ch)) |
482 | - return 1; | |
455 | + goto wait; | |
483 | 456 | |
484 | 457 | current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); |
485 | 458 | dbdma_cmdptr_save(ch); |
459 | + ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH); | |
486 | 460 | |
487 | 461 | conditional_interrupt(ch); |
488 | 462 | next(ch); |
489 | 463 | |
490 | - return 1; | |
464 | +wait: | |
465 | + qemu_bh_schedule(dbdma_bh); | |
491 | 466 | } |
492 | 467 | |
493 | -static int store_word(DBDMA_channel *ch, int key, uint32_t addr, | |
468 | +static void store_word(DBDMA_channel *ch, int key, uint32_t addr, | |
494 | 469 | uint16_t len) |
495 | 470 | { |
496 | 471 | dbdma_cmd *current = &ch->current; |
... | ... | @@ -503,7 +478,7 @@ static int store_word(DBDMA_channel *ch, int key, uint32_t addr, |
503 | 478 | if (key != KEY_SYSTEM) { |
504 | 479 | printf("DBDMA: STORE_WORD, unimplemented key %x\n", key); |
505 | 480 | kill_channel(ch); |
506 | - return 0; | |
481 | + return; | |
507 | 482 | } |
508 | 483 | |
509 | 484 | val = current->cmd_dep; |
... | ... | @@ -515,23 +490,25 @@ static int store_word(DBDMA_channel *ch, int key, uint32_t addr, |
515 | 490 | cpu_physical_memory_write(addr, (uint8_t*)&val, len); |
516 | 491 | |
517 | 492 | if (conditional_wait(ch)) |
518 | - return 1; | |
493 | + goto wait; | |
519 | 494 | |
520 | 495 | current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); |
521 | 496 | dbdma_cmdptr_save(ch); |
497 | + ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH); | |
522 | 498 | |
523 | 499 | conditional_interrupt(ch); |
524 | 500 | next(ch); |
525 | 501 | |
526 | - return 1; | |
502 | +wait: | |
503 | + qemu_bh_schedule(dbdma_bh); | |
527 | 504 | } |
528 | 505 | |
529 | -static int nop(DBDMA_channel *ch) | |
506 | +static void nop(DBDMA_channel *ch) | |
530 | 507 | { |
531 | 508 | dbdma_cmd *current = &ch->current; |
532 | 509 | |
533 | 510 | if (conditional_wait(ch)) |
534 | - return 1; | |
511 | + goto wait; | |
535 | 512 | |
536 | 513 | current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); |
537 | 514 | dbdma_cmdptr_save(ch); |
... | ... | @@ -539,19 +516,18 @@ static int nop(DBDMA_channel *ch) |
539 | 516 | conditional_interrupt(ch); |
540 | 517 | conditional_branch(ch); |
541 | 518 | |
542 | - return 1; | |
519 | +wait: | |
520 | + qemu_bh_schedule(dbdma_bh); | |
543 | 521 | } |
544 | 522 | |
545 | -static int stop(DBDMA_channel *ch) | |
523 | +static void stop(DBDMA_channel *ch) | |
546 | 524 | { |
547 | - ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD)); | |
525 | + ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD|FLUSH)); | |
548 | 526 | |
549 | 527 | /* the stop command does not increment command pointer */ |
550 | - | |
551 | - return 0; | |
552 | 528 | } |
553 | 529 | |
554 | -static int channel_run(DBDMA_channel *ch) | |
530 | +static void channel_run(DBDMA_channel *ch) | |
555 | 531 | { |
556 | 532 | dbdma_cmd *current = &ch->current; |
557 | 533 | uint16_t cmd, key; |
... | ... | @@ -569,10 +545,12 @@ static int channel_run(DBDMA_channel *ch) |
569 | 545 | |
570 | 546 | switch (cmd) { |
571 | 547 | case DBDMA_NOP: |
572 | - return nop(ch); | |
548 | + nop(ch); | |
549 | + return; | |
573 | 550 | |
574 | 551 | case DBDMA_STOP: |
575 | - return stop(ch); | |
552 | + stop(ch); | |
553 | + return; | |
576 | 554 | } |
577 | 555 | |
578 | 556 | key = le16_to_cpu(current->command) & 0x0700; |
... | ... | @@ -582,21 +560,25 @@ static int channel_run(DBDMA_channel *ch) |
582 | 560 | if (key == KEY_STREAM4) { |
583 | 561 | printf("command %x, invalid key 4\n", cmd); |
584 | 562 | kill_channel(ch); |
585 | - return 0; | |
563 | + return; | |
586 | 564 | } |
587 | 565 | |
588 | 566 | switch (cmd) { |
589 | 567 | case OUTPUT_MORE: |
590 | - return start_output(ch, key, phy_addr, req_count, 0); | |
568 | + start_output(ch, key, phy_addr, req_count, 0); | |
569 | + return; | |
591 | 570 | |
592 | 571 | case OUTPUT_LAST: |
593 | - return start_output(ch, key, phy_addr, req_count, 1); | |
572 | + start_output(ch, key, phy_addr, req_count, 1); | |
573 | + return; | |
594 | 574 | |
595 | 575 | case INPUT_MORE: |
596 | - return start_input(ch, key, phy_addr, req_count, 0); | |
576 | + start_input(ch, key, phy_addr, req_count, 0); | |
577 | + return; | |
597 | 578 | |
598 | 579 | case INPUT_LAST: |
599 | - return start_input(ch, key, phy_addr, req_count, 1); | |
580 | + start_input(ch, key, phy_addr, req_count, 1); | |
581 | + return; | |
600 | 582 | } |
601 | 583 | |
602 | 584 | if (key < KEY_REGS) { |
... | ... | @@ -620,35 +602,24 @@ static int channel_run(DBDMA_channel *ch) |
620 | 602 | |
621 | 603 | switch (cmd) { |
622 | 604 | case LOAD_WORD: |
623 | - return load_word(ch, key, phy_addr, req_count); | |
605 | + load_word(ch, key, phy_addr, req_count); | |
606 | + return; | |
624 | 607 | |
625 | 608 | case STORE_WORD: |
626 | - return store_word(ch, key, phy_addr, req_count); | |
609 | + store_word(ch, key, phy_addr, req_count); | |
610 | + return; | |
627 | 611 | } |
628 | - | |
629 | - return 0; | |
630 | 612 | } |
631 | 613 | |
632 | -static QEMUBH *dbdma_bh; | |
633 | - | |
634 | 614 | static void DBDMA_run (DBDMA_channel *ch) |
635 | 615 | { |
636 | 616 | int channel; |
637 | - int rearm = 0; | |
638 | 617 | |
639 | 618 | for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) { |
640 | 619 | uint32_t status = be32_to_cpu(ch->regs[DBDMA_STATUS]); |
641 | - if ((status & RUN) && (status & ACTIVE)) { | |
642 | - if (status & FLUSH) | |
643 | - while (channel_run(ch)); | |
644 | - else if (channel_run(ch)) | |
645 | - rearm = 1; | |
646 | - } | |
647 | - ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH); | |
620 | + if (!ch->processing && (status & RUN) && (status & ACTIVE)) | |
621 | + channel_run(ch); | |
648 | 622 | } |
649 | - | |
650 | - if (rearm) | |
651 | - qemu_bh_schedule_idle(dbdma_bh); | |
652 | 623 | } |
653 | 624 | |
654 | 625 | static void DBDMA_run_bh(void *opaque) |
... | ... | @@ -661,7 +632,7 @@ static void DBDMA_run_bh(void *opaque) |
661 | 632 | } |
662 | 633 | |
663 | 634 | void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, |
664 | - DBDMA_transfer_handler transfer_handler, | |
635 | + DBDMA_rw rw, | |
665 | 636 | void *opaque) |
666 | 637 | { |
667 | 638 | DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan; |
... | ... | @@ -670,7 +641,7 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, |
670 | 641 | |
671 | 642 | ch->irq = irq; |
672 | 643 | ch->channel = nchan; |
673 | - ch->transfer_handler = transfer_handler; | |
644 | + ch->rw = rw; | |
674 | 645 | ch->io.opaque = opaque; |
675 | 646 | ch->io.channel = ch; |
676 | 647 | } |
... | ... | @@ -714,11 +685,8 @@ dbdma_control_write(DBDMA_channel *ch) |
714 | 685 | |
715 | 686 | ch->regs[DBDMA_STATUS] = cpu_to_be32(status); |
716 | 687 | |
717 | - if (status & ACTIVE) { | |
718 | - qemu_bh_schedule_idle(dbdma_bh); | |
719 | - if (status & FLUSH) | |
720 | - DBDMA_schedule(); | |
721 | - } | |
688 | + if (status & ACTIVE) | |
689 | + qemu_bh_schedule(dbdma_bh); | |
722 | 690 | } |
723 | 691 | |
724 | 692 | static void dbdma_writel (void *opaque, | ... | ... |
hw/mac_dbdma.h
... | ... | @@ -20,22 +20,23 @@ |
20 | 20 | * THE SOFTWARE. |
21 | 21 | */ |
22 | 22 | |
23 | -typedef struct { | |
23 | +typedef struct DBDMA_io DBDMA_io; | |
24 | + | |
25 | +typedef void (*DBDMA_rw)(DBDMA_io *io); | |
26 | +typedef void (*DBDMA_end)(DBDMA_io *io); | |
27 | +struct DBDMA_io { | |
24 | 28 | void *opaque; |
25 | 29 | void *channel; |
30 | + target_phys_addr_t addr; | |
26 | 31 | int len; |
27 | 32 | int is_last; |
28 | - void *buf; | |
29 | - int buf_pos; | |
30 | - int buf_len; | |
31 | -} DBDMA_transfer; | |
33 | + int is_dma_out; | |
34 | + DBDMA_end dma_end; | |
35 | +}; | |
32 | 36 | |
33 | -typedef int (*DBDMA_transfer_cb)(DBDMA_transfer *info); | |
34 | -typedef int (*DBDMA_transfer_handler)(DBDMA_transfer *info, | |
35 | - DBDMA_transfer_cb cb); | |
36 | 37 | |
37 | 38 | void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, |
38 | - DBDMA_transfer_handler transfer_handler, | |
39 | + DBDMA_rw rw, | |
39 | 40 | void *opaque); |
40 | 41 | void DBDMA_schedule(void); |
41 | 42 | void* DBDMA_init (int *dbdma_mem_index); | ... | ... |