Revision 5c6c0e51 hw/scsi-disk.c

b/hw/scsi-disk.c
86 86
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
87 87
static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
88 88

  
89
static SCSIDiskReq *scsi_new_request(SCSIDiskState *s, uint32_t tag,
89
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
90 90
        uint32_t lun)
91 91
{
92
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
92 93
    SCSIRequest *req;
93 94
    SCSIDiskReq *r;
94 95

  
95 96
    req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun);
96 97
    r = DO_UPCAST(SCSIDiskReq, req, req);
97 98
    r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
98
    return r;
99
    return req;
99 100
}
100 101

  
101 102
static void scsi_free_request(SCSIRequest *req)
......
105 106
    qemu_vfree(r->iov.iov_base);
106 107
}
107 108

  
108
static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
109
{
110
    return DO_UPCAST(SCSIDiskReq, req, scsi_req_find(&s->qdev, tag));
111
}
112

  
113 109
static void scsi_disk_clear_sense(SCSIDiskState *s)
114 110
{
115 111
    memset(&s->sense, 0, sizeof(s->sense));
......
138 134
}
139 135

  
140 136
/* Cancel a pending data transfer.  */
141
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
137
static void scsi_cancel_io(SCSIRequest *req)
142 138
{
143
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
144
    SCSIDiskReq *r;
145
    DPRINTF("Cancel tag=0x%x\n", tag);
146
    r = scsi_find_request(s, tag);
147
    if (r) {
148
        if (r->req.aiocb)
149
            bdrv_aio_cancel(r->req.aiocb);
150
        r->req.aiocb = NULL;
151
        scsi_req_dequeue(&r->req);
139
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
140

  
141
    DPRINTF("Cancel tag=0x%x\n", req->tag);
142
    if (r->req.aiocb) {
143
        bdrv_aio_cancel(r->req.aiocb);
152 144
    }
145
    r->req.aiocb = NULL;
146
    scsi_req_dequeue(&r->req);
153 147
}
154 148

  
155 149
static void scsi_read_complete(void * opaque, int ret)
......
174 168
}
175 169

  
176 170

  
177
static void scsi_read_request(SCSIDiskReq *r)
171
/* Read more data from scsi device into buffer.  */
172
static void scsi_read_data(SCSIRequest *req)
178 173
{
174
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
179 175
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
180 176
    uint32_t n;
181 177

  
......
207 203
    }
208 204
}
209 205

  
210
/* Read more data from scsi device into buffer.  */
211
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
212
{
213
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
214
    SCSIDiskReq *r;
215

  
216
    r = scsi_find_request(s, tag);
217
    if (!r) {
218
        BADF("Bad read tag 0x%x\n", tag);
219
        /* ??? This is the wrong error.  */
220
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
221
        return;
222
    }
223

  
224
    scsi_read_request(r);
225
}
226

  
227 206
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
228 207
{
229 208
    int is_read = (type == SCSI_REQ_STATUS_RETRY_READ);
......
285 264
    }
286 265
}
287 266

  
288
static void scsi_write_request(SCSIDiskReq *r)
267
static int scsi_write_data(SCSIRequest *req)
289 268
{
269
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
290 270
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
291 271
    uint32_t n;
292 272

  
......
305 285
        /* Invoke completion routine to fetch data from host.  */
306 286
        scsi_write_complete(r, 0);
307 287
    }
308
}
309

  
310
/* Write data to a scsi device.  Returns nonzero on failure.
311
   The transfer may complete asynchronously.  */
312
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
313
{
314
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
315
    SCSIDiskReq *r;
316

  
317
    DPRINTF("Write data tag=0x%x\n", tag);
318
    r = scsi_find_request(s, tag);
319
    if (!r) {
320
        BADF("Bad write tag 0x%x\n", tag);
321
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
322
        return 1;
323
    }
324

  
325
    scsi_write_request(r);
326 288

  
327 289
    return 0;
328 290
}
......
347 309

  
348 310
            switch (status & SCSI_REQ_STATUS_RETRY_TYPE_MASK) {
349 311
            case SCSI_REQ_STATUS_RETRY_READ:
350
                scsi_read_request(r);
312
                scsi_read_data(&r->req);
351 313
                break;
352 314
            case SCSI_REQ_STATUS_RETRY_WRITE:
353
                scsi_write_request(r);
315
                scsi_write_data(&r->req);
354 316
                break;
355 317
            case SCSI_REQ_STATUS_RETRY_FLUSH:
356 318
                ret = scsi_disk_emulate_command(r, r->iov.iov_base);
......
376 338
}
377 339

  
378 340
/* Return a pointer to the data buffer.  */
379
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
341
static uint8_t *scsi_get_buf(SCSIRequest *req)
380 342
{
381
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
382
    SCSIDiskReq *r;
343
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
383 344

  
384
    r = scsi_find_request(s, tag);
385
    if (!r) {
386
        BADF("Bad buffer tag 0x%x\n", tag);
387
        return NULL;
388
    }
389 345
    return (uint8_t *)r->iov.iov_base;
390 346
}
391 347

  
......
1029 985
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
1030 986
   and zero if the command does not transfer any data.  */
1031 987

  
1032
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
1033
                                 uint8_t *buf, int lun)
988
static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
1034 989
{
1035
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
990
    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
991
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
1036 992
    int32_t len;
1037 993
    int is_write;
1038 994
    uint8_t command;
1039 995
    uint8_t *outbuf;
1040
    SCSIDiskReq *r;
1041 996
    int rc;
1042 997

  
998
    scsi_req_enqueue(req);
1043 999
    command = buf[0];
1044
    r = scsi_find_request(s, tag);
1045
    if (r) {
1046
        BADF("Tag 0x%x already in use\n", tag);
1047
        scsi_cancel_io(d, tag);
1048
    }
1049
    /* ??? Tags are not unique for different luns.  We only implement a
1050
       single lun, so this should not matter.  */
1051
    r = scsi_new_request(s, tag, lun);
1052 1000
    outbuf = (uint8_t *)r->iov.iov_base;
1053 1001
    is_write = 0;
1054 1002
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
......
1067 1015
    }
1068 1016
#endif
1069 1017

  
1070
    if (lun || buf[1] >> 5) {
1018
    if (req->lun || buf[1] >> 5) {
1071 1019
        /* Only LUN 0 supported.  */
1072
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
1020
        DPRINTF("Unimplemented LUN %d\n", req->lun ? req->lun : buf[1] >> 5);
1073 1021
        if (command != REQUEST_SENSE && command != INQUIRY)
1074 1022
            goto fail;
1075 1023
    }
......
1095 1043
    case REZERO_UNIT:
1096 1044
        rc = scsi_disk_emulate_command(r, outbuf);
1097 1045
        if (rc < 0) {
1098
            scsi_req_unref(&r->req);
1099 1046
            return 0;
1100 1047
        }
1101 1048

  
......
1105 1052
    case READ_10:
1106 1053
    case READ_12:
1107 1054
    case READ_16:
1108
        len = r->req.cmd.xfer / d->blocksize;
1055
        len = r->req.cmd.xfer / s->qdev.blocksize;
1109 1056
        DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
1110 1057
        if (r->req.cmd.lba > s->max_lba)
1111 1058
            goto illegal_lba;
......
1119 1066
    case WRITE_VERIFY:
1120 1067
    case WRITE_VERIFY_12:
1121 1068
    case WRITE_VERIFY_16:
1122
        len = r->req.cmd.xfer / d->blocksize;
1069
        len = r->req.cmd.xfer / s->qdev.blocksize;
1123 1070
        DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1124 1071
                (command & 0xe) == 0xe ? "And Verify " : "",
1125 1072
                r->req.cmd.lba, len);
......
1154 1101
        }
1155 1102
        break;
1156 1103
    case WRITE_SAME_16:
1157
        len = r->req.cmd.xfer / d->blocksize;
1104
        len = r->req.cmd.xfer / s->qdev.blocksize;
1158 1105

  
1159 1106
        DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n",
1160 1107
                r->req.cmd.lba, len);
......
1182 1129
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1183 1130
    fail:
1184 1131
        scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
1185
        scsi_req_unref(&r->req);
1186 1132
        return 0;
1187 1133
    illegal_lba:
1188 1134
        scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
1189
        scsi_req_unref(&r->req);
1190 1135
        return 0;
1191 1136
    }
1192 1137
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
......
1199 1144
        if (!r->sector_count)
1200 1145
            r->sector_count = -1;
1201 1146
    }
1202
    scsi_req_unref(&r->req);
1203 1147
    return len;
1204 1148
}
1205 1149

  
......
1213 1157
            bdrv_aio_cancel(r->req.aiocb);
1214 1158
        }
1215 1159
        scsi_req_dequeue(&r->req);
1160
        scsi_req_unref(&r->req);
1216 1161
    }
1217 1162
}
1218 1163

  
......
1325 1270
        .qdev.reset   = scsi_disk_reset,
1326 1271
        .init         = scsi_hd_initfn,
1327 1272
        .destroy      = scsi_destroy,
1273
        .alloc_req    = scsi_new_request,
1328 1274
        .free_req     = scsi_free_request,
1329 1275
        .send_command = scsi_send_command,
1330 1276
        .read_data    = scsi_read_data,
......
1344 1290
        .qdev.reset   = scsi_disk_reset,
1345 1291
        .init         = scsi_cd_initfn,
1346 1292
        .destroy      = scsi_destroy,
1293
        .alloc_req    = scsi_new_request,
1347 1294
        .free_req     = scsi_free_request,
1348 1295
        .send_command = scsi_send_command,
1349 1296
        .read_data    = scsi_read_data,
......
1362 1309
        .qdev.reset   = scsi_disk_reset,
1363 1310
        .init         = scsi_disk_initfn,
1364 1311
        .destroy      = scsi_destroy,
1312
        .alloc_req    = scsi_new_request,
1365 1313
        .free_req     = scsi_free_request,
1366 1314
        .send_command = scsi_send_command,
1367 1315
        .read_data    = scsi_read_data,

Also available in: Unified diff