]> git.proxmox.com Git - mirror_qemu.git/blame - hw/scsi/scsi-generic.c
Replace qemu_real_host_page variables with inlined functions
[mirror_qemu.git] / hw / scsi / scsi-generic.c
CommitLineData
2cc977e2
TS
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 *
8e31bf38 10 * This code is licensed under the LGPL.
2cc977e2
TS
11 *
12 */
13
a4ab4792 14#include "qemu/osdep.h"
da34e65c 15#include "qapi/error.h"
856dfd8a 16#include "qemu/ctype.h"
1de7afc9 17#include "qemu/error-report.h"
0b8fa32f 18#include "qemu/module.h"
0d09e41a 19#include "hw/scsi/scsi.h"
ca77ee28 20#include "migration/qemu-file-types.h"
a27bd6c7 21#include "hw/qdev-properties.h"
ce35e229 22#include "hw/qdev-properties-system.h"
3d4a8bf0 23#include "hw/scsi/emulation.h"
4be74634 24#include "sysemu/block-backend.h"
56853498 25#include "trace.h"
2cc977e2 26
d52affa7 27#ifdef __linux__
2cc977e2 28
2cc977e2 29#include <scsi/sg.h>
08e2c9f1 30#include "scsi/constants.h"
2cc977e2 31
2cc977e2
TS
32#ifndef MAX_UINT
33#define MAX_UINT ((unsigned int)-1)
34#endif
35
4c41d2ef
GH
36typedef struct SCSIGenericReq {
37 SCSIRequest req;
2cc977e2
TS
38 uint8_t *buf;
39 int buflen;
40 int len;
41 sg_io_hdr_t io_header;
4c41d2ef 42} SCSIGenericReq;
2cc977e2 43
56b1fc48
PB
44static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
45{
46 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
47
48 qemu_put_sbe32s(f, &r->buflen);
49 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
50 assert(!r->req.sg);
51 qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
52 }
53}
54
55static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
56{
57 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
58
59 qemu_get_sbe32s(f, &r->buflen);
60 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
61 assert(!r->req.sg);
62 qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
63 }
64}
65
ad2d30f7 66static void scsi_free_request(SCSIRequest *req)
2cc977e2 67{
ad2d30f7
PB
68 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
69
7267c094 70 g_free(r->buf);
2cc977e2
TS
71}
72
2cc977e2 73/* Helper function for command completion. */
fa0d653b 74static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
2cc977e2 75{
682a9b21 76 int status;
1ead6b4e 77 SCSISense sense;
a108557b 78 sg_io_hdr_t *io_hdr = &r->io_header;
2cc977e2 79
fa0d653b
PB
80 assert(r->req.aiocb == NULL);
81
6c25fa6c 82 if (r->req.io_canceled) {
d5776465 83 scsi_req_cancel_complete(&r->req);
6c25fa6c
FZ
84 goto done;
85 }
a108557b
HR
86 if (ret < 0) {
87 status = scsi_sense_from_errno(-ret, &sense);
88 if (status == CHECK_CONDITION) {
1ead6b4e 89 scsi_req_build_sense(&r->req, sense);
682a9b21 90 }
a108557b 91 } else if (io_hdr->host_status != SCSI_HOST_OK) {
f3126d65
HR
92 scsi_req_complete_failed(&r->req, io_hdr->host_status);
93 goto done;
a108557b
HR
94 } else if (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT) {
95 status = BUSY;
96 } else {
97 status = io_hdr->status;
98 if (io_hdr->driver_status & SG_ERR_DRIVER_SENSE) {
99 r->req.sense_len = io_hdr->sb_len_wr;
100 }
2cc977e2 101 }
56853498 102 trace_scsi_generic_command_complete_noio(r, r->req.tag, status);
ed3a34a3 103
682a9b21 104 scsi_req_complete(&r->req, status);
6c25fa6c 105done:
3df9caf8 106 scsi_req_unref(&r->req);
2cc977e2
TS
107}
108
fa0d653b
PB
109static void scsi_command_complete(void *opaque, int ret)
110{
111 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
b9e413dd 112 SCSIDevice *s = r->req.dev;
fa0d653b
PB
113
114 assert(r->req.aiocb != NULL);
115 r->req.aiocb = NULL;
b9e413dd
PB
116
117 aio_context_acquire(blk_get_aio_context(s->conf.blk));
fa0d653b 118 scsi_command_complete_noio(r, ret);
b9e413dd 119 aio_context_release(blk_get_aio_context(s->conf.blk));
fa0d653b
PB
120}
121
4be74634 122static int execute_command(BlockBackend *blk,
4c41d2ef 123 SCSIGenericReq *r, int direction,
097310b5 124 BlockCompletionFunc *complete)
2cc977e2 125{
c9b6609b
HR
126 SCSIDevice *s = r->req.dev;
127
2cc977e2
TS
128 r->io_header.interface_id = 'S';
129 r->io_header.dxfer_direction = direction;
130 r->io_header.dxferp = r->buf;
131 r->io_header.dxfer_len = r->buflen;
29362ebe
GH
132 r->io_header.cmdp = r->req.cmd.buf;
133 r->io_header.cmd_len = r->req.cmd.len;
b45ef674
PB
134 r->io_header.mx_sb_len = sizeof(r->req.sense);
135 r->io_header.sbp = r->req.sense;
c9b6609b 136 r->io_header.timeout = s->io_timeout * 1000;
2cc977e2
TS
137 r->io_header.usr_ptr = r;
138 r->io_header.flags |= SG_FLAG_DIRECT_IO;
139
b2d50a33
HR
140 trace_scsi_generic_aio_sgio_command(r->req.tag, r->req.cmd.buf[0],
141 r->io_header.timeout);
4be74634 142 r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
d836f8d3
PH
143 if (r->req.aiocb == NULL) {
144 return -EIO;
145 }
2cc977e2
TS
146
147 return 0;
148}
149
06b80795 150static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
0a96ca24 151{
6c219fc8 152 uint8_t page, page_idx;
a71c775b 153
0a96ca24
DHB
154 /*
155 * EVPD set to zero returns the standard INQUIRY data.
156 *
157 * Check if scsi_version is unset (-1) to avoid re-defining it
158 * each time an INQUIRY with standard data is received.
159 * scsi_version is initialized with -1 in scsi_generic_reset
160 * and scsi_disk_reset, making sure that we'll set the
161 * scsi_version after a reset. If the version field of the
162 * INQUIRY response somehow changes after a guest reboot,
163 * we'll be able to keep track of it.
164 *
165 * On SCSI-2 and older, first 3 bits of byte 2 is the
166 * ANSI-approved version, while on later versions the
167 * whole byte 2 contains the version. Check if we're dealing
168 * with a newer version and, in that case, assign the
169 * whole byte.
170 */
171 if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) {
172 s->scsi_version = r->buf[2] & 0x07;
173 if (s->scsi_version > 2) {
174 s->scsi_version = r->buf[2];
175 }
176 }
0a96ca24 177
afff2db6
DF
178 if ((s->type == TYPE_DISK || s->type == TYPE_ZBC) &&
179 (r->req.cmd.buf[1] & 0x01)) {
a71c775b
DHB
180 page = r->req.cmd.buf[2];
181 if (page == 0xb0) {
24b36e98 182 uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk);
cc071629 183 uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk);
a71c775b
DHB
184
185 assert(max_transfer);
8e3b0cbb 186 max_transfer = MIN_NON_ZERO(max_transfer, max_iov * qemu_real_host_page_size())
01ef8185 187 / s->blocksize;
a71c775b
DHB
188 stl_be_p(&r->buf[8], max_transfer);
189 /* Also take care of the opt xfer len. */
190 stl_be_p(&r->buf[12],
191 MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
e909ff93 192 } else if (s->needs_vpd_bl_emulation && page == 0x00 && r->buflen >= 4) {
a71c775b
DHB
193 /*
194 * Now we're capable of supplying the VPD Block Limits
195 * response if the hardware can't. Add it in the INQUIRY
196 * Supported VPD pages response in case we are using the
197 * emulation for this device.
198 *
199 * This way, the guest kernel will be aware of the support
200 * and will use it to proper setup the SCSI device.
6c219fc8
PB
201 *
202 * VPD page numbers must be sorted, so insert 0xb0 at the
e909ff93
PB
203 * right place with an in-place insert. When the while loop
204 * begins the device response is at r[0] to r[page_idx - 1].
a71c775b 205 */
e909ff93
PB
206 page_idx = lduw_be_p(r->buf + 2) + 4;
207 page_idx = MIN(page_idx, r->buflen);
208 while (page_idx > 4 && r->buf[page_idx - 1] >= 0xb0) {
6c219fc8
PB
209 if (page_idx < r->buflen) {
210 r->buf[page_idx] = r->buf[page_idx - 1];
211 }
e909ff93
PB
212 page_idx--;
213 }
214 if (page_idx < r->buflen) {
215 r->buf[page_idx] = 0xb0;
6c219fc8 216 }
6c219fc8 217 stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1);
06b80795
ML
218
219 if (len < r->buflen) {
220 len++;
221 }
a71c775b 222 }
0a96ca24 223 }
06b80795 224 return len;
0a96ca24
DHB
225}
226
3d4a8bf0 227static int scsi_generic_emulate_block_limits(SCSIGenericReq *r, SCSIDevice *s)
a71c775b 228{
3d4a8bf0
PB
229 int len;
230 uint8_t buf[64];
231
232 SCSIBlockLimits bl = {
233 .max_io_sectors = blk_get_max_transfer(s->conf.blk) / s->blocksize
234 };
235
236 memset(r->buf, 0, r->buflen);
237 stb_p(buf, s->type);
238 stb_p(buf + 1, 0xb0);
239 len = scsi_emulate_block_limits(buf + 4, &bl);
240 assert(len <= sizeof(buf) - 4);
241 stw_be_p(buf + 2, len);
242
243 memcpy(r->buf, buf, MIN(r->buflen, len + 4));
244
a71c775b
DHB
245 r->io_header.sb_len_wr = 0;
246
247 /*
248 * We have valid contents in the reply buffer but the
249 * io_header can report a sense error coming from
250 * the hardware in scsi_command_complete_noio. Clean
251 * up the io_header to avoid reporting it.
252 */
253 r->io_header.driver_status = 0;
254 r->io_header.status = 0;
255
256 return r->buflen;
257}
258
2cc977e2
TS
259static void scsi_read_complete(void * opaque, int ret)
260{
4c41d2ef 261 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
9b6eef8a 262 SCSIDevice *s = r->req.dev;
2cc977e2
TS
263 int len;
264
fa0d653b 265 assert(r->req.aiocb != NULL);
d33e0ce2 266 r->req.aiocb = NULL;
fa0d653b 267
b9e413dd
PB
268 aio_context_acquire(blk_get_aio_context(s->conf.blk));
269
6c25fa6c 270 if (ret || r->req.io_canceled) {
fa0d653b 271 scsi_command_complete_noio(r, ret);
b9e413dd 272 goto done;
2cc977e2 273 }
fa0d653b 274
2cc977e2 275 len = r->io_header.dxfer_len - r->io_header.resid;
56853498 276 trace_scsi_generic_read_complete(r->req.tag, len);
2cc977e2
TS
277
278 r->len = -1;
a71c775b 279
1849f297 280 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
763c5687
PB
281 SCSISense sense =
282 scsi_parse_sense_buf(r->req.sense, r->io_header.sb_len_wr);
1849f297
SK
283
284 /*
285 * Check if this is a VPD Block Limits request that
286 * resulted in sense error but would need emulation.
287 * In this case, emulate a valid VPD response.
288 */
289 if (sense.key == ILLEGAL_REQUEST &&
290 s->needs_vpd_bl_emulation &&
291 r->req.cmd.buf[0] == INQUIRY &&
292 (r->req.cmd.buf[1] & 0x01) &&
293 r->req.cmd.buf[2] == 0xb0) {
3d4a8bf0 294 len = scsi_generic_emulate_block_limits(r, s);
a71c775b 295 /*
1849f297
SK
296 * It's okay to jup to req_complete: no need to
297 * let scsi_handle_inquiry_reply handle an
a71c775b
DHB
298 * INQUIRY VPD BL request we created manually.
299 */
1849f297
SK
300 }
301 if (sense.key) {
a71c775b
DHB
302 goto req_complete;
303 }
304 }
305
9738c657
PB
306 if (r->io_header.host_status != SCSI_HOST_OK ||
307 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) ||
308 r->io_header.status != GOOD ||
309 len == 0) {
fa0d653b 310 scsi_command_complete_noio(r, 0);
b9e413dd 311 goto done;
fa0d653b 312 }
9b6eef8a 313
fa0d653b
PB
314 /* Snoop READ CAPACITY output to set the blocksize. */
315 if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
316 (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
317 s->blocksize = ldl_be_p(&r->buf[4]);
318 s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
319 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
320 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
321 s->blocksize = ldl_be_p(&r->buf[8]);
322 s->max_lba = ldq_be_p(&r->buf[0]);
40f16dd1 323 }
fa0d653b
PB
324 blk_set_guest_block_size(s->conf.blk, s->blocksize);
325
afff2db6
DF
326 /*
327 * Patch MODE SENSE device specific parameters if the BDS is opened
0eb2baeb
PB
328 * readonly.
329 */
afff2db6 330 if ((s->type == TYPE_DISK || s->type == TYPE_TAPE || s->type == TYPE_ZBC) &&
86b1cf32 331 !blk_is_writable(s->conf.blk) &&
0eb2baeb
PB
332 (r->req.cmd.buf[0] == MODE_SENSE ||
333 r->req.cmd.buf[0] == MODE_SENSE_10) &&
334 (r->req.cmd.buf[1] & 0x8) == 0) {
335 if (r->req.cmd.buf[0] == MODE_SENSE) {
336 r->buf[2] |= 0x80;
337 } else {
338 r->buf[3] |= 0x80;
339 }
340 }
29e560f0 341 if (r->req.cmd.buf[0] == INQUIRY) {
06b80795 342 len = scsi_handle_inquiry_reply(r, s, len);
063143d5 343 }
a71c775b
DHB
344
345req_complete:
fa0d653b
PB
346 scsi_req_data(&r->req, len);
347 scsi_req_unref(&r->req);
b9e413dd
PB
348
349done:
350 aio_context_release(blk_get_aio_context(s->conf.blk));
2cc977e2
TS
351}
352
353/* Read more data from scsi device into buffer. */
5c6c0e51 354static void scsi_read_data(SCSIRequest *req)
2cc977e2 355{
5c6c0e51 356 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
8869e103 357 SCSIDevice *s = r->req.dev;
2cc977e2
TS
358 int ret;
359
56853498 360 trace_scsi_generic_read_data(req->tag);
c9501c95
PB
361
362 /* The request is used as the AIO opaque value, so add a ref. */
363 scsi_req_ref(&r->req);
2cc977e2 364 if (r->len == -1) {
fa0d653b 365 scsi_command_complete_noio(r, 0);
2cc977e2
TS
366 return;
367 }
368
4be74634
MA
369 ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
370 scsi_read_complete);
a1f0cce2 371 if (ret < 0) {
fa0d653b 372 scsi_command_complete_noio(r, ret);
2cc977e2
TS
373 }
374}
375
376static void scsi_write_complete(void * opaque, int ret)
377{
4c41d2ef 378 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
8869e103 379 SCSIDevice *s = r->req.dev;
2cc977e2 380
56853498 381 trace_scsi_generic_write_complete(ret);
fa0d653b
PB
382
383 assert(r->req.aiocb != NULL);
d33e0ce2 384 r->req.aiocb = NULL;
fa0d653b 385
b9e413dd
PB
386 aio_context_acquire(blk_get_aio_context(s->conf.blk));
387
6c25fa6c 388 if (ret || r->req.io_canceled) {
fa0d653b 389 scsi_command_complete_noio(r, ret);
b9e413dd 390 goto done;
2cc977e2
TS
391 }
392
29362ebe 393 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
8869e103
PB
394 s->type == TYPE_TAPE) {
395 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
56853498 396 trace_scsi_generic_write_complete_blocksize(s->blocksize);
89c0f643
AJ
397 }
398
fa0d653b 399 scsi_command_complete_noio(r, ret);
b9e413dd
PB
400
401done:
402 aio_context_release(blk_get_aio_context(s->conf.blk));
2cc977e2
TS
403}
404
405/* Write data to a scsi device. Returns nonzero on failure.
406 The transfer may complete asynchronously. */
42741212 407static void scsi_write_data(SCSIRequest *req)
2cc977e2 408{
5c6c0e51 409 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
8869e103 410 SCSIDevice *s = r->req.dev;
2cc977e2
TS
411 int ret;
412
56853498 413 trace_scsi_generic_write_data(req->tag);
2cc977e2
TS
414 if (r->len == 0) {
415 r->len = r->buflen;
ab9adc88 416 scsi_req_data(&r->req, r->len);
42741212 417 return;
2cc977e2
TS
418 }
419
c9501c95
PB
420 /* The request is used as the AIO opaque value, so add a ref. */
421 scsi_req_ref(&r->req);
4be74634 422 ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
a1f0cce2 423 if (ret < 0) {
fa0d653b 424 scsi_command_complete_noio(r, ret);
2cc977e2 425 }
2cc977e2
TS
426}
427
428/* Return a pointer to the data buffer. */
5c6c0e51 429static uint8_t *scsi_get_buf(SCSIRequest *req)
2cc977e2 430{
5c6c0e51
HR
431 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
432
2cc977e2
TS
433 return r->buf;
434}
435
56853498
LV
436static void scsi_generic_command_dump(uint8_t *cmd, int len)
437{
438 int i;
439 char *line_buffer, *p;
440
441 line_buffer = g_malloc(len * 5 + 1);
442
443 for (i = 0, p = line_buffer; i < len; i++) {
444 p += sprintf(p, " 0x%02x", cmd[i]);
445 }
446 trace_scsi_generic_send_command(line_buffer);
447
448 g_free(line_buffer);
449}
450
2cc977e2
TS
451/* Execute a scsi command. Returns the length of the data expected by the
452 command. This will be Positive for data transfers from the device
453 (eg. disk reads), negative for transfers to the device (eg. disk writes),
454 and zero if the command does not transfer any data. */
455
5c6c0e51 456static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
2cc977e2 457{
5c6c0e51 458 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
8869e103 459 SCSIDevice *s = r->req.dev;
2cc977e2
TS
460 int ret;
461
56853498
LV
462 if (trace_event_get_state_backends(TRACE_SCSI_GENERIC_SEND_COMMAND)) {
463 scsi_generic_command_dump(cmd, r->req.cmd.len);
aa2b1e89 464 }
2cc977e2 465
2ec749cb 466 if (r->req.cmd.xfer == 0) {
1c3381af 467 g_free(r->buf);
2cc977e2
TS
468 r->buflen = 0;
469 r->buf = NULL;
c9501c95
PB
470 /* The request is used as the AIO opaque value, so add a ref. */
471 scsi_req_ref(&r->req);
4be74634
MA
472 ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
473 scsi_command_complete);
a1f0cce2 474 if (ret < 0) {
fa0d653b 475 scsi_command_complete_noio(r, ret);
a1f0cce2 476 return 0;
2cc977e2
TS
477 }
478 return 0;
479 }
480
2ec749cb 481 if (r->buflen != r->req.cmd.xfer) {
1c3381af 482 g_free(r->buf);
7267c094 483 r->buf = g_malloc(r->req.cmd.xfer);
2ec749cb 484 r->buflen = r->req.cmd.xfer;
2cc977e2
TS
485 }
486
487 memset(r->buf, 0, r->buflen);
2ec749cb 488 r->len = r->req.cmd.xfer;
97a06435 489 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
2cc977e2 490 r->len = 0;
5c6c0e51 491 return -r->req.cmd.xfer;
ad2d30f7 492 } else {
5c6c0e51 493 return r->req.cmd.xfer;
2cc977e2 494 }
2cc977e2
TS
495}
496
9fd7e859
PB
497static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
498{
499 int i;
500
501 if ((p[1] & 0xF) == 3) {
502 /* NAA designator type */
503 if (p[3] != 8) {
504 return -EINVAL;
505 }
506 *p_wwn = ldq_be_p(p + 4);
507 return 0;
508 }
509
510 if ((p[1] & 0xF) == 8) {
511 /* SCSI name string designator type */
512 if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) {
513 return -EINVAL;
514 }
515 if (p[3] > 20 && p[24] != ',') {
516 return -EINVAL;
517 }
518 *p_wwn = 0;
519 for (i = 8; i < 24; i++) {
95a5befc 520 char c = qemu_toupper(p[i]);
9fd7e859
PB
521 c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10);
522 *p_wwn = (*p_wwn << 4) | c;
523 }
524 return 0;
525 }
526
527 return -EINVAL;
528}
529
a0c7e35b 530int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size,
c9b6609b 531 uint8_t *buf, uint8_t buf_size, uint32_t timeout)
9fd7e859 532{
9fd7e859 533 sg_io_hdr_t io_header;
a0c7e35b 534 uint8_t sensebuf[8];
9fd7e859 535 int ret;
9fd7e859
PB
536
537 memset(&io_header, 0, sizeof(io_header));
538 io_header.interface_id = 'S';
539 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
a0c7e35b 540 io_header.dxfer_len = buf_size;
9fd7e859
PB
541 io_header.dxferp = buf;
542 io_header.cmdp = cmd;
a0c7e35b 543 io_header.cmd_len = cmd_size;
9fd7e859
PB
544 io_header.mx_sb_len = sizeof(sensebuf);
545 io_header.sbp = sensebuf;
c9b6609b 546 io_header.timeout = timeout * 1000;
9fd7e859 547
b2d50a33 548 trace_scsi_generic_ioctl_sgio_command(cmd[0], io_header.timeout);
a0c7e35b 549 ret = blk_ioctl(blk, SG_IO, &io_header);
b2d50a33
HR
550 if (ret < 0 || io_header.status ||
551 io_header.driver_status || io_header.host_status) {
552 trace_scsi_generic_ioctl_sgio_done(cmd[0], ret, io_header.status,
553 io_header.host_status);
a0c7e35b
DHB
554 return -1;
555 }
556 return 0;
557}
558
a71c775b
DHB
559/*
560 * Executes an INQUIRY request with EVPD set to retrieve the
561 * available VPD pages of the device. If the device does
562 * not support the Block Limits page (page 0xb0), set
563 * the needs_vpd_bl_emulation flag for future use.
564 */
565static void scsi_generic_set_vpd_bl_emulation(SCSIDevice *s)
566{
567 uint8_t cmd[6];
568 uint8_t buf[250];
569 uint8_t page_len;
570 int ret, i;
571
572 memset(cmd, 0, sizeof(cmd));
573 memset(buf, 0, sizeof(buf));
574 cmd[0] = INQUIRY;
575 cmd[1] = 1;
576 cmd[2] = 0x00;
577 cmd[4] = sizeof(buf);
578
579 ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd),
c9b6609b 580 buf, sizeof(buf), s->io_timeout);
a71c775b
DHB
581 if (ret < 0) {
582 /*
583 * Do not assume anything if we can't retrieve the
584 * INQUIRY response to assert the VPD Block Limits
585 * support.
586 */
587 s->needs_vpd_bl_emulation = false;
588 return;
589 }
590
591 page_len = buf[3];
57dbb58d 592 for (i = 4; i < MIN(sizeof(buf), page_len + 4); i++) {
a71c775b
DHB
593 if (buf[i] == 0xb0) {
594 s->needs_vpd_bl_emulation = false;
595 return;
596 }
597 }
598 s->needs_vpd_bl_emulation = true;
599}
600
601static void scsi_generic_read_device_identification(SCSIDevice *s)
a0c7e35b
DHB
602{
603 uint8_t cmd[6];
604 uint8_t buf[250];
605 int ret;
606 int i, len;
607
608 memset(cmd, 0, sizeof(cmd));
609 memset(buf, 0, sizeof(buf));
610 cmd[0] = INQUIRY;
611 cmd[1] = 1;
612 cmd[2] = 0x83;
613 cmd[4] = sizeof(buf);
614
615 ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd),
c9b6609b 616 buf, sizeof(buf), s->io_timeout);
a0c7e35b 617 if (ret < 0) {
9fd7e859
PB
618 return;
619 }
620
621 len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4);
622 for (i = 0; i + 3 <= len; ) {
623 const uint8_t *p = &buf[i + 4];
624 uint64_t wwn;
625
626 if (i + (p[3] + 4) > len) {
627 break;
628 }
629
630 if ((p[1] & 0x10) == 0) {
631 /* Associated with the logical unit */
632 if (read_naa_id(p, &wwn) == 0) {
633 s->wwn = wwn;
634 }
635 } else if ((p[1] & 0x10) == 0x10) {
636 /* Associated with the target port */
637 if (read_naa_id(p, &wwn) == 0) {
638 s->port_wwn = wwn;
639 }
640 }
641
642 i += p[3] + 4;
643 }
644}
645
a71c775b
DHB
646void scsi_generic_read_device_inquiry(SCSIDevice *s)
647{
648 scsi_generic_read_device_identification(s);
afff2db6 649 if (s->type == TYPE_DISK || s->type == TYPE_ZBC) {
a71c775b
DHB
650 scsi_generic_set_vpd_bl_emulation(s);
651 } else {
652 s->needs_vpd_bl_emulation = false;
653 }
654}
655
4be74634 656static int get_stream_blocksize(BlockBackend *blk)
89c0f643
AJ
657{
658 uint8_t cmd[6];
659 uint8_t buf[12];
89c0f643
AJ
660 int ret;
661
662 memset(cmd, 0, sizeof(cmd));
663 memset(buf, 0, sizeof(buf));
664 cmd[0] = MODE_SENSE;
665 cmd[4] = sizeof(buf);
666
c9b6609b 667 ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf), 6);
a0c7e35b 668 if (ret < 0) {
89c0f643 669 return -1;
fe0ed712 670 }
a0c7e35b 671
89c0f643
AJ
672 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
673}
674
f8b6d672
BK
675static void scsi_generic_reset(DeviceState *dev)
676{
b9eea3e6 677 SCSIDevice *s = SCSI_DEVICE(dev);
f8b6d672 678
2343be0d 679 s->scsi_version = s->default_scsi_version;
8869e103 680 scsi_device_purge_requests(s, SENSE_CODE(RESET));
f8b6d672
BK
681}
682
a818a4b6 683static void scsi_generic_realize(SCSIDevice *s, Error **errp)
2cc977e2 684{
6ee143a0 685 int rc;
2cc977e2 686 int sg_version;
2cc977e2
TS
687 struct sg_scsi_id scsiid;
688
4be74634 689 if (!s->conf.blk) {
a818a4b6
FZ
690 error_setg(errp, "drive property not set");
691 return;
d52affa7 692 }
2cc977e2 693
166854f7
ZC
694 if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC &&
695 blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) {
a818a4b6
FZ
696 error_setg(errp, "Device doesn't support drive option werror");
697 return;
620f862e 698 }
4be74634 699 if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
a818a4b6
FZ
700 error_setg(errp, "Device doesn't support drive option rerror");
701 return;
620f862e
MA
702 }
703
2cc977e2 704 /* check we are using a driver managing SG_IO (version 3 and after */
4be74634 705 rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
6ee143a0 706 if (rc < 0) {
09c2c6ff
PB
707 error_setg_errno(errp, -rc, "cannot get SG_IO version number");
708 if (rc != -EPERM) {
709 error_append_hint(errp, "Is this a SCSI device?\n");
710 }
a818a4b6 711 return;
98392453
RS
712 }
713 if (sg_version < 30000) {
a818a4b6
FZ
714 error_setg(errp, "scsi generic interface too old");
715 return;
d52affa7 716 }
2cc977e2
TS
717
718 /* get LUN of the /dev/sg? */
4be74634 719 if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
a818a4b6
FZ
720 error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
721 return;
d52affa7 722 }
c6caae55 723 if (!blkconf_apply_backend_options(&s->conf,
86b1cf32 724 !blk_supports_write_perm(s->conf.blk),
c6caae55 725 true, errp)) {
d9bcd6f7
FZ
726 return;
727 }
2cc977e2
TS
728
729 /* define device state */
8869e103 730 s->type = scsiid.scsi_type;
56853498 731 trace_scsi_generic_realize_type(s->type);
28b77657 732
9b6eef8a
PB
733 switch (s->type) {
734 case TYPE_TAPE:
4be74634 735 s->blocksize = get_stream_blocksize(s->conf.blk);
8869e103
PB
736 if (s->blocksize == -1) {
737 s->blocksize = 0;
738 }
9b6eef8a
PB
739 break;
740
741 /* Make a guess for block devices, we'll fix it when the guest sends.
742 * READ CAPACITY. If they don't, they likely would assume these sizes
743 * anyway. (TODO: they could also send MODE SENSE).
744 */
745 case TYPE_ROM:
746 case TYPE_WORM:
747 s->blocksize = 2048;
748 break;
749 default:
750 s->blocksize = 512;
751 break;
89c0f643 752 }
8869e103 753
56853498 754 trace_scsi_generic_realize_blocksize(s->blocksize);
9fd7e859 755
29e560f0
DHB
756 /* Only used by scsi-block, but initialize it nevertheless to be clean. */
757 s->default_scsi_version = -1;
c9b6609b 758 s->io_timeout = DEFAULT_IO_TIMEOUT;
a71c775b 759 scsi_generic_read_device_inquiry(s);
d52affa7 760}
2cc977e2 761
765d1525 762const SCSIReqOps scsi_generic_req_ops = {
8dbd4574 763 .size = sizeof(SCSIGenericReq),
12010e7b
PB
764 .free_req = scsi_free_request,
765 .send_command = scsi_send_command,
766 .read_data = scsi_read_data,
767 .write_data = scsi_write_data,
12010e7b 768 .get_buf = scsi_get_buf,
56b1fc48
PB
769 .load_request = scsi_generic_load_request,
770 .save_request = scsi_generic_save_request,
8dbd4574
PB
771};
772
773static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
63db0f0e 774 uint8_t *buf, void *hba_private)
8dbd4574 775{
9be38598 776 return scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
8dbd4574
PB
777}
778
39bffca2 779static Property scsi_generic_properties[] = {
4be74634 780 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
d9bcd6f7 781 DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
c9b6609b
HR
782 DEFINE_PROP_UINT32("io_timeout", SCSIDevice, io_timeout,
783 DEFAULT_IO_TIMEOUT),
39bffca2
AL
784 DEFINE_PROP_END_OF_LIST(),
785};
786
3e7e180a
PB
787static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
788 uint8_t *buf, void *hba_private)
789{
790 return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
791}
792
b9eea3e6
AL
793static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
794{
39bffca2 795 DeviceClass *dc = DEVICE_CLASS(klass);
b9eea3e6
AL
796 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
797
a818a4b6 798 sc->realize = scsi_generic_realize;
b9eea3e6 799 sc->alloc_req = scsi_new_request;
3e7e180a 800 sc->parse_cdb = scsi_generic_parse_cdb;
39bffca2
AL
801 dc->fw_name = "disk";
802 dc->desc = "pass through generic scsi device (/dev/sg*)";
803 dc->reset = scsi_generic_reset;
4f67d30b 804 device_class_set_props(dc, scsi_generic_properties);
56b1fc48 805 dc->vmsd = &vmstate_scsi_device;
b9eea3e6
AL
806}
807
8c43a6f0 808static const TypeInfo scsi_generic_info = {
39bffca2
AL
809 .name = "scsi-generic",
810 .parent = TYPE_SCSI_DEVICE,
811 .instance_size = sizeof(SCSIDevice),
812 .class_init = scsi_generic_class_initfn,
d52affa7 813};
2cc977e2 814
83f7d43a 815static void scsi_generic_register_types(void)
d52affa7 816{
39bffca2 817 type_register_static(&scsi_generic_info);
2cc977e2 818}
83f7d43a
AF
819
820type_init(scsi_generic_register_types)
d52affa7 821
2cc977e2 822#endif /* __linux__ */