Add access control support to qemu bridge helper
[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
156 return 0;
157 }
158
159 static void scsi_read_complete(void * opaque, int ret)
160 {
161 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
162 SCSIDevice *s = r->req.dev;
163 int len;
164
165 r->req.aiocb = NULL;
166 if (ret) {
167 DPRINTF("IO error ret %d\n", ret);
168 scsi_command_complete(r, ret);
169 return;
170 }
171 len = r->io_header.dxfer_len - r->io_header.resid;
172 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
173
174 r->len = -1;
175 if (len == 0) {
176 scsi_command_complete(r, 0);
177 } else {
178 /* Snoop READ CAPACITY output to set the blocksize. */
179 if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
180 s->blocksize = ldl_be_p(&r->buf[4]);
181 s->max_lba = ldl_be_p(&r->buf[0]);
182 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
183 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
184 s->blocksize = ldl_be_p(&r->buf[8]);
185 s->max_lba = ldq_be_p(&r->buf[0]);
186 }
187 bdrv_set_buffer_alignment(s->conf.bs, s->blocksize);
188
189 scsi_req_data(&r->req, len);
190 if (!r->req.io_canceled) {
191 scsi_req_unref(&r->req);
192 }
193 }
194 }
195
196 /* Read more data from scsi device into buffer. */
197 static void scsi_read_data(SCSIRequest *req)
198 {
199 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
200 SCSIDevice *s = r->req.dev;
201 int ret;
202
203 DPRINTF("scsi_read_data 0x%x\n", req->tag);
204
205 /* The request is used as the AIO opaque value, so add a ref. */
206 scsi_req_ref(&r->req);
207 if (r->len == -1) {
208 scsi_command_complete(r, 0);
209 return;
210 }
211
212 ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
213 if (ret < 0) {
214 scsi_command_complete(r, ret);
215 }
216 }
217
218 static void scsi_write_complete(void * opaque, int ret)
219 {
220 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
221 SCSIDevice *s = r->req.dev;
222
223 DPRINTF("scsi_write_complete() ret = %d\n", ret);
224 r->req.aiocb = NULL;
225 if (ret) {
226 DPRINTF("IO error\n");
227 scsi_command_complete(r, ret);
228 return;
229 }
230
231 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
232 s->type == TYPE_TAPE) {
233 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
234 DPRINTF("block size %d\n", s->blocksize);
235 }
236
237 scsi_command_complete(r, ret);
238 }
239
240 /* Write data to a scsi device. Returns nonzero on failure.
241 The transfer may complete asynchronously. */
242 static void scsi_write_data(SCSIRequest *req)
243 {
244 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
245 SCSIDevice *s = r->req.dev;
246 int ret;
247
248 DPRINTF("scsi_write_data 0x%x\n", req->tag);
249 if (r->len == 0) {
250 r->len = r->buflen;
251 scsi_req_data(&r->req, r->len);
252 return;
253 }
254
255 /* The request is used as the AIO opaque value, so add a ref. */
256 scsi_req_ref(&r->req);
257 ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
258 if (ret < 0) {
259 scsi_command_complete(r, ret);
260 }
261 }
262
263 /* Return a pointer to the data buffer. */
264 static uint8_t *scsi_get_buf(SCSIRequest *req)
265 {
266 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
267
268 return r->buf;
269 }
270
271 /* Execute a scsi command. Returns the length of the data expected by the
272 command. This will be Positive for data transfers from the device
273 (eg. disk reads), negative for transfers to the device (eg. disk writes),
274 and zero if the command does not transfer any data. */
275
276 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
277 {
278 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
279 SCSIDevice *s = r->req.dev;
280 int ret;
281
282 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
283 r->req.cmd.xfer, cmd[0]);
284
285 #ifdef DEBUG_SCSI
286 {
287 int i;
288 for (i = 1; i < r->req.cmd.len; i++) {
289 printf(" 0x%02x", cmd[i]);
290 }
291 printf("\n");
292 }
293 #endif
294
295 if (r->req.cmd.xfer == 0) {
296 if (r->buf != NULL)
297 g_free(r->buf);
298 r->buflen = 0;
299 r->buf = NULL;
300 /* The request is used as the AIO opaque value, so add a ref. */
301 scsi_req_ref(&r->req);
302 ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
303 if (ret < 0) {
304 scsi_command_complete(r, ret);
305 return 0;
306 }
307 return 0;
308 }
309
310 if (r->buflen != r->req.cmd.xfer) {
311 if (r->buf != NULL)
312 g_free(r->buf);
313 r->buf = g_malloc(r->req.cmd.xfer);
314 r->buflen = r->req.cmd.xfer;
315 }
316
317 memset(r->buf, 0, r->buflen);
318 r->len = r->req.cmd.xfer;
319 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
320 r->len = 0;
321 return -r->req.cmd.xfer;
322 } else {
323 return r->req.cmd.xfer;
324 }
325 }
326
327 static int get_stream_blocksize(BlockDriverState *bdrv)
328 {
329 uint8_t cmd[6];
330 uint8_t buf[12];
331 uint8_t sensebuf[8];
332 sg_io_hdr_t io_header;
333 int ret;
334
335 memset(cmd, 0, sizeof(cmd));
336 memset(buf, 0, sizeof(buf));
337 cmd[0] = MODE_SENSE;
338 cmd[4] = sizeof(buf);
339
340 memset(&io_header, 0, sizeof(io_header));
341 io_header.interface_id = 'S';
342 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
343 io_header.dxfer_len = sizeof(buf);
344 io_header.dxferp = buf;
345 io_header.cmdp = cmd;
346 io_header.cmd_len = sizeof(cmd);
347 io_header.mx_sb_len = sizeof(sensebuf);
348 io_header.sbp = sensebuf;
349 io_header.timeout = 6000; /* XXX */
350
351 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
352 if (ret < 0 || io_header.driver_status || io_header.host_status) {
353 return -1;
354 }
355 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
356 }
357
358 static void scsi_generic_reset(DeviceState *dev)
359 {
360 SCSIDevice *s = SCSI_DEVICE(dev);
361
362 scsi_device_purge_requests(s, SENSE_CODE(RESET));
363 }
364
365 static void scsi_destroy(SCSIDevice *s)
366 {
367 scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
368 blockdev_mark_auto_del(s->conf.bs);
369 }
370
371 static int scsi_generic_initfn(SCSIDevice *s)
372 {
373 int sg_version;
374 struct sg_scsi_id scsiid;
375
376 if (!s->conf.bs) {
377 error_report("drive property not set");
378 return -1;
379 }
380
381 /* check we are really using a /dev/sg* file */
382 if (!bdrv_is_sg(s->conf.bs)) {
383 error_report("not /dev/sg*");
384 return -1;
385 }
386
387 if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
388 error_report("Device doesn't support drive option werror");
389 return -1;
390 }
391 if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) {
392 error_report("Device doesn't support drive option rerror");
393 return -1;
394 }
395
396 /* check we are using a driver managing SG_IO (version 3 and after */
397 if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
398 sg_version < 30000) {
399 error_report("scsi generic interface too old");
400 return -1;
401 }
402
403 /* get LUN of the /dev/sg? */
404 if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
405 error_report("SG_GET_SCSI_ID ioctl failed");
406 return -1;
407 }
408
409 /* define device state */
410 s->type = scsiid.scsi_type;
411 DPRINTF("device type %d\n", s->type);
412 if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
413 add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
414 }
415
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 void scsi_generic_class_initfn(ObjectClass *klass, void *data)
461 {
462 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
463
464 sc->init = scsi_generic_initfn;
465 sc->destroy = scsi_destroy;
466 sc->alloc_req = scsi_new_request;
467 }
468
469 static DeviceInfo scsi_generic_info = {
470 .name = "scsi-generic",
471 .fw_name = "disk",
472 .desc = "pass through generic scsi device (/dev/sg*)",
473 .size = sizeof(SCSIDevice),
474 .reset = scsi_generic_reset,
475 .class_init = scsi_generic_class_initfn,
476 .props = (Property[]) {
477 DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
478 DEFINE_PROP_END_OF_LIST(),
479 },
480 };
481
482 static void scsi_generic_register_devices(void)
483 {
484 scsi_qdev_register(&scsi_generic_info);
485 }
486 device_init(scsi_generic_register_devices)
487
488 #endif /* __linux__ */