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;
G
Gerd Hoffmann 已提交
14 15
typedef struct SCSIDevice SCSIDevice;
typedef struct SCSIDeviceInfo SCSIDeviceInfo;
16
typedef struct SCSIRequest SCSIRequest;
P
Paolo Bonzini 已提交
17
typedef struct SCSIReqOps SCSIReqOps;
G
Gerd Hoffmann 已提交
18

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

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

31 32
#define SCSI_SENSE_BUF_SIZE 96

33
struct SCSIRequest {
34 35
    SCSIBus           *bus;
    SCSIDevice        *dev;
P
Paolo Bonzini 已提交
36
    SCSIReqOps        *ops;
P
Paolo Bonzini 已提交
37
    uint32_t          refcount;
38
    uint32_t          tag;
39
    uint32_t          lun;
G
Gerd Hoffmann 已提交
40
    uint32_t          status;
41 42 43
    struct {
        uint8_t buf[SCSI_CMD_BUF_SIZE];
        int len;
44 45
        size_t xfer;
        uint64_t lba;
G
Gerd Hoffmann 已提交
46
        enum SCSIXferMode mode;
47
    } cmd;
48
    BlockDriverAIOCB  *aiocb;
49 50
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
    uint32_t sense_len;
51
    bool enqueued;
52
    void *hba_private;
53
    QTAILQ_ENTRY(SCSIRequest) next;
54
};
55

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

/* 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 已提交
74 75
struct SCSIReqOps {
    size_t size;
76 77 78 79 80 81
    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 已提交
82 83
};

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

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

G
Gerd Hoffmann 已提交
100 101 102 103 104
struct SCSIBus {
    BusState qbus;
    int busnr;

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

107
    SCSIDevice *devs[MAX_SCSI_DEVS];
G
Gerd Hoffmann 已提交
108 109 110
};

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

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

119 120
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
                                      int unit, bool removable);
121
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
G
Gerd Hoffmann 已提交
122

123 124 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
/*
 * 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 已提交
154
SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
155 156
                            uint32_t lun, void *hba_private);
SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
157 158
                          uint8_t *buf, void *hba_private);
int32_t scsi_req_enqueue(SCSIRequest *req);
159
void scsi_req_free(SCSIRequest *req);
P
Paolo Bonzini 已提交
160 161
SCSIRequest *scsi_req_ref(SCSIRequest *req);
void scsi_req_unref(SCSIRequest *req);
162

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

G
Gerd Hoffmann 已提交
176
#endif