Statistics
| Branch: | Revision:

root / hw / scsi-disk.c @ 6b4c11cd

History | View | Annotate | Download (22.4 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 2e5d83bb pbrook
//#define DEBUG_SCSI
17 2e5d83bb pbrook
18 2e5d83bb pbrook
#ifdef DEBUG_SCSI
19 2e5d83bb pbrook
#define DPRINTF(fmt, args...) \
20 2e5d83bb pbrook
do { printf("scsi-disk: " fmt , ##args); } while (0)
21 2e5d83bb pbrook
#else
22 2e5d83bb pbrook
#define DPRINTF(fmt, args...) do {} while(0)
23 2e5d83bb pbrook
#endif
24 2e5d83bb pbrook
25 2e5d83bb pbrook
#define BADF(fmt, args...) \
26 2e5d83bb pbrook
do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
27 2e5d83bb pbrook
28 87ecb68b pbrook
#include "qemu-common.h"
29 87ecb68b pbrook
#include "block.h"
30 87ecb68b pbrook
#include "scsi-disk.h"
31 2e5d83bb pbrook
32 2e5d83bb pbrook
#define SENSE_NO_SENSE        0
33 1aacf348 pbrook
#define SENSE_NOT_READY       2
34 4d611c9a pbrook
#define SENSE_HARDWARE_ERROR  4
35 2e5d83bb pbrook
#define SENSE_ILLEGAL_REQUEST 5
36 2e5d83bb pbrook
37 a917d384 pbrook
#define SCSI_DMA_BUF_SIZE    65536
38 a917d384 pbrook
39 a917d384 pbrook
typedef struct SCSIRequest {
40 8ccc2ace ths
    SCSIDeviceState *dev;
41 2e5d83bb pbrook
    uint32_t tag;
42 2e5d83bb pbrook
    /* ??? We should probably keep track of whether the data trasfer is
43 2e5d83bb pbrook
       a read or a write.  Currently we rely on the host getting it right.  */
44 a917d384 pbrook
    /* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
45 2e5d83bb pbrook
    int sector;
46 2e5d83bb pbrook
    int sector_count;
47 a917d384 pbrook
    /* The amounnt of data in the buffer.  */
48 2e5d83bb pbrook
    int buf_len;
49 33f00271 balrog
    uint8_t *dma_buf;
50 4d611c9a pbrook
    BlockDriverAIOCB *aiocb;
51 a917d384 pbrook
    struct SCSIRequest *next;
52 a917d384 pbrook
} SCSIRequest;
53 a917d384 pbrook
54 8ccc2ace ths
struct SCSIDeviceState
55 a917d384 pbrook
{
56 a917d384 pbrook
    BlockDriverState *bdrv;
57 a917d384 pbrook
    SCSIRequest *requests;
58 a917d384 pbrook
    /* The qemu block layer uses a fixed 512 byte sector size.
59 a917d384 pbrook
       This is the number of 512 byte blocks in a single scsi sector.  */
60 a917d384 pbrook
    int cluster_size;
61 a917d384 pbrook
    int sense;
62 a917d384 pbrook
    int tcq;
63 4d611c9a pbrook
    /* Completion functions may be called from either scsi_{read,write}_data
64 4d611c9a pbrook
       or from the AIO completion routines.  */
65 2e5d83bb pbrook
    scsi_completionfn completion;
66 2e5d83bb pbrook
    void *opaque;
67 2e5d83bb pbrook
};
68 2e5d83bb pbrook
69 a917d384 pbrook
/* Global pool of SCSIRequest structures.  */
70 a917d384 pbrook
static SCSIRequest *free_requests = NULL;
71 a917d384 pbrook
72 8ccc2ace ths
static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
73 2e5d83bb pbrook
{
74 a917d384 pbrook
    SCSIRequest *r;
75 a917d384 pbrook
76 a917d384 pbrook
    if (free_requests) {
77 a917d384 pbrook
        r = free_requests;
78 a917d384 pbrook
        free_requests = r->next;
79 a917d384 pbrook
    } else {
80 a917d384 pbrook
        r = qemu_malloc(sizeof(SCSIRequest));
81 33f00271 balrog
        r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
82 a917d384 pbrook
    }
83 a917d384 pbrook
    r->dev = s;
84 a917d384 pbrook
    r->tag = tag;
85 a917d384 pbrook
    r->sector_count = 0;
86 a917d384 pbrook
    r->buf_len = 0;
87 a917d384 pbrook
    r->aiocb = NULL;
88 a917d384 pbrook
89 a917d384 pbrook
    r->next = s->requests;
90 a917d384 pbrook
    s->requests = r;
91 a917d384 pbrook
    return r;
92 2e5d83bb pbrook
}
93 2e5d83bb pbrook
94 a917d384 pbrook
static void scsi_remove_request(SCSIRequest *r)
95 4d611c9a pbrook
{
96 a917d384 pbrook
    SCSIRequest *last;
97 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
98 a917d384 pbrook
99 a917d384 pbrook
    if (s->requests == r) {
100 a917d384 pbrook
        s->requests = r->next;
101 a917d384 pbrook
    } else {
102 a917d384 pbrook
        last = s->requests;
103 a917d384 pbrook
        while (last && last->next != r)
104 a917d384 pbrook
            last = last->next;
105 a917d384 pbrook
        if (last) {
106 a917d384 pbrook
            last->next = r->next;
107 a917d384 pbrook
        } else {
108 a917d384 pbrook
            BADF("Orphaned request\n");
109 a917d384 pbrook
        }
110 a917d384 pbrook
    }
111 a917d384 pbrook
    r->next = free_requests;
112 a917d384 pbrook
    free_requests = r;
113 4d611c9a pbrook
}
114 4d611c9a pbrook
115 8ccc2ace ths
static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
116 4d611c9a pbrook
{
117 a917d384 pbrook
    SCSIRequest *r;
118 4d611c9a pbrook
119 a917d384 pbrook
    r = s->requests;
120 a917d384 pbrook
    while (r && r->tag != tag)
121 a917d384 pbrook
        r = r->next;
122 4d611c9a pbrook
123 a917d384 pbrook
    return r;
124 a917d384 pbrook
}
125 a917d384 pbrook
126 a917d384 pbrook
/* Helper function for command completion.  */
127 b1fa7164 blueswir1
static void scsi_command_complete(SCSIRequest *r, int sense)
128 a917d384 pbrook
{
129 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
130 a917d384 pbrook
    uint32_t tag;
131 a917d384 pbrook
    DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
132 a917d384 pbrook
    s->sense = sense;
133 a917d384 pbrook
    tag = r->tag;
134 a917d384 pbrook
    scsi_remove_request(r);
135 b1fa7164 blueswir1
    s->completion(s->opaque, SCSI_REASON_DONE, tag, sense);
136 4d611c9a pbrook
}
137 4d611c9a pbrook
138 4d611c9a pbrook
/* Cancel a pending data transfer.  */
139 8ccc2ace ths
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
140 4d611c9a pbrook
{
141 8ccc2ace ths
    SCSIDeviceState *s = d->state;
142 a917d384 pbrook
    SCSIRequest *r;
143 a917d384 pbrook
    DPRINTF("Cancel tag=0x%x\n", tag);
144 a917d384 pbrook
    r = scsi_find_request(s, tag);
145 a917d384 pbrook
    if (r) {
146 a917d384 pbrook
        if (r->aiocb)
147 a917d384 pbrook
            bdrv_aio_cancel(r->aiocb);
148 a917d384 pbrook
        r->aiocb = NULL;
149 a917d384 pbrook
        scsi_remove_request(r);
150 a917d384 pbrook
    }
151 a917d384 pbrook
}
152 a917d384 pbrook
153 a917d384 pbrook
static void scsi_read_complete(void * opaque, int ret)
154 a917d384 pbrook
{
155 a917d384 pbrook
    SCSIRequest *r = (SCSIRequest *)opaque;
156 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
157 a917d384 pbrook
158 a917d384 pbrook
    if (ret) {
159 a917d384 pbrook
        DPRINTF("IO error\n");
160 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
161 4d611c9a pbrook
        return;
162 4d611c9a pbrook
    }
163 a917d384 pbrook
    DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, r->buf_len);
164 a917d384 pbrook
165 a917d384 pbrook
    s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
166 4d611c9a pbrook
}
167 4d611c9a pbrook
168 a917d384 pbrook
/* Read more data from scsi device into buffer.  */
169 8ccc2ace ths
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
170 2e5d83bb pbrook
{
171 8ccc2ace ths
    SCSIDeviceState *s = d->state;
172 a917d384 pbrook
    SCSIRequest *r;
173 2e5d83bb pbrook
    uint32_t n;
174 2e5d83bb pbrook
175 a917d384 pbrook
    r = scsi_find_request(s, tag);
176 a917d384 pbrook
    if (!r) {
177 a917d384 pbrook
        BADF("Bad read tag 0x%x\n", tag);
178 b1fa7164 blueswir1
        /* ??? This is the wrong error.  */
179 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
180 a917d384 pbrook
        return;
181 2e5d83bb pbrook
    }
182 a917d384 pbrook
    if (r->sector_count == (uint32_t)-1) {
183 a917d384 pbrook
        DPRINTF("Read buf_len=%d\n", r->buf_len);
184 a917d384 pbrook
        r->sector_count = 0;
185 a917d384 pbrook
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->buf_len);
186 a917d384 pbrook
        return;
187 2e5d83bb pbrook
    }
188 a917d384 pbrook
    DPRINTF("Read sector_count=%d\n", r->sector_count);
189 a917d384 pbrook
    if (r->sector_count == 0) {
190 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_NO_SENSE);
191 a917d384 pbrook
        return;
192 2e5d83bb pbrook
    }
193 2e5d83bb pbrook
194 a917d384 pbrook
    n = r->sector_count;
195 a917d384 pbrook
    if (n > SCSI_DMA_BUF_SIZE / 512)
196 a917d384 pbrook
        n = SCSI_DMA_BUF_SIZE / 512;
197 a917d384 pbrook
198 a917d384 pbrook
    r->buf_len = n * 512;
199 a917d384 pbrook
    r->aiocb = bdrv_aio_read(s->bdrv, r->sector, r->dma_buf, n,
200 a917d384 pbrook
                             scsi_read_complete, r);
201 a917d384 pbrook
    if (r->aiocb == NULL)
202 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
203 a917d384 pbrook
    r->sector += n;
204 a917d384 pbrook
    r->sector_count -= n;
205 2e5d83bb pbrook
}
206 2e5d83bb pbrook
207 4d611c9a pbrook
static void scsi_write_complete(void * opaque, int ret)
208 4d611c9a pbrook
{
209 a917d384 pbrook
    SCSIRequest *r = (SCSIRequest *)opaque;
210 8ccc2ace ths
    SCSIDeviceState *s = r->dev;
211 a917d384 pbrook
    uint32_t len;
212 4d611c9a pbrook
213 4d611c9a pbrook
    if (ret) {
214 4d611c9a pbrook
        fprintf(stderr, "scsi-disc: IO write error\n");
215 4d611c9a pbrook
        exit(1);
216 4d611c9a pbrook
    }
217 4d611c9a pbrook
218 a917d384 pbrook
    r->aiocb = NULL;
219 a917d384 pbrook
    if (r->sector_count == 0) {
220 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_NO_SENSE);
221 a917d384 pbrook
    } else {
222 a917d384 pbrook
        len = r->sector_count * 512;
223 a917d384 pbrook
        if (len > SCSI_DMA_BUF_SIZE) {
224 a917d384 pbrook
            len = SCSI_DMA_BUF_SIZE;
225 a917d384 pbrook
        }
226 a917d384 pbrook
        r->buf_len = len;
227 a917d384 pbrook
        DPRINTF("Write complete tag=0x%x more=%d\n", r->tag, len);
228 a917d384 pbrook
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
229 4d611c9a pbrook
    }
230 4d611c9a pbrook
}
231 4d611c9a pbrook
232 4d611c9a pbrook
/* Write data to a scsi device.  Returns nonzero on failure.
233 4d611c9a pbrook
   The transfer may complete asynchronously.  */
234 8ccc2ace ths
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
235 2e5d83bb pbrook
{
236 8ccc2ace ths
    SCSIDeviceState *s = d->state;
237 a917d384 pbrook
    SCSIRequest *r;
238 2e5d83bb pbrook
    uint32_t n;
239 2e5d83bb pbrook
240 a917d384 pbrook
    DPRINTF("Write data tag=0x%x\n", tag);
241 a917d384 pbrook
    r = scsi_find_request(s, tag);
242 a917d384 pbrook
    if (!r) {
243 a917d384 pbrook
        BADF("Bad write tag 0x%x\n", tag);
244 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_HARDWARE_ERROR);
245 2e5d83bb pbrook
        return 1;
246 2e5d83bb pbrook
    }
247 a917d384 pbrook
    if (r->aiocb)
248 a917d384 pbrook
        BADF("Data transfer already in progress\n");
249 a917d384 pbrook
    n = r->buf_len / 512;
250 a917d384 pbrook
    if (n) {
251 a917d384 pbrook
        r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n,
252 a917d384 pbrook
                                  scsi_write_complete, r);
253 a917d384 pbrook
        if (r->aiocb == NULL)
254 b1fa7164 blueswir1
            scsi_command_complete(r, SENSE_HARDWARE_ERROR);
255 a917d384 pbrook
        r->sector += n;
256 a917d384 pbrook
        r->sector_count -= n;
257 a917d384 pbrook
    } else {
258 a917d384 pbrook
        /* Invoke completion routine to fetch data from host.  */
259 a917d384 pbrook
        scsi_write_complete(r, 0);
260 2e5d83bb pbrook
    }
261 2e5d83bb pbrook
262 a917d384 pbrook
    return 0;
263 a917d384 pbrook
}
264 2e5d83bb pbrook
265 a917d384 pbrook
/* Return a pointer to the data buffer.  */
266 8ccc2ace ths
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
267 a917d384 pbrook
{
268 8ccc2ace ths
    SCSIDeviceState *s = d->state;
269 a917d384 pbrook
    SCSIRequest *r;
270 2e5d83bb pbrook
271 a917d384 pbrook
    r = scsi_find_request(s, tag);
272 a917d384 pbrook
    if (!r) {
273 a917d384 pbrook
        BADF("Bad buffer tag 0x%x\n", tag);
274 a917d384 pbrook
        return NULL;
275 4d611c9a pbrook
    }
276 a917d384 pbrook
    return r->dma_buf;
277 2e5d83bb pbrook
}
278 2e5d83bb pbrook
279 2e5d83bb pbrook
/* Execute a scsi command.  Returns the length of the data expected by the
280 2e5d83bb pbrook
   command.  This will be Positive for data transfers from the device
281 2e5d83bb pbrook
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
282 2e5d83bb pbrook
   and zero if the command does not transfer any data.  */
283 2e5d83bb pbrook
284 8ccc2ace ths
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
285 8ccc2ace ths
                                 uint8_t *buf, int lun)
286 2e5d83bb pbrook
{
287 8ccc2ace ths
    SCSIDeviceState *s = d->state;
288 96b8f136 ths
    uint64_t nb_sectors;
289 2e5d83bb pbrook
    uint32_t lba;
290 2e5d83bb pbrook
    uint32_t len;
291 2e5d83bb pbrook
    int cmdlen;
292 2e5d83bb pbrook
    int is_write;
293 a917d384 pbrook
    uint8_t command;
294 a917d384 pbrook
    uint8_t *outbuf;
295 a917d384 pbrook
    SCSIRequest *r;
296 a917d384 pbrook
297 a917d384 pbrook
    command = buf[0];
298 a917d384 pbrook
    r = scsi_find_request(s, tag);
299 a917d384 pbrook
    if (r) {
300 a917d384 pbrook
        BADF("Tag 0x%x already in use\n", tag);
301 8ccc2ace ths
        scsi_cancel_io(d, tag);
302 a917d384 pbrook
    }
303 a917d384 pbrook
    /* ??? Tags are not unique for different luns.  We only implement a
304 a917d384 pbrook
       single lun, so this should not matter.  */
305 a917d384 pbrook
    r = scsi_new_request(s, tag);
306 a917d384 pbrook
    outbuf = r->dma_buf;
307 2e5d83bb pbrook
    is_write = 0;
308 a917d384 pbrook
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
309 a917d384 pbrook
    switch (command >> 5) {
310 2e5d83bb pbrook
    case 0:
311 2e5d83bb pbrook
        lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
312 2e5d83bb pbrook
        len = buf[4];
313 2e5d83bb pbrook
        cmdlen = 6;
314 2e5d83bb pbrook
        break;
315 2e5d83bb pbrook
    case 1:
316 2e5d83bb pbrook
    case 2:
317 2e5d83bb pbrook
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
318 2e5d83bb pbrook
        len = buf[8] | (buf[7] << 8);
319 2e5d83bb pbrook
        cmdlen = 10;
320 2e5d83bb pbrook
        break;
321 2e5d83bb pbrook
    case 4:
322 2e5d83bb pbrook
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
323 2e5d83bb pbrook
        len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
324 2e5d83bb pbrook
        cmdlen = 16;
325 2e5d83bb pbrook
        break;
326 2e5d83bb pbrook
    case 5:
327 2e5d83bb pbrook
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
328 2e5d83bb pbrook
        len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
329 2e5d83bb pbrook
        cmdlen = 12;
330 2e5d83bb pbrook
        break;
331 2e5d83bb pbrook
    default:
332 a917d384 pbrook
        BADF("Unsupported command length, command %x\n", command);
333 2e5d83bb pbrook
        goto fail;
334 2e5d83bb pbrook
    }
335 2e5d83bb pbrook
#ifdef DEBUG_SCSI
336 2e5d83bb pbrook
    {
337 2e5d83bb pbrook
        int i;
338 2e5d83bb pbrook
        for (i = 1; i < cmdlen; i++) {
339 2e5d83bb pbrook
            printf(" 0x%02x", buf[i]);
340 2e5d83bb pbrook
        }
341 2e5d83bb pbrook
        printf("\n");
342 2e5d83bb pbrook
    }
343 2e5d83bb pbrook
#endif
344 0fc5c15a pbrook
    if (lun || buf[1] >> 5) {
345 2e5d83bb pbrook
        /* Only LUN 0 supported.  */
346 0fc5c15a pbrook
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
347 2e5d83bb pbrook
        goto fail;
348 2e5d83bb pbrook
    }
349 a917d384 pbrook
    switch (command) {
350 2e5d83bb pbrook
    case 0x0:
351 2e5d83bb pbrook
        DPRINTF("Test Unit Ready\n");
352 2e5d83bb pbrook
        break;
353 2e5d83bb pbrook
    case 0x03:
354 2e5d83bb pbrook
        DPRINTF("Request Sense (len %d)\n", len);
355 2e5d83bb pbrook
        if (len < 4)
356 2e5d83bb pbrook
            goto fail;
357 67cd24a8 ths
        memset(outbuf, 0, 4);
358 a917d384 pbrook
        outbuf[0] = 0xf0;
359 a917d384 pbrook
        outbuf[1] = 0;
360 a917d384 pbrook
        outbuf[2] = s->sense;
361 a917d384 pbrook
        r->buf_len = 4;
362 2e5d83bb pbrook
        break;
363 2e5d83bb pbrook
    case 0x12:
364 7d8406be pbrook
        DPRINTF("Inquiry (len %d)\n", len);
365 1d4db89c balrog
        if (buf[1] & 0x2) {
366 1d4db89c balrog
            /* Command support data - optional, not implemented */
367 1d4db89c balrog
            BADF("optional INQUIRY command support request not implemented\n");
368 1d4db89c balrog
            goto fail;
369 1d4db89c balrog
        }
370 1d4db89c balrog
        else if (buf[1] & 0x1) {
371 1d4db89c balrog
            /* Vital product data */
372 1d4db89c balrog
            uint8_t page_code = buf[2];
373 1d4db89c balrog
            if (len < 4) {
374 1d4db89c balrog
                BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "
375 1d4db89c balrog
                     "less than 4\n", page_code, len);
376 1d4db89c balrog
                goto fail;
377 1d4db89c balrog
            }
378 1d4db89c balrog
379 1d4db89c balrog
            switch (page_code) {
380 1d4db89c balrog
                case 0x00:
381 1d4db89c balrog
                    {
382 1d4db89c balrog
                        /* Supported page codes, mandatory */
383 1d4db89c balrog
                        DPRINTF("Inquiry EVPD[Supported pages] "
384 1d4db89c balrog
                                "buffer size %d\n", len);
385 1d4db89c balrog
386 1d4db89c balrog
                        r->buf_len = 0;
387 1d4db89c balrog
388 1d4db89c balrog
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
389 1d4db89c balrog
                            outbuf[r->buf_len++] = 5;
390 1d4db89c balrog
                        } else {
391 1d4db89c balrog
                            outbuf[r->buf_len++] = 0;
392 1d4db89c balrog
                        }
393 1d4db89c balrog
394 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x00; // this page
395 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x00;
396 1d4db89c balrog
                        outbuf[r->buf_len++] = 3;    // number of pages
397 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)
398 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x80; // unit serial number
399 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x83; // device identification
400 1d4db89c balrog
                    }
401 1d4db89c balrog
                    break;
402 1d4db89c balrog
                case 0x80:
403 1d4db89c balrog
                    {
404 1d4db89c balrog
                        /* Device serial number, optional */
405 1d4db89c balrog
                        if (len < 4) {
406 1d4db89c balrog
                            BADF("Error: EVPD[Serial number] Inquiry buffer "
407 1d4db89c balrog
                                 "size %d too small, %d needed\n", len, 4);
408 1d4db89c balrog
                            goto fail;
409 1d4db89c balrog
                        }
410 1d4db89c balrog
411 1d4db89c balrog
                        DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);
412 1d4db89c balrog
413 1d4db89c balrog
                        r->buf_len = 0;
414 1d4db89c balrog
415 1d4db89c balrog
                        /* Supported page codes */
416 1d4db89c balrog
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
417 1d4db89c balrog
                            outbuf[r->buf_len++] = 5;
418 1d4db89c balrog
                        } else {
419 1d4db89c balrog
                            outbuf[r->buf_len++] = 0;
420 1d4db89c balrog
                        }
421 1d4db89c balrog
422 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x80; // this page
423 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x00;
424 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x01; // 1 byte data follow
425 1d4db89c balrog
426 1d4db89c balrog
                        outbuf[r->buf_len++] = '0';  // 1 byte data follow 
427 1d4db89c balrog
                    }
428 1d4db89c balrog
429 1d4db89c balrog
                    break;
430 1d4db89c balrog
                case 0x83:
431 1d4db89c balrog
                    {
432 1d4db89c balrog
                        /* Device identification page, mandatory */
433 1d4db89c balrog
                        int max_len = 255 - 8;
434 1d4db89c balrog
                        int id_len = strlen(bdrv_get_device_name(s->bdrv));
435 1d4db89c balrog
                        if (id_len > max_len)
436 1d4db89c balrog
                            id_len = max_len;
437 1d4db89c balrog
438 1d4db89c balrog
                        DPRINTF("Inquiry EVPD[Device identification] "
439 1d4db89c balrog
                                "buffer size %d\n", len);
440 1d4db89c balrog
                        r->buf_len = 0;
441 1d4db89c balrog
                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
442 1d4db89c balrog
                            outbuf[r->buf_len++] = 5;
443 1d4db89c balrog
                        } else {
444 1d4db89c balrog
                            outbuf[r->buf_len++] = 0;
445 1d4db89c balrog
                        }
446 1d4db89c balrog
447 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x83; // this page
448 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x00;
449 1d4db89c balrog
                        outbuf[r->buf_len++] = 3 + id_len;
450 1d4db89c balrog
451 1d4db89c balrog
                        outbuf[r->buf_len++] = 0x2; // ASCII
452 1d4db89c balrog
                        outbuf[r->buf_len++] = 0;   // not officially assigned
453 1d4db89c balrog
                        outbuf[r->buf_len++] = 0;   // reserved
454 1d4db89c balrog
                        outbuf[r->buf_len++] = id_len; // length of data following
455 1d4db89c balrog
456 1d4db89c balrog
                        memcpy(&outbuf[r->buf_len],
457 1d4db89c balrog
                               bdrv_get_device_name(s->bdrv), id_len);
458 1d4db89c balrog
                        r->buf_len += id_len;
459 1d4db89c balrog
                    }
460 1d4db89c balrog
                    break;
461 1d4db89c balrog
                default:
462 1d4db89c balrog
                    BADF("Error: unsupported Inquiry (EVPD[%02X]) "
463 1d4db89c balrog
                         "buffer size %d\n", page_code, len);
464 1d4db89c balrog
                    goto fail;
465 1d4db89c balrog
            }
466 1d4db89c balrog
            /* done with EVPD */
467 1d4db89c balrog
            break;
468 1d4db89c balrog
        }
469 1d4db89c balrog
        else {
470 1d4db89c balrog
            /* Standard INQUIRY data */
471 1d4db89c balrog
            if (buf[2] != 0) {
472 1d4db89c balrog
                BADF("Error: Inquiry (STANDARD) page or code "
473 1d4db89c balrog
                     "is non-zero [%02X]\n", buf[2]);
474 1d4db89c balrog
                goto fail;
475 1d4db89c balrog
            }
476 1d4db89c balrog
477 1d4db89c balrog
            /* PAGE CODE == 0 */
478 1d4db89c balrog
            if (len < 5) {
479 1d4db89c balrog
                BADF("Error: Inquiry (STANDARD) buffer size %d "
480 1d4db89c balrog
                     "is less than 5\n", len);
481 1d4db89c balrog
                goto fail;
482 1d4db89c balrog
            }
483 1d4db89c balrog
484 1d4db89c balrog
            if (len < 36) {
485 1d4db89c balrog
                BADF("Error: Inquiry (STANDARD) buffer size %d "
486 1d4db89c balrog
                     "is less than 36 (TODO: only 5 required)\n", len);
487 1d4db89c balrog
            }
488 2e5d83bb pbrook
        }
489 a917d384 pbrook
        memset(outbuf, 0, 36);
490 2e5d83bb pbrook
        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
491 a917d384 pbrook
            outbuf[0] = 5;
492 a917d384 pbrook
            outbuf[1] = 0x80;
493 a917d384 pbrook
            memcpy(&outbuf[16], "QEMU CD-ROM    ", 16);
494 2e5d83bb pbrook
        } else {
495 a917d384 pbrook
            outbuf[0] = 0;
496 a917d384 pbrook
            memcpy(&outbuf[16], "QEMU HARDDISK  ", 16);
497 2e5d83bb pbrook
        }
498 a917d384 pbrook
        memcpy(&outbuf[8], "QEMU   ", 8);
499 a917d384 pbrook
        memcpy(&outbuf[32], QEMU_VERSION, 4);
500 17acfe32 pbrook
        /* Identify device as SCSI-3 rev 1.
501 17acfe32 pbrook
           Some later commands are also implemented. */
502 a917d384 pbrook
        outbuf[2] = 3;
503 a917d384 pbrook
        outbuf[3] = 2; /* Format 2 */
504 67cd24a8 ths
        outbuf[4] = 31;
505 a917d384 pbrook
        /* Sync data transfer and TCQ.  */
506 a917d384 pbrook
        outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);
507 a917d384 pbrook
        r->buf_len = 36;
508 2e5d83bb pbrook
        break;
509 2e5d83bb pbrook
    case 0x16:
510 2e5d83bb pbrook
        DPRINTF("Reserve(6)\n");
511 2e5d83bb pbrook
        if (buf[1] & 1)
512 2e5d83bb pbrook
            goto fail;
513 2e5d83bb pbrook
        break;
514 2e5d83bb pbrook
    case 0x17:
515 2e5d83bb pbrook
        DPRINTF("Release(6)\n");
516 2e5d83bb pbrook
        if (buf[1] & 1)
517 2e5d83bb pbrook
            goto fail;
518 2e5d83bb pbrook
        break;
519 2e5d83bb pbrook
    case 0x1a:
520 7d8406be pbrook
    case 0x5a:
521 17acfe32 pbrook
        {
522 a917d384 pbrook
            uint8_t *p;
523 17acfe32 pbrook
            int page;
524 17acfe32 pbrook
525 17acfe32 pbrook
            page = buf[2] & 0x3f;
526 17acfe32 pbrook
            DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
527 a917d384 pbrook
            p = outbuf;
528 17acfe32 pbrook
            memset(p, 0, 4);
529 a917d384 pbrook
            outbuf[1] = 0; /* Default media type.  */
530 a917d384 pbrook
            outbuf[3] = 0; /* Block descriptor length.  */
531 17acfe32 pbrook
            if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
532 a917d384 pbrook
                outbuf[2] = 0x80; /* Readonly.  */
533 17acfe32 pbrook
            }
534 17acfe32 pbrook
            p += 4;
535 17acfe32 pbrook
            if ((page == 8 || page == 0x3f)) {
536 17acfe32 pbrook
                /* Caching page.  */
537 67cd24a8 ths
                memset(p,0,20);
538 17acfe32 pbrook
                p[0] = 8;
539 17acfe32 pbrook
                p[1] = 0x12;
540 17acfe32 pbrook
                p[2] = 4; /* WCE */
541 67cd24a8 ths
                p += 20;
542 17acfe32 pbrook
            }
543 17acfe32 pbrook
            if ((page == 0x3f || page == 0x2a)
544 17acfe32 pbrook
                    && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
545 17acfe32 pbrook
                /* CD Capabilities and Mechanical Status page. */
546 17acfe32 pbrook
                p[0] = 0x2a;
547 17acfe32 pbrook
                p[1] = 0x14;
548 17acfe32 pbrook
                p[2] = 3; // CD-R & CD-RW read
549 17acfe32 pbrook
                p[3] = 0; // Writing not supported
550 17acfe32 pbrook
                p[4] = 0x7f; /* Audio, composite, digital out,
551 17acfe32 pbrook
                                         mode 2 form 1&2, multi session */
552 17acfe32 pbrook
                p[5] = 0xff; /* CD DA, DA accurate, RW supported,
553 17acfe32 pbrook
                                         RW corrected, C2 errors, ISRC,
554 17acfe32 pbrook
                                         UPC, Bar code */
555 17acfe32 pbrook
                p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
556 17acfe32 pbrook
                /* Locking supported, jumper present, eject, tray */
557 17acfe32 pbrook
                p[7] = 0; /* no volume & mute control, no
558 17acfe32 pbrook
                                      changer */
559 17acfe32 pbrook
                p[8] = (50 * 176) >> 8; // 50x read speed
560 17acfe32 pbrook
                p[9] = (50 * 176) & 0xff;
561 17acfe32 pbrook
                p[10] = 0 >> 8; // No volume
562 17acfe32 pbrook
                p[11] = 0 & 0xff;
563 17acfe32 pbrook
                p[12] = 2048 >> 8; // 2M buffer
564 17acfe32 pbrook
                p[13] = 2048 & 0xff;
565 17acfe32 pbrook
                p[14] = (16 * 176) >> 8; // 16x read speed current
566 17acfe32 pbrook
                p[15] = (16 * 176) & 0xff;
567 17acfe32 pbrook
                p[18] = (16 * 176) >> 8; // 16x write speed
568 17acfe32 pbrook
                p[19] = (16 * 176) & 0xff;
569 17acfe32 pbrook
                p[20] = (16 * 176) >> 8; // 16x write speed current
570 17acfe32 pbrook
                p[21] = (16 * 176) & 0xff;
571 67cd24a8 ths
                p += 22;
572 17acfe32 pbrook
            }
573 a917d384 pbrook
            r->buf_len = p - outbuf;
574 a917d384 pbrook
            outbuf[0] = r->buf_len - 4;
575 a917d384 pbrook
            if (r->buf_len > len)
576 a917d384 pbrook
                r->buf_len = len;
577 7d8406be pbrook
        }
578 17acfe32 pbrook
        break;
579 17acfe32 pbrook
    case 0x1b:
580 17acfe32 pbrook
        DPRINTF("Start Stop Unit\n");
581 17acfe32 pbrook
        break;
582 17acfe32 pbrook
    case 0x1e:
583 17acfe32 pbrook
        DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
584 17acfe32 pbrook
        bdrv_set_locked(s->bdrv, buf[4] & 1);
585 2e5d83bb pbrook
        break;
586 2e5d83bb pbrook
    case 0x25:
587 2e5d83bb pbrook
        DPRINTF("Read Capacity\n");
588 2e5d83bb pbrook
        /* The normal LEN field for this command is zero.  */
589 a917d384 pbrook
        memset(outbuf, 0, 8);
590 2e5d83bb pbrook
        bdrv_get_geometry(s->bdrv, &nb_sectors);
591 51c1ebb1 pbrook
        /* Returned value is the address of the last sector.  */
592 51c1ebb1 pbrook
        if (nb_sectors) {
593 51c1ebb1 pbrook
            nb_sectors--;
594 a917d384 pbrook
            outbuf[0] = (nb_sectors >> 24) & 0xff;
595 a917d384 pbrook
            outbuf[1] = (nb_sectors >> 16) & 0xff;
596 a917d384 pbrook
            outbuf[2] = (nb_sectors >> 8) & 0xff;
597 a917d384 pbrook
            outbuf[3] = nb_sectors & 0xff;
598 a917d384 pbrook
            outbuf[4] = 0;
599 a917d384 pbrook
            outbuf[5] = 0;
600 a917d384 pbrook
            outbuf[6] = s->cluster_size * 2;
601 a917d384 pbrook
            outbuf[7] = 0;
602 a917d384 pbrook
            r->buf_len = 8;
603 51c1ebb1 pbrook
        } else {
604 b1fa7164 blueswir1
            scsi_command_complete(r, SENSE_NOT_READY);
605 35f1df84 pbrook
            return 0;
606 51c1ebb1 pbrook
        }
607 2e5d83bb pbrook
        break;
608 2e5d83bb pbrook
    case 0x08:
609 2e5d83bb pbrook
    case 0x28:
610 2e5d83bb pbrook
        DPRINTF("Read (sector %d, count %d)\n", lba, len);
611 a917d384 pbrook
        r->sector = lba * s->cluster_size;
612 a917d384 pbrook
        r->sector_count = len * s->cluster_size;
613 2e5d83bb pbrook
        break;
614 2e5d83bb pbrook
    case 0x0a:
615 2e5d83bb pbrook
    case 0x2a:
616 2e5d83bb pbrook
        DPRINTF("Write (sector %d, count %d)\n", lba, len);
617 a917d384 pbrook
        r->sector = lba * s->cluster_size;
618 a917d384 pbrook
        r->sector_count = len * s->cluster_size;
619 2e5d83bb pbrook
        is_write = 1;
620 2e5d83bb pbrook
        break;
621 7d8406be pbrook
    case 0x35:
622 e91c8a77 ths
        DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);
623 7a6cba61 pbrook
        bdrv_flush(s->bdrv);
624 7d8406be pbrook
        break;
625 2e5d83bb pbrook
    case 0x43:
626 2e5d83bb pbrook
        {
627 7c22dd52 pbrook
            int start_track, format, msf, toclen;
628 2e5d83bb pbrook
629 2e5d83bb pbrook
            msf = buf[1] & 2;
630 2e5d83bb pbrook
            format = buf[2] & 0xf;
631 2e5d83bb pbrook
            start_track = buf[6];
632 2e5d83bb pbrook
            bdrv_get_geometry(s->bdrv, &nb_sectors);
633 2e5d83bb pbrook
            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
634 2e5d83bb pbrook
            switch(format) {
635 2e5d83bb pbrook
            case 0:
636 a917d384 pbrook
                toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
637 2e5d83bb pbrook
                break;
638 2e5d83bb pbrook
            case 1:
639 2e5d83bb pbrook
                /* multi session : only a single session defined */
640 7c22dd52 pbrook
                toclen = 12;
641 a917d384 pbrook
                memset(outbuf, 0, 12);
642 a917d384 pbrook
                outbuf[1] = 0x0a;
643 a917d384 pbrook
                outbuf[2] = 0x01;
644 a917d384 pbrook
                outbuf[3] = 0x01;
645 2e5d83bb pbrook
                break;
646 2e5d83bb pbrook
            case 2:
647 a917d384 pbrook
                toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
648 2e5d83bb pbrook
                break;
649 2e5d83bb pbrook
            default:
650 7c22dd52 pbrook
                goto error_cmd;
651 7c22dd52 pbrook
            }
652 7c22dd52 pbrook
            if (toclen > 0) {
653 7c22dd52 pbrook
                if (len > toclen)
654 7c22dd52 pbrook
                  len = toclen;
655 a917d384 pbrook
                r->buf_len = len;
656 7c22dd52 pbrook
                break;
657 2e5d83bb pbrook
            }
658 7c22dd52 pbrook
        error_cmd:
659 7c22dd52 pbrook
            DPRINTF("Read TOC error\n");
660 7c22dd52 pbrook
            goto fail;
661 2e5d83bb pbrook
        }
662 17acfe32 pbrook
    case 0x46:
663 17acfe32 pbrook
        DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
664 a917d384 pbrook
        memset(outbuf, 0, 8);
665 17acfe32 pbrook
        /* ??? This shoud probably return much more information.  For now
666 17acfe32 pbrook
           just return the basic header indicating the CD-ROM profile.  */
667 a917d384 pbrook
        outbuf[7] = 8; // CD-ROM
668 a917d384 pbrook
        r->buf_len = 8;
669 17acfe32 pbrook
        break;
670 2e5d83bb pbrook
    case 0x56:
671 2e5d83bb pbrook
        DPRINTF("Reserve(10)\n");
672 2e5d83bb pbrook
        if (buf[1] & 3)
673 2e5d83bb pbrook
            goto fail;
674 2e5d83bb pbrook
        break;
675 2e5d83bb pbrook
    case 0x57:
676 2e5d83bb pbrook
        DPRINTF("Release(10)\n");
677 2e5d83bb pbrook
        if (buf[1] & 3)
678 2e5d83bb pbrook
            goto fail;
679 2e5d83bb pbrook
        break;
680 2e5d83bb pbrook
    case 0xa0:
681 2e5d83bb pbrook
        DPRINTF("Report LUNs (len %d)\n", len);
682 2e5d83bb pbrook
        if (len < 16)
683 2e5d83bb pbrook
            goto fail;
684 a917d384 pbrook
        memset(outbuf, 0, 16);
685 a917d384 pbrook
        outbuf[3] = 8;
686 a917d384 pbrook
        r->buf_len = 16;
687 2e5d83bb pbrook
        break;
688 2e5d83bb pbrook
    default:
689 2e5d83bb pbrook
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
690 2e5d83bb pbrook
    fail:
691 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_ILLEGAL_REQUEST);
692 2e5d83bb pbrook
        return 0;
693 2e5d83bb pbrook
    }
694 a917d384 pbrook
    if (r->sector_count == 0 && r->buf_len == 0) {
695 b1fa7164 blueswir1
        scsi_command_complete(r, SENSE_NO_SENSE);
696 a917d384 pbrook
    }
697 a917d384 pbrook
    len = r->sector_count * 512 + r->buf_len;
698 a917d384 pbrook
    if (is_write) {
699 a917d384 pbrook
        return -len;
700 a917d384 pbrook
    } else {
701 a917d384 pbrook
        if (!r->sector_count)
702 a917d384 pbrook
            r->sector_count = -1;
703 a917d384 pbrook
        return len;
704 2e5d83bb pbrook
    }
705 2e5d83bb pbrook
}
706 2e5d83bb pbrook
707 8ccc2ace ths
static void scsi_destroy(SCSIDevice *d)
708 2e5d83bb pbrook
{
709 8ccc2ace ths
    qemu_free(d->state);
710 8ccc2ace ths
    qemu_free(d);
711 2e5d83bb pbrook
}
712 2e5d83bb pbrook
713 8ccc2ace ths
SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
714 8ccc2ace ths
                           scsi_completionfn completion, void *opaque)
715 2e5d83bb pbrook
{
716 8ccc2ace ths
    SCSIDevice *d;
717 8ccc2ace ths
    SCSIDeviceState *s;
718 2e5d83bb pbrook
719 8ccc2ace ths
    s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
720 2e5d83bb pbrook
    s->bdrv = bdrv;
721 a917d384 pbrook
    s->tcq = tcq;
722 2e5d83bb pbrook
    s->completion = completion;
723 2e5d83bb pbrook
    s->opaque = opaque;
724 2e5d83bb pbrook
    if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
725 7c22dd52 pbrook
        s->cluster_size = 4;
726 2e5d83bb pbrook
    } else {
727 7c22dd52 pbrook
        s->cluster_size = 1;
728 2e5d83bb pbrook
    }
729 2e5d83bb pbrook
730 8ccc2ace ths
    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
731 8ccc2ace ths
    d->state = s;
732 8ccc2ace ths
    d->destroy = scsi_destroy;
733 8ccc2ace ths
    d->send_command = scsi_send_command;
734 8ccc2ace ths
    d->read_data = scsi_read_data;
735 8ccc2ace ths
    d->write_data = scsi_write_data;
736 8ccc2ace ths
    d->cancel_io = scsi_cancel_io;
737 8ccc2ace ths
    d->get_buf = scsi_get_buf;
738 2e5d83bb pbrook
739 8ccc2ace ths
    return d;
740 8ccc2ace ths
}