Statistics
| Branch: | Revision:

root / hw / scsi-generic.c @ 818220f5

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