]> git.proxmox.com Git - mirror_qemu.git/blob - hw/scsi-generic.c
Merge remote-tracking branch 'qemu-kvm-tmp/memory/int128' into staging
[mirror_qemu.git] / hw / scsi-generic.c
1 /*
2 * Generic SCSI Device support
3 *
4 * Copyright (c) 2007 Bull S.A.S.
5 * Based on code by Paul Brook
6 * Based on code by Fabrice Bellard
7 *
8 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
9 *
10 * This code is licensed under the LGPL.
11 *
12 */
13
14 #include "qemu-common.h"
15 #include "qemu-error.h"
16 #include "scsi.h"
17 #include "blockdev.h"
18
19 #ifdef __linux__
20
21 //#define DEBUG_SCSI
22
23 #ifdef DEBUG_SCSI
24 #define DPRINTF(fmt, ...) \
25 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
26 #else
27 #define DPRINTF(fmt, ...) do {} while(0)
28 #endif
29
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
32
33 #include <stdio.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <scsi/sg.h>
38 #include "scsi-defs.h"
39
40 #define SCSI_SENSE_BUF_SIZE 96
41
42 #define SG_ERR_DRIVER_TIMEOUT 0x06
43 #define SG_ERR_DRIVER_SENSE 0x08
44
45 #define SG_ERR_DID_OK 0x00
46 #define SG_ERR_DID_NO_CONNECT 0x01
47 #define SG_ERR_DID_BUS_BUSY 0x02
48 #define SG_ERR_DID_TIME_OUT 0x03
49
50 #ifndef MAX_UINT
51 #define MAX_UINT ((unsigned int)-1)
52 #endif
53
54 typedef struct SCSIGenericReq {
55 SCSIRequest req;
56 uint8_t *buf;
57 int buflen;
58 int len;
59 sg_io_hdr_t io_header;
60 } SCSIGenericReq;
61
62 static void scsi_free_request(SCSIRequest *req)
63 {
64 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
65
66 g_free(r->buf);
67 }
68
69 /* Helper function for command completion. */
70 static void scsi_command_complete(void *opaque, int ret)
71 {
72 int status;
73 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
74
75 r->req.aiocb = NULL;
76 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
77 r->req.sense_len = r->io_header.sb_len_wr;
78 }
79
80 if (ret != 0) {
81 switch (ret) {
82 case -EDOM:
83 status = TASK_SET_FULL;
84 break;
85 case -ENOMEM:
86 status = CHECK_CONDITION;
87 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
88 break;
89 default:
90 status = CHECK_CONDITION;
91 scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
92 break;
93 }
94 } else {
95 if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
96 r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
97 r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
98 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
99 status = BUSY;
100 BADF("Driver Timeout\n");
101 } else if (r->io_header.host_status) {
102 status = CHECK_CONDITION;
103 scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
104 } else if (r->io_header.status) {
105 status = r->io_header.status;
106 } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
107 status = CHECK_CONDITION;
108 } else {
109 status = GOOD;
110 }
111 }
112 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
113 r, r->req.tag, status);
114
115 scsi_req_complete(&r->req, status);
116 if (!r->req.io_canceled) {
117 scsi_req_unref(&r->req);
118 }
119 }
120
121 /* Cancel a pending data transfer. */
122 static void scsi_cancel_io(SCSIRequest *req)
123 {
124 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
125
126 DPRINTF("Cancel tag=0x%x\n", req->tag);
127 if (r->req.aiocb) {
128 bdrv_aio_cancel(r->req.aiocb);
129
130 /* This reference was left in by scsi_*_data. We take ownership of
131 * it independent of whether bdrv_aio_cancel completes the request
132 * or not. */
133 scsi_req_unref(&r->req);
134 }
135 r->req.aiocb = NULL;
136 }
137
138 static int execute_command(BlockDriverState *bdrv,
139 SCSIGenericReq *r, int direction,
140 BlockDriverCompletionFunc *complete)
141 {
142 r->io_header.interface_id = 'S';
143 r->io_header.dxfer_direction = direction;
144 r->io_header.dxferp = r->buf;
145 r->io_header.dxfer_len = r->buflen;
146 r->io_header.cmdp = r->req.cmd.buf;
147 r->io_header.cmd_len = r->req.cmd.len;
148 r->io_header.mx_sb_len = sizeof(r->req.sense);
149 r->io_header.sbp = r->req.sense;
150 r->io_header.timeout = MAX_UINT;
151 r->io_header.usr_ptr = r;
152 r->io_header.flags |= SG_FLAG_DIRECT_IO;
153
154 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
155 if (r->req.aiocb == NULL) {
156 BADF("execute_command: read failed !\n");
157 return -ENOMEM;
158 }
159
160 return 0;
161 }
162
163 static void scsi_read_complete(void * opaque, int ret)
164 {
165 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
166 SCSIDevice *s = r->req.dev;
167 int len;
168
169 r->req.aiocb = NULL;
170 if (ret) {
171 DPRINTF("IO error ret %d\n", ret);
172 scsi_command_complete(r, ret);
173 return;
174 }
175 len = r->io_header.dxfer_len - r->io_header.resid;
176 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
177
178 r->len = -1;
179 if (len == 0) {
180 scsi_command_complete(r, 0);
181 } else {
182 /* Snoop READ CAPACITY output to set the blocksize. */
183 if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
184 s->blocksize = ldl_be_p(&r->buf[4]);
185 s->max_lba = ldl_be_p(&r->buf[0]);
186 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
187 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
188 s->blocksize = ldl_be_p(&r->buf[8]);
189 s->max_lba = ldq_be_p(&r->buf[0]);
190 }
191 bdrv_set_buffer_alignment(s->conf.bs, s->blocksize);
192
193 scsi_req_data(&r->req, len);
194 if (!r->req.io_canceled) {
195 scsi_req_unref(&r->req);
196 }
197 }
198 }
199
200 /* Read more data from scsi device into buffer. */
201 static void scsi_read_data(SCSIRequest *req)
202 {
203 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
204 SCSIDevice *s = r->req.dev;
205 int ret;
206
207 DPRINTF("scsi_read_data 0x%x\n", req->tag);
208
209 /* The request is used as the AIO opaque value, so add a ref. */
210 scsi_req_ref(&r->req);
211 if (r->len == -1) {
212 scsi_command_complete(r, 0);
213 return;
214 }
215
216 ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
217 if (ret < 0) {
218 scsi_command_complete(r, ret);
219 }
220 }
221
222 static void scsi_write_complete(void * opaque, int ret)
223 {
224 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
225 SCSIDevice *s = r->req.dev;
226
227 DPRINTF("scsi_write_complete() ret = %d\n", ret);
228 r->req.aiocb = NULL;
229 if (ret) {
230 DPRINTF("IO error\n");
231 scsi_command_complete(r, ret);
232 return;
233 }
234
235 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
236 s->type == TYPE_TAPE) {
237 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
238 DPRINTF("block size %d\n", s->blocksize);
239 }
240
241 scsi_command_complete(r, ret);
242 }
243
244 /* Write data to a scsi device. Returns nonzero on failure.
245 The transfer may complete asynchronously. */
246 static void scsi_write_data(SCSIRequest *req)
247 {
248 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
249 SCSIDevice *s = r->req.dev;
250 int ret;
251
252 DPRINTF("scsi_write_data 0x%x\n", req->tag);
253 if (r->len == 0) {
254 r->len = r->buflen;
255 scsi_req_data(&r->req, r->len);
256 return;
257 }
258
259 /* The request is used as the AIO opaque value, so add a ref. */
260 scsi_req_ref(&r->req);
261 ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
262 if (ret < 0) {
263 scsi_command_complete(r, ret);
264 }
265 }
266
267 /* Return a pointer to the data buffer. */
268 static uint8_t *scsi_get_buf(SCSIRequest *req)
269 {
270 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
271
272 return r->buf;
273 }
274
275 /* Execute a scsi command. Returns the length of the data expected by the
276 command. This will be Positive for data transfers from the device
277 (eg. disk reads), negative for transfers to the device (eg. disk writes),
278 and zero if the command does not transfer any data. */
279
280 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
281 {
282 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
283 SCSIDevice *s = r->req.dev;
284 int ret;
285
286 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
287 r->req.cmd.xfer, cmd[0]);
288
289 #ifdef DEBUG_SCSI
290 {
291 int i;
292 for (i = 1; i < r->req.cmd.len; i++) {
293 printf(" 0x%02x", cmd[i]);
294 }
295 printf("\n");
296 }
297 #endif
298
299 if (r->req.cmd.xfer == 0) {
300 if (r->buf != NULL)
301 g_free(r->buf);
302 r->buflen = 0;
303 r->buf = NULL;
304 /* The request is used as the AIO opaque value, so add a ref. */
305 scsi_req_ref(&r->req);
306 ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
307 if (ret < 0) {
308 scsi_command_complete(r, ret);
309 return 0;
310 }
311 return 0;
312 }
313
314 if (r->buflen != r->req.cmd.xfer) {
315 if (r->buf != NULL)
316 g_free(r->buf);
317 r->buf = g_malloc(r->req.cmd.xfer);
318 r->buflen = r->req.cmd.xfer;
319 }
320
321 memset(r->buf, 0, r->buflen);
322 r->len = r->req.cmd.xfer;
323 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
324 r->len = 0;
325 return -r->req.cmd.xfer;
326 } else {
327 return r->req.cmd.xfer;
328 }
329 }
330
331 static int get_stream_blocksize(BlockDriverState *bdrv)
332 {
333 uint8_t cmd[6];
334 uint8_t buf[12];
335 uint8_t sensebuf[8];
336 sg_io_hdr_t io_header;
337 int ret;
338
339 memset(cmd, 0, sizeof(cmd));
340 memset(buf, 0, sizeof(buf));
341 cmd[0] = MODE_SENSE;
342 cmd[4] = sizeof(buf);
343
344 memset(&io_header, 0, sizeof(io_header));
345 io_header.interface_id = 'S';
346 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
347 io_header.dxfer_len = sizeof(buf);
348 io_header.dxferp = buf;
349 io_header.cmdp = cmd;
350 io_header.cmd_len = sizeof(cmd);
351 io_header.mx_sb_len = sizeof(sensebuf);
352 io_header.sbp = sensebuf;
353 io_header.timeout = 6000; /* XXX */
354
355 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
356 if (ret < 0 || io_header.driver_status || io_header.host_status) {
357 return -1;
358 }
359 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
360 }
361
362 static void scsi_generic_reset(DeviceState *dev)
363 {
364 SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
365
366 scsi_device_purge_requests(s, SENSE_CODE(RESET));
367 }
368
369 static void scsi_destroy(SCSIDevice *s)
370 {
371 scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
372 blockdev_mark_auto_del(s->conf.bs);
373 }
374
375 static int scsi_generic_initfn(SCSIDevice *s)
376 {
377 int sg_version;
378 struct sg_scsi_id scsiid;
379
380 if (!s->conf.bs) {
381 error_report("scsi-generic: drive property not set");
382 return -1;
383 }
384
385 /* check we are really using a /dev/sg* file */
386 if (!bdrv_is_sg(s->conf.bs)) {
387 error_report("scsi-generic: not /dev/sg*");
388 return -1;
389 }
390
391 if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
392 error_report("Device doesn't support drive option werror");
393 return -1;
394 }
395 if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) {
396 error_report("Device doesn't support drive option rerror");
397 return -1;
398 }
399
400 /* check we are using a driver managing SG_IO (version 3 and after */
401 if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
402 sg_version < 30000) {
403 error_report("scsi-generic: scsi generic interface too old");
404 return -1;
405 }
406
407 /* get LUN of the /dev/sg? */
408 if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
409 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
410 return -1;
411 }
412
413 /* define device state */
414 s->type = scsiid.scsi_type;
415 DPRINTF("device type %d\n", s->type);
416 switch (s->type) {
417 case TYPE_TAPE:
418 s->blocksize = get_stream_blocksize(s->conf.bs);
419 if (s->blocksize == -1) {
420 s->blocksize = 0;
421 }
422 break;
423
424 /* Make a guess for block devices, we'll fix it when the guest sends.
425 * READ CAPACITY. If they don't, they likely would assume these sizes
426 * anyway. (TODO: they could also send MODE SENSE).
427 */
428 case TYPE_ROM:
429 case TYPE_WORM:
430 s->blocksize = 2048;
431 break;
432 default:
433 s->blocksize = 512;
434 break;
435 }
436
437 DPRINTF("block size %d\n", s->blocksize);
438 return 0;
439 }
440
441 const SCSIReqOps scsi_generic_req_ops = {
442 .size = sizeof(SCSIGenericReq),
443 .free_req = scsi_free_request,
444 .send_command = scsi_send_command,
445 .read_data = scsi_read_data,
446 .write_data = scsi_write_data,
447 .cancel_io = scsi_cancel_io,
448 .get_buf = scsi_get_buf,
449 };
450
451 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
452 uint8_t *buf, void *hba_private)
453 {
454 SCSIRequest *req;
455
456 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
457 return req;
458 }
459
460 static SCSIDeviceInfo scsi_generic_info = {
461 .qdev.name = "scsi-generic",
462 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
463 .qdev.size = sizeof(SCSIDevice),
464 .qdev.reset = scsi_generic_reset,
465 .init = scsi_generic_initfn,
466 .destroy = scsi_destroy,
467 .alloc_req = scsi_new_request,
468 .qdev.props = (Property[]) {
469 DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
470 DEFINE_PROP_END_OF_LIST(),
471 },
472 };
473
474 static void scsi_generic_register_devices(void)
475 {
476 scsi_qdev_register(&scsi_generic_info);
477 }
478 device_init(scsi_generic_register_devices)
479
480 #endif /* __linux__ */