Commit 8ccad811e6c138102072d6ad10fea384538755f2

Authored by bellard
1 parent e84a4fed

use AIO for DMA transfers - enabled DMA for CDROMs


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2103 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 236 additions and 199 deletions
hw/ide.c
@@ -26,6 +26,8 @@ @@ -26,6 +26,8 @@
26 /* debug IDE devices */ 26 /* debug IDE devices */
27 //#define DEBUG_IDE 27 //#define DEBUG_IDE
28 //#define DEBUG_IDE_ATAPI 28 //#define DEBUG_IDE_ATAPI
  29 +//#define DEBUG_AIO
  30 +#define USE_DMA_CDROM
29 31
30 /* Bits of HD_STATUS */ 32 /* Bits of HD_STATUS */
31 #define ERR_STAT 0x01 33 #define ERR_STAT 0x01
@@ -368,19 +370,20 @@ typedef struct IDEState { @@ -368,19 +370,20 @@ typedef struct IDEState {
368 #define UDIDETCR0 0x73 370 #define UDIDETCR0 0x73
369 #define UDIDETCR1 0x7B 371 #define UDIDETCR1 0x7B
370 372
371 -typedef int IDEDMAFunc(IDEState *s,  
372 - target_phys_addr_t phys_addr,  
373 - int transfer_size1);  
374 -  
375 typedef struct BMDMAState { 373 typedef struct BMDMAState {
376 uint8_t cmd; 374 uint8_t cmd;
377 uint8_t status; 375 uint8_t status;
378 uint32_t addr; 376 uint32_t addr;
379 - 377 +
380 struct PCIIDEState *pci_dev; 378 struct PCIIDEState *pci_dev;
381 /* current transfer state */ 379 /* current transfer state */
  380 + uint32_t cur_addr;
  381 + uint32_t cur_prd_last;
  382 + uint32_t cur_prd_addr;
  383 + uint32_t cur_prd_len;
382 IDEState *ide_if; 384 IDEState *ide_if;
383 - IDEDMAFunc *dma_cb; 385 + BlockDriverCompletionFunc *dma_cb;
  386 + BlockDriverAIOCB *aiocb;
384 } BMDMAState; 387 } BMDMAState;
385 388
386 typedef struct PCIIDEState { 389 typedef struct PCIIDEState {
@@ -390,7 +393,7 @@ typedef struct PCIIDEState { @@ -390,7 +393,7 @@ typedef struct PCIIDEState {
390 int type; /* see IDE_TYPE_xxx */ 393 int type; /* see IDE_TYPE_xxx */
391 } PCIIDEState; 394 } PCIIDEState;
392 395
393 -static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); 396 +static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
394 397
395 static void padstr(char *str, const char *src, int len) 398 static void padstr(char *str, const char *src, int len)
396 { 399 {
@@ -513,10 +516,17 @@ static void ide_atapi_identify(IDEState *s) @@ -513,10 +516,17 @@ static void ide_atapi_identify(IDEState *s)
513 padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */ 516 padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
514 padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */ 517 padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
515 put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */ 518 put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
  519 +#ifdef USE_DMA_CDROM
  520 + put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
  521 + put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
  522 + put_le16(p + 63, 7); /* mdma0-2 supported */
  523 + put_le16(p + 64, 0x3f); /* PIO modes supported */
  524 +#else
516 put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */ 525 put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
517 put_le16(p + 53, 3); /* words 64-70, 54-58 valid */ 526 put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
518 put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */ 527 put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
519 put_le16(p + 64, 1); /* PIO modes */ 528 put_le16(p + 64, 1); /* PIO modes */
  529 +#endif
520 put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */ 530 put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
521 put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */ 531 put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
522 put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */ 532 put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
@@ -526,7 +536,9 @@ static void ide_atapi_identify(IDEState *s) @@ -526,7 +536,9 @@ static void ide_atapi_identify(IDEState *s)
526 put_le16(p + 72, 30); /* in ns */ 536 put_le16(p + 72, 30); /* in ns */
527 537
528 put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */ 538 put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
529 - 539 +#ifdef USE_DMA_CDROM
  540 + put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
  541 +#endif
530 memcpy(s->identify_data, p, sizeof(s->identify_data)); 542 memcpy(s->identify_data, p, sizeof(s->identify_data));
531 s->identify_set = 1; 543 s->identify_set = 1;
532 } 544 }
@@ -659,54 +671,101 @@ static void ide_sector_read(IDEState *s) @@ -659,54 +671,101 @@ static void ide_sector_read(IDEState *s)
659 } 671 }
660 } 672 }
661 673
662 -static int ide_read_dma_cb(IDEState *s,  
663 - target_phys_addr_t phys_addr,  
664 - int transfer_size1) 674 +/* return 0 if buffer completed */
  675 +static int dma_buf_rw(BMDMAState *bm, int is_write)
665 { 676 {
666 - int len, transfer_size, n;  
667 - int64_t sector_num; 677 + IDEState *s = bm->ide_if;
  678 + struct {
  679 + uint32_t addr;
  680 + uint32_t size;
  681 + } prd;
  682 + int l, len;
668 683
669 - transfer_size = transfer_size1;  
670 - while (transfer_size > 0) {  
671 - len = s->io_buffer_size - s->io_buffer_index;  
672 - if (len <= 0) {  
673 - /* transfert next data */  
674 - n = s->nsector;  
675 - if (n == 0)  
676 - break;  
677 - if (n > MAX_MULT_SECTORS)  
678 - n = MAX_MULT_SECTORS;  
679 - sector_num = ide_get_sector(s);  
680 - bdrv_read(s->bs, sector_num, s->io_buffer, n);  
681 - s->io_buffer_index = 0;  
682 - s->io_buffer_size = n * 512;  
683 - len = s->io_buffer_size;  
684 - sector_num += n;  
685 - ide_set_sector(s, sector_num);  
686 - s->nsector -= n; 684 + for(;;) {
  685 + l = s->io_buffer_size - s->io_buffer_index;
  686 + if (l <= 0)
  687 + break;
  688 + if (bm->cur_prd_len == 0) {
  689 + /* end of table (with a fail safe of one page) */
  690 + if (bm->cur_prd_last ||
  691 + (bm->cur_addr - bm->addr) >= 4096)
  692 + return 0;
  693 + cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);
  694 + bm->cur_addr += 8;
  695 + prd.addr = le32_to_cpu(prd.addr);
  696 + prd.size = le32_to_cpu(prd.size);
  697 + len = prd.size & 0xfffe;
  698 + if (len == 0)
  699 + len = 0x10000;
  700 + bm->cur_prd_len = len;
  701 + bm->cur_prd_addr = prd.addr;
  702 + bm->cur_prd_last = (prd.size & 0x80000000);
  703 + }
  704 + if (l > bm->cur_prd_len)
  705 + l = bm->cur_prd_len;
  706 + if (l > 0) {
  707 + if (is_write) {
  708 + cpu_physical_memory_write(bm->cur_prd_addr,
  709 + s->io_buffer + s->io_buffer_index, l);
  710 + } else {
  711 + cpu_physical_memory_read(bm->cur_prd_addr,
  712 + s->io_buffer + s->io_buffer_index, l);
  713 + }
  714 + bm->cur_prd_addr += l;
  715 + bm->cur_prd_len -= l;
  716 + s->io_buffer_index += l;
687 } 717 }
688 - if (len > transfer_size)  
689 - len = transfer_size;  
690 - cpu_physical_memory_write(phys_addr,  
691 - s->io_buffer + s->io_buffer_index, len);  
692 - s->io_buffer_index += len;  
693 - transfer_size -= len;  
694 - phys_addr += len;  
695 } 718 }
696 - if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) { 719 + return 1;
  720 +}
  721 +
  722 +/* XXX: handle errors */
  723 +static void ide_read_dma_cb(void *opaque, int ret)
  724 +{
  725 + BMDMAState *bm = opaque;
  726 + IDEState *s = bm->ide_if;
  727 + int n;
  728 + int64_t sector_num;
  729 +
  730 + n = s->io_buffer_size >> 9;
  731 + sector_num = ide_get_sector(s);
  732 + if (n > 0) {
  733 + sector_num += n;
  734 + ide_set_sector(s, sector_num);
  735 + s->nsector -= n;
  736 + if (dma_buf_rw(bm, 1) == 0)
  737 + goto eot;
  738 + }
  739 +
  740 + /* end of transfer ? */
  741 + if (s->nsector == 0) {
697 s->status = READY_STAT | SEEK_STAT; 742 s->status = READY_STAT | SEEK_STAT;
698 ide_set_irq(s); 743 ide_set_irq(s);
699 -#ifdef DEBUG_IDE_ATAPI  
700 - printf("dma status=0x%x\n", s->status);  
701 -#endif  
702 - return 0; 744 + eot:
  745 + bm->status &= ~BM_STATUS_DMAING;
  746 + bm->status |= BM_STATUS_INT;
  747 + bm->dma_cb = NULL;
  748 + bm->ide_if = NULL;
  749 + bm->aiocb = NULL;
  750 + return;
703 } 751 }
704 - return transfer_size1 - transfer_size; 752 +
  753 + /* launch next transfer */
  754 + n = s->nsector;
  755 + if (n > MAX_MULT_SECTORS)
  756 + n = MAX_MULT_SECTORS;
  757 + s->io_buffer_index = 0;
  758 + s->io_buffer_size = n * 512;
  759 +#ifdef DEBUG_AIO
  760 + printf("aio_read: sector_num=%lld n=%d\n", sector_num, n);
  761 +#endif
  762 + bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n,
  763 + ide_read_dma_cb, bm);
705 } 764 }
706 765
707 static void ide_sector_read_dma(IDEState *s) 766 static void ide_sector_read_dma(IDEState *s)
708 { 767 {
709 - s->status = READY_STAT | SEEK_STAT | DRQ_STAT; 768 + s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
710 s->io_buffer_index = 0; 769 s->io_buffer_index = 0;
711 s->io_buffer_size = 0; 770 s->io_buffer_size = 0;
712 ide_dma_start(s, ide_read_dma_cb); 771 ide_dma_start(s, ide_read_dma_cb);
@@ -761,71 +820,56 @@ static void ide_sector_write(IDEState *s) @@ -761,71 +820,56 @@ static void ide_sector_write(IDEState *s)
761 } 820 }
762 } 821 }
763 822
764 -static int ide_write_dma_cb(IDEState *s,  
765 - target_phys_addr_t phys_addr,  
766 - int transfer_size1) 823 +/* XXX: handle errors */
  824 +static void ide_write_dma_cb(void *opaque, int ret)
767 { 825 {
768 - int len, transfer_size, n; 826 + BMDMAState *bm = opaque;
  827 + IDEState *s = bm->ide_if;
  828 + int n;
769 int64_t sector_num; 829 int64_t sector_num;
770 830
771 - transfer_size = transfer_size1;  
772 - for(;;) {  
773 - len = s->io_buffer_size - s->io_buffer_index;  
774 - if (len == 0) {  
775 - n = s->io_buffer_size >> 9;  
776 - sector_num = ide_get_sector(s);  
777 - bdrv_write(s->bs, sector_num, s->io_buffer,  
778 - s->io_buffer_size >> 9);  
779 - sector_num += n;  
780 - ide_set_sector(s, sector_num);  
781 - s->nsector -= n;  
782 - n = s->nsector;  
783 - if (n == 0) {  
784 - /* end of transfer */  
785 - s->status = READY_STAT | SEEK_STAT;  
786 -#ifdef TARGET_I386  
787 - if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {  
788 - /* It seems there is a bug in the Windows 2000 installer  
789 - HDD IDE driver which fills the disk with empty logs  
790 - when the IDE write IRQ comes too early. This hack tries  
791 - to correct that at the expense of slower write  
792 - performances. Use this option _only_ to install Windows  
793 - 2000. You must disable it for normal use. */  
794 - qemu_mod_timer(s->sector_write_timer,  
795 - qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));  
796 - } else  
797 -#endif  
798 - ide_set_irq(s);  
799 - return 0;  
800 - }  
801 - if (n > MAX_MULT_SECTORS)  
802 - n = MAX_MULT_SECTORS;  
803 - s->io_buffer_index = 0;  
804 - s->io_buffer_size = n * 512;  
805 - len = s->io_buffer_size;  
806 - }  
807 - if (transfer_size <= 0)  
808 - break;  
809 - if (len > transfer_size)  
810 - len = transfer_size;  
811 - cpu_physical_memory_read(phys_addr,  
812 - s->io_buffer + s->io_buffer_index, len);  
813 - s->io_buffer_index += len;  
814 - transfer_size -= len;  
815 - phys_addr += len; 831 + n = s->io_buffer_size >> 9;
  832 + sector_num = ide_get_sector(s);
  833 + if (n > 0) {
  834 + sector_num += n;
  835 + ide_set_sector(s, sector_num);
  836 + s->nsector -= n;
816 } 837 }
817 - return transfer_size1 - transfer_size;  
818 -}  
819 838
820 -static void ide_sector_write_dma(IDEState *s)  
821 -{  
822 - int n;  
823 - s->status = READY_STAT | SEEK_STAT | DRQ_STAT; 839 + /* end of transfer ? */
  840 + if (s->nsector == 0) {
  841 + s->status = READY_STAT | SEEK_STAT;
  842 + ide_set_irq(s);
  843 + eot:
  844 + bm->status &= ~BM_STATUS_DMAING;
  845 + bm->status |= BM_STATUS_INT;
  846 + bm->dma_cb = NULL;
  847 + bm->ide_if = NULL;
  848 + bm->aiocb = NULL;
  849 + return;
  850 + }
  851 +
  852 + /* launch next transfer */
824 n = s->nsector; 853 n = s->nsector;
825 if (n > MAX_MULT_SECTORS) 854 if (n > MAX_MULT_SECTORS)
826 n = MAX_MULT_SECTORS; 855 n = MAX_MULT_SECTORS;
827 s->io_buffer_index = 0; 856 s->io_buffer_index = 0;
828 s->io_buffer_size = n * 512; 857 s->io_buffer_size = n * 512;
  858 +
  859 + if (dma_buf_rw(bm, 0) == 0)
  860 + goto eot;
  861 +#ifdef DEBUG_AIO
  862 + printf("aio_write: sector_num=%lld n=%d\n", sector_num, n);
  863 +#endif
  864 + bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
  865 + ide_write_dma_cb, bm);
  866 +}
  867 +
  868 +static void ide_sector_write_dma(IDEState *s)
  869 +{
  870 + s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
  871 + s->io_buffer_index = 0;
  872 + s->io_buffer_size = 0;
829 ide_dma_start(s, ide_write_dma_cb); 873 ide_dma_start(s, ide_write_dma_cb);
830 } 874 }
831 875
@@ -882,6 +926,23 @@ static void lba_to_msf(uint8_t *buf, int lba) @@ -882,6 +926,23 @@ static void lba_to_msf(uint8_t *buf, int lba)
882 buf[2] = lba % 75; 926 buf[2] = lba % 75;
883 } 927 }
884 928
  929 +static void cd_data_to_raw(uint8_t *buf, int lba)
  930 +{
  931 + /* sync bytes */
  932 + buf[0] = 0x00;
  933 + memset(buf + 1, 0xff, 10);
  934 + buf[11] = 0x00;
  935 + buf += 12;
  936 + /* MSF */
  937 + lba_to_msf(buf, lba);
  938 + buf[3] = 0x01; /* mode 1 data */
  939 + buf += 4;
  940 + /* data */
  941 + buf += 2048;
  942 + /* XXX: ECC not computed */
  943 + memset(buf, 0, 288);
  944 +}
  945 +
885 static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 946 static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
886 int sector_size) 947 int sector_size)
887 { 948 {
@@ -890,20 +951,8 @@ static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, @@ -890,20 +951,8 @@ static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
890 bdrv_read(bs, (int64_t)lba << 2, buf, 4); 951 bdrv_read(bs, (int64_t)lba << 2, buf, 4);
891 break; 952 break;
892 case 2352: 953 case 2352:
893 - /* sync bytes */  
894 - buf[0] = 0x00;  
895 - memset(buf + 1, 0xff, 10);  
896 - buf[11] = 0x00;  
897 - buf += 12;  
898 - /* MSF */  
899 - lba_to_msf(buf, lba);  
900 - buf[3] = 0x01; /* mode 1 data */  
901 - buf += 4;  
902 - /* data */  
903 - bdrv_read(bs, (int64_t)lba << 2, buf, 4);  
904 - buf += 2048;  
905 - /* ECC */  
906 - memset(buf, 0, 288); 954 + bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
  955 + cd_data_to_raw(buf, lba);
907 break; 956 break;
908 default: 957 default:
909 break; 958 break;
@@ -1013,46 +1062,58 @@ static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors, @@ -1013,46 +1062,58 @@ static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
1013 } 1062 }
1014 1063
1015 /* ATAPI DMA support */ 1064 /* ATAPI DMA support */
1016 -static int ide_atapi_cmd_read_dma_cb(IDEState *s,  
1017 - target_phys_addr_t phys_addr,  
1018 - int transfer_size1) 1065 +
  1066 +/* XXX: handle read errors */
  1067 +static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
1019 { 1068 {
1020 - int len, transfer_size;  
1021 -  
1022 - transfer_size = transfer_size1;  
1023 - while (transfer_size > 0) {  
1024 -#ifdef DEBUG_IDE_ATAPI  
1025 - printf("transfer_size: %d phys_addr=%08x\n", transfer_size, phys_addr);  
1026 -#endif  
1027 - if (s->packet_transfer_size <= 0)  
1028 - break;  
1029 - len = s->cd_sector_size - s->io_buffer_index;  
1030 - if (len <= 0) {  
1031 - /* transfert next data */  
1032 - cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);  
1033 - s->lba++;  
1034 - s->io_buffer_index = 0;  
1035 - len = s->cd_sector_size; 1069 + BMDMAState *bm = opaque;
  1070 + IDEState *s = bm->ide_if;
  1071 + int data_offset, n;
  1072 +
  1073 + if (s->io_buffer_size > 0) {
  1074 + if (s->cd_sector_size == 2352) {
  1075 + n = 1;
  1076 + cd_data_to_raw(s->io_buffer, s->lba);
  1077 + } else {
  1078 + n = s->io_buffer_size >> 11;
1036 } 1079 }
1037 - if (len > transfer_size)  
1038 - len = transfer_size;  
1039 - cpu_physical_memory_write(phys_addr,  
1040 - s->io_buffer + s->io_buffer_index, len);  
1041 - s->packet_transfer_size -= len;  
1042 - s->io_buffer_index += len;  
1043 - transfer_size -= len;  
1044 - phys_addr += len; 1080 + s->packet_transfer_size -= s->io_buffer_size;
  1081 + s->lba += n;
  1082 + if (dma_buf_rw(bm, 1) == 0)
  1083 + goto eot;
1045 } 1084 }
  1085 +
1046 if (s->packet_transfer_size <= 0) { 1086 if (s->packet_transfer_size <= 0) {
1047 s->status = READY_STAT; 1087 s->status = READY_STAT;
1048 s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; 1088 s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1049 ide_set_irq(s); 1089 ide_set_irq(s);
1050 -#ifdef DEBUG_IDE_ATAPI  
1051 - printf("dma status=0x%x\n", s->status);  
1052 -#endif  
1053 - return 0; 1090 + eot:
  1091 + bm->status &= ~BM_STATUS_DMAING;
  1092 + bm->status |= BM_STATUS_INT;
  1093 + bm->dma_cb = NULL;
  1094 + bm->ide_if = NULL;
  1095 + bm->aiocb = NULL;
  1096 + return;
  1097 + }
  1098 +
  1099 + s->io_buffer_index = 0;
  1100 + if (s->cd_sector_size == 2352) {
  1101 + n = 1;
  1102 + s->io_buffer_size = s->cd_sector_size;
  1103 + data_offset = 16;
  1104 + } else {
  1105 + n = s->packet_transfer_size >> 11;
  1106 + if (n > (MAX_MULT_SECTORS / 4))
  1107 + n = (MAX_MULT_SECTORS / 4);
  1108 + s->io_buffer_size = n * 2048;
  1109 + data_offset = 0;
1054 } 1110 }
1055 - return transfer_size1 - transfer_size; 1111 +#ifdef DEBUG_AIO
  1112 + printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
  1113 +#endif
  1114 + bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
  1115 + s->io_buffer + data_offset, n * 4,
  1116 + ide_atapi_cmd_read_dma_cb, bm);
1056 } 1117 }
1057 1118
1058 /* start a CD-CDROM read command with DMA */ 1119 /* start a CD-CDROM read command with DMA */
@@ -1062,10 +1123,12 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors, @@ -1062,10 +1123,12 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1062 { 1123 {
1063 s->lba = lba; 1124 s->lba = lba;
1064 s->packet_transfer_size = nb_sectors * sector_size; 1125 s->packet_transfer_size = nb_sectors * sector_size;
1065 - s->io_buffer_index = sector_size; 1126 + s->io_buffer_index = 0;
  1127 + s->io_buffer_size = 0;
1066 s->cd_sector_size = sector_size; 1128 s->cd_sector_size = sector_size;
1067 1129
1068 - s->status = READY_STAT | DRQ_STAT; 1130 + /* XXX: check if BUSY_STAT should be set */
  1131 + s->status = READY_STAT | DRQ_STAT | BUSY_STAT;
1069 ide_dma_start(s, ide_atapi_cmd_read_dma_cb); 1132 ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1070 } 1133 }
1071 1134
@@ -2103,59 +2166,19 @@ static void ide_map(PCIDevice *pci_dev, int region_num, @@ -2103,59 +2166,19 @@ static void ide_map(PCIDevice *pci_dev, int region_num,
2103 } 2166 }
2104 } 2167 }
2105 2168
2106 -/* XXX: full callback usage to prepare non blocking I/Os support -  
2107 - error handling */  
2108 -static void ide_dma_loop(BMDMAState *bm)  
2109 -{  
2110 - struct {  
2111 - uint32_t addr;  
2112 - uint32_t size;  
2113 - } prd;  
2114 - target_phys_addr_t cur_addr;  
2115 - int len, i, len1;  
2116 -  
2117 - cur_addr = bm->addr;  
2118 - /* at most one page to avoid hanging if erroneous parameters */  
2119 - for(i = 0; i < 512; i++) {  
2120 - cpu_physical_memory_read(cur_addr, (uint8_t *)&prd, 8);  
2121 - prd.addr = le32_to_cpu(prd.addr);  
2122 - prd.size = le32_to_cpu(prd.size);  
2123 -#ifdef DEBUG_IDE  
2124 - printf("ide: dma: prd: %08x: addr=0x%08x size=0x%08x\n",  
2125 - (int)cur_addr, prd.addr, prd.size);  
2126 -#endif  
2127 - len = prd.size & 0xfffe;  
2128 - if (len == 0)  
2129 - len = 0x10000;  
2130 - while (len > 0) {  
2131 - len1 = bm->dma_cb(bm->ide_if, prd.addr, len);  
2132 - if (len1 == 0)  
2133 - goto the_end;  
2134 - prd.addr += len1;  
2135 - len -= len1;  
2136 - }  
2137 - /* end of transfer */  
2138 - if (prd.size & 0x80000000)  
2139 - break;  
2140 - cur_addr += 8;  
2141 - }  
2142 - /* end of transfer */  
2143 - the_end:  
2144 - bm->status &= ~BM_STATUS_DMAING;  
2145 - bm->status |= BM_STATUS_INT;  
2146 - bm->dma_cb = NULL;  
2147 - bm->ide_if = NULL;  
2148 -}  
2149 -  
2150 -static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb) 2169 +static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
2151 { 2170 {
2152 BMDMAState *bm = s->bmdma; 2171 BMDMAState *bm = s->bmdma;
2153 if(!bm) 2172 if(!bm)
2154 return; 2173 return;
2155 bm->ide_if = s; 2174 bm->ide_if = s;
2156 bm->dma_cb = dma_cb; 2175 bm->dma_cb = dma_cb;
  2176 + bm->cur_addr = bm->addr;
  2177 + bm->cur_prd_last = 0;
  2178 + bm->cur_prd_addr = 0;
  2179 + bm->cur_prd_len = 0;
2157 if (bm->status & BM_STATUS_DMAING) { 2180 if (bm->status & BM_STATUS_DMAING) {
2158 - ide_dma_loop(bm); 2181 + bm->dma_cb(bm, 0);
2159 } 2182 }
2160 } 2183 }
2161 2184
@@ -2167,14 +2190,28 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) @@ -2167,14 +2190,28 @@ static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2167 #endif 2190 #endif
2168 if (!(val & BM_CMD_START)) { 2191 if (!(val & BM_CMD_START)) {
2169 /* XXX: do it better */ 2192 /* XXX: do it better */
2170 - bm->status &= ~BM_STATUS_DMAING; 2193 + if (bm->status & BM_STATUS_DMAING) {
  2194 + bm->status &= ~BM_STATUS_DMAING;
  2195 + /* cancel DMA request */
  2196 + bm->ide_if = NULL;
  2197 + bm->dma_cb = NULL;
  2198 + if (bm->aiocb) {
  2199 +#ifdef DEBUG_AIO
  2200 + printf("aio_cancel\n");
  2201 +#endif
  2202 + bdrv_aio_cancel(bm->aiocb);
  2203 + bm->aiocb = NULL;
  2204 + }
  2205 + }
2171 bm->cmd = val & 0x09; 2206 bm->cmd = val & 0x09;
2172 } else { 2207 } else {
2173 - bm->status |= BM_STATUS_DMAING; 2208 + if (!(bm->status & BM_STATUS_DMAING)) {
  2209 + bm->status |= BM_STATUS_DMAING;
  2210 + /* start dma transfer if possible */
  2211 + if (bm->dma_cb)
  2212 + bm->dma_cb(bm, 0);
  2213 + }
2174 bm->cmd = val & 0x09; 2214 bm->cmd = val & 0x09;
2175 - /* start dma transfer if possible */  
2176 - if (bm->dma_cb)  
2177 - ide_dma_loop(bm);  
2178 } 2215 }
2179 } 2216 }
2180 2217