Revision efb9ee02 hw/scsi-disk.c

b/hw/scsi-disk.c
51 51

  
52 52
typedef struct SCSIDiskReq {
53 53
    SCSIRequest req;
54
    /* ??? We should probably keep track of whether the data transfer is
55
       a read or a write.  Currently we rely on the host getting it right.  */
56 54
    /* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
57 55
    uint64_t sector;
58 56
    uint32_t sector_count;
......
180 178
    /* No data transfer may already be in progress */
181 179
    assert(r->req.aiocb == NULL);
182 180

  
181
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
182
        DPRINTF("Data transfer direction invalid\n");
183
        scsi_read_complete(r, -EINVAL);
184
        return;
185
    }
186

  
183 187
    n = r->sector_count;
184 188
    if (n > SCSI_DMA_BUF_SIZE / 512)
185 189
        n = SCSI_DMA_BUF_SIZE / 512;
......
216 220
        if (type == SCSI_REQ_STATUS_RETRY_READ) {
217 221
            scsi_req_data(&r->req, 0);
218 222
        }
219
        if (error == ENOMEM) {
223
        switch (error) {
224
        case ENOMEM:
220 225
            scsi_command_complete(r, CHECK_CONDITION,
221 226
                                  SENSE_CODE(TARGET_FAILURE));
222
        } else {
227
            break;
228
        case EINVAL:
229
            scsi_command_complete(r, CHECK_CONDITION,
230
                                  SENSE_CODE(INVALID_FIELD));
231
            break;
232
        default:
223 233
            scsi_command_complete(r, CHECK_CONDITION,
224 234
                                  SENSE_CODE(IO_ERROR));
235
            break;
225 236
        }
226 237
        bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
227 238
    }
228

  
229 239
    return 1;
230 240
}
231 241

  
......
268 278
    /* No data transfer may already be in progress */
269 279
    assert(r->req.aiocb == NULL);
270 280

  
281
    if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
282
        DPRINTF("Data transfer direction invalid\n");
283
        scsi_write_complete(r, -EINVAL);
284
        return 0;
285
    }
286

  
271 287
    n = r->iov.iov_len / 512;
272 288
    if (n) {
273 289
        qemu_iovec_init_external(&r->qiov, &r->iov, 1);
......
987 1003
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
988 1004
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
989 1005
    int32_t len;
990
    int is_write;
991 1006
    uint8_t command;
992 1007
    uint8_t *outbuf;
993 1008
    int rc;
994 1009

  
995 1010
    command = buf[0];
996 1011
    outbuf = (uint8_t *)r->iov.iov_base;
997
    is_write = 0;
998 1012
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
999 1013

  
1000 1014
    if (scsi_req_parse(&r->req, buf) != 0) {
......
1074 1088
            goto illegal_lba;
1075 1089
        r->sector = r->req.cmd.lba * s->cluster_size;
1076 1090
        r->sector_count = len * s->cluster_size;
1077
        is_write = 1;
1078 1091
        break;
1079 1092
    case MODE_SELECT:
1080 1093
        DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
......
1140 1153
        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
1141 1154
    }
1142 1155
    len = r->sector_count * 512 + r->iov.iov_len;
1143
    if (is_write) {
1144
        len = -len;
1156
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
1157
        return -len;
1145 1158
    } else {
1146 1159
        if (!r->sector_count)
1147 1160
            r->sector_count = -1;
1161
        return len;
1148 1162
    }
1149
    return len;
1150 1163
}
1151 1164

  
1152 1165
static void scsi_disk_reset(DeviceState *dev)

Also available in: Unified diff