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