Revision a1f0cce2 hw/scsi-generic.c

b/hw/scsi-generic.c
66 66
    uint8_t senselen;
67 67
};
68 68

  
69
static void scsi_set_sense(SCSIGenericState *s, SCSISense sense)
70
{
71
    s->senselen = scsi_build_sense(sense, s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
72
    s->driver_status = SG_ERR_DRIVER_SENSE;
73
}
74

  
75
static void scsi_clear_sense(SCSIGenericState *s)
76
{
77
    memset(s->sensebuf, 0, SCSI_SENSE_BUF_SIZE);
78
    s->senselen = 0;
79
    s->driver_status = 0;
80
}
81

  
69 82
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
70 83
{
71 84
    SCSIRequest *req;
......
92 105
    if (s->driver_status & SG_ERR_DRIVER_SENSE)
93 106
        s->senselen = r->io_header.sb_len_wr;
94 107

  
95
    if (ret != 0)
96
        r->req.status = BUSY;
97
    else {
108
    if (ret != 0) {
109
        switch (ret) {
110
        case -EINVAL:
111
            r->req.status = CHECK_CONDITION;
112
            scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
113
            break;
114
        case -ENOMEM:
115
            r->req.status = CHECK_CONDITION;
116
            scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
117
            break;
118
        default:
119
            r->req.status = CHECK_CONDITION;
120
            scsi_set_sense(s, SENSE_CODE(IO_ERROR));
121
            break;
122
        }
123
    } else {
98 124
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
99 125
            r->req.status = BUSY;
100 126
            BADF("Driver Timeout\n");
......
144 170
    r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
145 171
    if (r->req.aiocb == NULL) {
146 172
        BADF("execute_command: read failed !\n");
147
        return -1;
173
        return -ENOMEM;
148 174
    }
149 175

  
150 176
    return 0;
......
198 224
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
199 225
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
200 226
        scsi_req_data(&r->req, s->senselen);
227
        /* Clear sensebuf after REQUEST_SENSE */
228
        scsi_clear_sense(s);
201 229
        return;
202 230
    }
203 231

  
204 232
    ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
205
    if (ret == -1) {
206
        scsi_command_complete(r, -EINVAL);
233
    if (ret < 0) {
234
        scsi_command_complete(r, ret);
207 235
        return;
208 236
    }
209 237
}
......
246 274
    }
247 275

  
248 276
    ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
249
    if (ret == -1) {
250
        scsi_command_complete(r, -EINVAL);
277
    if (ret < 0) {
278
        scsi_command_complete(r, ret);
251 279
        return 1;
252 280
    }
253 281

  
......
296 324
    if (cmd[0] != REQUEST_SENSE &&
297 325
        (req->lun != s->lun || (cmd[1] >> 5) != s->lun)) {
298 326
        DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : cmd[1] >> 5);
299

  
300
        s->sensebuf[0] = 0x70;
301
        s->sensebuf[1] = 0x00;
302
        s->sensebuf[2] = ILLEGAL_REQUEST;
303
        s->sensebuf[3] = 0x00;
304
        s->sensebuf[4] = 0x00;
305
        s->sensebuf[5] = 0x00;
306
        s->sensebuf[6] = 0x00;
307
        s->senselen = 7;
308
        s->driver_status = SG_ERR_DRIVER_SENSE;
327
        scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
309 328
        r->req.status = CHECK_CONDITION;
310 329
        scsi_req_complete(&r->req);
311 330
        return 0;
......
313 332

  
314 333
    if (-1 == scsi_req_parse(&r->req, cmd)) {
315 334
        BADF("Unsupported command length, command %x\n", cmd[0]);
316
        scsi_req_dequeue(&r->req);
317
        scsi_req_unref(&r->req);
335
        scsi_command_complete(r, -EINVAL);
318 336
        return 0;
319 337
    }
320 338
    scsi_req_fixup(&r->req);
......
338 356
        r->buflen = 0;
339 357
        r->buf = NULL;
340 358
        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
341
        if (ret == -1) {
342
            scsi_command_complete(r, -EINVAL);
359
        if (ret < 0) {
360
            scsi_command_complete(r, ret);
361
            return 0;
343 362
        }
344 363
        return 0;
345 364
    }

Also available in: Unified diff