Statistics
| Branch: | Revision:

root / hw / scsi-disk.c @ cedd91d2

History | View | Annotate | Download (31.2 kB)

1 2e5d83bb pbrook
/*
2 2e5d83bb pbrook
 * SCSI Device emulation
3 2e5d83bb pbrook
 *
4 2e5d83bb pbrook
 * Copyright (c) 2006 CodeSourcery.
5 2e5d83bb pbrook
 * Based on code by Fabrice Bellard
6 2e5d83bb pbrook
 *
7 2e5d83bb pbrook
 * Written by Paul Brook
8 2e5d83bb pbrook
 *
9 2e5d83bb pbrook
 * This code is licenced under the LGPL.
10 a917d384 pbrook
 *
11 a917d384 pbrook
 * Note that this file only handles the SCSI architecture model and device
12 1d4db89c balrog
 * commands.  Emulation of interface/link layer protocols is handled by
13 1d4db89c balrog
 * the host adapter emulator.
14 2e5d83bb pbrook
 */
15 2e5d83bb pbrook
16 fa879c64 aliguori
#include <qemu-common.h>
17 fa879c64 aliguori
#include <sysemu.h>
18 2e5d83bb pbrook
//#define DEBUG_SCSI
19 2e5d83bb pbrook
20 2e5d83bb pbrook
#ifdef DEBUG_SCSI
21 001faf32 Blue Swirl
#define DPRINTF(fmt, ...) \
22 001faf32 Blue Swirl
do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
23 2e5d83bb pbrook
#else
24 001faf32 Blue Swirl
#define DPRINTF(fmt, ...) do {} while(0)
25 2e5d83bb pbrook
#endif
26 2e5d83bb pbrook
27 001faf32 Blue Swirl
#define BADF(fmt, ...) \
28 001faf32 Blue Swirl
do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
29 2e5d83bb pbrook
30 87ecb68b pbrook
#include "qemu-common.h"
31 87ecb68b pbrook
#include "block.h"
32 87ecb68b pbrook
#include "scsi-disk.h"
33 2e5d83bb pbrook
34 2e5d83bb pbrook
#define SENSE_NO_SENSE        0
35 1aacf348 pbrook
#define SENSE_NOT_READY       2
36 4d611c9a pbrook
#define SENSE_HARDWARE_ERROR  4
37 2e5d83bb pbrook
#define SENSE_ILLEGAL_REQUEST 5
38 2e5d83bb pbrook
39 22864256 blueswir1
#define STATUS_GOOD            0
40 22864256 blueswir1
#define STATUS_CHECK_CONDITION 2
41 22864256 blueswir1
42 f0f72ffe aurel32
#define SCSI_DMA_BUF_SIZE    131072
43 57575058 balrog
#define SCSI_MAX_INQUIRY_LEN 256
44 a917d384 pbrook
45 ea8a5d7f aliguori
#define SCSI_REQ_STATUS_RETRY 0x01
46 ea8a5d7f aliguori
47 a917d384 pbrook
typedef struct SCSIRequest {
48 8ccc2ace ths
    SCSIDeviceState *dev;
49 2e5d83bb pbrook
    uint32_t tag;
50 e035b43d aliguori
    /* ??? We should probably keep track of whether the data transfer is
51 2e5d83bb pbrook
       a read or a write.  Currently we rely on the host getting it right.  */
52 a917d384 pbrook
    /* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
53 e035b43d aliguori
    uint64_t sector;
54 e035b43d aliguori
    uint32_t sector_count;
55 c87c0672 aliguori
    struct iovec iov;
56 c87c0672 aliguori
    QEMUIOVector qiov;
57 4d611c9a pbrook
    BlockDriverAIOCB *aiocb;
58 a917d384 pbrook
    struct SCSIRequest *next;
59 ea8a5d7f aliguori
    uint32_t status;
60 a917d384 pbrook
} SCSIRequest;
61 a917d384 pbrook
62 8ccc2ace ths
struct SCSIDeviceState
63 a917d384 pbrook
{
64 a917d384 pbrook
    BlockDriverState *bdrv;
65 a917d384 pbrook
    SCSIRequest *requests;
66 a917d384 pbrook
    /* The qemu block layer uses a fixed 512 byte sector size.
67 a917d384 pbrook
       This is the number of 512 byte blocks in a single scsi sector.  */
68 a917d384 pbrook
    int cluster_size;
69 274fb0e1 aliguori
    uint64_t max_lba;
70 a917d384 pbrook
    int sense;
71 a917d384 pbrook
    int tcq;
72 4d611c9a pbrook
    /* Completion functions may be called from either scsi_{read,write}_data
73 4d611c9a pbrook
       or from the AIO completion routines.  */
74 2e5d83bb pbrook
    scsi_completionfn completion;
75 2e5d83bb pbrook
    void *opaque;
76 fa879c64 aliguori
    char drive_serial_str[21];
77 213189ab Markus Armbruster
    QEMUBH *bh;
78 2e5d83bb pbrook
};
79 2e5d83bb pbrook
80 a917d384 pbrook
/* Global pool of SCSIRequest structures.  */
81 a917d384 pbrook
static SCSIRequest *free_requests = NULL;
82 a917d384 pbrook
83 8ccc2ace ths
static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
84 2e5d83bb pbrook
{
85 a917d384 pbrook
    SCSIRequest *r;
86 a917d384 pbrook
87 a917d384 pbrook
    if (free_requests) {
88 a917d384 pbrook
        r = free_requests;
89 a917d384 pbrook
        free_requests = r->next;
90 a917d384 pbrook
    } else {
91 a917d384 pbrook
        r = qemu_malloc(sizeof(SCSIRequest));
92 c87c0672 aliguori
        r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
93 a917d384 pbrook
    }
94 a917d384 pbrook
    r->dev = s;
95 a917d384 pbrook
    r->tag = tag;
96 a917d384 pbrook
    r->sector_count = 0;
97 c87c0672 aliguori
    r->iov.iov_len = 0;
98 a917d384 pbrook
    r->aiocb = NULL;
99 ea8a5d7f aliguori
    r->status = 0;
100 a917d384 pbrook
101 a917d384 pbrook
    r->next = s->requests;
102 a917d384 pbrook
    s->requests = r;
103 a917d384 pbrook
    return r;
104 2e5d83bb pbrook
}
105 2e5d83bb pbrook
106 a917d384 pbrook
static void scsi_remove_request(SCSIRequest *r)
107 4d611c9a pbrook
{
108 a917d384 pbrook
    SCSIRequest *last;
109 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
110 a917d384 pbrook
111 a917d384 pbrook
    if (s->requests == r) {
112 a917d384 pbrook
        s->requests = r->next;
113 a917d384 pbrook
    } else {
114 a917d384 pbrook
        last = s->requests;
115 a917d384 pbrook
        while (last && last->next != r)
116 a917d384 pbrook
            last = last->next;
117 a917d384 pbrook
        if (last) {
118 a917d384 pbrook
            last->next = r->next;
119 a917d384 pbrook
        } else {
120 a917d384 pbrook
            BADF("Orphaned request\n");
121 a917d384 pbrook
        }
122 a917d384 pbrook
    }
123 a917d384 pbrook
    r->next = free_requests;
124 a917d384 pbrook
    free_requests = r;
125 4d611c9a pbrook
}
126 4d611c9a pbrook
127 8ccc2ace ths
static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
128 4d611c9a pbrook
{
129 a917d384 pbrook
    SCSIRequest *r;
130 4d611c9a pbrook
131 a917d384 pbrook
    r = s->requests;
132 a917d384 pbrook
    while (r && r->tag != tag)
133 a917d384 pbrook
        r = r->next;
134 4d611c9a pbrook
135 a917d384 pbrook
    return r;
136 a917d384 pbrook
}
137 a917d384 pbrook
138 a917d384 pbrook
/* Helper function for command completion.  */
139 22864256 blueswir1
static void scsi_command_complete(SCSIRequest *r, int status, int sense)
140 a917d384 pbrook
{
141 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
142 a917d384 pbrook
    uint32_t tag;
143 22864256 blueswir1
    DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", r->tag, status, sense);
144 a917d384 pbrook
    s->sense = sense;
145 a917d384 pbrook
    tag = r->tag;
146 a917d384 pbrook
    scsi_remove_request(r);
147 22864256 blueswir1
    s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
148 4d611c9a pbrook
}
149 4d611c9a pbrook
150 4d611c9a pbrook
/* Cancel a pending data transfer.  */
151 8ccc2ace ths
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
152 4d611c9a pbrook
{
153 8ccc2ace ths
    SCSIDeviceState *s = d->state;
154 a917d384 pbrook
    SCSIRequest *r;
155 a917d384 pbrook
    DPRINTF("Cancel tag=0x%x\n", tag);
156 a917d384 pbrook
    r = scsi_find_request(s, tag);
157 a917d384 pbrook
    if (r) {
158 a917d384 pbrook
        if (r->aiocb)
159 a917d384 pbrook
            bdrv_aio_cancel(r->aiocb);
160 a917d384 pbrook
        r->aiocb = NULL;
161 a917d384 pbrook
        scsi_remove_request(r);
162 a917d384 pbrook
    }
163 a917d384 pbrook
}
164 a917d384 pbrook
165 a917d384 pbrook
static void scsi_read_complete(void * opaque, int ret)
166 a917d384 pbrook
{
167 a917d384 pbrook
    SCSIRequest *r = (SCSIRequest *)opaque;
168 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
169 a917d384 pbrook
170 a917d384 pbrook
    if (ret) {
171 a917d384 pbrook
        DPRINTF("IO error\n");
172 22864256 blueswir1
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, 0);
173 22864256 blueswir1
        scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NO_SENSE);
174 4d611c9a pbrook
        return;
175 4d611c9a pbrook
    }
176 0bf9e31a Blue Swirl
    DPRINTF("Data ready tag=0x%x len=%" PRId64 "\n", r->tag, r->iov.iov_len);
177 a917d384 pbrook
178 c87c0672 aliguori
    s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
179 4d611c9a pbrook
}
180 4d611c9a pbrook
181 a917d384 pbrook
/* Read more data from scsi device into buffer.  */
182 8ccc2ace ths
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
183 2e5d83bb pbrook
{
184 8ccc2ace ths
    SCSIDeviceState *s = d->state;
185 a917d384 pbrook
    SCSIRequest *r;
186 2e5d83bb pbrook
    uint32_t n;
187 2e5d83bb pbrook
188 a917d384 pbrook
    r = scsi_find_request(s, tag);
189 a917d384 pbrook
    if (!r) {
190 a917d384 pbrook
        BADF("Bad read tag 0x%x\n", tag);
191 b1fa7164 blueswir1
        /* ??? This is the wrong error.  */
192 22864256 blueswir1
        scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
193 a917d384 pbrook
        return;
194 2e5d83bb pbrook
    }
195 a917d384 pbrook
    if (r->sector_count == (uint32_t)-1) {
196 0bf9e31a Blue Swirl
        DPRINTF("Read buf_len=%" PRId64 "\n", r->iov.iov_len);
197 a917d384 pbrook
        r->sector_count = 0;
198 c87c0672 aliguori
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->iov.iov_len);
199 a917d384 pbrook
        return;
200 2e5d83bb pbrook
    }
201 a917d384 pbrook
    DPRINTF("Read sector_count=%d\n", r->sector_count);
202 a917d384 pbrook
    if (r->sector_count == 0) {
203 22864256 blueswir1
        scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
204 a917d384 pbrook
        return;
205 2e5d83bb pbrook
    }
206 2e5d83bb pbrook
207 a917d384 pbrook
    n = r->sector_count;
208 a917d384 pbrook
    if (n > SCSI_DMA_BUF_SIZE / 512)
209 a917d384 pbrook
        n = SCSI_DMA_BUF_SIZE / 512;
210 a917d384 pbrook
211 c87c0672 aliguori
    r->iov.iov_len = n * 512;
212 c87c0672 aliguori
    qemu_iovec_init_external(&r->qiov, &r->iov, 1);
213 c87c0672 aliguori
    r->aiocb = bdrv_aio_readv(s->bdrv, r->sector, &r->qiov, n,
214 c87c0672 aliguori
                              scsi_read_complete, r);
215 a917d384 pbrook
    if (r->aiocb == NULL)
216 22864256 blueswir1
        scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
217 a917d384 pbrook
    r->sector += n;
218 a917d384 pbrook
    r->sector_count -= n;
219 2e5d83bb pbrook
}
220 2e5d83bb pbrook
221 ea8a5d7f aliguori
static int scsi_handle_write_error(SCSIRequest *r, int error)
222 ea8a5d7f aliguori
{
223 ea8a5d7f aliguori
    BlockInterfaceErrorAction action = drive_get_onerror(r->dev->bdrv);
224 ea8a5d7f aliguori
225 ea8a5d7f aliguori
    if (action == BLOCK_ERR_IGNORE)
226 ea8a5d7f aliguori
        return 0;
227 ea8a5d7f aliguori
228 ea8a5d7f aliguori
    if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
229 ea8a5d7f aliguori
            || action == BLOCK_ERR_STOP_ANY) {
230 ea8a5d7f aliguori
        r->status |= SCSI_REQ_STATUS_RETRY;
231 ea8a5d7f aliguori
        vm_stop(0);
232 ea8a5d7f aliguori
    } else {
233 ea8a5d7f aliguori
        scsi_command_complete(r, STATUS_CHECK_CONDITION,
234 ea8a5d7f aliguori
                SENSE_HARDWARE_ERROR);
235 ea8a5d7f aliguori
    }
236 ea8a5d7f aliguori
237 ea8a5d7f aliguori
    return 1;
238 ea8a5d7f aliguori
}
239 ea8a5d7f aliguori
240 4d611c9a pbrook
static void scsi_write_complete(void * opaque, int ret)
241 4d611c9a pbrook
{
242 a917d384 pbrook
    SCSIRequest *r = (SCSIRequest *)opaque;
243 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
244 a917d384 pbrook
    uint32_t len;
245 ea8a5d7f aliguori
    uint32_t n;
246 ea8a5d7f aliguori
247 ea8a5d7f aliguori
    r->aiocb = NULL;
248 4d611c9a pbrook
249 4d611c9a pbrook
    if (ret) {
250 ea8a5d7f aliguori
        if (scsi_handle_write_error(r, -ret))
251 ea8a5d7f aliguori
            return;
252 4d611c9a pbrook
    }
253 4d611c9a pbrook
254 c87c0672 aliguori
    n = r->iov.iov_len / 512;
255 ea8a5d7f aliguori
    r->sector += n;
256 ea8a5d7f aliguori
    r->sector_count -= n;
257 a917d384 pbrook
    if (r->sector_count == 0) {
258 22864256 blueswir1
        scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
259 a917d384 pbrook
    } else {
260 a917d384 pbrook
        len = r->sector_count * 512;
261 a917d384 pbrook
        if (len > SCSI_DMA_BUF_SIZE) {
262 a917d384 pbrook
            len = SCSI_DMA_BUF_SIZE;
263 a917d384 pbrook
        }
264 c87c0672 aliguori
        r->iov.iov_len = len;
265 a917d384 pbrook
        DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
266 a917d384 pbrook
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
267 4d611c9a pbrook
    }
268 4d611c9a pbrook
}
269 4d611c9a pbrook
270 ea8a5d7f aliguori
static void scsi_write_request(SCSIRequest *r)
271 ea8a5d7f aliguori
{
272 ea8a5d7f aliguori
    SCSIDeviceState *s = r->dev;
273 ea8a5d7f aliguori
    uint32_t n;
274 ea8a5d7f aliguori
275 c87c0672 aliguori
    n = r->iov.iov_len / 512;
276 ea8a5d7f aliguori
    if (n) {
277 c87c0672 aliguori
        qemu_iovec_init_external(&r->qiov, &r->iov, 1);
278 c87c0672 aliguori
        r->aiocb = bdrv_aio_writev(s->bdrv, r->sector, &r->qiov, n,
279 c87c0672 aliguori
                                   scsi_write_complete, r);
280 ea8a5d7f aliguori
        if (r->aiocb == NULL)
281 ea8a5d7f aliguori
            scsi_command_complete(r, STATUS_CHECK_CONDITION,
282 ea8a5d7f aliguori
                                  SENSE_HARDWARE_ERROR);
283 ea8a5d7f aliguori
    } else {
284 ea8a5d7f aliguori
        /* Invoke completion routine to fetch data from host.  */
285 ea8a5d7f aliguori
        scsi_write_complete(r, 0);
286 ea8a5d7f aliguori
    }
287 ea8a5d7f aliguori
}
288 ea8a5d7f aliguori
289 4d611c9a pbrook
/* Write data to a scsi device.  Returns nonzero on failure.
290 4d611c9a pbrook
   The transfer may complete asynchronously.  */
291 8ccc2ace ths
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
292 2e5d83bb pbrook
{
293 8ccc2ace ths
    SCSIDeviceState *s = d->state;
294 a917d384 pbrook
    SCSIRequest *r;
295 2e5d83bb pbrook
296 a917d384 pbrook
    DPRINTF("Write data tag=0x%x\n", tag);
297 a917d384 pbrook
    r = scsi_find_request(s, tag);
298 a917d384 pbrook
    if (!r) {
299 a917d384 pbrook
        BADF("Bad write tag 0x%x\n", tag);
300 22864256 blueswir1
        scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
301 2e5d83bb pbrook
        return 1;
302 2e5d83bb pbrook
    }
303 ea8a5d7f aliguori
304 a917d384 pbrook
    if (r->aiocb)
305 a917d384 pbrook
        BADF("Data transfer already in progress\n");
306 ea8a5d7f aliguori
307 ea8a5d7f aliguori
    scsi_write_request(r);
308 2e5d83bb pbrook
309 a917d384 pbrook
    return 0;
310 a917d384 pbrook
}
311 2e5d83bb pbrook
312 213189ab Markus Armbruster
static void scsi_dma_restart_bh(void *opaque)
313 ea8a5d7f aliguori
{
314 ea8a5d7f aliguori
    SCSIDeviceState *s = opaque;
315 ea8a5d7f aliguori
    SCSIRequest *r = s->requests;
316 213189ab Markus Armbruster
317 213189ab Markus Armbruster
    qemu_bh_delete(s->bh);
318 213189ab Markus Armbruster
    s->bh = NULL;
319 ea8a5d7f aliguori
320 ea8a5d7f aliguori
    while (r) {
321 ea8a5d7f aliguori
        if (r->status & SCSI_REQ_STATUS_RETRY) {
322 ea8a5d7f aliguori
            r->status &= ~SCSI_REQ_STATUS_RETRY;
323 ea8a5d7f aliguori
            scsi_write_request(r); 
324 ea8a5d7f aliguori
        }
325 ea8a5d7f aliguori
        r = r->next;
326 ea8a5d7f aliguori
    }
327 ea8a5d7f aliguori
}
328 ea8a5d7f aliguori
329 213189ab Markus Armbruster
static void scsi_dma_restart_cb(void *opaque, int running, int reason)
330 213189ab Markus Armbruster
{
331 213189ab Markus Armbruster
    SCSIDeviceState *s = opaque;
332 213189ab Markus Armbruster
333 213189ab Markus Armbruster
    if (!running)
334 213189ab Markus Armbruster
        return;
335 213189ab Markus Armbruster
336 213189ab Markus Armbruster
    if (!s->bh) {
337 213189ab Markus Armbruster
        s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
338 213189ab Markus Armbruster
        qemu_bh_schedule(s->bh);
339 213189ab Markus Armbruster
    }
340 213189ab Markus Armbruster
}
341 213189ab Markus Armbruster
342 a917d384 pbrook
/* Return a pointer to the data buffer.  */
343 8ccc2ace ths
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
344 a917d384 pbrook
{
345 8ccc2ace ths
    SCSIDeviceState *s = d->state;
346 a917d384 pbrook
    SCSIRequest *r;
347 2e5d83bb pbrook
348 a917d384 pbrook
    r = scsi_find_request(s, tag);
349 a917d384 pbrook
    if (!r) {
350 a917d384 pbrook
        BADF("Bad buffer tag 0x%x\n", tag);
351 a917d384 pbrook
        return NULL;
352 4d611c9a pbrook
    }
353 3f4cb3d3 blueswir1
    return (uint8_t *)r->iov.iov_base;
354 2e5d83bb pbrook
}
355 2e5d83bb pbrook
356 2e5d83bb pbrook
/* Execute a scsi command.  Returns the length of the data expected by the
357 2e5d83bb pbrook
   command.  This will be Positive for data transfers from the device
358 2e5d83bb pbrook
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
359 2e5d83bb pbrook
   and zero if the command does not transfer any data.  */
360 2e5d83bb pbrook
361 8ccc2ace ths
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
362 8ccc2ace ths
                                 uint8_t *buf, int lun)
363 2e5d83bb pbrook
{
364 8ccc2ace ths
    SCSIDeviceState *s = d->state;
365 96b8f136 ths
    uint64_t nb_sectors;
366 86106e59 aliguori
    uint64_t lba;
367 2e5d83bb pbrook
    uint32_t len;
368 2e5d83bb pbrook
    int cmdlen;
369 2e5d83bb pbrook
    int is_write;
370 a917d384 pbrook
    uint8_t command;
371 a917d384 pbrook
    uint8_t *outbuf;
372 a917d384 pbrook
    SCSIRequest *r;
373 a917d384 pbrook
374 a917d384 pbrook
    command = buf[0];
375 a917d384 pbrook
    r = scsi_find_request(s, tag);
376 a917d384 pbrook
    if (r) {
377 a917d384 pbrook
        BADF("Tag 0x%x already in use\n", tag);
378 8ccc2ace ths
        scsi_cancel_io(d, tag);
379 a917d384 pbrook
    }
380 a917d384 pbrook
    /* ??? Tags are not unique for different luns.  We only implement a
381 a917d384 pbrook
       single lun, so this should not matter.  */
382 a917d384 pbrook
    r = scsi_new_request(s, tag);
383 3f4cb3d3 blueswir1
    outbuf = (uint8_t *)r->iov.iov_base;
384 2e5d83bb pbrook
    is_write = 0;
385 a917d384 pbrook
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
386 a917d384 pbrook
    switch (command >> 5) {
387 2e5d83bb pbrook
    case 0:
388 86106e59 aliguori
        lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
389 86106e59 aliguori
              (((uint64_t) buf[1] & 0x1f) << 16);
390 2e5d83bb pbrook
        len = buf[4];
391 2e5d83bb pbrook
        cmdlen = 6;
392 2e5d83bb pbrook
        break;
393 2e5d83bb pbrook
    case 1:
394 2e5d83bb pbrook
    case 2:
395 86106e59 aliguori
        lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
396 86106e59 aliguori
              ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
397 2e5d83bb pbrook
        len = buf[8] | (buf[7] << 8);
398 2e5d83bb pbrook
        cmdlen = 10;
399 2e5d83bb pbrook
        break;
400 2e5d83bb pbrook
    case 4:
401 86106e59 aliguori
        lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
402 86106e59 aliguori
              ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
403 86106e59 aliguori
              ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
404 86106e59 aliguori
              ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
405 2e5d83bb pbrook
        len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
406 2e5d83bb pbrook
        cmdlen = 16;
407 2e5d83bb pbrook
        break;
408 2e5d83bb pbrook
    case 5:
409 86106e59 aliguori
        lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
410 86106e59 aliguori
              ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
411 2e5d83bb pbrook
        len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
412 2e5d83bb pbrook
        cmdlen = 12;
413 2e5d83bb pbrook
        break;
414 2e5d83bb pbrook
    default:
415 a917d384 pbrook
        BADF("Unsupported command length, command %x\n", command);
416 2e5d83bb pbrook
        goto fail;
417 2e5d83bb pbrook
    }
418 2e5d83bb pbrook
#ifdef DEBUG_SCSI
419 2e5d83bb pbrook
    {
420 2e5d83bb pbrook
        int i;
421 2e5d83bb pbrook
        for (i = 1; i < cmdlen; i++) {
422 2e5d83bb pbrook
            printf(" 0x%02x", buf[i]);
423 2e5d83bb pbrook
        }
424 2e5d83bb pbrook
        printf("\n");
425 2e5d83bb pbrook
    }
426 2e5d83bb pbrook
#endif
427 0fc5c15a pbrook
    if (lun || buf[1] >> 5) {
428 2e5d83bb pbrook
        /* Only LUN 0 supported.  */
429 0fc5c15a pbrook
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
430 22864256 blueswir1
        if (command != 0x03 && command != 0x12) /* REQUEST SENSE and INQUIRY */
431 22864256 blueswir1
            goto fail;
432 2e5d83bb pbrook
    }
433 a917d384 pbrook
    switch (command) {
434 2e5d83bb pbrook
    case 0x0:
435 2e5d83bb pbrook
        DPRINTF("Test Unit Ready\n");
436 58a2c436 blueswir1
        if (!bdrv_is_inserted(s->bdrv))
437 58a2c436 blueswir1
            goto notready;
438 2e5d83bb pbrook
        break;
439 2e5d83bb pbrook
    case 0x03:
440 2e5d83bb pbrook
        DPRINTF("Request Sense (len %d)\n", len);
441 2e5d83bb pbrook
        if (len < 4)
442 2e5d83bb pbrook
            goto fail;
443 67cd24a8 ths
        memset(outbuf, 0, 4);
444 c87c0672 aliguori
        r->iov.iov_len = 4;
445 ed6a9b30 blueswir1
        if (s->sense == SENSE_NOT_READY && len >= 18) {
446 ed6a9b30 blueswir1
            memset(outbuf, 0, 18);
447 c87c0672 aliguori
            r->iov.iov_len = 18;
448 ed6a9b30 blueswir1
            outbuf[7] = 10;
449 ed6a9b30 blueswir1
            /* asc 0x3a, ascq 0: Medium not present */
450 ed6a9b30 blueswir1
            outbuf[12] = 0x3a;
451 ed6a9b30 blueswir1
            outbuf[13] = 0;
452 ed6a9b30 blueswir1
        }
453 a917d384 pbrook
        outbuf[0] = 0xf0;
454 a917d384 pbrook
        outbuf[1] = 0;
455 a917d384 pbrook
        outbuf[2] = s->sense;
456 2e5d83bb pbrook
        break;
457 2e5d83bb pbrook
    case 0x12:
458 7d8406be pbrook
        DPRINTF("Inquiry (len %d)\n", len);
459 1d4db89c balrog
        if (buf[1] & 0x2) {
460 1d4db89c balrog
            /* Command support data - optional, not implemented */
461 1d4db89c balrog
            BADF("optional INQUIRY command support request not implemented\n");
462 1d4db89c balrog
            goto fail;
463 1d4db89c balrog
        }
464 1d4db89c balrog
        else if (buf[1] & 0x1) {
465 1d4db89c balrog
            /* Vital product data */
466 1d4db89c balrog
            uint8_t page_code = buf[2];
467 1d4db89c balrog
            if (len < 4) {
468 1d4db89c balrog
                BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
469 1d4db89c balrog
                     "less than 4\n", page_code, len);
470 1d4db89c balrog
                goto fail;
471 1d4db89c balrog
            }
472 1d4db89c balrog
473 1d4db89c balrog
            switch (page_code) {
474 1d4db89c balrog
                case 0x00:
475 1d4db89c balrog
                    {
476 1d4db89c balrog
                        /* Supported page codes, mandatory */
477 1d4db89c balrog
                        DPRINTF("Inquiry EVPD[Supported pages] "
478 1d4db89c balrog
                                "buffer size %d\n", len);
479 1d4db89c balrog
480 c87c0672 aliguori
                        r->iov.iov_len = 0;
481 1d4db89c balrog
482 1d4db89c balrog
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
483 c87c0672 aliguori
                            outbuf[r->iov.iov_len++] = 5;
484 1d4db89c balrog
                        } else {
485 c87c0672 aliguori
                            outbuf[r->iov.iov_len++] = 0;
486 1d4db89c balrog
                        }
487 1d4db89c balrog
488 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x00; // this page
489 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x00;
490 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 3;    // number of pages
491 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x00; // list of supported pages (this page)
492 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x80; // unit serial number
493 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x83; // device identification
494 1d4db89c balrog
                    }
495 1d4db89c balrog
                    break;
496 1d4db89c balrog
                case 0x80:
497 1d4db89c balrog
                    {
498 fa879c64 aliguori
                        int l;
499 fa879c64 aliguori
500 1d4db89c balrog
                        /* Device serial number, optional */
501 1d4db89c balrog
                        if (len < 4) {
502 1d4db89c balrog
                            BADF("Error: EVPD[Serial number] Inquiry buffer "
503 1d4db89c balrog
                                 "size %d too small, %d needed\n", len, 4);
504 1d4db89c balrog
                            goto fail;
505 1d4db89c balrog
                        }
506 1d4db89c balrog
507 1d4db89c balrog
                        DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
508 fa879c64 aliguori
                        l = MIN(len, strlen(s->drive_serial_str));
509 1d4db89c balrog
510 c87c0672 aliguori
                        r->iov.iov_len = 0;
511 1d4db89c balrog
512 1d4db89c balrog
                        /* Supported page codes */
513 1d4db89c balrog
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
514 c87c0672 aliguori
                            outbuf[r->iov.iov_len++] = 5;
515 1d4db89c balrog
                        } else {
516 c87c0672 aliguori
                            outbuf[r->iov.iov_len++] = 0;
517 1d4db89c balrog
                        }
518 1d4db89c balrog
519 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x80; // this page
520 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x00;
521 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = l;
522 c87c0672 aliguori
                        memcpy(&outbuf[r->iov.iov_len], s->drive_serial_str, l);
523 c87c0672 aliguori
                        r->iov.iov_len += l;
524 1d4db89c balrog
                    }
525 1d4db89c balrog
526 1d4db89c balrog
                    break;
527 1d4db89c balrog
                case 0x83:
528 1d4db89c balrog
                    {
529 1d4db89c balrog
                        /* Device identification page, mandatory */
530 1d4db89c balrog
                        int max_len = 255 - 8;
531 1d4db89c balrog
                        int id_len = strlen(bdrv_get_device_name(s->bdrv));
532 1d4db89c balrog
                        if (id_len > max_len)
533 1d4db89c balrog
                            id_len = max_len;
534 1d4db89c balrog
535 1d4db89c balrog
                        DPRINTF("Inquiry EVPD[Device identification] "
536 1d4db89c balrog
                                "buffer size %d\n", len);
537 c87c0672 aliguori
                        r->iov.iov_len = 0;
538 1d4db89c balrog
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
539 c87c0672 aliguori
                            outbuf[r->iov.iov_len++] = 5;
540 1d4db89c balrog
                        } else {
541 c87c0672 aliguori
                            outbuf[r->iov.iov_len++] = 0;
542 1d4db89c balrog
                        }
543 1d4db89c balrog
544 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x83; // this page
545 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x00;
546 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 3 + id_len;
547 1d4db89c balrog
548 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0x2; // ASCII
549 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0;   // not officially assigned
550 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = 0;   // reserved
551 c87c0672 aliguori
                        outbuf[r->iov.iov_len++] = id_len; // length of data following
552 1d4db89c balrog
553 c87c0672 aliguori
                        memcpy(&outbuf[r->iov.iov_len],
554 1d4db89c balrog
                               bdrv_get_device_name(s->bdrv), id_len);
555 c87c0672 aliguori
                        r->iov.iov_len += id_len;
556 1d4db89c balrog
                    }
557 1d4db89c balrog
                    break;
558 1d4db89c balrog
                default:
559 1d4db89c balrog
                    BADF("Error: unsupported Inquiry (EVPD[%02X]) "
560 1d4db89c balrog
                         "buffer size %d\n", page_code, len);
561 1d4db89c balrog
                    goto fail;
562 1d4db89c balrog
            }
563 1d4db89c balrog
            /* done with EVPD */
564 1d4db89c balrog
            break;
565 1d4db89c balrog
        }
566 1d4db89c balrog
        else {
567 1d4db89c balrog
            /* Standard INQUIRY data */
568 1d4db89c balrog
            if (buf[2] != 0) {
569 1d4db89c balrog
                BADF("Error: Inquiry (STANDARD) page or code "
570 1d4db89c balrog
                     "is non-zero [%02X]\n", buf[2]);
571 1d4db89c balrog
                goto fail;
572 1d4db89c balrog
            }
573 1d4db89c balrog
574 1d4db89c balrog
            /* PAGE CODE == 0 */
575 1d4db89c balrog
            if (len < 5) {
576 1d4db89c balrog
                BADF("Error: Inquiry (STANDARD) buffer size %d "
577 1d4db89c balrog
                     "is less than 5\n", len);
578 1d4db89c balrog
                goto fail;
579 1d4db89c balrog
            }
580 1d4db89c balrog
581 1d4db89c balrog
            if (len < 36) {
582 1d4db89c balrog
                BADF("Error: Inquiry (STANDARD) buffer size %d "
583 1d4db89c balrog
                     "is less than 36 (TODO: only 5 required)\n", len);
584 1d4db89c balrog
            }
585 2e5d83bb pbrook
        }
586 57575058 balrog
587 57575058 balrog
        if(len > SCSI_MAX_INQUIRY_LEN)
588 57575058 balrog
            len = SCSI_MAX_INQUIRY_LEN;
589 57575058 balrog
590 57575058 balrog
        memset(outbuf, 0, len);
591 22864256 blueswir1
592 22864256 blueswir1
        if (lun || buf[1] >> 5) {
593 22864256 blueswir1
            outbuf[0] = 0x7f;        /* LUN not supported */
594 22864256 blueswir1
        } else if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
595 a917d384 pbrook
            outbuf[0] = 5;
596 a917d384 pbrook
            outbuf[1] = 0x80;
597 a917d384 pbrook
            memcpy(&outbuf[16], "QEMU CD-ROM    ", 16);
598 2e5d83bb pbrook
        } else {
599 a917d384 pbrook
            outbuf[0] = 0;
600 a917d384 pbrook
            memcpy(&outbuf[16], "QEMU HARDDISK  ", 16);
601 2e5d83bb pbrook
        }
602 a917d384 pbrook
        memcpy(&outbuf[8], "QEMU   ", 8);
603 a917d384 pbrook
        memcpy(&outbuf[32], QEMU_VERSION, 4);
604 17acfe32 pbrook
        /* Identify device as SCSI-3 rev 1.
605 17acfe32 pbrook
           Some later commands are also implemented. */
606 a917d384 pbrook
        outbuf[2] = 3;
607 a917d384 pbrook
        outbuf[3] = 2; /* Format 2 */
608 57575058 balrog
        outbuf[4] = len - 5; /* Additional Length = (Len - 1) - 4 */
609 a917d384 pbrook
        /* Sync data transfer and TCQ.  */
610 a917d384 pbrook
        outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
611 c87c0672 aliguori
        r->iov.iov_len = len;
612 2e5d83bb pbrook
        break;
613 2e5d83bb pbrook
    case 0x16:
614 2e5d83bb pbrook
        DPRINTF("Reserve(6)\n");
615 2e5d83bb pbrook
        if (buf[1] & 1)
616 2e5d83bb pbrook
            goto fail;
617 2e5d83bb pbrook
        break;
618 2e5d83bb pbrook
    case 0x17:
619 2e5d83bb pbrook
        DPRINTF("Release(6)\n");
620 2e5d83bb pbrook
        if (buf[1] & 1)
621 2e5d83bb pbrook
            goto fail;
622 2e5d83bb pbrook
        break;
623 2e5d83bb pbrook
    case 0x1a:
624 7d8406be pbrook
    case 0x5a:
625 17acfe32 pbrook
        {
626 a917d384 pbrook
            uint8_t *p;
627 17acfe32 pbrook
            int page;
628 17acfe32 pbrook
629 17acfe32 pbrook
            page = buf[2] & 0x3f;
630 17acfe32 pbrook
            DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
631 a917d384 pbrook
            p = outbuf;
632 17acfe32 pbrook
            memset(p, 0, 4);
633 a917d384 pbrook
            outbuf[1] = 0; /* Default media type.  */
634 a917d384 pbrook
            outbuf[3] = 0; /* Block descriptor length.  */
635 17acfe32 pbrook
            if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
636 a917d384 pbrook
                outbuf[2] = 0x80; /* Readonly.  */
637 17acfe32 pbrook
            }
638 17acfe32 pbrook
            p += 4;
639 5e65a310 blueswir1
            if (page == 4) {
640 5e65a310 blueswir1
                int cylinders, heads, secs;
641 5e65a310 blueswir1
642 5e65a310 blueswir1
                /* Rigid disk device geometry page. */
643 5e65a310 blueswir1
                p[0] = 4;
644 5e65a310 blueswir1
                p[1] = 0x16;
645 5e65a310 blueswir1
                /* if a geometry hint is available, use it */
646 5e65a310 blueswir1
                bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
647 5e65a310 blueswir1
                p[2] = (cylinders >> 16) & 0xff;
648 5e65a310 blueswir1
                p[3] = (cylinders >> 8) & 0xff;
649 5e65a310 blueswir1
                p[4] = cylinders & 0xff;
650 5e65a310 blueswir1
                p[5] = heads & 0xff;
651 5e65a310 blueswir1
                /* Write precomp start cylinder, disabled */
652 5e65a310 blueswir1
                p[6] = (cylinders >> 16) & 0xff;
653 5e65a310 blueswir1
                p[7] = (cylinders >> 8) & 0xff;
654 5e65a310 blueswir1
                p[8] = cylinders & 0xff;
655 5e65a310 blueswir1
                /* Reduced current start cylinder, disabled */
656 5e65a310 blueswir1
                p[9] = (cylinders >> 16) & 0xff;
657 5e65a310 blueswir1
                p[10] = (cylinders >> 8) & 0xff;
658 5e65a310 blueswir1
                p[11] = cylinders & 0xff;
659 5e65a310 blueswir1
                /* Device step rate [ns], 200ns */
660 5e65a310 blueswir1
                p[12] = 0;
661 5e65a310 blueswir1
                p[13] = 200;
662 5e65a310 blueswir1
                /* Landing zone cylinder */
663 5e65a310 blueswir1
                p[14] = 0xff;
664 5e65a310 blueswir1
                p[15] =  0xff;
665 5e65a310 blueswir1
                p[16] = 0xff;
666 5e65a310 blueswir1
                /* Medium rotation rate [rpm], 5400 rpm */
667 5e65a310 blueswir1
                p[20] = (5400 >> 8) & 0xff;
668 5e65a310 blueswir1
                p[21] = 5400 & 0xff;
669 5e65a310 blueswir1
                p += 0x16;
670 5e65a310 blueswir1
            } else if (page == 5) {
671 5e65a310 blueswir1
                int cylinders, heads, secs;
672 5e65a310 blueswir1
673 5e65a310 blueswir1
                /* Flexible disk device geometry page. */
674 5e65a310 blueswir1
                p[0] = 5;
675 5e65a310 blueswir1
                p[1] = 0x1e;
676 5e65a310 blueswir1
                /* Transfer rate [kbit/s], 5Mbit/s */
677 5e65a310 blueswir1
                p[2] = 5000 >> 8;
678 5e65a310 blueswir1
                p[3] = 5000 & 0xff;
679 5e65a310 blueswir1
                /* if a geometry hint is available, use it */
680 5e65a310 blueswir1
                bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);
681 5e65a310 blueswir1
                p[4] = heads & 0xff;
682 5e65a310 blueswir1
                p[5] = secs & 0xff;
683 5e65a310 blueswir1
                p[6] = s->cluster_size * 2;
684 5e65a310 blueswir1
                p[8] = (cylinders >> 8) & 0xff;
685 5e65a310 blueswir1
                p[9] = cylinders & 0xff;
686 5e65a310 blueswir1
                /* Write precomp start cylinder, disabled */
687 5e65a310 blueswir1
                p[10] = (cylinders >> 8) & 0xff;
688 5e65a310 blueswir1
                p[11] = cylinders & 0xff;
689 5e65a310 blueswir1
                /* Reduced current start cylinder, disabled */
690 5e65a310 blueswir1
                p[12] = (cylinders >> 8) & 0xff;
691 5e65a310 blueswir1
                p[13] = cylinders & 0xff;
692 5e65a310 blueswir1
                /* Device step rate [100us], 100us */
693 5e65a310 blueswir1
                p[14] = 0;
694 5e65a310 blueswir1
                p[15] = 1;
695 5e65a310 blueswir1
                /* Device step pulse width [us], 1us */
696 5e65a310 blueswir1
                p[16] = 1;
697 5e65a310 blueswir1
                /* Device head settle delay [100us], 100us */
698 5e65a310 blueswir1
                p[17] = 0;
699 5e65a310 blueswir1
                p[18] = 1;
700 5e65a310 blueswir1
                /* Motor on delay [0.1s], 0.1s */
701 5e65a310 blueswir1
                p[19] = 1;
702 5e65a310 blueswir1
                /* Motor off delay [0.1s], 0.1s */
703 5e65a310 blueswir1
                p[20] = 1;
704 5e65a310 blueswir1
                /* Medium rotation rate [rpm], 5400 rpm */
705 5e65a310 blueswir1
                p[28] = (5400 >> 8) & 0xff;
706 5e65a310 blueswir1
                p[29] = 5400 & 0xff;
707 5e65a310 blueswir1
                p += 0x1e;
708 5e65a310 blueswir1
            } else if ((page == 8 || page == 0x3f)) {
709 17acfe32 pbrook
                /* Caching page.  */
710 67cd24a8 ths
                memset(p,0,20);
711 17acfe32 pbrook
                p[0] = 8;
712 17acfe32 pbrook
                p[1] = 0x12;
713 17acfe32 pbrook
                p[2] = 4; /* WCE */
714 67cd24a8 ths
                p += 20;
715 17acfe32 pbrook
            }
716 17acfe32 pbrook
            if ((page == 0x3f || page == 0x2a)
717 17acfe32 pbrook
                    && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
718 17acfe32 pbrook
                /* CD Capabilities and Mechanical Status page. */
719 17acfe32 pbrook
                p[0] = 0x2a;
720 17acfe32 pbrook
                p[1] = 0x14;
721 17acfe32 pbrook
                p[2] = 3; // CD-R & CD-RW read
722 17acfe32 pbrook
                p[3] = 0; // Writing not supported
723 17acfe32 pbrook
                p[4] = 0x7f; /* Audio, composite, digital out,
724 17acfe32 pbrook
                                         mode 2 form 1&2, multi session */
725 17acfe32 pbrook
                p[5] = 0xff; /* CD DA, DA accurate, RW supported,
726 17acfe32 pbrook
                                         RW corrected, C2 errors, ISRC,
727 17acfe32 pbrook
                                         UPC, Bar code */
728 17acfe32 pbrook
                p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
729 17acfe32 pbrook
                /* Locking supported, jumper present, eject, tray */
730 17acfe32 pbrook
                p[7] = 0; /* no volume & mute control, no
731 17acfe32 pbrook
                                      changer */
732 17acfe32 pbrook
                p[8] = (50 * 176) >> 8; // 50x read speed
733 17acfe32 pbrook
                p[9] = (50 * 176) & 0xff;
734 17acfe32 pbrook
                p[10] = 0 >> 8; // No volume
735 17acfe32 pbrook
                p[11] = 0 & 0xff;
736 17acfe32 pbrook
                p[12] = 2048 >> 8; // 2M buffer
737 17acfe32 pbrook
                p[13] = 2048 & 0xff;
738 17acfe32 pbrook
                p[14] = (16 * 176) >> 8; // 16x read speed current
739 17acfe32 pbrook
                p[15] = (16 * 176) & 0xff;
740 17acfe32 pbrook
                p[18] = (16 * 176) >> 8; // 16x write speed
741 17acfe32 pbrook
                p[19] = (16 * 176) & 0xff;
742 17acfe32 pbrook
                p[20] = (16 * 176) >> 8; // 16x write speed current
743 17acfe32 pbrook
                p[21] = (16 * 176) & 0xff;
744 67cd24a8 ths
                p += 22;
745 17acfe32 pbrook
            }
746 c87c0672 aliguori
            r->iov.iov_len = p - outbuf;
747 c87c0672 aliguori
            outbuf[0] = r->iov.iov_len - 4;
748 c87c0672 aliguori
            if (r->iov.iov_len > len)
749 c87c0672 aliguori
                r->iov.iov_len = len;
750 7d8406be pbrook
        }
751 17acfe32 pbrook
        break;
752 17acfe32 pbrook
    case 0x1b:
753 17acfe32 pbrook
        DPRINTF("Start Stop Unit\n");
754 b2056c16 blueswir1
        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM &&
755 b2056c16 blueswir1
            (buf[4] & 2))
756 b2056c16 blueswir1
            /* load/eject medium */
757 b2056c16 blueswir1
            bdrv_eject(s->bdrv, !(buf[4] & 1));
758 17acfe32 pbrook
        break;
759 17acfe32 pbrook
    case 0x1e:
760 17acfe32 pbrook
        DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
761 17acfe32 pbrook
        bdrv_set_locked(s->bdrv, buf[4] & 1);
762 2e5d83bb pbrook
        break;
763 2e5d83bb pbrook
    case 0x25:
764 2e5d83bb pbrook
        DPRINTF("Read Capacity\n");
765 2e5d83bb pbrook
        /* The normal LEN field for this command is zero.  */
766 a917d384 pbrook
        memset(outbuf, 0, 8);
767 2e5d83bb pbrook
        bdrv_get_geometry(s->bdrv, &nb_sectors);
768 c1c0438c aliguori
        nb_sectors /= s->cluster_size;
769 51c1ebb1 pbrook
        /* Returned value is the address of the last sector.  */
770 51c1ebb1 pbrook
        if (nb_sectors) {
771 51c1ebb1 pbrook
            nb_sectors--;
772 274fb0e1 aliguori
            /* Remember the new size for read/write sanity checking. */
773 274fb0e1 aliguori
            s->max_lba = nb_sectors;
774 e035b43d aliguori
            /* Clip to 2TB, instead of returning capacity modulo 2TB. */
775 e035b43d aliguori
            if (nb_sectors > UINT32_MAX)
776 e035b43d aliguori
                nb_sectors = UINT32_MAX;
777 a917d384 pbrook
            outbuf[0] = (nb_sectors >> 24) & 0xff;
778 a917d384 pbrook
            outbuf[1] = (nb_sectors >> 16) & 0xff;
779 a917d384 pbrook
            outbuf[2] = (nb_sectors >> 8) & 0xff;
780 a917d384 pbrook
            outbuf[3] = nb_sectors & 0xff;
781 a917d384 pbrook
            outbuf[4] = 0;
782 a917d384 pbrook
            outbuf[5] = 0;
783 a917d384 pbrook
            outbuf[6] = s->cluster_size * 2;
784 a917d384 pbrook
            outbuf[7] = 0;
785 c87c0672 aliguori
            r->iov.iov_len = 8;
786 51c1ebb1 pbrook
        } else {
787 58a2c436 blueswir1
        notready:
788 22864256 blueswir1
            scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
789 35f1df84 pbrook
            return 0;
790 51c1ebb1 pbrook
        }
791 2e5d83bb pbrook
        break;
792 2e5d83bb pbrook
    case 0x08:
793 2e5d83bb pbrook
    case 0x28:
794 86106e59 aliguori
    case 0x88:
795 0bf9e31a Blue Swirl
        DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len);
796 274fb0e1 aliguori
        if (lba > s->max_lba)
797 274fb0e1 aliguori
            goto illegal_lba;
798 a917d384 pbrook
        r->sector = lba * s->cluster_size;
799 a917d384 pbrook
        r->sector_count = len * s->cluster_size;
800 2e5d83bb pbrook
        break;
801 2e5d83bb pbrook
    case 0x0a:
802 2e5d83bb pbrook
    case 0x2a:
803 86106e59 aliguori
    case 0x8a:
804 0bf9e31a Blue Swirl
        DPRINTF("Write (sector %" PRId64 ", count %d)\n", lba, len);
805 274fb0e1 aliguori
        if (lba > s->max_lba)
806 274fb0e1 aliguori
            goto illegal_lba;
807 a917d384 pbrook
        r->sector = lba * s->cluster_size;
808 a917d384 pbrook
        r->sector_count = len * s->cluster_size;
809 2e5d83bb pbrook
        is_write = 1;
810 2e5d83bb pbrook
        break;
811 7d8406be pbrook
    case 0x35:
812 0bf9e31a Blue Swirl
        DPRINTF("Synchronise cache (sector %" PRId64 ", count %d)\n", lba, len);
813 7a6cba61 pbrook
        bdrv_flush(s->bdrv);
814 7d8406be pbrook
        break;
815 2e5d83bb pbrook
    case 0x43:
816 2e5d83bb pbrook
        {
817 7c22dd52 pbrook
            int start_track, format, msf, toclen;
818 2e5d83bb pbrook
819 2e5d83bb pbrook
            msf = buf[1] & 2;
820 2e5d83bb pbrook
            format = buf[2] & 0xf;
821 2e5d83bb pbrook
            start_track = buf[6];
822 2e5d83bb pbrook
            bdrv_get_geometry(s->bdrv, &nb_sectors);
823 2e5d83bb pbrook
            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
824 ee16b24a blueswir1
            nb_sectors /= s->cluster_size;
825 2e5d83bb pbrook
            switch(format) {
826 2e5d83bb pbrook
            case 0:
827 a917d384 pbrook
                toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
828 2e5d83bb pbrook
                break;
829 2e5d83bb pbrook
            case 1:
830 2e5d83bb pbrook
                /* multi session : only a single session defined */
831 7c22dd52 pbrook
                toclen = 12;
832 a917d384 pbrook
                memset(outbuf, 0, 12);
833 a917d384 pbrook
                outbuf[1] = 0x0a;
834 a917d384 pbrook
                outbuf[2] = 0x01;
835 a917d384 pbrook
                outbuf[3] = 0x01;
836 2e5d83bb pbrook
                break;
837 2e5d83bb pbrook
            case 2:
838 a917d384 pbrook
                toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
839 2e5d83bb pbrook
                break;
840 2e5d83bb pbrook
            default:
841 7c22dd52 pbrook
                goto error_cmd;
842 7c22dd52 pbrook
            }
843 7c22dd52 pbrook
            if (toclen > 0) {
844 7c22dd52 pbrook
                if (len > toclen)
845 7c22dd52 pbrook
                  len = toclen;
846 c87c0672 aliguori
                r->iov.iov_len = len;
847 7c22dd52 pbrook
                break;
848 2e5d83bb pbrook
            }
849 7c22dd52 pbrook
        error_cmd:
850 7c22dd52 pbrook
            DPRINTF("Read TOC error\n");
851 7c22dd52 pbrook
            goto fail;
852 2e5d83bb pbrook
        }
853 17acfe32 pbrook
    case 0x46:
854 17acfe32 pbrook
        DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
855 a917d384 pbrook
        memset(outbuf, 0, 8);
856 1235fc06 ths
        /* ??? This should probably return much more information.  For now
857 17acfe32 pbrook
           just return the basic header indicating the CD-ROM profile.  */
858 a917d384 pbrook
        outbuf[7] = 8; // CD-ROM
859 c87c0672 aliguori
        r->iov.iov_len = 8;
860 17acfe32 pbrook
        break;
861 2e5d83bb pbrook
    case 0x56:
862 2e5d83bb pbrook
        DPRINTF("Reserve(10)\n");
863 2e5d83bb pbrook
        if (buf[1] & 3)
864 2e5d83bb pbrook
            goto fail;
865 2e5d83bb pbrook
        break;
866 2e5d83bb pbrook
    case 0x57:
867 2e5d83bb pbrook
        DPRINTF("Release(10)\n");
868 2e5d83bb pbrook
        if (buf[1] & 3)
869 2e5d83bb pbrook
            goto fail;
870 2e5d83bb pbrook
        break;
871 86106e59 aliguori
    case 0x9e:
872 86106e59 aliguori
        /* Service Action In subcommands. */
873 86106e59 aliguori
        if ((buf[1] & 31) == 0x10) {
874 86106e59 aliguori
            DPRINTF("SAI READ CAPACITY(16)\n");
875 86106e59 aliguori
            memset(outbuf, 0, len);
876 86106e59 aliguori
            bdrv_get_geometry(s->bdrv, &nb_sectors);
877 c1c0438c aliguori
            nb_sectors /= s->cluster_size;
878 86106e59 aliguori
            /* Returned value is the address of the last sector.  */
879 86106e59 aliguori
            if (nb_sectors) {
880 86106e59 aliguori
                nb_sectors--;
881 274fb0e1 aliguori
                /* Remember the new size for read/write sanity checking. */
882 274fb0e1 aliguori
                s->max_lba = nb_sectors;
883 86106e59 aliguori
                outbuf[0] = (nb_sectors >> 56) & 0xff;
884 86106e59 aliguori
                outbuf[1] = (nb_sectors >> 48) & 0xff;
885 86106e59 aliguori
                outbuf[2] = (nb_sectors >> 40) & 0xff;
886 86106e59 aliguori
                outbuf[3] = (nb_sectors >> 32) & 0xff;
887 86106e59 aliguori
                outbuf[4] = (nb_sectors >> 24) & 0xff;
888 86106e59 aliguori
                outbuf[5] = (nb_sectors >> 16) & 0xff;
889 86106e59 aliguori
                outbuf[6] = (nb_sectors >> 8) & 0xff;
890 86106e59 aliguori
                outbuf[7] = nb_sectors & 0xff;
891 86106e59 aliguori
                outbuf[8] = 0;
892 86106e59 aliguori
                outbuf[9] = 0;
893 86106e59 aliguori
                outbuf[10] = s->cluster_size * 2;
894 86106e59 aliguori
                outbuf[11] = 0;
895 86106e59 aliguori
                /* Protection, exponent and lowest lba field left blank. */
896 c87c0672 aliguori
                r->iov.iov_len = len;
897 86106e59 aliguori
            } else {
898 86106e59 aliguori
                scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);
899 86106e59 aliguori
                return 0;
900 86106e59 aliguori
            }
901 86106e59 aliguori
            break;
902 86106e59 aliguori
        }
903 86106e59 aliguori
        DPRINTF("Unsupported Service Action In\n");
904 86106e59 aliguori
        goto fail;
905 2e5d83bb pbrook
    case 0xa0:
906 2e5d83bb pbrook
        DPRINTF("Report LUNs (len %d)\n", len);
907 2e5d83bb pbrook
        if (len < 16)
908 2e5d83bb pbrook
            goto fail;
909 a917d384 pbrook
        memset(outbuf, 0, 16);
910 a917d384 pbrook
        outbuf[3] = 8;
911 c87c0672 aliguori
        r->iov.iov_len = 16;
912 2e5d83bb pbrook
        break;
913 22864256 blueswir1
    case 0x2f:
914 0bf9e31a Blue Swirl
        DPRINTF("Verify (sector %" PRId64 ", count %d)\n", lba, len);
915 22864256 blueswir1
        break;
916 2e5d83bb pbrook
    default:
917 2e5d83bb pbrook
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
918 2e5d83bb pbrook
    fail:
919 22864256 blueswir1
        scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_ILLEGAL_REQUEST);
920 2e5d83bb pbrook
        return 0;
921 274fb0e1 aliguori
    illegal_lba:
922 274fb0e1 aliguori
        scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR);
923 274fb0e1 aliguori
        return 0;
924 2e5d83bb pbrook
    }
925 c87c0672 aliguori
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
926 22864256 blueswir1
        scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);
927 a917d384 pbrook
    }
928 c87c0672 aliguori
    len = r->sector_count * 512 + r->iov.iov_len;
929 a917d384 pbrook
    if (is_write) {
930 a917d384 pbrook
        return -len;
931 a917d384 pbrook
    } else {
932 a917d384 pbrook
        if (!r->sector_count)
933 a917d384 pbrook
            r->sector_count = -1;
934 a917d384 pbrook
        return len;
935 2e5d83bb pbrook
    }
936 2e5d83bb pbrook
}
937 2e5d83bb pbrook
938 8ccc2ace ths
static void scsi_destroy(SCSIDevice *d)
939 2e5d83bb pbrook
{
940 8ccc2ace ths
    qemu_free(d->state);
941 8ccc2ace ths
    qemu_free(d);
942 2e5d83bb pbrook
}
943 2e5d83bb pbrook
944 8ccc2ace ths
SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
945 8ccc2ace ths
                           scsi_completionfn completion, void *opaque)
946 2e5d83bb pbrook
{
947 8ccc2ace ths
    SCSIDevice *d;
948 8ccc2ace ths
    SCSIDeviceState *s;
949 274fb0e1 aliguori
    uint64_t nb_sectors;
950 2e5d83bb pbrook
951 8ccc2ace ths
    s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
952 2e5d83bb pbrook
    s->bdrv = bdrv;
953 a917d384 pbrook
    s->tcq = tcq;
954 2e5d83bb pbrook
    s->completion = completion;
955 2e5d83bb pbrook
    s->opaque = opaque;
956 2e5d83bb pbrook
    if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
957 7c22dd52 pbrook
        s->cluster_size = 4;
958 2e5d83bb pbrook
    } else {
959 7c22dd52 pbrook
        s->cluster_size = 1;
960 2e5d83bb pbrook
    }
961 274fb0e1 aliguori
    bdrv_get_geometry(s->bdrv, &nb_sectors);
962 274fb0e1 aliguori
    nb_sectors /= s->cluster_size;
963 274fb0e1 aliguori
    if (nb_sectors)
964 274fb0e1 aliguori
        nb_sectors--;
965 274fb0e1 aliguori
    s->max_lba = nb_sectors;
966 fa879c64 aliguori
    strncpy(s->drive_serial_str, drive_get_serial(s->bdrv),
967 fa879c64 aliguori
            sizeof(s->drive_serial_str));
968 fa879c64 aliguori
    if (strlen(s->drive_serial_str) == 0)
969 00766a4e blueswir1
        pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), "0");
970 ea8a5d7f aliguori
    qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
971 8ccc2ace ths
    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
972 8ccc2ace ths
    d->state = s;
973 8ccc2ace ths
    d->destroy = scsi_destroy;
974 8ccc2ace ths
    d->send_command = scsi_send_command;
975 8ccc2ace ths
    d->read_data = scsi_read_data;
976 8ccc2ace ths
    d->write_data = scsi_write_data;
977 8ccc2ace ths
    d->cancel_io = scsi_cancel_io;
978 8ccc2ace ths
    d->get_buf = scsi_get_buf;
979 2e5d83bb pbrook
980 8ccc2ace ths
    return d;
981 8ccc2ace ths
}