Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ dfb021bc

History | View | Annotate | Download (18.9 kB)

1 2cc977e2 ths
/*
2 2cc977e2 ths
 * Generic SCSI Device support
3 2cc977e2 ths
 *
4 2cc977e2 ths
 * Copyright (c) 2007 Bull S.A.S.
5 2cc977e2 ths
 * Based on code by Paul Brook
6 2cc977e2 ths
 * Based on code by Fabrice Bellard
7 2cc977e2 ths
 *
8 2cc977e2 ths
 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
9 2cc977e2 ths
 *
10 2cc977e2 ths
 * This code is licenced under the LGPL.
11 2cc977e2 ths
 *
12 2cc977e2 ths
 */
13 2cc977e2 ths
14 2cc977e2 ths
#include "qemu-common.h"
15 2cc977e2 ths
#include "block.h"
16 2cc977e2 ths
#include "scsi-disk.h"
17 2cc977e2 ths
18 2cc977e2 ths
#ifndef __linux__
19 2cc977e2 ths
20 2cc977e2 ths
SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
21 2cc977e2 ths
                              scsi_completionfn completion, void *opaque)
22 2cc977e2 ths
{
23 2cc977e2 ths
    return NULL;
24 2cc977e2 ths
}
25 2cc977e2 ths
26 2cc977e2 ths
#else /* __linux__ */
27 2cc977e2 ths
28 2cc977e2 ths
//#define DEBUG_SCSI
29 2cc977e2 ths
30 2cc977e2 ths
#ifdef DEBUG_SCSI
31 2cc977e2 ths
#define DPRINTF(fmt, args...) \
32 2cc977e2 ths
do { printf("scsi-generic: " fmt , ##args); } while (0)
33 2cc977e2 ths
#else
34 2cc977e2 ths
#define DPRINTF(fmt, args...) do {} while(0)
35 2cc977e2 ths
#endif
36 2cc977e2 ths
37 2cc977e2 ths
#define BADF(fmt, args...) \
38 2cc977e2 ths
do { fprintf(stderr, "scsi-generic: " fmt , ##args); } while (0)
39 2cc977e2 ths
40 2cc977e2 ths
#include <stdio.h>
41 2cc977e2 ths
#include <sys/types.h>
42 2cc977e2 ths
#include <sys/stat.h>
43 2cc977e2 ths
#include <unistd.h>
44 2cc977e2 ths
#include <scsi/sg.h>
45 2cc977e2 ths
#include <scsi/scsi.h>
46 2cc977e2 ths
47 a9dd6843 aliguori
#define REWIND 0x01
48 a9dd6843 aliguori
#define REPORT_DENSITY_SUPPORT 0x44
49 2cc977e2 ths
#define LOAD_UNLOAD 0xa6
50 2cc977e2 ths
#define SET_CD_SPEED 0xbb
51 2cc977e2 ths
#define BLANK 0xa1
52 2cc977e2 ths
53 2cc977e2 ths
#define SCSI_CMD_BUF_SIZE     16
54 a9dd6843 aliguori
#define SCSI_SENSE_BUF_SIZE 96
55 2cc977e2 ths
56 2cc977e2 ths
#define SG_ERR_DRIVER_TIMEOUT 0x06
57 2cc977e2 ths
#define SG_ERR_DRIVER_SENSE 0x08
58 2cc977e2 ths
59 2cc977e2 ths
#ifndef MAX_UINT
60 2cc977e2 ths
#define MAX_UINT ((unsigned int)-1)
61 2cc977e2 ths
#endif
62 2cc977e2 ths
63 2cc977e2 ths
typedef struct SCSIRequest {
64 2cc977e2 ths
    BlockDriverAIOCB *aiocb;
65 2cc977e2 ths
    struct SCSIRequest *next;
66 2cc977e2 ths
    SCSIDeviceState *dev;
67 2cc977e2 ths
    uint32_t tag;
68 2cc977e2 ths
    uint8_t cmd[SCSI_CMD_BUF_SIZE];
69 2cc977e2 ths
    int cmdlen;
70 2cc977e2 ths
    uint8_t *buf;
71 2cc977e2 ths
    int buflen;
72 2cc977e2 ths
    int len;
73 2cc977e2 ths
    sg_io_hdr_t io_header;
74 2cc977e2 ths
} SCSIRequest;
75 2cc977e2 ths
76 2cc977e2 ths
struct SCSIDeviceState
77 2cc977e2 ths
{
78 2cc977e2 ths
    SCSIRequest *requests;
79 2cc977e2 ths
    BlockDriverState *bdrv;
80 a9dd6843 aliguori
    int type;
81 2cc977e2 ths
    int blocksize;
82 2cc977e2 ths
    int lun;
83 2cc977e2 ths
    scsi_completionfn completion;
84 2cc977e2 ths
    void *opaque;
85 2cc977e2 ths
    int driver_status;
86 2cc977e2 ths
    uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
87 89c0f643 aurel32
    uint8_t senselen;
88 2cc977e2 ths
};
89 2cc977e2 ths
90 2cc977e2 ths
/* Global pool of SCSIRequest structures.  */
91 2cc977e2 ths
static SCSIRequest *free_requests = NULL;
92 2cc977e2 ths
93 2cc977e2 ths
static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
94 2cc977e2 ths
{
95 2cc977e2 ths
    SCSIRequest *r;
96 2cc977e2 ths
97 2cc977e2 ths
    if (free_requests) {
98 2cc977e2 ths
        r = free_requests;
99 2cc977e2 ths
        free_requests = r->next;
100 2cc977e2 ths
    } else {
101 2cc977e2 ths
        r = qemu_malloc(sizeof(SCSIRequest));
102 2cc977e2 ths
        r->buf = NULL;
103 2cc977e2 ths
        r->buflen = 0;
104 2cc977e2 ths
    }
105 2cc977e2 ths
    r->dev = s;
106 2cc977e2 ths
    r->tag = tag;
107 2cc977e2 ths
    memset(r->cmd, 0, sizeof(r->cmd));
108 2cc977e2 ths
    memset(&r->io_header, 0, sizeof(r->io_header));
109 2cc977e2 ths
    r->cmdlen = 0;
110 2cc977e2 ths
    r->len = 0;
111 2cc977e2 ths
    r->aiocb = NULL;
112 2cc977e2 ths
113 2cc977e2 ths
    /* link */
114 2cc977e2 ths
115 2cc977e2 ths
    r->next = s->requests;
116 2cc977e2 ths
    s->requests = r;
117 2cc977e2 ths
    return r;
118 2cc977e2 ths
}
119 2cc977e2 ths
120 2cc977e2 ths
static void scsi_remove_request(SCSIRequest *r)
121 2cc977e2 ths
{
122 2cc977e2 ths
    SCSIRequest *last;
123 2cc977e2 ths
    SCSIDeviceState *s = r->dev;
124 2cc977e2 ths
125 2cc977e2 ths
    if (s->requests == r) {
126 2cc977e2 ths
        s->requests = r->next;
127 2cc977e2 ths
    } else {
128 2cc977e2 ths
        last = s->requests;
129 2cc977e2 ths
        while (last && last->next != r)
130 2cc977e2 ths
            last = last->next;
131 2cc977e2 ths
        if (last) {
132 2cc977e2 ths
            last->next = r->next;
133 2cc977e2 ths
        } else {
134 2cc977e2 ths
            BADF("Orphaned request\n");
135 2cc977e2 ths
        }
136 2cc977e2 ths
    }
137 2cc977e2 ths
    r->next = free_requests;
138 2cc977e2 ths
    free_requests = r;
139 2cc977e2 ths
}
140 2cc977e2 ths
141 2cc977e2 ths
static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
142 2cc977e2 ths
{
143 2cc977e2 ths
    SCSIRequest *r;
144 2cc977e2 ths
145 2cc977e2 ths
    r = s->requests;
146 2cc977e2 ths
    while (r && r->tag != tag)
147 2cc977e2 ths
        r = r->next;
148 2cc977e2 ths
149 2cc977e2 ths
    return r;
150 2cc977e2 ths
}
151 2cc977e2 ths
152 2cc977e2 ths
/* Helper function for command completion.  */
153 2cc977e2 ths
static void scsi_command_complete(void *opaque, int ret)
154 2cc977e2 ths
{
155 2cc977e2 ths
    SCSIRequest *r = (SCSIRequest *)opaque;
156 2cc977e2 ths
    SCSIDeviceState *s = r->dev;
157 2cc977e2 ths
    uint32_t tag;
158 89c0f643 aurel32
    int status;
159 2cc977e2 ths
160 2cc977e2 ths
    s->driver_status = r->io_header.driver_status;
161 89c0f643 aurel32
    if (s->driver_status & SG_ERR_DRIVER_SENSE)
162 89c0f643 aurel32
        s->senselen = r->io_header.sb_len_wr;
163 89c0f643 aurel32
164 2cc977e2 ths
    if (ret != 0)
165 89c0f643 aurel32
        status = BUSY << 1;
166 2cc977e2 ths
    else {
167 2cc977e2 ths
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
168 89c0f643 aurel32
            status = BUSY << 1;
169 2cc977e2 ths
            BADF("Driver Timeout\n");
170 89c0f643 aurel32
        } else if (r->io_header.status)
171 89c0f643 aurel32
            status = r->io_header.status;
172 89c0f643 aurel32
        else if (s->driver_status & SG_ERR_DRIVER_SENSE)
173 89c0f643 aurel32
            status = CHECK_CONDITION << 1;
174 2cc977e2 ths
        else
175 89c0f643 aurel32
            status = GOOD << 1;
176 2cc977e2 ths
    }
177 89c0f643 aurel32
    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
178 89c0f643 aurel32
            r, r->tag, status);
179 2cc977e2 ths
    tag = r->tag;
180 2cc977e2 ths
    scsi_remove_request(r);
181 89c0f643 aurel32
    s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
182 2cc977e2 ths
}
183 2cc977e2 ths
184 2cc977e2 ths
/* Cancel a pending data transfer.  */
185 2cc977e2 ths
static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
186 2cc977e2 ths
{
187 2cc977e2 ths
    DPRINTF("scsi_cancel_io 0x%x\n", tag);
188 2cc977e2 ths
    SCSIDeviceState *s = d->state;
189 2cc977e2 ths
    SCSIRequest *r;
190 2cc977e2 ths
    DPRINTF("Cancel tag=0x%x\n", tag);
191 2cc977e2 ths
    r = scsi_find_request(s, tag);
192 2cc977e2 ths
    if (r) {
193 2cc977e2 ths
        if (r->aiocb)
194 2cc977e2 ths
            bdrv_aio_cancel(r->aiocb);
195 2cc977e2 ths
        r->aiocb = NULL;
196 2cc977e2 ths
        scsi_remove_request(r);
197 2cc977e2 ths
    }
198 2cc977e2 ths
}
199 2cc977e2 ths
200 2cc977e2 ths
static int execute_command(BlockDriverState *bdrv,
201 2cc977e2 ths
                           SCSIRequest *r, int direction,
202 2cc977e2 ths
                           BlockDriverCompletionFunc *complete)
203 2cc977e2 ths
{
204 2cc977e2 ths
205 2cc977e2 ths
    r->io_header.interface_id = 'S';
206 2cc977e2 ths
    r->io_header.dxfer_direction = direction;
207 2cc977e2 ths
    r->io_header.dxferp = r->buf;
208 2cc977e2 ths
    r->io_header.dxfer_len = r->buflen;
209 2cc977e2 ths
    r->io_header.cmdp = r->cmd;
210 2cc977e2 ths
    r->io_header.cmd_len = r->cmdlen;
211 2cc977e2 ths
    r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
212 2cc977e2 ths
    r->io_header.sbp = r->dev->sensebuf;
213 2cc977e2 ths
    r->io_header.timeout = MAX_UINT;
214 2cc977e2 ths
    r->io_header.usr_ptr = r;
215 2cc977e2 ths
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
216 2cc977e2 ths
217 2cc977e2 ths
    if (bdrv_pwrite(bdrv, -1, &r->io_header, sizeof(r->io_header)) == -1) {
218 2cc977e2 ths
        BADF("execute_command: write failed ! (%d)\n", errno);
219 2cc977e2 ths
        return -1;
220 2cc977e2 ths
    }
221 2cc977e2 ths
    if (complete == NULL) {
222 2cc977e2 ths
        int ret;
223 2cc977e2 ths
        r->aiocb = NULL;
224 2cc977e2 ths
        while ((ret = bdrv_pread(bdrv, -1, &r->io_header,
225 2cc977e2 ths
                                           sizeof(r->io_header))) == -1 &&
226 2cc977e2 ths
                      errno == EINTR);
227 2cc977e2 ths
        if (ret == -1) {
228 2cc977e2 ths
            BADF("execute_command: read failed !\n");
229 2cc977e2 ths
            return -1;
230 2cc977e2 ths
        }
231 2cc977e2 ths
        return 0;
232 2cc977e2 ths
    }
233 2cc977e2 ths
234 2cc977e2 ths
    r->aiocb = bdrv_aio_read(bdrv, 0, (uint8_t*)&r->io_header,
235 2cc977e2 ths
                          -(int64_t)sizeof(r->io_header), complete, r);
236 2cc977e2 ths
    if (r->aiocb == NULL) {
237 2cc977e2 ths
        BADF("execute_command: read failed !\n");
238 2cc977e2 ths
        return -1;
239 2cc977e2 ths
    }
240 2cc977e2 ths
241 2cc977e2 ths
    return 0;
242 2cc977e2 ths
}
243 2cc977e2 ths
244 2cc977e2 ths
static void scsi_read_complete(void * opaque, int ret)
245 2cc977e2 ths
{
246 2cc977e2 ths
    SCSIRequest *r = (SCSIRequest *)opaque;
247 2cc977e2 ths
    SCSIDeviceState *s = r->dev;
248 2cc977e2 ths
    int len;
249 2cc977e2 ths
250 2cc977e2 ths
    if (ret) {
251 2cc977e2 ths
        DPRINTF("IO error\n");
252 2cc977e2 ths
        scsi_command_complete(r, ret);
253 2cc977e2 ths
        return;
254 2cc977e2 ths
    }
255 2cc977e2 ths
    len = r->io_header.dxfer_len - r->io_header.resid;
256 2cc977e2 ths
    DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
257 2cc977e2 ths
258 2cc977e2 ths
    r->len = -1;
259 2cc977e2 ths
    s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
260 89c0f643 aurel32
    if (len == 0)
261 89c0f643 aurel32
        scsi_command_complete(r, 0);
262 2cc977e2 ths
}
263 2cc977e2 ths
264 2cc977e2 ths
/* Read more data from scsi device into buffer.  */
265 2cc977e2 ths
static void scsi_read_data(SCSIDevice *d, uint32_t tag)
266 2cc977e2 ths
{
267 2cc977e2 ths
    SCSIDeviceState *s = d->state;
268 2cc977e2 ths
    SCSIRequest *r;
269 2cc977e2 ths
    int ret;
270 2cc977e2 ths
271 2cc977e2 ths
    DPRINTF("scsi_read_data 0x%x\n", tag);
272 2cc977e2 ths
    r = scsi_find_request(s, tag);
273 2cc977e2 ths
    if (!r) {
274 2cc977e2 ths
        BADF("Bad read tag 0x%x\n", tag);
275 2cc977e2 ths
        /* ??? This is the wrong error.  */
276 2cc977e2 ths
        scsi_command_complete(r, -EINVAL);
277 2cc977e2 ths
        return;
278 2cc977e2 ths
    }
279 2cc977e2 ths
280 2cc977e2 ths
    if (r->len == -1) {
281 2cc977e2 ths
        scsi_command_complete(r, 0);
282 2cc977e2 ths
        return;
283 2cc977e2 ths
    }
284 2cc977e2 ths
285 2cc977e2 ths
    if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
286 2cc977e2 ths
    {
287 89c0f643 aurel32
        s->senselen = MIN(r->len, s->senselen);
288 89c0f643 aurel32
        memcpy(r->buf, s->sensebuf, s->senselen);
289 2cc977e2 ths
        r->io_header.driver_status = 0;
290 89c0f643 aurel32
        r->io_header.status = 0;
291 89c0f643 aurel32
        r->io_header.dxfer_len  = s->senselen;
292 2cc977e2 ths
        r->len = -1;
293 89c0f643 aurel32
        DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, s->senselen);
294 a9dd6843 aliguori
        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
295 a9dd6843 aliguori
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
296 a9dd6843 aliguori
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
297 89c0f643 aurel32
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, s->senselen);
298 2cc977e2 ths
        return;
299 2cc977e2 ths
    }
300 2cc977e2 ths
301 2cc977e2 ths
    ret = execute_command(s->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
302 2cc977e2 ths
    if (ret == -1) {
303 2cc977e2 ths
        scsi_command_complete(r, -EINVAL);
304 2cc977e2 ths
        return;
305 2cc977e2 ths
    }
306 2cc977e2 ths
}
307 2cc977e2 ths
308 2cc977e2 ths
static void scsi_write_complete(void * opaque, int ret)
309 2cc977e2 ths
{
310 2cc977e2 ths
    SCSIRequest *r = (SCSIRequest *)opaque;
311 2cc977e2 ths
312 2cc977e2 ths
    DPRINTF("scsi_write_complete() ret = %d\n", ret);
313 2cc977e2 ths
    if (ret) {
314 2cc977e2 ths
        DPRINTF("IO error\n");
315 2cc977e2 ths
        scsi_command_complete(r, ret);
316 2cc977e2 ths
        return;
317 2cc977e2 ths
    }
318 2cc977e2 ths
319 89c0f643 aurel32
    if (r->cmd[0] == MODE_SELECT && r->cmd[4] == 12 &&
320 89c0f643 aurel32
        r->dev->type == TYPE_TAPE) {
321 89c0f643 aurel32
        r->dev->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
322 89c0f643 aurel32
        DPRINTF("block size %d\n", r->dev->blocksize);
323 89c0f643 aurel32
    }
324 89c0f643 aurel32
325 2cc977e2 ths
    scsi_command_complete(r, ret);
326 2cc977e2 ths
}
327 2cc977e2 ths
328 2cc977e2 ths
/* Write data to a scsi device.  Returns nonzero on failure.
329 2cc977e2 ths
   The transfer may complete asynchronously.  */
330 2cc977e2 ths
static int scsi_write_data(SCSIDevice *d, uint32_t tag)
331 2cc977e2 ths
{
332 2cc977e2 ths
    SCSIDeviceState *s = d->state;
333 2cc977e2 ths
    SCSIRequest *r;
334 2cc977e2 ths
    int ret;
335 2cc977e2 ths
336 2cc977e2 ths
    DPRINTF("scsi_write_data 0x%x\n", tag);
337 2cc977e2 ths
    r = scsi_find_request(s, tag);
338 2cc977e2 ths
    if (!r) {
339 2cc977e2 ths
        BADF("Bad write tag 0x%x\n", tag);
340 2cc977e2 ths
        /* ??? This is the wrong error.  */
341 2cc977e2 ths
        scsi_command_complete(r, -EINVAL);
342 2cc977e2 ths
        return 0;
343 2cc977e2 ths
    }
344 2cc977e2 ths
345 2cc977e2 ths
    if (r->len == 0) {
346 2cc977e2 ths
        r->len = r->buflen;
347 2cc977e2 ths
        s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->len);
348 2cc977e2 ths
        return 0;
349 2cc977e2 ths
    }
350 2cc977e2 ths
351 2cc977e2 ths
    ret = execute_command(s->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
352 2cc977e2 ths
    if (ret == -1) {
353 2cc977e2 ths
        scsi_command_complete(r, -EINVAL);
354 2cc977e2 ths
        return 1;
355 2cc977e2 ths
    }
356 2cc977e2 ths
357 2cc977e2 ths
    return 0;
358 2cc977e2 ths
}
359 2cc977e2 ths
360 2cc977e2 ths
/* Return a pointer to the data buffer.  */
361 2cc977e2 ths
static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
362 2cc977e2 ths
{
363 2cc977e2 ths
    SCSIDeviceState *s = d->state;
364 2cc977e2 ths
    SCSIRequest *r;
365 2cc977e2 ths
    r = scsi_find_request(s, tag);
366 2cc977e2 ths
    if (!r) {
367 2cc977e2 ths
        BADF("Bad buffer tag 0x%x\n", tag);
368 2cc977e2 ths
        return NULL;
369 2cc977e2 ths
    }
370 2cc977e2 ths
    return r->buf;
371 2cc977e2 ths
}
372 2cc977e2 ths
373 2cc977e2 ths
static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
374 2cc977e2 ths
{
375 2cc977e2 ths
    switch (cmd[0] >> 5) {
376 2cc977e2 ths
    case 0:
377 2cc977e2 ths
        *len = cmd[4];
378 2cc977e2 ths
        *cmdlen = 6;
379 72ecb8d9 aliguori
        /* length 0 means 256 blocks */
380 72ecb8d9 aliguori
        if (*len == 0)
381 72ecb8d9 aliguori
            *len = 256;
382 2cc977e2 ths
        break;
383 2cc977e2 ths
    case 1:
384 2cc977e2 ths
    case 2:
385 2cc977e2 ths
        *len = cmd[8] | (cmd[7] << 8);
386 2cc977e2 ths
        *cmdlen = 10;
387 2cc977e2 ths
        break;
388 2cc977e2 ths
    case 4:
389 2cc977e2 ths
        *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
390 2cc977e2 ths
        *cmdlen = 16;
391 2cc977e2 ths
        break;
392 2cc977e2 ths
    case 5:
393 2cc977e2 ths
        *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
394 2cc977e2 ths
        *cmdlen = 12;
395 2cc977e2 ths
        break;
396 2cc977e2 ths
    default:
397 2cc977e2 ths
        return -1;
398 2cc977e2 ths
    }
399 2cc977e2 ths
400 2cc977e2 ths
    switch(cmd[0]) {
401 2cc977e2 ths
    case TEST_UNIT_READY:
402 2cc977e2 ths
    case REZERO_UNIT:
403 2cc977e2 ths
    case START_STOP:
404 2cc977e2 ths
    case SEEK_6:
405 2cc977e2 ths
    case WRITE_FILEMARKS:
406 2cc977e2 ths
    case SPACE:
407 2cc977e2 ths
    case ERASE:
408 2cc977e2 ths
    case ALLOW_MEDIUM_REMOVAL:
409 2cc977e2 ths
    case VERIFY:
410 2cc977e2 ths
    case SEEK_10:
411 2cc977e2 ths
    case SYNCHRONIZE_CACHE:
412 2cc977e2 ths
    case LOCK_UNLOCK_CACHE:
413 2cc977e2 ths
    case LOAD_UNLOAD:
414 2cc977e2 ths
    case SET_CD_SPEED:
415 2cc977e2 ths
    case SET_LIMITS:
416 2cc977e2 ths
    case WRITE_LONG:
417 2cc977e2 ths
    case MOVE_MEDIUM:
418 2cc977e2 ths
    case UPDATE_BLOCK:
419 2cc977e2 ths
        *len = 0;
420 2cc977e2 ths
        break;
421 2cc977e2 ths
    case MODE_SENSE:
422 2cc977e2 ths
        break;
423 2cc977e2 ths
    case WRITE_SAME:
424 2cc977e2 ths
        *len = 1;
425 2cc977e2 ths
        break;
426 2cc977e2 ths
    case READ_CAPACITY:
427 2cc977e2 ths
        *len = 8;
428 2cc977e2 ths
        break;
429 2cc977e2 ths
    case READ_BLOCK_LIMITS:
430 2cc977e2 ths
        *len = 6;
431 2cc977e2 ths
        break;
432 2cc977e2 ths
    case READ_POSITION:
433 2cc977e2 ths
        *len = 20;
434 2cc977e2 ths
        break;
435 2cc977e2 ths
    case SEND_VOLUME_TAG:
436 2cc977e2 ths
        *len *= 40;
437 2cc977e2 ths
        break;
438 2cc977e2 ths
    case MEDIUM_SCAN:
439 2cc977e2 ths
        *len *= 8;
440 2cc977e2 ths
        break;
441 2cc977e2 ths
    case WRITE_10:
442 2cc977e2 ths
        cmd[1] &= ~0x08;        /* disable FUA */
443 2cc977e2 ths
    case WRITE_VERIFY:
444 2cc977e2 ths
    case WRITE_6:
445 2cc977e2 ths
    case WRITE_12:
446 2cc977e2 ths
    case WRITE_VERIFY_12:
447 2cc977e2 ths
        *len *= blocksize;
448 2cc977e2 ths
        break;
449 2cc977e2 ths
    case READ_10:
450 2cc977e2 ths
        cmd[1] &= ~0x08;        /* disable FUA */
451 2cc977e2 ths
    case READ_6:
452 2cc977e2 ths
    case READ_REVERSE:
453 2cc977e2 ths
    case RECOVER_BUFFERED_DATA:
454 2cc977e2 ths
    case READ_12:
455 2cc977e2 ths
        *len *= blocksize;
456 2cc977e2 ths
        break;
457 89c0f643 aurel32
    case INQUIRY:
458 89c0f643 aurel32
        *len = cmd[4] | (cmd[3] << 8);
459 89c0f643 aurel32
        break;
460 2cc977e2 ths
    }
461 2cc977e2 ths
    return 0;
462 2cc977e2 ths
}
463 2cc977e2 ths
464 a9dd6843 aliguori
static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
465 a9dd6843 aliguori
{
466 a9dd6843 aliguori
    switch(cmd[0]) {
467 a9dd6843 aliguori
    /* stream commands */
468 a9dd6843 aliguori
    case READ_6:
469 a9dd6843 aliguori
    case READ_REVERSE:
470 a9dd6843 aliguori
    case RECOVER_BUFFERED_DATA:
471 a9dd6843 aliguori
    case WRITE_6:
472 a9dd6843 aliguori
        *cmdlen = 6;
473 a9dd6843 aliguori
        *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
474 a9dd6843 aliguori
        if (cmd[1] & 0x01) /* fixed */
475 a9dd6843 aliguori
            *len *= blocksize;
476 a9dd6843 aliguori
        break;
477 a9dd6843 aliguori
    case REWIND:
478 a9dd6843 aliguori
    case START_STOP:
479 a9dd6843 aliguori
        *cmdlen = 6;
480 a9dd6843 aliguori
        *len = 0;
481 a9dd6843 aliguori
        cmd[1] = 0x01;        /* force IMMED, otherwise qemu waits end of command */
482 a9dd6843 aliguori
        break;
483 a9dd6843 aliguori
    /* generic commands */
484 a9dd6843 aliguori
    default:
485 a9dd6843 aliguori
        return scsi_length(cmd, blocksize, cmdlen, len);
486 a9dd6843 aliguori
    }
487 a9dd6843 aliguori
    return 0;
488 a9dd6843 aliguori
}
489 a9dd6843 aliguori
490 2cc977e2 ths
static int is_write(int command)
491 2cc977e2 ths
{
492 2cc977e2 ths
    switch (command) {
493 2cc977e2 ths
    case COPY:
494 2cc977e2 ths
    case COPY_VERIFY:
495 2cc977e2 ths
    case COMPARE:
496 2cc977e2 ths
    case CHANGE_DEFINITION:
497 2cc977e2 ths
    case LOG_SELECT:
498 2cc977e2 ths
    case MODE_SELECT:
499 2cc977e2 ths
    case MODE_SELECT_10:
500 2cc977e2 ths
    case SEND_DIAGNOSTIC:
501 2cc977e2 ths
    case WRITE_BUFFER:
502 2cc977e2 ths
    case FORMAT_UNIT:
503 2cc977e2 ths
    case REASSIGN_BLOCKS:
504 2cc977e2 ths
    case RESERVE:
505 2cc977e2 ths
    case SEARCH_EQUAL:
506 2cc977e2 ths
    case SEARCH_HIGH:
507 2cc977e2 ths
    case SEARCH_LOW:
508 2cc977e2 ths
    case WRITE_6:
509 2cc977e2 ths
    case WRITE_10:
510 2cc977e2 ths
    case WRITE_VERIFY:
511 2cc977e2 ths
    case UPDATE_BLOCK:
512 2cc977e2 ths
    case WRITE_LONG:
513 2cc977e2 ths
    case WRITE_SAME:
514 2cc977e2 ths
    case SEARCH_HIGH_12:
515 2cc977e2 ths
    case SEARCH_EQUAL_12:
516 2cc977e2 ths
    case SEARCH_LOW_12:
517 2cc977e2 ths
    case WRITE_12:
518 2cc977e2 ths
    case WRITE_VERIFY_12:
519 2cc977e2 ths
    case SET_WINDOW:
520 2cc977e2 ths
    case MEDIUM_SCAN:
521 2cc977e2 ths
    case SEND_VOLUME_TAG:
522 2cc977e2 ths
    case WRITE_LONG_2:
523 2cc977e2 ths
        return 1;
524 2cc977e2 ths
    }
525 2cc977e2 ths
    return 0;
526 2cc977e2 ths
}
527 2cc977e2 ths
528 2cc977e2 ths
/* Execute a scsi command.  Returns the length of the data expected by the
529 2cc977e2 ths
   command.  This will be Positive for data transfers from the device
530 2cc977e2 ths
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
531 2cc977e2 ths
   and zero if the command does not transfer any data.  */
532 2cc977e2 ths
533 2cc977e2 ths
static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
534 2cc977e2 ths
                                 uint8_t *cmd, int lun)
535 2cc977e2 ths
{
536 2cc977e2 ths
    SCSIDeviceState *s = d->state;
537 37e828b4 aurel32
    uint32_t len=0;
538 37e828b4 aurel32
    int cmdlen=0;
539 2cc977e2 ths
    SCSIRequest *r;
540 2cc977e2 ths
    int ret;
541 2cc977e2 ths
542 a9dd6843 aliguori
    if (s->type == TYPE_TAPE) {
543 a9dd6843 aliguori
        if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
544 a9dd6843 aliguori
            BADF("Unsupported command length, command %x\n", cmd[0]);
545 a9dd6843 aliguori
            return 0;
546 a9dd6843 aliguori
        }
547 a9dd6843 aliguori
     } else {
548 a9dd6843 aliguori
        if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
549 a9dd6843 aliguori
            BADF("Unsupported command length, command %x\n", cmd[0]);
550 a9dd6843 aliguori
            return 0;
551 a9dd6843 aliguori
        }
552 2cc977e2 ths
    }
553 2cc977e2 ths
554 2cc977e2 ths
    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
555 2cc977e2 ths
            cmd[0], len);
556 2cc977e2 ths
557 89c0f643 aurel32
    if (cmd[0] != REQUEST_SENSE &&
558 89c0f643 aurel32
        (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
559 89c0f643 aurel32
        DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
560 89c0f643 aurel32
561 89c0f643 aurel32
        s->sensebuf[0] = 0x70;
562 89c0f643 aurel32
        s->sensebuf[1] = 0x00;
563 89c0f643 aurel32
        s->sensebuf[2] = ILLEGAL_REQUEST;
564 89c0f643 aurel32
        s->sensebuf[3] = 0x00;
565 89c0f643 aurel32
        s->sensebuf[4] = 0x00;
566 89c0f643 aurel32
        s->sensebuf[5] = 0x00;
567 89c0f643 aurel32
        s->sensebuf[6] = 0x00;
568 89c0f643 aurel32
        s->senselen = 7;
569 89c0f643 aurel32
        s->driver_status = SG_ERR_DRIVER_SENSE;
570 89c0f643 aurel32
        s->completion(s->opaque, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
571 89c0f643 aurel32
        return 0;
572 89c0f643 aurel32
    }
573 89c0f643 aurel32
574 2cc977e2 ths
    r = scsi_find_request(s, tag);
575 2cc977e2 ths
    if (r) {
576 2cc977e2 ths
        BADF("Tag 0x%x already in use %p\n", tag, r);
577 2cc977e2 ths
        scsi_cancel_io(d, tag);
578 2cc977e2 ths
    }
579 2cc977e2 ths
    r = scsi_new_request(s, tag);
580 2cc977e2 ths
581 2cc977e2 ths
    memcpy(r->cmd, cmd, cmdlen);
582 2cc977e2 ths
    r->cmdlen = cmdlen;
583 2cc977e2 ths
584 2cc977e2 ths
    if (len == 0) {
585 2cc977e2 ths
        if (r->buf != NULL)
586 2cc977e2 ths
            free(r->buf);
587 2cc977e2 ths
        r->buflen = 0;
588 2cc977e2 ths
        r->buf = NULL;
589 2cc977e2 ths
        ret = execute_command(s->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
590 2cc977e2 ths
        if (ret == -1) {
591 2cc977e2 ths
            scsi_command_complete(r, -EINVAL);
592 2cc977e2 ths
            return 0;
593 2cc977e2 ths
        }
594 2cc977e2 ths
        return 0;
595 2cc977e2 ths
    }
596 2cc977e2 ths
597 2cc977e2 ths
    if (r->buflen != len) {
598 2cc977e2 ths
        if (r->buf != NULL)
599 2cc977e2 ths
            free(r->buf);
600 2cc977e2 ths
        r->buf = qemu_malloc(len);
601 2cc977e2 ths
        r->buflen = len;
602 2cc977e2 ths
    }
603 2cc977e2 ths
604 2cc977e2 ths
    memset(r->buf, 0, r->buflen);
605 2cc977e2 ths
    r->len = len;
606 2cc977e2 ths
    if (is_write(cmd[0])) {
607 2cc977e2 ths
        r->len = 0;
608 2cc977e2 ths
        return -len;
609 2cc977e2 ths
    }
610 2cc977e2 ths
611 2cc977e2 ths
    return len;
612 2cc977e2 ths
}
613 2cc977e2 ths
614 2cc977e2 ths
static int get_blocksize(BlockDriverState *bdrv)
615 2cc977e2 ths
{
616 2cc977e2 ths
    uint8_t cmd[10];
617 2cc977e2 ths
    uint8_t buf[8];
618 2cc977e2 ths
    uint8_t sensebuf[8];
619 2cc977e2 ths
    sg_io_hdr_t io_header;
620 2cc977e2 ths
    int ret;
621 2cc977e2 ths
622 4f26a486 aliguori
    memset(cmd, 0, sizeof(cmd));
623 4f26a486 aliguori
    memset(buf, 0, sizeof(buf));
624 2cc977e2 ths
    cmd[0] = READ_CAPACITY;
625 2cc977e2 ths
626 2cc977e2 ths
    memset(&io_header, 0, sizeof(io_header));
627 2cc977e2 ths
    io_header.interface_id = 'S';
628 2cc977e2 ths
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
629 2cc977e2 ths
    io_header.dxfer_len = sizeof(buf);
630 2cc977e2 ths
    io_header.dxferp = buf;
631 2cc977e2 ths
    io_header.cmdp = cmd;
632 2cc977e2 ths
    io_header.cmd_len = sizeof(cmd);
633 2cc977e2 ths
    io_header.mx_sb_len = sizeof(sensebuf);
634 2cc977e2 ths
    io_header.sbp = sensebuf;
635 2cc977e2 ths
    io_header.timeout = 6000; /* XXX */
636 2cc977e2 ths
637 2cc977e2 ths
    ret = bdrv_pwrite(bdrv, -1, &io_header, sizeof(io_header));
638 2cc977e2 ths
    if (ret == -1)
639 2cc977e2 ths
        return -1;
640 2cc977e2 ths
641 2cc977e2 ths
    while ((ret = bdrv_pread(bdrv, -1, &io_header, sizeof(io_header))) == -1 &&
642 2cc977e2 ths
           errno == EINTR);
643 2cc977e2 ths
644 2cc977e2 ths
    if (ret == -1)
645 2cc977e2 ths
        return -1;
646 2cc977e2 ths
647 2cc977e2 ths
    return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
648 2cc977e2 ths
}
649 2cc977e2 ths
650 89c0f643 aurel32
static int get_stream_blocksize(BlockDriverState *bdrv)
651 89c0f643 aurel32
{
652 89c0f643 aurel32
    uint8_t cmd[6];
653 89c0f643 aurel32
    uint8_t buf[12];
654 89c0f643 aurel32
    uint8_t sensebuf[8];
655 89c0f643 aurel32
    sg_io_hdr_t io_header;
656 89c0f643 aurel32
    int ret;
657 89c0f643 aurel32
658 89c0f643 aurel32
    memset(cmd, 0, sizeof(cmd));
659 89c0f643 aurel32
    memset(buf, 0, sizeof(buf));
660 89c0f643 aurel32
    cmd[0] = MODE_SENSE;
661 89c0f643 aurel32
    cmd[4] = sizeof(buf);
662 89c0f643 aurel32
663 89c0f643 aurel32
    memset(&io_header, 0, sizeof(io_header));
664 89c0f643 aurel32
    io_header.interface_id = 'S';
665 89c0f643 aurel32
    io_header.dxfer_direction = SG_DXFER_FROM_DEV;
666 89c0f643 aurel32
    io_header.dxfer_len = sizeof(buf);
667 89c0f643 aurel32
    io_header.dxferp = buf;
668 89c0f643 aurel32
    io_header.cmdp = cmd;
669 89c0f643 aurel32
    io_header.cmd_len = sizeof(cmd);
670 89c0f643 aurel32
    io_header.mx_sb_len = sizeof(sensebuf);
671 89c0f643 aurel32
    io_header.sbp = sensebuf;
672 89c0f643 aurel32
    io_header.timeout = 6000; /* XXX */
673 89c0f643 aurel32
674 89c0f643 aurel32
    ret = bdrv_pwrite(bdrv, -1, &io_header, sizeof(io_header));
675 89c0f643 aurel32
    if (ret == -1)
676 89c0f643 aurel32
        return -1;
677 89c0f643 aurel32
678 89c0f643 aurel32
    while ((ret = bdrv_pread(bdrv, -1, &io_header, sizeof(io_header))) == -1 &&
679 89c0f643 aurel32
           errno == EINTR);
680 89c0f643 aurel32
681 89c0f643 aurel32
    if (ret == -1)
682 89c0f643 aurel32
        return -1;
683 89c0f643 aurel32
684 89c0f643 aurel32
    return (buf[9] << 16) | (buf[10] << 8) | buf[11];
685 89c0f643 aurel32
}
686 89c0f643 aurel32
687 2cc977e2 ths
static void scsi_destroy(SCSIDevice *d)
688 2cc977e2 ths
{
689 2cc977e2 ths
    SCSIRequest *r, *n;
690 2cc977e2 ths
691 2cc977e2 ths
    r = d->state->requests;
692 2cc977e2 ths
    while (r) {
693 2cc977e2 ths
        n = r->next;
694 2cc977e2 ths
        qemu_free(r);
695 2cc977e2 ths
        r = n;
696 2cc977e2 ths
    }
697 2cc977e2 ths
698 2cc977e2 ths
    r = free_requests;
699 2cc977e2 ths
    while (r) {
700 2cc977e2 ths
        n = r->next;
701 2cc977e2 ths
        qemu_free(r);
702 2cc977e2 ths
        r = n;
703 2cc977e2 ths
    }
704 2cc977e2 ths
705 2cc977e2 ths
    qemu_free(d->state);
706 2cc977e2 ths
    qemu_free(d);
707 2cc977e2 ths
}
708 2cc977e2 ths
709 2cc977e2 ths
SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
710 2cc977e2 ths
                              scsi_completionfn completion, void *opaque)
711 2cc977e2 ths
{
712 2cc977e2 ths
    int sg_version;
713 2cc977e2 ths
    SCSIDevice *d;
714 2cc977e2 ths
    SCSIDeviceState *s;
715 2cc977e2 ths
    struct sg_scsi_id scsiid;
716 2cc977e2 ths
717 2cc977e2 ths
    /* check we are really using a /dev/sg* file */
718 2cc977e2 ths
719 2cc977e2 ths
    if (!bdrv_is_sg(bdrv))
720 2cc977e2 ths
        return NULL;
721 2cc977e2 ths
722 2cc977e2 ths
    /* check we are using a driver managing SG_IO (version 3 and after */
723 2cc977e2 ths
724 2cc977e2 ths
    if (bdrv_ioctl(bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
725 2cc977e2 ths
        sg_version < 30000)
726 2cc977e2 ths
        return NULL;
727 2cc977e2 ths
728 2cc977e2 ths
    /* get LUN of the /dev/sg? */
729 2cc977e2 ths
730 2cc977e2 ths
    if (bdrv_ioctl(bdrv, SG_GET_SCSI_ID, &scsiid))
731 2cc977e2 ths
        return NULL;
732 2cc977e2 ths
733 2cc977e2 ths
    /* define device state */
734 2cc977e2 ths
735 2cc977e2 ths
    s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
736 2cc977e2 ths
    s->bdrv = bdrv;
737 2cc977e2 ths
    s->requests = NULL;
738 2cc977e2 ths
    s->completion = completion;
739 2cc977e2 ths
    s->opaque = opaque;
740 2cc977e2 ths
    s->lun = scsiid.lun;
741 89c0f643 aurel32
    DPRINTF("LUN %d\n", s->lun);
742 a9dd6843 aliguori
    s->type = scsiid.scsi_type;
743 89c0f643 aurel32
    DPRINTF("device type %d\n", s->type);
744 89c0f643 aurel32
    if (s->type == TYPE_TAPE) {
745 89c0f643 aurel32
        s->blocksize = get_stream_blocksize(s->bdrv);
746 89c0f643 aurel32
        if (s->blocksize == -1)
747 89c0f643 aurel32
            s->blocksize = 0;
748 89c0f643 aurel32
    } else {
749 89c0f643 aurel32
        s->blocksize = get_blocksize(s->bdrv);
750 89c0f643 aurel32
        /* removable media returns 0 if not present */
751 89c0f643 aurel32
        if (s->blocksize <= 0) {
752 89c0f643 aurel32
            if (s->type == TYPE_ROM || s->type  == TYPE_WORM)
753 89c0f643 aurel32
                s->blocksize = 2048;
754 89c0f643 aurel32
            else
755 89c0f643 aurel32
                s->blocksize = 512;
756 89c0f643 aurel32
        }
757 89c0f643 aurel32
    }
758 89c0f643 aurel32
    DPRINTF("block size %d\n", s->blocksize);
759 2cc977e2 ths
    s->driver_status = 0;
760 2cc977e2 ths
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
761 2cc977e2 ths
762 2cc977e2 ths
    /* define function to manage device */
763 2cc977e2 ths
764 2cc977e2 ths
    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
765 2cc977e2 ths
    d->state = s;
766 2cc977e2 ths
    d->destroy = scsi_destroy;
767 2cc977e2 ths
    d->send_command = scsi_send_command;
768 2cc977e2 ths
    d->read_data = scsi_read_data;
769 2cc977e2 ths
    d->write_data = scsi_write_data;
770 2cc977e2 ths
    d->cancel_io = scsi_cancel_io;
771 2cc977e2 ths
    d->get_buf = scsi_get_buf;
772 2cc977e2 ths
773 2cc977e2 ths
    return d;
774 2cc977e2 ths
}
775 2cc977e2 ths
#endif /* __linux__ */