Statistics
| Branch: | Revision:

root / hw / scsi.h @ fa2ddcb4

History | View | Annotate | Download (8.8 kB)

1 1e37607b Gerd Hoffmann
#ifndef QEMU_HW_SCSI_H
2 1e37607b Gerd Hoffmann
#define QEMU_HW_SCSI_H
3 43b443b6 Gerd Hoffmann
4 43b443b6 Gerd Hoffmann
#include "qdev.h"
5 4c41d2ef Gerd Hoffmann
#include "block.h"
6 31e404f4 Markus Armbruster
#include "hw/block-common.h"
7 71544d30 Paolo Bonzini
#include "sysemu.h"
8 43b443b6 Gerd Hoffmann
9 27d6bf40 Markus Armbruster
#define MAX_SCSI_DEVS        255
10 27d6bf40 Markus Armbruster
11 29362ebe Gerd Hoffmann
#define SCSI_CMD_BUF_SIZE     16
12 29362ebe Gerd Hoffmann
13 43b443b6 Gerd Hoffmann
typedef struct SCSIBus SCSIBus;
14 afd4030c Paolo Bonzini
typedef struct SCSIBusInfo SCSIBusInfo;
15 2599aece Paolo Bonzini
typedef struct SCSICommand SCSICommand;
16 43b443b6 Gerd Hoffmann
typedef struct SCSIDevice SCSIDevice;
17 5c6c0e51 Hannes Reinecke
typedef struct SCSIRequest SCSIRequest;
18 8dbd4574 Paolo Bonzini
typedef struct SCSIReqOps SCSIReqOps;
19 43b443b6 Gerd Hoffmann
20 97a06435 Gerd Hoffmann
enum SCSIXferMode {
21 97a06435 Gerd Hoffmann
    SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
22 97a06435 Gerd Hoffmann
    SCSI_XFER_FROM_DEV,  /*  READ, INQUIRY, MODE_SENSE, ...  */
23 97a06435 Gerd Hoffmann
    SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
24 97a06435 Gerd Hoffmann
};
25 97a06435 Gerd Hoffmann
26 a1f0cce2 Hannes Reinecke
typedef struct SCSISense {
27 a1f0cce2 Hannes Reinecke
    uint8_t key;
28 a1f0cce2 Hannes Reinecke
    uint8_t asc;
29 a1f0cce2 Hannes Reinecke
    uint8_t ascq;
30 a1f0cce2 Hannes Reinecke
} SCSISense;
31 a1f0cce2 Hannes Reinecke
32 b45ef674 Paolo Bonzini
#define SCSI_SENSE_BUF_SIZE 96
33 b45ef674 Paolo Bonzini
34 2599aece Paolo Bonzini
struct SCSICommand {
35 2599aece Paolo Bonzini
    uint8_t buf[SCSI_CMD_BUF_SIZE];
36 2599aece Paolo Bonzini
    int len;
37 2599aece Paolo Bonzini
    size_t xfer;
38 2599aece Paolo Bonzini
    uint64_t lba;
39 2599aece Paolo Bonzini
    enum SCSIXferMode mode;
40 2599aece Paolo Bonzini
};
41 2599aece Paolo Bonzini
42 5c6c0e51 Hannes Reinecke
struct SCSIRequest {
43 4c41d2ef Gerd Hoffmann
    SCSIBus           *bus;
44 4c41d2ef Gerd Hoffmann
    SCSIDevice        *dev;
45 adcf2754 Paolo Bonzini
    const SCSIReqOps  *ops;
46 ad2d30f7 Paolo Bonzini
    uint32_t          refcount;
47 4c41d2ef Gerd Hoffmann
    uint32_t          tag;
48 89b08ae1 Gerd Hoffmann
    uint32_t          lun;
49 ed3a34a3 Gerd Hoffmann
    uint32_t          status;
50 01e95455 Paolo Bonzini
    size_t            resid;
51 2599aece Paolo Bonzini
    SCSICommand       cmd;
52 4c41d2ef Gerd Hoffmann
    BlockDriverAIOCB  *aiocb;
53 3d5aba97 Paolo Bonzini
    QEMUSGList        *sg;
54 3d5aba97 Paolo Bonzini
    bool              dma_started;
55 b45ef674 Paolo Bonzini
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
56 b45ef674 Paolo Bonzini
    uint32_t sense_len;
57 e8637c90 Jan Kiszka
    bool enqueued;
58 e88c591d Paolo Bonzini
    bool io_canceled;
59 71544d30 Paolo Bonzini
    bool retry;
60 c5bf71a9 Hannes Reinecke
    void *hba_private;
61 9af99d98 Gerd Hoffmann
    QTAILQ_ENTRY(SCSIRequest) next;
62 5c6c0e51 Hannes Reinecke
};
63 4c41d2ef Gerd Hoffmann
64 b9eea3e6 Anthony Liguori
#define TYPE_SCSI_DEVICE "scsi-device"
65 b9eea3e6 Anthony Liguori
#define SCSI_DEVICE(obj) \
66 b9eea3e6 Anthony Liguori
     OBJECT_CHECK(SCSIDevice, (obj), TYPE_SCSI_DEVICE)
67 b9eea3e6 Anthony Liguori
#define SCSI_DEVICE_CLASS(klass) \
68 b9eea3e6 Anthony Liguori
     OBJECT_CLASS_CHECK(SCSIDeviceClass, (klass), TYPE_SCSI_DEVICE)
69 b9eea3e6 Anthony Liguori
#define SCSI_DEVICE_GET_CLASS(obj) \
70 b9eea3e6 Anthony Liguori
     OBJECT_GET_CLASS(SCSIDeviceClass, (obj), TYPE_SCSI_DEVICE)
71 b9eea3e6 Anthony Liguori
72 b9eea3e6 Anthony Liguori
typedef struct SCSIDeviceClass {
73 b9eea3e6 Anthony Liguori
    DeviceClass parent_class;
74 b9eea3e6 Anthony Liguori
    int (*init)(SCSIDevice *dev);
75 b9eea3e6 Anthony Liguori
    void (*destroy)(SCSIDevice *s);
76 b9eea3e6 Anthony Liguori
    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
77 b9eea3e6 Anthony Liguori
                              uint8_t *buf, void *hba_private);
78 b9eea3e6 Anthony Liguori
    void (*unit_attention_reported)(SCSIDevice *s);
79 b9eea3e6 Anthony Liguori
} SCSIDeviceClass;
80 b9eea3e6 Anthony Liguori
81 43b443b6 Gerd Hoffmann
struct SCSIDevice
82 43b443b6 Gerd Hoffmann
{
83 43b443b6 Gerd Hoffmann
    DeviceState qdev;
84 71544d30 Paolo Bonzini
    VMChangeStateEntry *vmsentry;
85 71544d30 Paolo Bonzini
    QEMUBH *bh;
86 43b443b6 Gerd Hoffmann
    uint32_t id;
87 428c149b Christoph Hellwig
    BlockConf conf;
88 6dc06f08 Paolo Bonzini
    SCSISense unit_attention;
89 3653d8c4 Paolo Bonzini
    bool sense_is_ua;
90 b45ef674 Paolo Bonzini
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
91 b45ef674 Paolo Bonzini
    uint32_t sense_len;
92 9af99d98 Gerd Hoffmann
    QTAILQ_HEAD(, SCSIRequest) requests;
93 0d3545e7 Paolo Bonzini
    uint32_t channel;
94 87dcd1b2 Paolo Bonzini
    uint32_t lun;
95 b07995e3 Gerd Hoffmann
    int blocksize;
96 91376656 Gerd Hoffmann
    int type;
97 7877903a Paolo Bonzini
    uint64_t max_lba;
98 43b443b6 Gerd Hoffmann
};
99 43b443b6 Gerd Hoffmann
100 63f740dd Paolo Bonzini
extern const VMStateDescription vmstate_scsi_device;
101 63f740dd Paolo Bonzini
102 63f740dd Paolo Bonzini
#define VMSTATE_SCSI_DEVICE(_field, _state) {                        \
103 63f740dd Paolo Bonzini
    .name       = (stringify(_field)),                               \
104 63f740dd Paolo Bonzini
    .size       = sizeof(SCSIDevice),                                \
105 63f740dd Paolo Bonzini
    .vmsd       = &vmstate_scsi_device,                              \
106 63f740dd Paolo Bonzini
    .flags      = VMS_STRUCT,                                        \
107 63f740dd Paolo Bonzini
    .offset     = vmstate_offset_value(_state, _field, SCSIDevice),  \
108 63f740dd Paolo Bonzini
}
109 63f740dd Paolo Bonzini
110 43b443b6 Gerd Hoffmann
/* cdrom.c */
111 43b443b6 Gerd Hoffmann
int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
112 43b443b6 Gerd Hoffmann
int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
113 43b443b6 Gerd Hoffmann
114 43b443b6 Gerd Hoffmann
/* scsi-bus.c */
115 8dbd4574 Paolo Bonzini
struct SCSIReqOps {
116 8dbd4574 Paolo Bonzini
    size_t size;
117 12010e7b Paolo Bonzini
    void (*free_req)(SCSIRequest *req);
118 12010e7b Paolo Bonzini
    int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
119 12010e7b Paolo Bonzini
    void (*read_data)(SCSIRequest *req);
120 12010e7b Paolo Bonzini
    void (*write_data)(SCSIRequest *req);
121 12010e7b Paolo Bonzini
    void (*cancel_io)(SCSIRequest *req);
122 12010e7b Paolo Bonzini
    uint8_t *(*get_buf)(SCSIRequest *req);
123 63f740dd Paolo Bonzini
124 63f740dd Paolo Bonzini
    void (*save_request)(QEMUFile *f, SCSIRequest *req);
125 63f740dd Paolo Bonzini
    void (*load_request)(QEMUFile *f, SCSIRequest *req);
126 8dbd4574 Paolo Bonzini
};
127 8dbd4574 Paolo Bonzini
128 afd4030c Paolo Bonzini
struct SCSIBusInfo {
129 7e0380b9 Paolo Bonzini
    int tcq;
130 0d3545e7 Paolo Bonzini
    int max_channel, max_target, max_lun;
131 c6df7102 Paolo Bonzini
    void (*transfer_data)(SCSIRequest *req, uint32_t arg);
132 01e95455 Paolo Bonzini
    void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid);
133 94d3f98a Paolo Bonzini
    void (*cancel)(SCSIRequest *req);
134 350e6e41 Cong Meng
    void (*hotplug)(SCSIBus *bus, SCSIDevice *dev);
135 350e6e41 Cong Meng
    void (*hot_unplug)(SCSIBus *bus, SCSIDevice *dev);
136 53200fad Paolo Bonzini
    void (*change)(SCSIBus *bus, SCSIDevice *dev, SCSISense sense);
137 3d5aba97 Paolo Bonzini
    QEMUSGList *(*get_sg_list)(SCSIRequest *req);
138 63f740dd Paolo Bonzini
139 63f740dd Paolo Bonzini
    void (*save_request)(QEMUFile *f, SCSIRequest *req);
140 63f740dd Paolo Bonzini
    void *(*load_request)(QEMUFile *f, SCSIRequest *req);
141 8e86b93c Paolo Bonzini
    void (*free_request)(SCSIBus *bus, void *priv);
142 cfdc1bb0 Paolo Bonzini
};
143 cfdc1bb0 Paolo Bonzini
144 0d936928 Anthony Liguori
#define TYPE_SCSI_BUS "SCSI"
145 0d936928 Anthony Liguori
#define SCSI_BUS(obj) OBJECT_CHECK(SCSIBus, (obj), TYPE_SCSI_BUS)
146 0d936928 Anthony Liguori
147 43b443b6 Gerd Hoffmann
struct SCSIBus {
148 43b443b6 Gerd Hoffmann
    BusState qbus;
149 43b443b6 Gerd Hoffmann
    int busnr;
150 43b443b6 Gerd Hoffmann
151 6dc06f08 Paolo Bonzini
    SCSISense unit_attention;
152 afd4030c Paolo Bonzini
    const SCSIBusInfo *info;
153 43b443b6 Gerd Hoffmann
};
154 43b443b6 Gerd Hoffmann
155 afd4030c Paolo Bonzini
void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info);
156 43b443b6 Gerd Hoffmann
157 43b443b6 Gerd Hoffmann
static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
158 43b443b6 Gerd Hoffmann
{
159 43b443b6 Gerd Hoffmann
    return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
160 43b443b6 Gerd Hoffmann
}
161 43b443b6 Gerd Hoffmann
162 2d1fd261 Stefan Hajnoczi
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
163 ce4e7e46 Paolo Bonzini
                                      int unit, bool removable, int bootindex);
164 fa66b909 Markus Armbruster
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
165 43b443b6 Gerd Hoffmann
166 a1f0cce2 Hannes Reinecke
/*
167 a1f0cce2 Hannes Reinecke
 * Predefined sense codes
168 a1f0cce2 Hannes Reinecke
 */
169 a1f0cce2 Hannes Reinecke
170 a1f0cce2 Hannes Reinecke
/* No sense data available */
171 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_NO_SENSE;
172 a1f0cce2 Hannes Reinecke
/* LUN not ready, Manual intervention required */
173 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_LUN_NOT_READY;
174 a1f0cce2 Hannes Reinecke
/* LUN not ready, Medium not present */
175 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_NO_MEDIUM;
176 68bb01f3 Markus Armbruster
/* LUN not ready, medium removal prevented */
177 68bb01f3 Markus Armbruster
extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED;
178 a1f0cce2 Hannes Reinecke
/* Hardware error, internal target failure */
179 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_TARGET_FAILURE;
180 a1f0cce2 Hannes Reinecke
/* Illegal request, invalid command operation code */
181 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_INVALID_OPCODE;
182 a1f0cce2 Hannes Reinecke
/* Illegal request, LBA out of range */
183 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
184 a1f0cce2 Hannes Reinecke
/* Illegal request, Invalid field in CDB */
185 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_INVALID_FIELD;
186 380feaff Paolo Bonzini
/* Illegal request, Invalid field in parameter list */
187 380feaff Paolo Bonzini
extern const struct SCSISense sense_code_INVALID_PARAM;
188 380feaff Paolo Bonzini
/* Illegal request, Parameter list length error */
189 380feaff Paolo Bonzini
extern const struct SCSISense sense_code_INVALID_PARAM_LEN;
190 a1f0cce2 Hannes Reinecke
/* Illegal request, LUN not supported */
191 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
192 a872a304 Paolo Bonzini
/* Illegal request, Saving parameters not supported */
193 a872a304 Paolo Bonzini
extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
194 a872a304 Paolo Bonzini
/* Illegal request, Incompatible format */
195 a872a304 Paolo Bonzini
extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
196 68bb01f3 Markus Armbruster
/* Illegal request, medium removal prevented */
197 68bb01f3 Markus Armbruster
extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
198 a1f0cce2 Hannes Reinecke
/* Command aborted, I/O process terminated */
199 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_IO_ERROR;
200 a1f0cce2 Hannes Reinecke
/* Command aborted, I_T Nexus loss occurred */
201 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
202 a1f0cce2 Hannes Reinecke
/* Command aborted, Logical Unit failure */
203 a1f0cce2 Hannes Reinecke
extern const struct SCSISense sense_code_LUN_FAILURE;
204 aaebacef Paolo Bonzini
/* LUN not ready, Capacity data has changed */
205 aaebacef Paolo Bonzini
extern const struct SCSISense sense_code_CAPACITY_CHANGED;
206 8a9c16f6 Paolo Bonzini
/* LUN not ready, Medium not present */
207 8a9c16f6 Paolo Bonzini
extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
208 a872a304 Paolo Bonzini
/* Unit attention, Power on, reset or bus device reset occurred */
209 a872a304 Paolo Bonzini
extern const struct SCSISense sense_code_RESET;
210 a872a304 Paolo Bonzini
/* Unit attention, Medium may have changed*/
211 a872a304 Paolo Bonzini
extern const struct SCSISense sense_code_MEDIUM_CHANGED;
212 a872a304 Paolo Bonzini
/* Unit attention, Reported LUNs data has changed */
213 a872a304 Paolo Bonzini
extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
214 a872a304 Paolo Bonzini
/* Unit attention, Device internal reset */
215 a872a304 Paolo Bonzini
extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
216 6a8a685c Ronnie Sahlberg
/* Data Protection, Write Protected */
217 6a8a685c Ronnie Sahlberg
extern const struct SCSISense sense_code_WRITE_PROTECTED;
218 a1f0cce2 Hannes Reinecke
219 a1f0cce2 Hannes Reinecke
#define SENSE_CODE(x) sense_code_ ## x
220 a1f0cce2 Hannes Reinecke
221 bb729f75 Paolo Bonzini
uint32_t scsi_data_cdb_length(uint8_t *buf);
222 bb729f75 Paolo Bonzini
uint32_t scsi_cdb_length(uint8_t *buf);
223 a1f0cce2 Hannes Reinecke
int scsi_sense_valid(SCSISense sense);
224 f3b338ef Paolo Bonzini
int scsi_build_sense(uint8_t *in_buf, int in_len,
225 f3b338ef Paolo Bonzini
                     uint8_t *buf, int len, bool fixed);
226 a1f0cce2 Hannes Reinecke
227 adcf2754 Paolo Bonzini
SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
228 adcf2754 Paolo Bonzini
                            uint32_t tag, uint32_t lun, void *hba_private);
229 c5bf71a9 Hannes Reinecke
SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
230 c39ce112 Paolo Bonzini
                          uint8_t *buf, void *hba_private);
231 c39ce112 Paolo Bonzini
int32_t scsi_req_enqueue(SCSIRequest *req);
232 89b08ae1 Gerd Hoffmann
void scsi_req_free(SCSIRequest *req);
233 ad2d30f7 Paolo Bonzini
SCSIRequest *scsi_req_ref(SCSIRequest *req);
234 ad2d30f7 Paolo Bonzini
void scsi_req_unref(SCSIRequest *req);
235 37659e51 Gerd Hoffmann
236 b45ef674 Paolo Bonzini
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
237 ec766865 Gerd Hoffmann
void scsi_req_print(SCSIRequest *req);
238 ad3376cc Paolo Bonzini
void scsi_req_continue(SCSIRequest *req);
239 ab9adc88 Paolo Bonzini
void scsi_req_data(SCSIRequest *req, int len);
240 682a9b21 Paolo Bonzini
void scsi_req_complete(SCSIRequest *req, int status);
241 0c34459b Paolo Bonzini
uint8_t *scsi_req_get_buf(SCSIRequest *req);
242 74382217 Hannes Reinecke
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
243 19d110ab Paolo Bonzini
void scsi_req_abort(SCSIRequest *req, int status);
244 94d3f98a Paolo Bonzini
void scsi_req_cancel(SCSIRequest *req);
245 71544d30 Paolo Bonzini
void scsi_req_retry(SCSIRequest *req);
246 c7b48872 Paolo Bonzini
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
247 e48e84ea Paolo Bonzini
void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense);
248 53200fad Paolo Bonzini
void scsi_device_report_change(SCSIDevice *dev, SCSISense sense);
249 b45ef674 Paolo Bonzini
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
250 0d3545e7 Paolo Bonzini
SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);
251 89b08ae1 Gerd Hoffmann
252 765d1525 Paolo Bonzini
/* scsi-generic.c. */
253 765d1525 Paolo Bonzini
extern const SCSIReqOps scsi_generic_req_ops;
254 765d1525 Paolo Bonzini
255 43b443b6 Gerd Hoffmann
#endif