scsi.h 3.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 13 14 15 16 17 18
/* scsi-disk.c */
enum scsi_reason {
    SCSI_REASON_DONE, /* Command complete.  */
    SCSI_REASON_DATA  /* Transfer complete, more data required.  */
};

typedef struct SCSIBus SCSIBus;
P
Paolo Bonzini 已提交
19
typedef struct SCSIBusOps SCSIBusOps;
G
Gerd Hoffmann 已提交
20 21
typedef struct SCSIDevice SCSIDevice;
typedef struct SCSIDeviceInfo SCSIDeviceInfo;
22
typedef struct SCSIRequest SCSIRequest;
G
Gerd Hoffmann 已提交
23

G
Gerd Hoffmann 已提交
24 25 26 27 28 29
enum SCSIXferMode {
    SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
    SCSI_XFER_FROM_DEV,  /*  READ, INQUIRY, MODE_SENSE, ...  */
    SCSI_XFER_TO_DEV,    /*  WRITE, MODE_SELECT, ...         */
};

30
struct SCSIRequest {
31 32
    SCSIBus           *bus;
    SCSIDevice        *dev;
P
Paolo Bonzini 已提交
33
    uint32_t          refcount;
34
    uint32_t          tag;
35
    uint32_t          lun;
G
Gerd Hoffmann 已提交
36
    uint32_t          status;
37 38 39
    struct {
        uint8_t buf[SCSI_CMD_BUF_SIZE];
        int len;
40 41
        size_t xfer;
        uint64_t lba;
G
Gerd Hoffmann 已提交
42
        enum SCSIXferMode mode;
43
    } cmd;
44
    BlockDriverAIOCB  *aiocb;
45
    bool enqueued;
46
    QTAILQ_ENTRY(SCSIRequest) next;
47
};
48

G
Gerd Hoffmann 已提交
49 50 51 52
struct SCSIDevice
{
    DeviceState qdev;
    uint32_t id;
53
    BlockConf conf;
G
Gerd Hoffmann 已提交
54
    SCSIDeviceInfo *info;
55
    QTAILQ_HEAD(, SCSIRequest) requests;
56
    int blocksize;
57
    int type;
G
Gerd Hoffmann 已提交
58 59 60 61 62 63 64 65 66 67 68 69
};

/* 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 */
typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
struct SCSIDeviceInfo {
    DeviceInfo qdev;
    scsi_qdev_initfn init;
    void (*destroy)(SCSIDevice *s);
70
    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
P
Paolo Bonzini 已提交
71
    void (*free_req)(SCSIRequest *req);
72 73 74 75 76
    int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
    void (*read_data)(SCSIRequest *req);
    int (*write_data)(SCSIRequest *req);
    void (*cancel_io)(SCSIRequest *req);
    uint8_t *(*get_buf)(SCSIRequest *req);
G
Gerd Hoffmann 已提交
77 78
};

P
Paolo Bonzini 已提交
79
struct SCSIBusOps {
80
    void (*complete)(SCSIRequest *req, int reason, uint32_t arg);
P
Paolo Bonzini 已提交
81 82
};

G
Gerd Hoffmann 已提交
83 84 85 86 87
struct SCSIBus {
    BusState qbus;
    int busnr;

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

90
    SCSIDevice *devs[MAX_SCSI_DEVS];
G
Gerd Hoffmann 已提交
91 92 93
};

void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
P
Paolo Bonzini 已提交
94
                  const SCSIBusOps *ops);
G
Gerd Hoffmann 已提交
95 96 97 98 99 100 101
void scsi_qdev_register(SCSIDeviceInfo *info);

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

102 103
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
                                      int unit, bool removable);
104
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
G
Gerd Hoffmann 已提交
105

106
SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun);
107
void scsi_req_enqueue(SCSIRequest *req);
108
void scsi_req_free(SCSIRequest *req);
P
Paolo Bonzini 已提交
109 110 111
void scsi_req_dequeue(SCSIRequest *req);
SCSIRequest *scsi_req_ref(SCSIRequest *req);
void scsi_req_unref(SCSIRequest *req);
112

113
int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
G
Gerd Hoffmann 已提交
114
void scsi_req_print(SCSIRequest *req);
P
Paolo Bonzini 已提交
115
void scsi_req_data(SCSIRequest *req, int len);
G
Gerd Hoffmann 已提交
116
void scsi_req_complete(SCSIRequest *req);
P
Paolo Bonzini 已提交
117
void scsi_req_abort(SCSIRequest *req, int status);
P
Paolo Bonzini 已提交
118
void scsi_device_purge_requests(SCSIDevice *sdev);
119

G
Gerd Hoffmann 已提交
120
#endif