Revision 47e4ca5a hw/scsi-disk.c
b/hw/scsi-disk.c | ||
---|---|---|
34 | 34 |
#define SENSE_HARDWARE_ERROR 4 |
35 | 35 |
#define SENSE_ILLEGAL_REQUEST 5 |
36 | 36 |
|
37 |
#define SCSI_OK 0 |
|
38 |
#define SCSI_CHECK_COND 0x2 |
|
39 |
#define SCSI_COND_MET 0x4 |
|
40 |
#define SCSI_BUSY 0x8 |
|
41 |
#define SCSI_INTERMEDIATE 0x10 |
|
42 |
#define SCSI_INTER_MET 0x14 |
|
43 |
#define SCSI_RES_CONFLICT 0x18 |
|
44 |
#define SCSI_CMD_TERMINATED 0x22 |
|
45 |
#define SCSI_QUEUE_FULL 0x28 |
|
46 |
#define SCSI_ACA_ACTIVE 0x30 |
|
47 |
#define SCSI_TASK_ABORTED 0x40 |
|
48 |
|
|
37 | 49 |
#define SCSI_DMA_BUF_SIZE 65536 |
38 | 50 |
|
39 | 51 |
typedef struct SCSIRequest { |
... | ... | |
124 | 136 |
} |
125 | 137 |
|
126 | 138 |
/* Helper function for command completion. */ |
127 |
static void scsi_command_complete(SCSIRequest *r, int sense) |
|
139 |
static void scsi_command_complete(SCSIRequest *r, int status, int sense)
|
|
128 | 140 |
{ |
129 | 141 |
SCSIDeviceState *s = r->dev; |
130 | 142 |
uint32_t tag; |
... | ... | |
132 | 144 |
s->sense = sense; |
133 | 145 |
tag = r->tag; |
134 | 146 |
scsi_remove_request(r); |
135 |
s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
|
|
147 |
s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
|
|
136 | 148 |
} |
137 | 149 |
|
138 | 150 |
/* Cancel a pending data transfer. */ |
... | ... | |
157 | 169 |
|
158 | 170 |
if (ret) { |
159 | 171 |
DPRINTF("IO error\n"); |
160 |
scsi_command_complete(r, SENSE_HARDWARE_ERROR); |
|
172 |
scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
|
|
161 | 173 |
return; |
162 | 174 |
} |
163 | 175 |
DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len); |
... | ... | |
175 | 187 |
r = scsi_find_request(s, tag); |
176 | 188 |
if (!r) { |
177 | 189 |
BADF("Bad read tag 0x%x\n", tag); |
178 |
/* ??? This is the wrong error. */ |
|
179 |
scsi_command_complete(r, SENSE_HARDWARE_ERROR); |
|
190 |
scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR); |
|
180 | 191 |
return; |
181 | 192 |
} |
182 | 193 |
if (r->sector_count == (uint32_t)-1) { |
... | ... | |
187 | 198 |
} |
188 | 199 |
DPRINTF("Read sector_count=%d\n", r->sector_count); |
189 | 200 |
if (r->sector_count == 0) { |
190 |
scsi_command_complete(r, SENSE_NO_SENSE); |
|
201 |
scsi_command_complete(r, SCSI_OK, SENSE_NO_SENSE);
|
|
191 | 202 |
return; |
192 | 203 |
} |
193 | 204 |
|
... | ... | |
199 | 210 |
r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n, |
200 | 211 |
scsi_read_complete, r); |
201 | 212 |
if (r->aiocb == NULL) |
202 |
scsi_command_complete(r, SENSE_HARDWARE_ERROR); |
|
213 |
scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
|
|
203 | 214 |
r->sector += n; |
204 | 215 |
r->sector_count -= n; |
205 | 216 |
} |
... | ... | |
217 | 228 |
|
218 | 229 |
r->aiocb = NULL; |
219 | 230 |
if (r->sector_count == 0) { |
220 |
scsi_command_complete(r, SENSE_NO_SENSE); |
|
231 |
scsi_command_complete(r, SCSI_OK, SENSE_NO_SENSE);
|
|
221 | 232 |
} else { |
222 | 233 |
len = r->sector_count * 512; |
223 | 234 |
if (len > SCSI_DMA_BUF_SIZE) { |
... | ... | |
241 | 252 |
r = scsi_find_request(s, tag); |
242 | 253 |
if (!r) { |
243 | 254 |
BADF("Bad write tag 0x%x\n", tag); |
244 |
scsi_command_complete(r, SENSE_HARDWARE_ERROR); |
|
255 |
scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
|
|
245 | 256 |
return 1; |
246 | 257 |
} |
247 | 258 |
if (r->aiocb) |
... | ... | |
251 | 262 |
r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n, |
252 | 263 |
scsi_write_complete, r); |
253 | 264 |
if (r->aiocb == NULL) |
254 |
scsi_command_complete(r, SENSE_HARDWARE_ERROR); |
|
265 |
scsi_command_complete(r, SCSI_CHECK_COND, SENSE_HARDWARE_ERROR);
|
|
255 | 266 |
r->sector += n; |
256 | 267 |
r->sector_count -= n; |
257 | 268 |
} else { |
... | ... | |
601 | 612 |
outbuf[7] = 0; |
602 | 613 |
r->buf_len = 8; |
603 | 614 |
} else { |
604 |
scsi_command_complete(r, SENSE_NOT_READY); |
|
615 |
scsi_command_complete(r, SCSI_CHECK_COND, SENSE_NOT_READY);
|
|
605 | 616 |
return 0; |
606 | 617 |
} |
607 | 618 |
break; |
... | ... | |
688 | 699 |
default: |
689 | 700 |
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]); |
690 | 701 |
fail: |
691 |
scsi_command_complete(r, SENSE_ILLEGAL_REQUEST); |
|
702 |
scsi_command_complete(r, SCSI_CHECK_COND, SENSE_ILLEGAL_REQUEST);
|
|
692 | 703 |
return 0; |
693 | 704 |
} |
694 | 705 |
if (r->sector_count == 0 && r->buf_len == 0) { |
695 |
scsi_command_complete(r, SENSE_NO_SENSE); |
|
706 |
scsi_command_complete(r, SCSI_OK, SENSE_NO_SENSE);
|
|
696 | 707 |
} |
697 | 708 |
len = r->sector_count * 512 + r->buf_len; |
698 | 709 |
if (is_write) { |
Also available in: Unified diff