scsi.h 5.3 KB
Newer Older
G
Gerd Hoffmann 已提交
1 2
#ifndef QEMU_HW_SCSI_H
#define QEMU_HW_SCSI_H
G
Gerd Hoffmann 已提交
3 4

#include "qdev.h"
5
#include "block.h"
6
#include "block_int.h"
G
Gerd Hoffmann 已提交
7

8 9
#define MAX_SCSI_DEVS	255

10 11
#define SCSI_CMD_BUF_SIZE     16

G
Gerd Hoffmann 已提交
12
typedef struct SCSIBus SCSIBus;
P
Paolo Bonzini 已提交
13
typedef struct SCSIBusOps SCSIBusOps;
P
Paolo Bonzini 已提交
14
typedef struct SCSICommand SCSICommand;
G
Gerd Hoffmann 已提交
15 16
typedef struct SCSIDevice SCSIDevice;
typedef struct SCSIDeviceInfo SCSIDeviceInfo;
17
typedef struct SCSIRequest SCSIRequest;
P
Paolo Bonzini 已提交
18
typedef struct SCSIReqOps SCSIReqOps;
G
Gerd Hoffmann 已提交
19

G
Gerd Hoffmann 已提交
20 21 22 23 24 25
enum SCSIXferMode {
    SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
    SCSI_XFER_FROM_DEV,  /*  READ, INQUIRY, MODE_SENSE, ...  */
    SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
};

26 27 28 29 30 31
typedef struct SCSISense {
    uint8_t key;
    uint8_t asc;
    uint8_t ascq;
} SCSISense;

32 33
#define SCSI_SENSE_BUF_SIZE 96

P
Paolo Bonzini 已提交
34 35 36 37 38 39 40 41
struct SCSICommand {
    uint8_t buf[SCSI_CMD_BUF_SIZE];
    int len;
    size_t xfer;
    uint64_t lba;
    enum SCSIXferMode mode;
};

42
struct SCSIRequest {
43 44
    SCSIBus           *bus;
    SCSIDevice        *dev;
P
Paolo Bonzini 已提交
45
    SCSIReqOps        *ops;
P
Paolo Bonzini 已提交
46
    uint32_t          refcount;
47
    uint32_t          tag;
48
    uint32_t          lun;
G
Gerd Hoffmann 已提交
49
    uint32_t          status;
P
Paolo Bonzini 已提交
50
    SCSICommand       cmd;
51
    BlockDriverAIOCB  *aiocb;
52 53
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
    uint32_t sense_len;
54
    bool enqueued;
55
    void *hba_private;
56
    QTAILQ_ENTRY(SCSIRequest) next;
57
};
58

G
Gerd Hoffmann 已提交
59 60 61 62
struct SCSIDevice
{
    DeviceState qdev;
    uint32_t id;
63
    BlockConf conf;
G
Gerd Hoffmann 已提交
64
    SCSIDeviceInfo *info;
65 66
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
    uint32_t sense_len;
67
    QTAILQ_HEAD(, SCSIRequest) requests;
68
    int blocksize;
69
    int type;
G
Gerd Hoffmann 已提交
70 71 72 73 74 75 76
};

/* cdrom.c */
int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);

/* scsi-bus.c */
P
Paolo Bonzini 已提交
77 78
struct SCSIReqOps {
    size_t size;
79 80 81 82 83 84
    void (*free_req)(SCSIRequest *req);
    int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
    void (*read_data)(SCSIRequest *req);
    void (*write_data)(SCSIRequest *req);
    void (*cancel_io)(SCSIRequest *req);
    uint8_t *(*get_buf)(SCSIRequest *req);
P
Paolo Bonzini 已提交
85 86
};

G
Gerd Hoffmann 已提交
87 88 89 90 91
typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
struct SCSIDeviceInfo {
    DeviceInfo qdev;
    scsi_qdev_initfn init;
    void (*destroy)(SCSIDevice *s);
92 93
    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
                              void *hba_private);
94
    SCSIReqOps reqops;
G
Gerd Hoffmann 已提交
95 96
};

P
Paolo Bonzini 已提交
97
struct SCSIBusOps {
98 99
    void (*transfer_data)(SCSIRequest *req, uint32_t arg);
    void (*complete)(SCSIRequest *req, uint32_t arg);
P
Paolo Bonzini 已提交
100
    void (*cancel)(SCSIRequest *req);
P
Paolo Bonzini 已提交
101 102
};

G
Gerd Hoffmann 已提交
103 104 105 106 107
struct SCSIBus {
    BusState qbus;
    int busnr;

    int tcq, ndev;
P
Paolo Bonzini 已提交
108
    const SCSIBusOps *ops;
G
Gerd Hoffmann 已提交
109

110
    SCSIDevice *devs[MAX_SCSI_DEVS];
G
Gerd Hoffmann 已提交
111 112 113
};

void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
P
Paolo Bonzini 已提交
114
                  const SCSIBusOps *ops);
G
Gerd Hoffmann 已提交
115 116 117 118 119 120 121
void scsi_qdev_register(SCSIDeviceInfo *info);

static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
{
    return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
}

122 123
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
                                      int unit, bool removable);
124
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
G
Gerd Hoffmann 已提交
125

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
/*
 * Predefined sense codes
 */

/* No sense data available */
extern const struct SCSISense sense_code_NO_SENSE;
/* LUN not ready, Manual intervention required */
extern const struct SCSISense sense_code_LUN_NOT_READY;
/* LUN not ready, Medium not present */
extern const struct SCSISense sense_code_NO_MEDIUM;
/* Hardware error, internal target failure */
extern const struct SCSISense sense_code_TARGET_FAILURE;
/* Illegal request, invalid command operation code */
extern const struct SCSISense sense_code_INVALID_OPCODE;
/* Illegal request, LBA out of range */
extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
/* Illegal request, Invalid field in CDB */
extern const struct SCSISense sense_code_INVALID_FIELD;
/* Illegal request, LUN not supported */
extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
/* Command aborted, I/O process terminated */
extern const struct SCSISense sense_code_IO_ERROR;
/* Command aborted, I_T Nexus loss occurred */
extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
/* Command aborted, Logical Unit failure */
extern const struct SCSISense sense_code_LUN_FAILURE;

#define SENSE_CODE(x) sense_code_ ## x

int scsi_sense_valid(SCSISense sense);

P
Paolo Bonzini 已提交
157
SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
158 159
                            uint32_t lun, void *hba_private);
SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
160 161
                          uint8_t *buf, void *hba_private);
int32_t scsi_req_enqueue(SCSIRequest *req);
162
void scsi_req_free(SCSIRequest *req);
P
Paolo Bonzini 已提交
163 164
SCSIRequest *scsi_req_ref(SCSIRequest *req);
void scsi_req_unref(SCSIRequest *req);
165

166
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
167
int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
G
Gerd Hoffmann 已提交
168
void scsi_req_print(SCSIRequest *req);
169
void scsi_req_continue(SCSIRequest *req);
P
Paolo Bonzini 已提交
170
void scsi_req_data(SCSIRequest *req, int len);
171
void scsi_req_complete(SCSIRequest *req, int status);
P
Paolo Bonzini 已提交
172
uint8_t *scsi_req_get_buf(SCSIRequest *req);
173
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
P
Paolo Bonzini 已提交
174
void scsi_req_abort(SCSIRequest *req, int status);
P
Paolo Bonzini 已提交
175
void scsi_req_cancel(SCSIRequest *req);
P
Paolo Bonzini 已提交
176
void scsi_device_purge_requests(SCSIDevice *sdev);
177
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
178

G
Gerd Hoffmann 已提交
179
#endif