Commit 0fc5c15a4fad2dac00126c802554d9ca33c4ccc7
1 parent
cac782d4
SCSI lun probing fix.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1945 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
23 additions
and
19 deletions
hw/esp.c
| @@ -55,6 +55,7 @@ struct ESPState { | @@ -55,6 +55,7 @@ struct ESPState { | ||
| 55 | uint32_t ti_size; | 55 | uint32_t ti_size; |
| 56 | uint32_t ti_rptr, ti_wptr; | 56 | uint32_t ti_rptr, ti_wptr; |
| 57 | uint8_t ti_buf[TI_BUFSZ]; | 57 | uint8_t ti_buf[TI_BUFSZ]; |
| 58 | + int sense; | ||
| 58 | int dma; | 59 | int dma; |
| 59 | SCSIDevice *scsi_dev[MAX_DISKS]; | 60 | SCSIDevice *scsi_dev[MAX_DISKS]; |
| 60 | SCSIDevice *current_dev; | 61 | SCSIDevice *current_dev; |
| @@ -84,6 +85,7 @@ static void handle_satn(ESPState *s) | @@ -84,6 +85,7 @@ static void handle_satn(ESPState *s) | ||
| 84 | uint32_t dmaptr, dmalen; | 85 | uint32_t dmaptr, dmalen; |
| 85 | int target; | 86 | int target; |
| 86 | int32_t datalen; | 87 | int32_t datalen; |
| 88 | + int lun; | ||
| 87 | 89 | ||
| 88 | dmalen = s->wregs[0] | (s->wregs[1] << 8); | 90 | dmalen = s->wregs[0] | (s->wregs[1] << 8); |
| 89 | target = s->wregs[4] & 7; | 91 | target = s->wregs[4] & 7; |
| @@ -98,6 +100,8 @@ static void handle_satn(ESPState *s) | @@ -98,6 +100,8 @@ static void handle_satn(ESPState *s) | ||
| 98 | memcpy(&buf[1], s->ti_buf, dmalen); | 100 | memcpy(&buf[1], s->ti_buf, dmalen); |
| 99 | dmalen++; | 101 | dmalen++; |
| 100 | } | 102 | } |
| 103 | + DPRINTF("busid 0x%x\n", buf[0]); | ||
| 104 | + lun = buf[0] & 7; | ||
| 101 | 105 | ||
| 102 | s->ti_size = 0; | 106 | s->ti_size = 0; |
| 103 | s->ti_rptr = 0; | 107 | s->ti_rptr = 0; |
| @@ -113,7 +117,7 @@ static void handle_satn(ESPState *s) | @@ -113,7 +117,7 @@ static void handle_satn(ESPState *s) | ||
| 113 | return; | 117 | return; |
| 114 | } | 118 | } |
| 115 | s->current_dev = s->scsi_dev[target]; | 119 | s->current_dev = s->scsi_dev[target]; |
| 116 | - datalen = scsi_send_command(s->current_dev, 0, &buf[1]); | 120 | + datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun); |
| 117 | if (datalen == 0) { | 121 | if (datalen == 0) { |
| 118 | s->ti_size = 0; | 122 | s->ti_size = 0; |
| 119 | } else { | 123 | } else { |
| @@ -132,34 +136,33 @@ static void handle_satn(ESPState *s) | @@ -132,34 +136,33 @@ static void handle_satn(ESPState *s) | ||
| 132 | pic_set_irq(s->irq, 1); | 136 | pic_set_irq(s->irq, 1); |
| 133 | } | 137 | } |
| 134 | 138 | ||
| 135 | -static void dma_write(ESPState *s, const uint8_t *buf, uint32_t len) | 139 | +static void write_response(ESPState *s) |
| 136 | { | 140 | { |
| 137 | uint32_t dmaptr; | 141 | uint32_t dmaptr; |
| 138 | 142 | ||
| 139 | - DPRINTF("Transfer status len %d\n", len); | 143 | + DPRINTF("Transfer status (sense=%d)\n", s->sense); |
| 144 | + s->ti_buf[0] = s->sense; | ||
| 145 | + s->ti_buf[1] = 0; | ||
| 140 | if (s->dma) { | 146 | if (s->dma) { |
| 141 | dmaptr = iommu_translate(s->espdmaregs[1]); | 147 | dmaptr = iommu_translate(s->espdmaregs[1]); |
| 142 | DPRINTF("DMA Direction: %c\n", | 148 | DPRINTF("DMA Direction: %c\n", |
| 143 | s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r'); | 149 | s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r'); |
| 144 | - cpu_physical_memory_write(dmaptr, buf, len); | 150 | + cpu_physical_memory_write(dmaptr, s->ti_buf, 2); |
| 145 | s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; | 151 | s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
| 146 | s->rregs[5] = INTR_BS | INTR_FC; | 152 | s->rregs[5] = INTR_BS | INTR_FC; |
| 147 | s->rregs[6] = SEQ_CD; | 153 | s->rregs[6] = SEQ_CD; |
| 148 | } else { | 154 | } else { |
| 149 | - memcpy(s->ti_buf, buf, len); | ||
| 150 | - s->ti_size = len; | 155 | + s->ti_size = 2; |
| 151 | s->ti_rptr = 0; | 156 | s->ti_rptr = 0; |
| 152 | s->ti_wptr = 0; | 157 | s->ti_wptr = 0; |
| 153 | - s->rregs[7] = len; | 158 | + s->rregs[7] = 2; |
| 154 | } | 159 | } |
| 155 | s->espdmaregs[0] |= DMA_INTR; | 160 | s->espdmaregs[0] |= DMA_INTR; |
| 156 | pic_set_irq(s->irq, 1); | 161 | pic_set_irq(s->irq, 1); |
| 157 | 162 | ||
| 158 | } | 163 | } |
| 159 | 164 | ||
| 160 | -static const uint8_t okbuf[] = {0, 0}; | ||
| 161 | - | ||
| 162 | -static void esp_command_complete(void *opaque, uint32_t tag, int fail) | 165 | +static void esp_command_complete(void *opaque, uint32_t tag, int sense) |
| 163 | { | 166 | { |
| 164 | ESPState *s = (ESPState *)opaque; | 167 | ESPState *s = (ESPState *)opaque; |
| 165 | 168 | ||
| @@ -167,9 +170,9 @@ static void esp_command_complete(void *opaque, uint32_t tag, int fail) | @@ -167,9 +170,9 @@ static void esp_command_complete(void *opaque, uint32_t tag, int fail) | ||
| 167 | if (s->ti_size != 0) | 170 | if (s->ti_size != 0) |
| 168 | DPRINTF("SCSI command completed unexpectedly\n"); | 171 | DPRINTF("SCSI command completed unexpectedly\n"); |
| 169 | s->ti_size = 0; | 172 | s->ti_size = 0; |
| 170 | - /* ??? Report failures. */ | ||
| 171 | - if (fail) | 173 | + if (sense) |
| 172 | DPRINTF("Command failed\n"); | 174 | DPRINTF("Command failed\n"); |
| 175 | + s->sense = sense; | ||
| 173 | s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; | 176 | s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
| 174 | } | 177 | } |
| 175 | 178 | ||
| @@ -333,11 +336,11 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) | @@ -333,11 +336,11 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) | ||
| 333 | break; | 336 | break; |
| 334 | case 0x11: | 337 | case 0x11: |
| 335 | DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); | 338 | DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); |
| 336 | - dma_write(s, okbuf, 2); | 339 | + write_response(s); |
| 337 | break; | 340 | break; |
| 338 | case 0x12: | 341 | case 0x12: |
| 339 | DPRINTF("Message Accepted (%2.2x)\n", val); | 342 | DPRINTF("Message Accepted (%2.2x)\n", val); |
| 340 | - dma_write(s, okbuf, 2); | 343 | + write_response(s); |
| 341 | s->rregs[5] = INTR_DC; | 344 | s->rregs[5] = INTR_DC; |
| 342 | s->rregs[6] = 0; | 345 | s->rregs[6] = 0; |
| 343 | break; | 346 | break; |
hw/scsi-disk.c
| @@ -53,7 +53,7 @@ struct SCSIDevice | @@ -53,7 +53,7 @@ struct SCSIDevice | ||
| 53 | static void scsi_command_complete(SCSIDevice *s, int sense) | 53 | static void scsi_command_complete(SCSIDevice *s, int sense) |
| 54 | { | 54 | { |
| 55 | s->sense = sense; | 55 | s->sense = sense; |
| 56 | - s->completion(s->opaque, s->tag, sense != SENSE_NO_SENSE); | 56 | + s->completion(s->opaque, s->tag, sense); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | /* Read data from a scsi device. Returns nonzero on failure. */ | 59 | /* Read data from a scsi device. Returns nonzero on failure. */ |
| @@ -175,7 +175,7 @@ int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len) | @@ -175,7 +175,7 @@ int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len) | ||
| 175 | (eg. disk reads), negative for transfers to the device (eg. disk writes), | 175 | (eg. disk reads), negative for transfers to the device (eg. disk writes), |
| 176 | and zero if the command does not transfer any data. */ | 176 | and zero if the command does not transfer any data. */ |
| 177 | 177 | ||
| 178 | -int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf) | 178 | +int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun) |
| 179 | { | 179 | { |
| 180 | int64_t nb_sectors; | 180 | int64_t nb_sectors; |
| 181 | uint32_t lba; | 181 | uint32_t lba; |
| @@ -225,8 +225,9 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf) | @@ -225,8 +225,9 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf) | ||
| 225 | printf("\n"); | 225 | printf("\n"); |
| 226 | } | 226 | } |
| 227 | #endif | 227 | #endif |
| 228 | - if (buf[1] >> 5) { | 228 | + if (lun || buf[1] >> 5) { |
| 229 | /* Only LUN 0 supported. */ | 229 | /* Only LUN 0 supported. */ |
| 230 | + DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5); | ||
| 230 | goto fail; | 231 | goto fail; |
| 231 | } | 232 | } |
| 232 | switch (s->command) { | 233 | switch (s->command) { |
hw/usb-msd.c
| @@ -295,7 +295,7 @@ static int usb_msd_handle_data(USBDevice *dev, int pid, uint8_t devep, | @@ -295,7 +295,7 @@ static int usb_msd_handle_data(USBDevice *dev, int pid, uint8_t devep, | ||
| 295 | } | 295 | } |
| 296 | DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", | 296 | DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", |
| 297 | s->tag, cbw.flags, cbw.cmd_len, s->data_len); | 297 | s->tag, cbw.flags, cbw.cmd_len, s->data_len); |
| 298 | - scsi_send_command(s->scsi_dev, s->tag, cbw.cmd); | 298 | + scsi_send_command(s->scsi_dev, s->tag, cbw.cmd, 0); |
| 299 | ret = len; | 299 | ret = len; |
| 300 | break; | 300 | break; |
| 301 | 301 |
vl.h
| @@ -1044,7 +1044,7 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, | @@ -1044,7 +1044,7 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, | ||
| 1044 | void *opaque); | 1044 | void *opaque); |
| 1045 | void scsi_disk_destroy(SCSIDevice *s); | 1045 | void scsi_disk_destroy(SCSIDevice *s); |
| 1046 | 1046 | ||
| 1047 | -int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf); | 1047 | +int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun); |
| 1048 | int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len); | 1048 | int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len); |
| 1049 | int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len); | 1049 | int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len); |
| 1050 | 1050 |