Commit c968ef8df5052100683a4bb375078e46d96203a7

Authored by edgar_igl
1 parent 31c18d87

ETRAX-FS: Process outgoing DMA channels until EOL.

For outgoing DMA channels, keep processing descriptors until hitting end
of list.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5553 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 69 additions and 67 deletions
hw/etraxfs_dma.c
... ... @@ -393,72 +393,74 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c)
393 393 uint32_t saved_data_buf;
394 394 unsigned char buf[2 * 1024];
395 395  
396   - if (ctrl->channels[c].eol == 1)
397   - return;
398   -
399   - saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
400   -
401   - D(printf("ch=%d buf=%x after=%x saved_data_buf=%x\n",
402   - c,
403   - (uint32_t)ctrl->channels[c].current_d.buf,
404   - (uint32_t)ctrl->channels[c].current_d.after,
405   - saved_data_buf));
406   -
407   - len = (uint32_t)(unsigned long) ctrl->channels[c].current_d.after;
408   - len -= saved_data_buf;
409   -
410   - if (len > sizeof buf)
411   - len = sizeof buf;
412   - cpu_physical_memory_read (saved_data_buf, buf, len);
413   -
414   - D(printf("channel %d pushes %x %u bytes\n", c,
415   - saved_data_buf, len));
416   -
417   - if (ctrl->channels[c].client->client.push)
418   - ctrl->channels[c].client->client.push(
419   - ctrl->channels[c].client->client.opaque, buf, len);
420   - else
421   - printf("WARNING: DMA ch%d dataloss, no attached client.\n", c);
422   -
423   - saved_data_buf += len;
424   -
425   - if (saved_data_buf ==
426   - (uint32_t)(unsigned long)ctrl->channels[c].current_d.after) {
427   - /* Done. Step to next. */
428   - if (ctrl->channels[c].current_d.out_eop) {
429   - /* TODO: signal eop to the client. */
430   - D(printf("signal eop\n"));
  396 + while (ctrl->channels[c].eol != 1) {
  397 + saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
  398 +
  399 + D(printf("ch=%d buf=%x after=%x saved_data_buf=%x\n",
  400 + c,
  401 + (uint32_t)ctrl->channels[c].current_d.buf,
  402 + (uint32_t)ctrl->channels[c].current_d.after,
  403 + saved_data_buf));
  404 +
  405 + len = (uint32_t)ctrl->channels[c].current_d.after;
  406 + len -= saved_data_buf;
  407 +
  408 + if (len > sizeof buf)
  409 + len = sizeof buf;
  410 + cpu_physical_memory_read (saved_data_buf, buf, len);
  411 +
  412 + D(printf("channel %d pushes %x %u bytes\n", c,
  413 + saved_data_buf, len));
  414 +
  415 + if (ctrl->channels[c].client->client.push)
  416 + ctrl->channels[c].client->client.push(
  417 + ctrl->channels[c].client->client.opaque,
  418 + buf, len);
  419 + else
  420 + printf("WARNING: DMA ch%d dataloss,"
  421 + " no attached client.\n", c);
  422 +
  423 + saved_data_buf += len;
  424 +
  425 + if (saved_data_buf ==
  426 + (uint32_t)ctrl->channels[c].current_d.after) {
  427 + /* Done. Step to next. */
  428 + if (ctrl->channels[c].current_d.out_eop) {
  429 + /* TODO: signal eop to the client. */
  430 + D(printf("signal eop\n"));
  431 + }
  432 + if (ctrl->channels[c].current_d.intr) {
  433 + /* TODO: signal eop to the client. */
  434 + /* data intr. */
  435 + D(printf("signal intr\n"));
  436 + ctrl->channels[c].regs[R_INTR] |= (1 << 2);
  437 + channel_update_irq(ctrl, c);
  438 + }
  439 + if (ctrl->channels[c].current_d.eol) {
  440 + D(printf("channel %d EOL\n", c));
  441 + ctrl->channels[c].eol = 1;
  442 +
  443 + /* Mark the context as disabled. */
  444 + ctrl->channels[c].current_c.dis = 1;
  445 + channel_store_c(ctrl, c);
  446 +
  447 + channel_stop(ctrl, c);
  448 + } else {
  449 + ctrl->channels[c].regs[RW_SAVED_DATA] =
  450 + (uint32_t)ctrl->channels[c].current_d.next;
  451 + /* Load new descriptor. */
  452 + channel_load_d(ctrl, c);
  453 + saved_data_buf = (uint32_t)(unsigned long)
  454 + ctrl->channels[c].current_d.buf;
  455 + }
  456 +
  457 + channel_store_d(ctrl, c);
  458 + ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
  459 + saved_data_buf;
  460 + D(dump_d(c, &ctrl->channels[c].current_d));
431 461 }
432   - if (ctrl->channels[c].current_d.intr) {
433   - /* TODO: signal eop to the client. */
434   - /* data intr. */
435   - D(printf("signal intr\n"));
436   - ctrl->channels[c].regs[R_INTR] |= (1 << 2);
437   - channel_update_irq(ctrl, c);
438   - }
439   - if (ctrl->channels[c].current_d.eol) {
440   - D(printf("channel %d EOL\n", c));
441   - ctrl->channels[c].eol = 1;
442   -
443   - /* Mark the context as disabled. */
444   - ctrl->channels[c].current_c.dis = 1;
445   - channel_store_c(ctrl, c);
446   -
447   - channel_stop(ctrl, c);
448   - } else {
449   - ctrl->channels[c].regs[RW_SAVED_DATA] =
450   - (uint32_t)(unsigned long) ctrl->channels[c].current_d.next;
451   - /* Load new descriptor. */
452   - channel_load_d(ctrl, c);
453   - saved_data_buf = (uint32_t)(unsigned long)
454   - ctrl->channels[c].current_d.buf;
455   - }
456   -
457   - channel_store_d(ctrl, c);
458 462 ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
459   - D(dump_d(c, &ctrl->channels[c].current_d));
460 463 }
461   - ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
462 464 }
463 465  
464 466 static int channel_in_process(struct fs_dma_ctrl *ctrl, int c,
... ... @@ -471,7 +473,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c,
471 473 return 0;
472 474  
473 475 saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
474   - len = (uint32_t)(unsigned long) ctrl->channels[c].current_d.after;
  476 + len = (uint32_t)ctrl->channels[c].current_d.after;
475 477 len -= saved_data_buf;
476 478  
477 479 if (len > buflen)
... ... @@ -481,7 +483,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c,
481 483 saved_data_buf += len;
482 484  
483 485 if (saved_data_buf ==
484   - (uint32_t)(unsigned long)ctrl->channels[c].current_d.after
  486 + (uint32_t)ctrl->channels[c].current_d.after
485 487 || eop) {
486 488 uint32_t r_intr = ctrl->channels[c].regs[R_INTR];
487 489  
... ... @@ -518,10 +520,10 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c,
518 520 channel_stop(ctrl, c);
519 521 } else {
520 522 ctrl->channels[c].regs[RW_SAVED_DATA] =
521   - (uint32_t)(unsigned long) ctrl->channels[c].current_d.next;
  523 + (uint32_t)ctrl->channels[c].current_d.next;
522 524 /* Load new descriptor. */
523 525 channel_load_d(ctrl, c);
524   - saved_data_buf = (uint32_t)(unsigned long)
  526 + saved_data_buf = (uint32_t)
525 527 ctrl->channels[c].current_d.buf;
526 528 }
527 529 }
... ...