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 76 77
struct SCSIReqOps {
    size_t size;
};

G
Gerd Hoffmann 已提交
78 79 80 81 82
typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
struct SCSIDeviceInfo {
    DeviceInfo qdev;
    scsi_qdev_initfn init;
    void (*destroy)(SCSIDevice *s);
83 84
    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
                              void *hba_private);
P
Paolo Bonzini 已提交
85
    void (*free_req)(SCSIRequest *req);
86 87
    int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
    void (*read_data)(SCSIRequest *req);
88
    void (*write_data)(SCSIRequest *req);
89 90
    void (*cancel_io)(SCSIRequest *req);
    uint8_t *(*get_buf)(SCSIRequest *req);
G
Gerd Hoffmann 已提交
91 92
};

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

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

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

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

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

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

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

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

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

G
Gerd Hoffmann 已提交
175
#endif