Commit b42ec42d4306e6da1e72a32167262343025116ed

Authored by aurel32
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
hw/ide.c
@@ -3429,71 +3429,69 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, @@ -3429,71 +3429,69 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3429 3429
3430 typedef struct MACIOIDEState { 3430 typedef struct MACIOIDEState {
3431 IDEState ide_if[2]; 3431 IDEState ide_if[2];
3432 - void *dbdma;  
3433 int stream_index; 3432 int stream_index;
3434 } MACIOIDEState; 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 IDEState *s = m->ide_if->cur_drive; 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 if (ret < 0) { 3446 if (ret < 0) {
  3447 + io->dma_end(io);
3451 ide_transfer_stop(s); 3448 ide_transfer_stop(s);
3452 ide_atapi_io_error(s, ret); 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 /* db-dma can ask for 512 bytes whereas block size is 2048... */ 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 s->lba += m->stream_index / s->cd_sector_size; 3462 s->lba += m->stream_index / s->cd_sector_size;
3468 m->stream_index %= s->cd_sector_size; 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 if (s->packet_transfer_size <= 0) { 3473 if (s->packet_transfer_size <= 0) {
3474 s->status = READY_STAT | SEEK_STAT; 3474 s->status = READY_STAT | SEEK_STAT;
3475 s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO 3475 s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO
3476 | ATAPI_INT_REASON_CD; 3476 | ATAPI_INT_REASON_CD;
3477 ide_set_irq(s); 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 IDEState *s = m->ide_if->cur_drive; 3484 IDEState *s = m->ide_if->cur_drive;
3488 int64_t sector_num; 3485 int64_t sector_num;
3489 int ret, n; 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 sector_num = ide_get_sector(s); 3496 sector_num = ide_get_sector(s);
3499 3497
@@ -3501,36 +3499,40 @@ static int pmac_ide_transfer(DBDMA_transfer *info, @@ -3501,36 +3499,40 @@ static int pmac_ide_transfer(DBDMA_transfer *info,
3501 if (n > IDE_DMA_BUF_SECTORS) 3499 if (n > IDE_DMA_BUF_SECTORS)
3502 n = IDE_DMA_BUF_SECTORS; 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 if (s->is_read) { 3507 if (s->is_read) {
3510 ret = bdrv_read(s->bs, sector_num, s->io_buffer, n); 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 } else { 3510 } else {
3514 - cb(info); 3511 + cpu_physical_memory_read(io->addr, s->io_buffer, len);
3515 ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); 3512 ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
3516 } 3513 }
3517 3514
3518 if (ret != 0) { 3515 if (ret != 0) {
  3516 + io->dma_end(io);
3519 ide_rw_error(s); 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 ide_set_sector(s, sector_num + n); 3523 ide_set_sector(s, sector_num + n);
3525 s->nsector -= n; 3524 s->nsector -= n;
3526 } 3525 }
3527 3526
  3527 + if (io->len <= 0)
  3528 + io->dma_end(io);
  3529 +
3528 if (s->nsector <= 0) { 3530 if (s->nsector <= 0) {
3529 s->status = READY_STAT | SEEK_STAT; 3531 s->status = READY_STAT | SEEK_STAT;
3530 ide_set_irq(s); 3532 ide_set_irq(s);
3531 } 3533 }
3532 3534
3533 - return info->buf_pos; 3535 + return;
3534 } 3536 }
3535 3537
3536 /* PowerMac IDE memory IO */ 3538 /* PowerMac IDE memory IO */
@@ -3709,10 +3711,8 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq, @@ -3709,10 +3711,8 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq,
3709 d = qemu_mallocz(sizeof(MACIOIDEState)); 3711 d = qemu_mallocz(sizeof(MACIOIDEState));
3710 ide_init2(d->ide_if, hd_table[0], hd_table[1], irq); 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 DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, d); 3715 DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, d);
3715 - }  
3716 3716
3717 pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, 3717 pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
3718 pmac_ide_write, d); 3718 pmac_ide_write, d);
hw/mac_dbdma.c
@@ -158,9 +158,10 @@ typedef struct DBDMA_channel { @@ -158,9 +158,10 @@ typedef struct DBDMA_channel {
158 int channel; 158 int channel;
159 uint32_t regs[DBDMA_REGS]; 159 uint32_t regs[DBDMA_REGS];
160 qemu_irq irq; 160 qemu_irq irq;
161 - DBDMA_transfer io;  
162 - DBDMA_transfer_handler transfer_handler; 161 + DBDMA_io io;
  162 + DBDMA_rw rw;
163 dbdma_cmd current; 163 dbdma_cmd current;
  164 + int processing;
164 } DBDMA_channel; 165 } DBDMA_channel;
165 166
166 #ifdef DEBUG_DBDMA 167 #ifdef DEBUG_DBDMA
@@ -218,7 +219,7 @@ static void conditional_interrupt(DBDMA_channel *ch) @@ -218,7 +219,7 @@ static void conditional_interrupt(DBDMA_channel *ch)
218 219
219 DBDMA_DPRINTF("conditional_interrupt\n"); 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 switch(intr) { 224 switch(intr) {
224 case INTR_NEVER: /* don't interrupt */ 225 case INTR_NEVER: /* don't interrupt */
@@ -257,7 +258,7 @@ static int conditional_wait(DBDMA_channel *ch) @@ -257,7 +258,7 @@ static int conditional_wait(DBDMA_channel *ch)
257 258
258 DBDMA_DPRINTF("conditional_wait\n"); 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 switch(wait) { 263 switch(wait) {
263 case WAIT_NEVER: /* don't wait */ 264 case WAIT_NEVER: /* don't wait */
@@ -318,7 +319,7 @@ static void conditional_branch(DBDMA_channel *ch) @@ -318,7 +319,7 @@ static void conditional_branch(DBDMA_channel *ch)
318 319
319 /* check if we must branch */ 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 switch(br) { 324 switch(br) {
324 case BR_NEVER: /* don't branch */ 325 case BR_NEVER: /* don't branch */
@@ -352,38 +353,35 @@ static void conditional_branch(DBDMA_channel *ch) @@ -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 DBDMA_channel *ch = io->channel; 361 DBDMA_channel *ch = io->channel;
371 dbdma_cmd *current = &ch->current; 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 uint16_t req_count, int is_last) 383 uint16_t req_count, int is_last)
383 { 384 {
384 - dbdma_cmd *current = &ch->current;  
385 - uint32_t n;  
386 -  
387 DBDMA_DPRINTF("start_output\n"); 385 DBDMA_DPRINTF("start_output\n");
388 386
389 /* KEY_REGS, KEY_DEVICE and KEY_STREAM 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,35 +391,21 @@ static int start_output(DBDMA_channel *ch, int key, uint32_t addr,
393 DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key); 391 DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
394 if (!addr || key > KEY_STREAM3) { 392 if (!addr || key > KEY_STREAM3) {
395 kill_channel(ch); 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 ch->io.len = req_count; 398 ch->io.len = req_count;
403 ch->io.is_last = is_last; 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 uint16_t req_count, int is_last) 407 uint16_t req_count, int is_last)
421 { 408 {
422 - dbdma_cmd *current = &ch->current;  
423 - uint32_t n;  
424 -  
425 DBDMA_DPRINTF("start_input\n"); 409 DBDMA_DPRINTF("start_input\n");
426 410
427 /* KEY_REGS, KEY_DEVICE and KEY_STREAM 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,30 +414,19 @@ static int start_input(DBDMA_channel *ch, int key, uint32_t addr,
430 414
431 if (!addr || key > KEY_STREAM3) { 415 if (!addr || key > KEY_STREAM3) {
432 kill_channel(ch); 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 ch->io.len = req_count; 421 ch->io.len = req_count;
440 ch->io.is_last = is_last; 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 uint16_t len) 430 uint16_t len)
458 { 431 {
459 dbdma_cmd *current = &ch->current; 432 dbdma_cmd *current = &ch->current;
@@ -466,7 +439,7 @@ static int load_word(DBDMA_channel *ch, int key, uint32_t addr, @@ -466,7 +439,7 @@ static int load_word(DBDMA_channel *ch, int key, uint32_t addr,
466 if (key != KEY_SYSTEM) { 439 if (key != KEY_SYSTEM) {
467 printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key); 440 printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key);
468 kill_channel(ch); 441 kill_channel(ch);
469 - return 0; 442 + return;
470 } 443 }
471 444
472 cpu_physical_memory_read(addr, (uint8_t*)&val, len); 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,18 +452,20 @@ static int load_word(DBDMA_channel *ch, int key, uint32_t addr,
479 current->cmd_dep = val; 452 current->cmd_dep = val;
480 453
481 if (conditional_wait(ch)) 454 if (conditional_wait(ch))
482 - return 1; 455 + goto wait;
483 456
484 current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); 457 current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
485 dbdma_cmdptr_save(ch); 458 dbdma_cmdptr_save(ch);
  459 + ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
486 460
487 conditional_interrupt(ch); 461 conditional_interrupt(ch);
488 next(ch); 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 uint16_t len) 469 uint16_t len)
495 { 470 {
496 dbdma_cmd *current = &ch->current; 471 dbdma_cmd *current = &ch->current;
@@ -503,7 +478,7 @@ static int store_word(DBDMA_channel *ch, int key, uint32_t addr, @@ -503,7 +478,7 @@ static int store_word(DBDMA_channel *ch, int key, uint32_t addr,
503 if (key != KEY_SYSTEM) { 478 if (key != KEY_SYSTEM) {
504 printf("DBDMA: STORE_WORD, unimplemented key %x\n", key); 479 printf("DBDMA: STORE_WORD, unimplemented key %x\n", key);
505 kill_channel(ch); 480 kill_channel(ch);
506 - return 0; 481 + return;
507 } 482 }
508 483
509 val = current->cmd_dep; 484 val = current->cmd_dep;
@@ -515,23 +490,25 @@ static int store_word(DBDMA_channel *ch, int key, uint32_t addr, @@ -515,23 +490,25 @@ static int store_word(DBDMA_channel *ch, int key, uint32_t addr,
515 cpu_physical_memory_write(addr, (uint8_t*)&val, len); 490 cpu_physical_memory_write(addr, (uint8_t*)&val, len);
516 491
517 if (conditional_wait(ch)) 492 if (conditional_wait(ch))
518 - return 1; 493 + goto wait;
519 494
520 current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); 495 current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
521 dbdma_cmdptr_save(ch); 496 dbdma_cmdptr_save(ch);
  497 + ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
522 498
523 conditional_interrupt(ch); 499 conditional_interrupt(ch);
524 next(ch); 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 dbdma_cmd *current = &ch->current; 508 dbdma_cmd *current = &ch->current;
532 509
533 if (conditional_wait(ch)) 510 if (conditional_wait(ch))
534 - return 1; 511 + goto wait;
535 512
536 current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); 513 current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
537 dbdma_cmdptr_save(ch); 514 dbdma_cmdptr_save(ch);
@@ -539,19 +516,18 @@ static int nop(DBDMA_channel *ch) @@ -539,19 +516,18 @@ static int nop(DBDMA_channel *ch)
539 conditional_interrupt(ch); 516 conditional_interrupt(ch);
540 conditional_branch(ch); 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 /* the stop command does not increment command pointer */ 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 dbdma_cmd *current = &ch->current; 532 dbdma_cmd *current = &ch->current;
557 uint16_t cmd, key; 533 uint16_t cmd, key;
@@ -569,10 +545,12 @@ static int channel_run(DBDMA_channel *ch) @@ -569,10 +545,12 @@ static int channel_run(DBDMA_channel *ch)
569 545
570 switch (cmd) { 546 switch (cmd) {
571 case DBDMA_NOP: 547 case DBDMA_NOP:
572 - return nop(ch); 548 + nop(ch);
  549 + return;
573 550
574 case DBDMA_STOP: 551 case DBDMA_STOP:
575 - return stop(ch); 552 + stop(ch);
  553 + return;
576 } 554 }
577 555
578 key = le16_to_cpu(current->command) & 0x0700; 556 key = le16_to_cpu(current->command) & 0x0700;
@@ -582,21 +560,25 @@ static int channel_run(DBDMA_channel *ch) @@ -582,21 +560,25 @@ static int channel_run(DBDMA_channel *ch)
582 if (key == KEY_STREAM4) { 560 if (key == KEY_STREAM4) {
583 printf("command %x, invalid key 4\n", cmd); 561 printf("command %x, invalid key 4\n", cmd);
584 kill_channel(ch); 562 kill_channel(ch);
585 - return 0; 563 + return;
586 } 564 }
587 565
588 switch (cmd) { 566 switch (cmd) {
589 case OUTPUT_MORE: 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 case OUTPUT_LAST: 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 case INPUT_MORE: 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 case INPUT_LAST: 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 if (key < KEY_REGS) { 584 if (key < KEY_REGS) {
@@ -620,35 +602,24 @@ static int channel_run(DBDMA_channel *ch) @@ -620,35 +602,24 @@ static int channel_run(DBDMA_channel *ch)
620 602
621 switch (cmd) { 603 switch (cmd) {
622 case LOAD_WORD: 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 case STORE_WORD: 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 static void DBDMA_run (DBDMA_channel *ch) 614 static void DBDMA_run (DBDMA_channel *ch)
635 { 615 {
636 int channel; 616 int channel;
637 - int rearm = 0;  
638 617
639 for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) { 618 for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {
640 uint32_t status = be32_to_cpu(ch->regs[DBDMA_STATUS]); 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 static void DBDMA_run_bh(void *opaque) 625 static void DBDMA_run_bh(void *opaque)
@@ -661,7 +632,7 @@ static void DBDMA_run_bh(void *opaque) @@ -661,7 +632,7 @@ static void DBDMA_run_bh(void *opaque)
661 } 632 }
662 633
663 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, 634 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
664 - DBDMA_transfer_handler transfer_handler, 635 + DBDMA_rw rw,
665 void *opaque) 636 void *opaque)
666 { 637 {
667 DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan; 638 DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan;
@@ -670,7 +641,7 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, @@ -670,7 +641,7 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
670 641
671 ch->irq = irq; 642 ch->irq = irq;
672 ch->channel = nchan; 643 ch->channel = nchan;
673 - ch->transfer_handler = transfer_handler; 644 + ch->rw = rw;
674 ch->io.opaque = opaque; 645 ch->io.opaque = opaque;
675 ch->io.channel = ch; 646 ch->io.channel = ch;
676 } 647 }
@@ -714,11 +685,8 @@ dbdma_control_write(DBDMA_channel *ch) @@ -714,11 +685,8 @@ dbdma_control_write(DBDMA_channel *ch)
714 685
715 ch->regs[DBDMA_STATUS] = cpu_to_be32(status); 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 static void dbdma_writel (void *opaque, 692 static void dbdma_writel (void *opaque,
hw/mac_dbdma.h
@@ -20,22 +20,23 @@ @@ -20,22 +20,23 @@
20 * THE SOFTWARE. 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 void *opaque; 28 void *opaque;
25 void *channel; 29 void *channel;
  30 + target_phys_addr_t addr;
26 int len; 31 int len;
27 int is_last; 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 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, 38 void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
38 - DBDMA_transfer_handler transfer_handler, 39 + DBDMA_rw rw,
39 void *opaque); 40 void *opaque);
40 void DBDMA_schedule(void); 41 void DBDMA_schedule(void);
41 void* DBDMA_init (int *dbdma_mem_index); 42 void* DBDMA_init (int *dbdma_mem_index);