Commit 5f12ab4b10075e5ae87e95cdef305172e0de17c0
1 parent
af23902b
Add more ATAPI CDROM DMA support, by Juergen Keil.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2338 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
27 additions
and
10 deletions
hw/ide.c
... | ... | @@ -394,6 +394,7 @@ typedef struct PCIIDEState { |
394 | 394 | } PCIIDEState; |
395 | 395 | |
396 | 396 | static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb); |
397 | +static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret); | |
397 | 398 | |
398 | 399 | static void padstr(char *str, const char *src, int len) |
399 | 400 | { |
... | ... | @@ -1063,11 +1064,17 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) |
1063 | 1064 | size = max_size; |
1064 | 1065 | s->lba = -1; /* no sector read */ |
1065 | 1066 | s->packet_transfer_size = size; |
1067 | + s->io_buffer_size = size; /* dma: send the reply data as one chunk */ | |
1066 | 1068 | s->elementary_transfer_size = 0; |
1067 | 1069 | s->io_buffer_index = 0; |
1068 | 1070 | |
1069 | - s->status = READY_STAT; | |
1070 | - ide_atapi_cmd_reply_end(s); | |
1071 | + if (s->atapi_dma) { | |
1072 | + s->status = READY_STAT | DRQ_STAT; | |
1073 | + ide_dma_start(s, ide_atapi_cmd_read_dma_cb); | |
1074 | + } else { | |
1075 | + s->status = READY_STAT; | |
1076 | + ide_atapi_cmd_reply_end(s); | |
1077 | + } | |
1071 | 1078 | } |
1072 | 1079 | |
1073 | 1080 | /* start a CD-CDROM read command */ |
... | ... | @@ -1099,14 +1106,23 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) |
1099 | 1106 | } |
1100 | 1107 | |
1101 | 1108 | if (s->io_buffer_size > 0) { |
1102 | - if (s->cd_sector_size == 2352) { | |
1103 | - n = 1; | |
1104 | - cd_data_to_raw(s->io_buffer, s->lba); | |
1105 | - } else { | |
1106 | - n = s->io_buffer_size >> 11; | |
1107 | - } | |
1109 | + /* | |
1110 | + * For a cdrom read sector command (s->lba != -1), | |
1111 | + * adjust the lba for the next s->io_buffer_size chunk | |
1112 | + * and dma the current chunk. | |
1113 | + * For a command != read (s->lba == -1), just transfer | |
1114 | + * the reply data. | |
1115 | + */ | |
1116 | + if (s->lba != -1) { | |
1117 | + if (s->cd_sector_size == 2352) { | |
1118 | + n = 1; | |
1119 | + cd_data_to_raw(s->io_buffer, s->lba); | |
1120 | + } else { | |
1121 | + n = s->io_buffer_size >> 11; | |
1122 | + } | |
1123 | + s->lba += n; | |
1124 | + } | |
1108 | 1125 | s->packet_transfer_size -= s->io_buffer_size; |
1109 | - s->lba += n; | |
1110 | 1126 | if (dma_buf_rw(bm, 1) == 0) |
1111 | 1127 | goto eot; |
1112 | 1128 | } |
... | ... | @@ -1170,7 +1186,8 @@ static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, |
1170 | 1186 | int sector_size) |
1171 | 1187 | { |
1172 | 1188 | #ifdef DEBUG_IDE_ATAPI |
1173 | - printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors); | |
1189 | + printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio", | |
1190 | + lba, nb_sectors); | |
1174 | 1191 | #endif |
1175 | 1192 | if (s->atapi_dma) { |
1176 | 1193 | ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size); | ... | ... |