Gerd Hoffmann | 1e37607 | 2009-11-26 15:33:47 +0100 | [diff] [blame] | 1 | #ifndef QEMU_HW_SCSI_H |
| 2 | #define QEMU_HW_SCSI_H |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 3 | |
Markus Armbruster | db72581 | 2019-08-12 07:23:50 +0200 | [diff] [blame] | 4 | #include "block/aio.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 5 | #include "hw/block/block.h" |
Markus Armbruster | a27bd6c | 2019-08-12 07:23:51 +0200 | [diff] [blame] | 6 | #include "hw/qdev-core.h" |
Paolo Bonzini | e5b5728 | 2017-08-22 07:08:27 +0200 | [diff] [blame] | 7 | #include "scsi/utils.h" |
Fam Zheng | 8e0a932 | 2014-09-28 09:48:00 +0800 | [diff] [blame] | 8 | #include "qemu/notify.h" |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 9 | #include "qom/object.h" |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 10 | |
Markus Armbruster | 27d6bf4 | 2011-01-28 11:21:40 +0100 | [diff] [blame] | 11 | #define MAX_SCSI_DEVS 255 |
| 12 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 13 | typedef struct SCSIBus SCSIBus; |
Paolo Bonzini | afd4030 | 2011-08-13 15:44:45 +0200 | [diff] [blame] | 14 | typedef struct SCSIBusInfo SCSIBusInfo; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 15 | typedef struct SCSIDevice SCSIDevice; |
Hannes Reinecke | 5c6c0e5 | 2011-04-18 12:35:39 +0200 | [diff] [blame] | 16 | typedef struct SCSIRequest SCSIRequest; |
Paolo Bonzini | 8dbd457 | 2011-08-03 10:49:08 +0200 | [diff] [blame] | 17 | typedef struct SCSIReqOps SCSIReqOps; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 18 | |
Fam Zheng | 2e323f0 | 2014-03-06 16:26:02 +0800 | [diff] [blame] | 19 | #define SCSI_SENSE_BUF_SIZE_OLD 96 |
Fam Zheng | c5f5287 | 2014-01-24 15:02:24 +0800 | [diff] [blame] | 20 | #define SCSI_SENSE_BUF_SIZE 252 |
Hannes Reinecke | c9b6609 | 2020-11-16 19:31:13 +0100 | [diff] [blame] | 21 | #define DEFAULT_IO_TIMEOUT 30 |
Paolo Bonzini | b45ef67 | 2011-08-03 10:49:07 +0200 | [diff] [blame] | 22 | |
Hannes Reinecke | 5c6c0e5 | 2011-04-18 12:35:39 +0200 | [diff] [blame] | 23 | struct SCSIRequest { |
Gerd Hoffmann | 4c41d2e | 2009-11-26 15:33:48 +0100 | [diff] [blame] | 24 | SCSIBus *bus; |
| 25 | SCSIDevice *dev; |
Paolo Bonzini | adcf275 | 2011-10-12 12:57:59 +0200 | [diff] [blame] | 26 | const SCSIReqOps *ops; |
Paolo Bonzini | ad2d30f | 2011-04-18 16:01:56 +0200 | [diff] [blame] | 27 | uint32_t refcount; |
Gerd Hoffmann | 4c41d2e | 2009-11-26 15:33:48 +0100 | [diff] [blame] | 28 | uint32_t tag; |
Gerd Hoffmann | 89b08ae | 2009-11-26 15:33:50 +0100 | [diff] [blame] | 29 | uint32_t lun; |
Hannes Reinecke | f3126d6 | 2021-02-24 19:14:50 +0100 | [diff] [blame] | 30 | int16_t status; |
| 31 | int16_t host_status; |
Fam Zheng | 61e68b3 | 2014-09-16 15:20:17 +0800 | [diff] [blame] | 32 | void *hba_private; |
Paolo Bonzini | 01e9545 | 2011-07-06 11:55:37 +0200 | [diff] [blame] | 33 | size_t resid; |
Paolo Bonzini | 2599aec | 2011-08-03 10:49:11 +0200 | [diff] [blame] | 34 | SCSICommand cmd; |
Fam Zheng | 8e0a932 | 2014-09-28 09:48:00 +0800 | [diff] [blame] | 35 | NotifierList cancel_notifiers; |
Fam Zheng | 61e68b3 | 2014-09-16 15:20:17 +0800 | [diff] [blame] | 36 | |
| 37 | /* Note: |
| 38 | * - fields before sense are initialized by scsi_req_alloc; |
| 39 | * - sense[] is uninitialized; |
| 40 | * - fields after sense are memset to 0 by scsi_req_alloc. |
| 41 | * */ |
| 42 | |
| 43 | uint8_t sense[SCSI_SENSE_BUF_SIZE]; |
| 44 | uint32_t sense_len; |
| 45 | bool enqueued; |
| 46 | bool io_canceled; |
| 47 | bool retry; |
| 48 | bool dma_started; |
Markus Armbruster | 7c84b1b | 2014-10-07 13:59:14 +0200 | [diff] [blame] | 49 | BlockAIOCB *aiocb; |
Paolo Bonzini | 3d5aba9 | 2011-07-06 11:26:47 +0200 | [diff] [blame] | 50 | QEMUSGList *sg; |
Gerd Hoffmann | 9af99d9 | 2009-11-26 15:33:49 +0100 | [diff] [blame] | 51 | QTAILQ_ENTRY(SCSIRequest) next; |
Hannes Reinecke | 5c6c0e5 | 2011-04-18 12:35:39 +0200 | [diff] [blame] | 52 | }; |
Gerd Hoffmann | 4c41d2e | 2009-11-26 15:33:48 +0100 | [diff] [blame] | 53 | |
Anthony Liguori | b9eea3e | 2011-12-15 14:50:08 -0600 | [diff] [blame] | 54 | #define TYPE_SCSI_DEVICE "scsi-device" |
Eduardo Habkost | a489d19 | 2020-09-16 14:25:18 -0400 | [diff] [blame] | 55 | OBJECT_DECLARE_TYPE(SCSIDevice, SCSIDeviceClass, SCSI_DEVICE) |
Anthony Liguori | b9eea3e | 2011-12-15 14:50:08 -0600 | [diff] [blame] | 56 | |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 57 | struct SCSIDeviceClass { |
Anthony Liguori | b9eea3e | 2011-12-15 14:50:08 -0600 | [diff] [blame] | 58 | DeviceClass parent_class; |
Fam Zheng | a818a4b | 2014-08-12 10:12:55 +0800 | [diff] [blame] | 59 | void (*realize)(SCSIDevice *dev, Error **errp); |
Markus Armbruster | b69c3c2 | 2020-05-05 17:29:24 +0200 | [diff] [blame] | 60 | void (*unrealize)(SCSIDevice *dev); |
Paolo Bonzini | ff34c32 | 2014-07-16 10:39:05 +0200 | [diff] [blame] | 61 | int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf, |
| 62 | void *hba_private); |
Anthony Liguori | b9eea3e | 2011-12-15 14:50:08 -0600 | [diff] [blame] | 63 | SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun, |
| 64 | uint8_t *buf, void *hba_private); |
| 65 | void (*unit_attention_reported)(SCSIDevice *s); |
Eduardo Habkost | db1015e | 2020-09-03 16:43:22 -0400 | [diff] [blame] | 66 | }; |
Anthony Liguori | b9eea3e | 2011-12-15 14:50:08 -0600 | [diff] [blame] | 67 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 68 | struct SCSIDevice |
| 69 | { |
| 70 | DeviceState qdev; |
Paolo Bonzini | 71544d3 | 2011-10-25 12:53:36 +0200 | [diff] [blame] | 71 | VMChangeStateEntry *vmsentry; |
| 72 | QEMUBH *bh; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 73 | uint32_t id; |
Christoph Hellwig | 428c149 | 2010-02-10 23:37:09 +0100 | [diff] [blame] | 74 | BlockConf conf; |
Paolo Bonzini | 6dc06f0 | 2011-08-03 10:49:17 +0200 | [diff] [blame] | 75 | SCSISense unit_attention; |
Paolo Bonzini | 3653d8c | 2011-09-13 16:19:53 +0200 | [diff] [blame] | 76 | bool sense_is_ua; |
Paolo Bonzini | b45ef67 | 2011-08-03 10:49:07 +0200 | [diff] [blame] | 77 | uint8_t sense[SCSI_SENSE_BUF_SIZE]; |
| 78 | uint32_t sense_len; |
Gerd Hoffmann | 9af99d9 | 2009-11-26 15:33:49 +0100 | [diff] [blame] | 79 | QTAILQ_HEAD(, SCSIRequest) requests; |
Paolo Bonzini | 0d3545e | 2011-07-27 23:24:50 +0200 | [diff] [blame] | 80 | uint32_t channel; |
Paolo Bonzini | 87dcd1b | 2011-08-03 10:49:12 +0200 | [diff] [blame] | 81 | uint32_t lun; |
Gerd Hoffmann | b07995e | 2009-11-26 15:33:52 +0100 | [diff] [blame] | 82 | int blocksize; |
Gerd Hoffmann | 9137665 | 2009-11-26 15:33:54 +0100 | [diff] [blame] | 83 | int type; |
Paolo Bonzini | 7877903 | 2011-10-13 10:39:50 +0200 | [diff] [blame] | 84 | uint64_t max_lba; |
Paolo Bonzini | 2ecab40 | 2016-01-12 11:47:00 +0100 | [diff] [blame] | 85 | uint64_t wwn; |
| 86 | uint64_t port_wwn; |
Paolo Bonzini | 2343be0 | 2018-04-05 18:09:51 +0200 | [diff] [blame] | 87 | int scsi_version; |
| 88 | int default_scsi_version; |
Hannes Reinecke | c9b6609 | 2020-11-16 19:31:13 +0100 | [diff] [blame] | 89 | uint32_t io_timeout; |
Daniel Henrique Barboza | a71c775 | 2018-06-27 14:24:32 -0300 | [diff] [blame] | 90 | bool needs_vpd_bl_emulation; |
Kevin Wolf | 4f71fb4 | 2019-04-26 19:29:47 +0200 | [diff] [blame] | 91 | bool hba_supports_iothread; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 92 | }; |
| 93 | |
Paolo Bonzini | 63f740d | 2011-12-02 16:27:02 +0100 | [diff] [blame] | 94 | extern const VMStateDescription vmstate_scsi_device; |
| 95 | |
| 96 | #define VMSTATE_SCSI_DEVICE(_field, _state) { \ |
| 97 | .name = (stringify(_field)), \ |
| 98 | .size = sizeof(SCSIDevice), \ |
| 99 | .vmsd = &vmstate_scsi_device, \ |
| 100 | .flags = VMS_STRUCT, \ |
| 101 | .offset = vmstate_offset_value(_state, _field, SCSIDevice), \ |
| 102 | } |
| 103 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 104 | /* cdrom.c */ |
| 105 | int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track); |
| 106 | int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num); |
| 107 | |
| 108 | /* scsi-bus.c */ |
Paolo Bonzini | 8dbd457 | 2011-08-03 10:49:08 +0200 | [diff] [blame] | 109 | struct SCSIReqOps { |
| 110 | size_t size; |
Paolo Bonzini | 12010e7 | 2011-08-03 10:49:09 +0200 | [diff] [blame] | 111 | void (*free_req)(SCSIRequest *req); |
| 112 | int32_t (*send_command)(SCSIRequest *req, uint8_t *buf); |
| 113 | void (*read_data)(SCSIRequest *req); |
| 114 | void (*write_data)(SCSIRequest *req); |
Paolo Bonzini | 12010e7 | 2011-08-03 10:49:09 +0200 | [diff] [blame] | 115 | uint8_t *(*get_buf)(SCSIRequest *req); |
Paolo Bonzini | 63f740d | 2011-12-02 16:27:02 +0100 | [diff] [blame] | 116 | |
| 117 | void (*save_request)(QEMUFile *f, SCSIRequest *req); |
| 118 | void (*load_request)(QEMUFile *f, SCSIRequest *req); |
Paolo Bonzini | 8dbd457 | 2011-08-03 10:49:08 +0200 | [diff] [blame] | 119 | }; |
| 120 | |
Paolo Bonzini | afd4030 | 2011-08-13 15:44:45 +0200 | [diff] [blame] | 121 | struct SCSIBusInfo { |
Paolo Bonzini | 7e0380b | 2011-08-13 18:55:17 +0200 | [diff] [blame] | 122 | int tcq; |
Paolo Bonzini | 0d3545e | 2011-07-27 23:24:50 +0200 | [diff] [blame] | 123 | int max_channel, max_target, max_lun; |
Paolo Bonzini | ff34c32 | 2014-07-16 10:39:05 +0200 | [diff] [blame] | 124 | int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf, |
| 125 | void *hba_private); |
Paolo Bonzini | c6df710 | 2011-04-22 12:27:30 +0200 | [diff] [blame] | 126 | void (*transfer_data)(SCSIRequest *req, uint32_t arg); |
Hannes Reinecke | f3126d6 | 2021-02-24 19:14:50 +0100 | [diff] [blame] | 127 | void (*fail)(SCSIRequest *req); |
Hannes Reinecke | 17ea26c2 | 2020-11-16 19:40:36 +0100 | [diff] [blame] | 128 | void (*complete)(SCSIRequest *req, size_t resid); |
Paolo Bonzini | 94d3f98 | 2011-04-18 22:53:08 +0200 | [diff] [blame] | 129 | void (*cancel)(SCSIRequest *req); |
Paolo Bonzini | 53200fa | 2012-07-16 14:22:36 +0200 | [diff] [blame] | 130 | void (*change)(SCSIBus *bus, SCSIDevice *dev, SCSISense sense); |
Paolo Bonzini | 3d5aba9 | 2011-07-06 11:26:47 +0200 | [diff] [blame] | 131 | QEMUSGList *(*get_sg_list)(SCSIRequest *req); |
Paolo Bonzini | 63f740d | 2011-12-02 16:27:02 +0100 | [diff] [blame] | 132 | |
| 133 | void (*save_request)(QEMUFile *f, SCSIRequest *req); |
| 134 | void *(*load_request)(QEMUFile *f, SCSIRequest *req); |
Paolo Bonzini | 8e86b93 | 2012-07-09 12:06:28 +0200 | [diff] [blame] | 135 | void (*free_request)(SCSIBus *bus, void *priv); |
Paolo Bonzini | cfdc1bb | 2011-04-18 17:11:14 +0200 | [diff] [blame] | 136 | }; |
| 137 | |
Anthony Liguori | 0d93692 | 2012-05-02 09:00:20 +0200 | [diff] [blame] | 138 | #define TYPE_SCSI_BUS "SCSI" |
Eduardo Habkost | 8063396 | 2020-09-16 14:25:19 -0400 | [diff] [blame] | 139 | OBJECT_DECLARE_SIMPLE_TYPE(SCSIBus, SCSI_BUS) |
Anthony Liguori | 0d93692 | 2012-05-02 09:00:20 +0200 | [diff] [blame] | 140 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 141 | struct SCSIBus { |
| 142 | BusState qbus; |
| 143 | int busnr; |
| 144 | |
Paolo Bonzini | 6dc06f0 | 2011-08-03 10:49:17 +0200 | [diff] [blame] | 145 | SCSISense unit_attention; |
Paolo Bonzini | afd4030 | 2011-08-13 15:44:45 +0200 | [diff] [blame] | 146 | const SCSIBusInfo *info; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 147 | }; |
| 148 | |
Andreas Färber | b1187b5 | 2013-08-23 20:30:03 +0200 | [diff] [blame] | 149 | void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host, |
| 150 | const SCSIBusInfo *info, const char *bus_name); |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 151 | |
| 152 | static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) |
| 153 | { |
| 154 | return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); |
| 155 | } |
| 156 | |
Markus Armbruster | 4be7463 | 2014-10-07 13:59:18 +0200 | [diff] [blame] | 157 | SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, |
Kevin Wolf | 76534da | 2013-04-03 12:41:46 +0200 | [diff] [blame] | 158 | int unit, bool removable, int bootindex, |
Fam Zheng | 395b953 | 2018-01-17 08:52:22 +0800 | [diff] [blame] | 159 | bool share_rw, |
Kevin Wolf | b8efb36 | 2018-06-25 18:39:00 +0200 | [diff] [blame] | 160 | BlockdevOnError rerror, |
| 161 | BlockdevOnError werror, |
Andreas Färber | caad4eb | 2013-07-21 12:16:34 +0200 | [diff] [blame] | 162 | const char *serial, Error **errp); |
Thomas Huth | 1454509 | 2018-02-20 11:42:37 +0100 | [diff] [blame] | 163 | void scsi_bus_legacy_handle_cmdline(SCSIBus *bus); |
Markus Armbruster | fb8b660 | 2017-02-15 13:18:54 +0100 | [diff] [blame] | 164 | void scsi_legacy_handle_cmdline(void); |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 165 | |
Paolo Bonzini | adcf275 | 2011-10-12 12:57:59 +0200 | [diff] [blame] | 166 | SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, |
| 167 | uint32_t tag, uint32_t lun, void *hba_private); |
Hannes Reinecke | c5bf71a | 2011-07-11 15:02:24 +0200 | [diff] [blame] | 168 | SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, |
Paolo Bonzini | c39ce11 | 2011-08-03 10:49:10 +0200 | [diff] [blame] | 169 | uint8_t *buf, void *hba_private); |
| 170 | int32_t scsi_req_enqueue(SCSIRequest *req); |
Paolo Bonzini | ad2d30f | 2011-04-18 16:01:56 +0200 | [diff] [blame] | 171 | SCSIRequest *scsi_req_ref(SCSIRequest *req); |
| 172 | void scsi_req_unref(SCSIRequest *req); |
Gerd Hoffmann | 37659e5 | 2009-11-26 15:33:58 +0100 | [diff] [blame] | 173 | |
Paolo Bonzini | ff34c32 | 2014-07-16 10:39:05 +0200 | [diff] [blame] | 174 | int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf, |
| 175 | void *hba_private); |
Paolo Bonzini | 3e7e180 | 2014-07-16 12:22:26 +0200 | [diff] [blame] | 176 | int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf); |
Paolo Bonzini | b45ef67 | 2011-08-03 10:49:07 +0200 | [diff] [blame] | 177 | void scsi_req_build_sense(SCSIRequest *req, SCSISense sense); |
Gerd Hoffmann | ec76686 | 2009-11-26 15:34:01 +0100 | [diff] [blame] | 178 | void scsi_req_print(SCSIRequest *req); |
Paolo Bonzini | ad3376c | 2011-04-18 15:28:11 +0200 | [diff] [blame] | 179 | void scsi_req_continue(SCSIRequest *req); |
Paolo Bonzini | ab9adc8 | 2011-04-18 14:59:13 +0200 | [diff] [blame] | 180 | void scsi_req_data(SCSIRequest *req, int len); |
Paolo Bonzini | 682a9b2 | 2011-08-03 10:49:06 +0200 | [diff] [blame] | 181 | void scsi_req_complete(SCSIRequest *req, int status); |
Hannes Reinecke | f3126d6 | 2021-02-24 19:14:50 +0100 | [diff] [blame] | 182 | void scsi_req_complete_failed(SCSIRequest *req, int host_status); |
Paolo Bonzini | 0c34459 | 2011-04-21 13:21:02 +0200 | [diff] [blame] | 183 | uint8_t *scsi_req_get_buf(SCSIRequest *req); |
Hannes Reinecke | 7438221 | 2011-04-18 13:36:02 +0200 | [diff] [blame] | 184 | int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len); |
Fam Zheng | d577646 | 2014-09-25 10:20:47 +0800 | [diff] [blame] | 185 | void scsi_req_cancel_complete(SCSIRequest *req); |
Paolo Bonzini | 94d3f98 | 2011-04-18 22:53:08 +0200 | [diff] [blame] | 186 | void scsi_req_cancel(SCSIRequest *req); |
Fam Zheng | 8e0a932 | 2014-09-28 09:48:00 +0800 | [diff] [blame] | 187 | void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier); |
Paolo Bonzini | 71544d3 | 2011-10-25 12:53:36 +0200 | [diff] [blame] | 188 | void scsi_req_retry(SCSIRequest *req); |
Paolo Bonzini | c7b4887 | 2011-08-03 10:49:18 +0200 | [diff] [blame] | 189 | void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); |
Paolo Bonzini | e48e84e | 2012-07-16 14:18:58 +0200 | [diff] [blame] | 190 | void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense); |
Paolo Bonzini | 53200fa | 2012-07-16 14:22:36 +0200 | [diff] [blame] | 191 | void scsi_device_report_change(SCSIDevice *dev, SCSISense sense); |
Hannes Reinecke | 8d72db6 | 2014-10-29 13:00:11 +0100 | [diff] [blame] | 192 | void scsi_device_unit_attention_reported(SCSIDevice *dev); |
Daniel Henrique Barboza | a71c775 | 2018-06-27 14:24:32 -0300 | [diff] [blame] | 193 | void scsi_generic_read_device_inquiry(SCSIDevice *dev); |
Paolo Bonzini | b45ef67 | 2011-08-03 10:49:07 +0200 | [diff] [blame] | 194 | int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); |
Daniel Henrique Barboza | a0c7e35 | 2018-06-27 14:24:31 -0300 | [diff] [blame] | 195 | int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, |
Hannes Reinecke | c9b6609 | 2020-11-16 19:31:13 +0100 | [diff] [blame] | 196 | uint8_t *buf, uint8_t buf_size, uint32_t timeout); |
Paolo Bonzini | 0d3545e | 2011-07-27 23:24:50 +0200 | [diff] [blame] | 197 | SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); |
Maxim Levitsky | 8ff3449 | 2020-10-06 15:39:02 +0300 | [diff] [blame] | 198 | SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int target, int lun); |
Gerd Hoffmann | 89b08ae | 2009-11-26 15:33:50 +0100 | [diff] [blame] | 199 | |
Paolo Bonzini | 765d152 | 2011-10-12 12:54:31 +0200 | [diff] [blame] | 200 | /* scsi-generic.c. */ |
| 201 | extern const SCSIReqOps scsi_generic_req_ops; |
| 202 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 203 | #endif |