fix bad indentation in pcie_cap_slot_write_config()
[qemu/ar7.git] / hw / scsi / scsi-generic.c
bloba4626f72c1d81110b851e7120e237e5a78af705a
1 /*
2 * Generic SCSI Device support
4 * Copyright (c) 2007 Bull S.A.S.
5 * Based on code by Paul Brook
6 * Based on code by Fabrice Bellard
8 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
10 * This code is licensed under the LGPL.
14 #include "qemu-common.h"
15 #include "qemu/error-report.h"
16 #include "hw/scsi/scsi.h"
17 #include "sysemu/block-backend.h"
18 #include "sysemu/blockdev.h"
20 #ifdef __linux__
22 //#define DEBUG_SCSI
24 #ifdef DEBUG_SCSI
25 #define DPRINTF(fmt, ...) \
26 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
27 #else
28 #define DPRINTF(fmt, ...) do {} while(0)
29 #endif
31 #define BADF(fmt, ...) \
32 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
34 #include <stdio.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38 #include <scsi/sg.h>
39 #include "block/scsi.h"
41 #define SG_ERR_DRIVER_TIMEOUT 0x06
42 #define SG_ERR_DRIVER_SENSE 0x08
44 #define SG_ERR_DID_OK 0x00
45 #define SG_ERR_DID_NO_CONNECT 0x01
46 #define SG_ERR_DID_BUS_BUSY 0x02
47 #define SG_ERR_DID_TIME_OUT 0x03
49 #ifndef MAX_UINT
50 #define MAX_UINT ((unsigned int)-1)
51 #endif
53 typedef struct SCSIGenericReq {
54 SCSIRequest req;
55 uint8_t *buf;
56 int buflen;
57 int len;
58 sg_io_hdr_t io_header;
59 } SCSIGenericReq;
61 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
63 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
65 qemu_put_sbe32s(f, &r->buflen);
66 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
67 assert(!r->req.sg);
68 qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
72 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
74 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
76 qemu_get_sbe32s(f, &r->buflen);
77 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
78 assert(!r->req.sg);
79 qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
83 static void scsi_free_request(SCSIRequest *req)
85 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
87 g_free(r->buf);
90 /* Helper function for command completion. */
91 static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
93 int status;
95 assert(r->req.aiocb == NULL);
97 if (r->req.io_canceled) {
98 scsi_req_cancel_complete(&r->req);
99 goto done;
101 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
102 r->req.sense_len = r->io_header.sb_len_wr;
105 if (ret != 0) {
106 switch (ret) {
107 case -EDOM:
108 status = TASK_SET_FULL;
109 break;
110 case -ENOMEM:
111 status = CHECK_CONDITION;
112 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
113 break;
114 default:
115 status = CHECK_CONDITION;
116 scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
117 break;
119 } else {
120 if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
121 r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
122 r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
123 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
124 status = BUSY;
125 BADF("Driver Timeout\n");
126 } else if (r->io_header.host_status) {
127 status = CHECK_CONDITION;
128 scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
129 } else if (r->io_header.status) {
130 status = r->io_header.status;
131 } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
132 status = CHECK_CONDITION;
133 } else {
134 status = GOOD;
137 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
138 r, r->req.tag, status);
140 scsi_req_complete(&r->req, status);
141 done:
142 scsi_req_unref(&r->req);
145 static void scsi_command_complete(void *opaque, int ret)
147 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
149 assert(r->req.aiocb != NULL);
150 r->req.aiocb = NULL;
151 scsi_command_complete_noio(r, ret);
154 static int execute_command(BlockBackend *blk,
155 SCSIGenericReq *r, int direction,
156 BlockCompletionFunc *complete)
158 r->io_header.interface_id = 'S';
159 r->io_header.dxfer_direction = direction;
160 r->io_header.dxferp = r->buf;
161 r->io_header.dxfer_len = r->buflen;
162 r->io_header.cmdp = r->req.cmd.buf;
163 r->io_header.cmd_len = r->req.cmd.len;
164 r->io_header.mx_sb_len = sizeof(r->req.sense);
165 r->io_header.sbp = r->req.sense;
166 r->io_header.timeout = MAX_UINT;
167 r->io_header.usr_ptr = r;
168 r->io_header.flags |= SG_FLAG_DIRECT_IO;
170 r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
171 if (r->req.aiocb == NULL) {
172 return -EIO;
175 return 0;
178 static void scsi_read_complete(void * opaque, int ret)
180 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
181 SCSIDevice *s = r->req.dev;
182 int len;
184 assert(r->req.aiocb != NULL);
185 r->req.aiocb = NULL;
187 if (ret || r->req.io_canceled) {
188 scsi_command_complete_noio(r, ret);
189 return;
192 len = r->io_header.dxfer_len - r->io_header.resid;
193 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
195 r->len = -1;
196 if (len == 0) {
197 scsi_command_complete_noio(r, 0);
198 return;
201 /* Snoop READ CAPACITY output to set the blocksize. */
202 if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
203 (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
204 s->blocksize = ldl_be_p(&r->buf[4]);
205 s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
206 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
207 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
208 s->blocksize = ldl_be_p(&r->buf[8]);
209 s->max_lba = ldq_be_p(&r->buf[0]);
211 blk_set_guest_block_size(s->conf.blk, s->blocksize);
213 /* Patch MODE SENSE device specific parameters if the BDS is opened
214 * readonly.
216 if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
217 blk_is_read_only(s->conf.blk) &&
218 (r->req.cmd.buf[0] == MODE_SENSE ||
219 r->req.cmd.buf[0] == MODE_SENSE_10) &&
220 (r->req.cmd.buf[1] & 0x8) == 0) {
221 if (r->req.cmd.buf[0] == MODE_SENSE) {
222 r->buf[2] |= 0x80;
223 } else {
224 r->buf[3] |= 0x80;
227 scsi_req_data(&r->req, len);
228 scsi_req_unref(&r->req);
231 /* Read more data from scsi device into buffer. */
232 static void scsi_read_data(SCSIRequest *req)
234 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
235 SCSIDevice *s = r->req.dev;
236 int ret;
238 DPRINTF("scsi_read_data 0x%x\n", req->tag);
240 /* The request is used as the AIO opaque value, so add a ref. */
241 scsi_req_ref(&r->req);
242 if (r->len == -1) {
243 scsi_command_complete_noio(r, 0);
244 return;
247 ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
248 scsi_read_complete);
249 if (ret < 0) {
250 scsi_command_complete_noio(r, ret);
254 static void scsi_write_complete(void * opaque, int ret)
256 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
257 SCSIDevice *s = r->req.dev;
259 DPRINTF("scsi_write_complete() ret = %d\n", ret);
261 assert(r->req.aiocb != NULL);
262 r->req.aiocb = NULL;
264 if (ret || r->req.io_canceled) {
265 scsi_command_complete_noio(r, ret);
266 return;
269 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
270 s->type == TYPE_TAPE) {
271 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
272 DPRINTF("block size %d\n", s->blocksize);
275 scsi_command_complete_noio(r, ret);
278 /* Write data to a scsi device. Returns nonzero on failure.
279 The transfer may complete asynchronously. */
280 static void scsi_write_data(SCSIRequest *req)
282 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
283 SCSIDevice *s = r->req.dev;
284 int ret;
286 DPRINTF("scsi_write_data 0x%x\n", req->tag);
287 if (r->len == 0) {
288 r->len = r->buflen;
289 scsi_req_data(&r->req, r->len);
290 return;
293 /* The request is used as the AIO opaque value, so add a ref. */
294 scsi_req_ref(&r->req);
295 ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
296 if (ret < 0) {
297 scsi_command_complete_noio(r, ret);
301 /* Return a pointer to the data buffer. */
302 static uint8_t *scsi_get_buf(SCSIRequest *req)
304 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
306 return r->buf;
309 /* Execute a scsi command. Returns the length of the data expected by the
310 command. This will be Positive for data transfers from the device
311 (eg. disk reads), negative for transfers to the device (eg. disk writes),
312 and zero if the command does not transfer any data. */
314 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
316 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
317 SCSIDevice *s = r->req.dev;
318 int ret;
320 #ifdef DEBUG_SCSI
322 int i;
323 for (i = 1; i < r->req.cmd.len; i++) {
324 printf(" 0x%02x", cmd[i]);
326 printf("\n");
328 #endif
330 if (r->req.cmd.xfer == 0) {
331 g_free(r->buf);
332 r->buflen = 0;
333 r->buf = NULL;
334 /* The request is used as the AIO opaque value, so add a ref. */
335 scsi_req_ref(&r->req);
336 ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
337 scsi_command_complete);
338 if (ret < 0) {
339 scsi_command_complete_noio(r, ret);
340 return 0;
342 return 0;
345 if (r->buflen != r->req.cmd.xfer) {
346 g_free(r->buf);
347 r->buf = g_malloc(r->req.cmd.xfer);
348 r->buflen = r->req.cmd.xfer;
351 memset(r->buf, 0, r->buflen);
352 r->len = r->req.cmd.xfer;
353 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
354 r->len = 0;
355 return -r->req.cmd.xfer;
356 } else {
357 return r->req.cmd.xfer;
361 static int get_stream_blocksize(BlockBackend *blk)
363 uint8_t cmd[6];
364 uint8_t buf[12];
365 uint8_t sensebuf[8];
366 sg_io_hdr_t io_header;
367 int ret;
369 memset(cmd, 0, sizeof(cmd));
370 memset(buf, 0, sizeof(buf));
371 cmd[0] = MODE_SENSE;
372 cmd[4] = sizeof(buf);
374 memset(&io_header, 0, sizeof(io_header));
375 io_header.interface_id = 'S';
376 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
377 io_header.dxfer_len = sizeof(buf);
378 io_header.dxferp = buf;
379 io_header.cmdp = cmd;
380 io_header.cmd_len = sizeof(cmd);
381 io_header.mx_sb_len = sizeof(sensebuf);
382 io_header.sbp = sensebuf;
383 io_header.timeout = 6000; /* XXX */
385 ret = blk_ioctl(blk, SG_IO, &io_header);
386 if (ret < 0 || io_header.driver_status || io_header.host_status) {
387 return -1;
389 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
392 static void scsi_generic_reset(DeviceState *dev)
394 SCSIDevice *s = SCSI_DEVICE(dev);
396 scsi_device_purge_requests(s, SENSE_CODE(RESET));
399 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
401 int rc;
402 int sg_version;
403 struct sg_scsi_id scsiid;
405 if (!s->conf.blk) {
406 error_setg(errp, "drive property not set");
407 return;
410 if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
411 error_setg(errp, "Device doesn't support drive option werror");
412 return;
414 if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
415 error_setg(errp, "Device doesn't support drive option rerror");
416 return;
419 /* check we are using a driver managing SG_IO (version 3 and after */
420 rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
421 if (rc < 0) {
422 error_setg(errp, "cannot get SG_IO version number: %s. "
423 "Is this a SCSI device?",
424 strerror(-rc));
425 return;
427 if (sg_version < 30000) {
428 error_setg(errp, "scsi generic interface too old");
429 return;
432 /* get LUN of the /dev/sg? */
433 if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
434 error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
435 return;
438 /* define device state */
439 s->type = scsiid.scsi_type;
440 DPRINTF("device type %d\n", s->type);
442 switch (s->type) {
443 case TYPE_TAPE:
444 s->blocksize = get_stream_blocksize(s->conf.blk);
445 if (s->blocksize == -1) {
446 s->blocksize = 0;
448 break;
450 /* Make a guess for block devices, we'll fix it when the guest sends.
451 * READ CAPACITY. If they don't, they likely would assume these sizes
452 * anyway. (TODO: they could also send MODE SENSE).
454 case TYPE_ROM:
455 case TYPE_WORM:
456 s->blocksize = 2048;
457 break;
458 default:
459 s->blocksize = 512;
460 break;
463 DPRINTF("block size %d\n", s->blocksize);
466 const SCSIReqOps scsi_generic_req_ops = {
467 .size = sizeof(SCSIGenericReq),
468 .free_req = scsi_free_request,
469 .send_command = scsi_send_command,
470 .read_data = scsi_read_data,
471 .write_data = scsi_write_data,
472 .get_buf = scsi_get_buf,
473 .load_request = scsi_generic_load_request,
474 .save_request = scsi_generic_save_request,
477 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
478 uint8_t *buf, void *hba_private)
480 SCSIRequest *req;
482 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
483 return req;
486 static Property scsi_generic_properties[] = {
487 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
488 DEFINE_PROP_END_OF_LIST(),
491 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
492 uint8_t *buf, void *hba_private)
494 return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
497 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
499 DeviceClass *dc = DEVICE_CLASS(klass);
500 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
502 sc->realize = scsi_generic_realize;
503 sc->alloc_req = scsi_new_request;
504 sc->parse_cdb = scsi_generic_parse_cdb;
505 dc->fw_name = "disk";
506 dc->desc = "pass through generic scsi device (/dev/sg*)";
507 dc->reset = scsi_generic_reset;
508 dc->props = scsi_generic_properties;
509 dc->vmsd = &vmstate_scsi_device;
512 static const TypeInfo scsi_generic_info = {
513 .name = "scsi-generic",
514 .parent = TYPE_SCSI_DEVICE,
515 .instance_size = sizeof(SCSIDevice),
516 .class_init = scsi_generic_class_initfn,
519 static void scsi_generic_register_types(void)
521 type_register_static(&scsi_generic_info);
524 type_init(scsi_generic_register_types)
526 #endif /* __linux__ */