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,6 +394,7 @@ typedef struct PCIIDEState { | ||
394 | } PCIIDEState; | 394 | } PCIIDEState; |
395 | 395 | ||
396 | static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb); | 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 | static void padstr(char *str, const char *src, int len) | 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,11 +1064,17 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) | ||
1063 | size = max_size; | 1064 | size = max_size; |
1064 | s->lba = -1; /* no sector read */ | 1065 | s->lba = -1; /* no sector read */ |
1065 | s->packet_transfer_size = size; | 1066 | s->packet_transfer_size = size; |
1067 | + s->io_buffer_size = size; /* dma: send the reply data as one chunk */ | ||
1066 | s->elementary_transfer_size = 0; | 1068 | s->elementary_transfer_size = 0; |
1067 | s->io_buffer_index = 0; | 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 | /* start a CD-CDROM read command */ | 1080 | /* start a CD-CDROM read command */ |
@@ -1099,14 +1106,23 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) | @@ -1099,14 +1106,23 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) | ||
1099 | } | 1106 | } |
1100 | 1107 | ||
1101 | if (s->io_buffer_size > 0) { | 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 | s->packet_transfer_size -= s->io_buffer_size; | 1125 | s->packet_transfer_size -= s->io_buffer_size; |
1109 | - s->lba += n; | ||
1110 | if (dma_buf_rw(bm, 1) == 0) | 1126 | if (dma_buf_rw(bm, 1) == 0) |
1111 | goto eot; | 1127 | goto eot; |
1112 | } | 1128 | } |
@@ -1170,7 +1186,8 @@ static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, | @@ -1170,7 +1186,8 @@ static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, | ||
1170 | int sector_size) | 1186 | int sector_size) |
1171 | { | 1187 | { |
1172 | #ifdef DEBUG_IDE_ATAPI | 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 | #endif | 1191 | #endif |
1175 | if (s->atapi_dma) { | 1192 | if (s->atapi_dma) { |
1176 | ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size); | 1193 | ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size); |