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 | 55 | uint32_t ti_size; |
56 | 56 | uint32_t ti_rptr, ti_wptr; |
57 | 57 | uint8_t ti_buf[TI_BUFSZ]; |
58 | + int sense; | |
58 | 59 | int dma; |
59 | 60 | SCSIDevice *scsi_dev[MAX_DISKS]; |
60 | 61 | SCSIDevice *current_dev; |
... | ... | @@ -84,6 +85,7 @@ static void handle_satn(ESPState *s) |
84 | 85 | uint32_t dmaptr, dmalen; |
85 | 86 | int target; |
86 | 87 | int32_t datalen; |
88 | + int lun; | |
87 | 89 | |
88 | 90 | dmalen = s->wregs[0] | (s->wregs[1] << 8); |
89 | 91 | target = s->wregs[4] & 7; |
... | ... | @@ -98,6 +100,8 @@ static void handle_satn(ESPState *s) |
98 | 100 | memcpy(&buf[1], s->ti_buf, dmalen); |
99 | 101 | dmalen++; |
100 | 102 | } |
103 | + DPRINTF("busid 0x%x\n", buf[0]); | |
104 | + lun = buf[0] & 7; | |
101 | 105 | |
102 | 106 | s->ti_size = 0; |
103 | 107 | s->ti_rptr = 0; |
... | ... | @@ -113,7 +117,7 @@ static void handle_satn(ESPState *s) |
113 | 117 | return; |
114 | 118 | } |
115 | 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 | 121 | if (datalen == 0) { |
118 | 122 | s->ti_size = 0; |
119 | 123 | } else { |
... | ... | @@ -132,34 +136,33 @@ static void handle_satn(ESPState *s) |
132 | 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 | 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 | 146 | if (s->dma) { |
141 | 147 | dmaptr = iommu_translate(s->espdmaregs[1]); |
142 | 148 | DPRINTF("DMA Direction: %c\n", |
143 | 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 | 151 | s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
146 | 152 | s->rregs[5] = INTR_BS | INTR_FC; |
147 | 153 | s->rregs[6] = SEQ_CD; |
148 | 154 | } else { |
149 | - memcpy(s->ti_buf, buf, len); | |
150 | - s->ti_size = len; | |
155 | + s->ti_size = 2; | |
151 | 156 | s->ti_rptr = 0; |
152 | 157 | s->ti_wptr = 0; |
153 | - s->rregs[7] = len; | |
158 | + s->rregs[7] = 2; | |
154 | 159 | } |
155 | 160 | s->espdmaregs[0] |= DMA_INTR; |
156 | 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 | 167 | ESPState *s = (ESPState *)opaque; |
165 | 168 | |
... | ... | @@ -167,9 +170,9 @@ static void esp_command_complete(void *opaque, uint32_t tag, int fail) |
167 | 170 | if (s->ti_size != 0) |
168 | 171 | DPRINTF("SCSI command completed unexpectedly\n"); |
169 | 172 | s->ti_size = 0; |
170 | - /* ??? Report failures. */ | |
171 | - if (fail) | |
173 | + if (sense) | |
172 | 174 | DPRINTF("Command failed\n"); |
175 | + s->sense = sense; | |
173 | 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 | 336 | break; |
334 | 337 | case 0x11: |
335 | 338 | DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); |
336 | - dma_write(s, okbuf, 2); | |
339 | + write_response(s); | |
337 | 340 | break; |
338 | 341 | case 0x12: |
339 | 342 | DPRINTF("Message Accepted (%2.2x)\n", val); |
340 | - dma_write(s, okbuf, 2); | |
343 | + write_response(s); | |
341 | 344 | s->rregs[5] = INTR_DC; |
342 | 345 | s->rregs[6] = 0; |
343 | 346 | break; | ... | ... |
hw/scsi-disk.c
... | ... | @@ -53,7 +53,7 @@ struct SCSIDevice |
53 | 53 | static void scsi_command_complete(SCSIDevice *s, int sense) |
54 | 54 | { |
55 | 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 | 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 | 175 | (eg. disk reads), negative for transfers to the device (eg. disk writes), |
176 | 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 | 180 | int64_t nb_sectors; |
181 | 181 | uint32_t lba; |
... | ... | @@ -225,8 +225,9 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf) |
225 | 225 | printf("\n"); |
226 | 226 | } |
227 | 227 | #endif |
228 | - if (buf[1] >> 5) { | |
228 | + if (lun || buf[1] >> 5) { | |
229 | 229 | /* Only LUN 0 supported. */ |
230 | + DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5); | |
230 | 231 | goto fail; |
231 | 232 | } |
232 | 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 | 295 | } |
296 | 296 | DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", |
297 | 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 | 299 | ret = len; |
300 | 300 | break; |
301 | 301 | ... | ... |
vl.h
... | ... | @@ -1044,7 +1044,7 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, |
1044 | 1044 | void *opaque); |
1045 | 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 | 1048 | int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len); |
1049 | 1049 | int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len); |
1050 | 1050 | ... | ... |