Gerd Hoffmann | 1e37607 | 2009-11-26 15:33:47 +0100 | [diff] [blame] | 1 | #ifndef QEMU_HW_SCSI_H |
| 2 | #define QEMU_HW_SCSI_H |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 3 | |
| 4 | #include "qdev.h" |
Gerd Hoffmann | 4c41d2e | 2009-11-26 15:33:48 +0100 | [diff] [blame] | 5 | #include "block.h" |
Hannes Reinecke | 622b520 | 2010-11-24 12:15:56 +0100 | [diff] [blame] | 6 | #include "blockdev.h" |
Christoph Hellwig | 428c149 | 2010-02-10 23:37:09 +0100 | [diff] [blame] | 7 | #include "block_int.h" |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 8 | |
Gerd Hoffmann | 29362eb | 2009-11-26 15:33:51 +0100 | [diff] [blame] | 9 | #define SCSI_CMD_BUF_SIZE 16 |
| 10 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 11 | /* scsi-disk.c */ |
| 12 | enum scsi_reason { |
| 13 | SCSI_REASON_DONE, /* Command complete. */ |
| 14 | SCSI_REASON_DATA /* Transfer complete, more data required. */ |
| 15 | }; |
| 16 | |
| 17 | typedef struct SCSIBus SCSIBus; |
| 18 | typedef struct SCSIDevice SCSIDevice; |
| 19 | typedef struct SCSIDeviceInfo SCSIDeviceInfo; |
| 20 | typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag, |
| 21 | uint32_t arg); |
| 22 | |
Gerd Hoffmann | 97a0643 | 2009-11-26 15:33:57 +0100 | [diff] [blame] | 23 | enum SCSIXferMode { |
| 24 | SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */ |
| 25 | SCSI_XFER_FROM_DEV, /* READ, INQUIRY, MODE_SENSE, ... */ |
| 26 | SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */ |
| 27 | }; |
| 28 | |
Gerd Hoffmann | 4c41d2e | 2009-11-26 15:33:48 +0100 | [diff] [blame] | 29 | typedef struct SCSIRequest { |
| 30 | SCSIBus *bus; |
| 31 | SCSIDevice *dev; |
| 32 | uint32_t tag; |
Gerd Hoffmann | 89b08ae | 2009-11-26 15:33:50 +0100 | [diff] [blame] | 33 | uint32_t lun; |
Gerd Hoffmann | ed3a34a | 2009-11-26 15:34:00 +0100 | [diff] [blame] | 34 | uint32_t status; |
Gerd Hoffmann | 29362eb | 2009-11-26 15:33:51 +0100 | [diff] [blame] | 35 | struct { |
| 36 | uint8_t buf[SCSI_CMD_BUF_SIZE]; |
| 37 | int len; |
Gerd Hoffmann | 2ec749c | 2009-11-26 15:33:55 +0100 | [diff] [blame] | 38 | size_t xfer; |
| 39 | uint64_t lba; |
Gerd Hoffmann | 97a0643 | 2009-11-26 15:33:57 +0100 | [diff] [blame] | 40 | enum SCSIXferMode mode; |
Gerd Hoffmann | 29362eb | 2009-11-26 15:33:51 +0100 | [diff] [blame] | 41 | } cmd; |
Gerd Hoffmann | 4c41d2e | 2009-11-26 15:33:48 +0100 | [diff] [blame] | 42 | BlockDriverAIOCB *aiocb; |
Jan Kiszka | e8637c9 | 2010-07-13 14:13:45 +0200 | [diff] [blame] | 43 | bool enqueued; |
Gerd Hoffmann | 9af99d9 | 2009-11-26 15:33:49 +0100 | [diff] [blame] | 44 | QTAILQ_ENTRY(SCSIRequest) next; |
Gerd Hoffmann | 4c41d2e | 2009-11-26 15:33:48 +0100 | [diff] [blame] | 45 | } SCSIRequest; |
| 46 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 47 | struct SCSIDevice |
| 48 | { |
| 49 | DeviceState qdev; |
| 50 | uint32_t id; |
Christoph Hellwig | 428c149 | 2010-02-10 23:37:09 +0100 | [diff] [blame] | 51 | BlockConf conf; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 52 | SCSIDeviceInfo *info; |
Gerd Hoffmann | 9af99d9 | 2009-11-26 15:33:49 +0100 | [diff] [blame] | 53 | QTAILQ_HEAD(, SCSIRequest) requests; |
Gerd Hoffmann | b07995e | 2009-11-26 15:33:52 +0100 | [diff] [blame] | 54 | int blocksize; |
Gerd Hoffmann | 9137665 | 2009-11-26 15:33:54 +0100 | [diff] [blame] | 55 | int type; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 56 | }; |
| 57 | |
| 58 | /* cdrom.c */ |
| 59 | int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track); |
| 60 | int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num); |
| 61 | |
| 62 | /* scsi-bus.c */ |
| 63 | typedef int (*scsi_qdev_initfn)(SCSIDevice *dev); |
| 64 | struct SCSIDeviceInfo { |
| 65 | DeviceInfo qdev; |
| 66 | scsi_qdev_initfn init; |
| 67 | void (*destroy)(SCSIDevice *s); |
| 68 | int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf, |
| 69 | int lun); |
| 70 | void (*read_data)(SCSIDevice *s, uint32_t tag); |
| 71 | int (*write_data)(SCSIDevice *s, uint32_t tag); |
| 72 | void (*cancel_io)(SCSIDevice *s, uint32_t tag); |
| 73 | uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag); |
| 74 | }; |
| 75 | |
| 76 | typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, |
| 77 | int unit); |
| 78 | struct SCSIBus { |
| 79 | BusState qbus; |
| 80 | int busnr; |
| 81 | |
| 82 | int tcq, ndev; |
| 83 | scsi_completionfn complete; |
| 84 | |
Hannes Reinecke | 622b520 | 2010-11-24 12:15:56 +0100 | [diff] [blame] | 85 | SCSIDevice *devs[MAX_SCSI_DEVS]; |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 86 | }; |
| 87 | |
| 88 | void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev, |
| 89 | scsi_completionfn complete); |
| 90 | void scsi_qdev_register(SCSIDeviceInfo *info); |
| 91 | |
| 92 | static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) |
| 93 | { |
| 94 | return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); |
| 95 | } |
| 96 | |
Markus Armbruster | f8b6cc0 | 2010-05-05 16:36:52 +0200 | [diff] [blame] | 97 | SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int unit); |
Markus Armbruster | fa66b90 | 2010-06-25 18:53:21 +0200 | [diff] [blame] | 98 | int scsi_bus_legacy_handle_cmdline(SCSIBus *bus); |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 99 | |
Gerd Hoffmann | 89b08ae | 2009-11-26 15:33:50 +0100 | [diff] [blame] | 100 | SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun); |
| 101 | SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag); |
| 102 | void scsi_req_free(SCSIRequest *req); |
Gerd Hoffmann | 37659e5 | 2009-11-26 15:33:58 +0100 | [diff] [blame] | 103 | |
Gerd Hoffmann | 2ec749c | 2009-11-26 15:33:55 +0100 | [diff] [blame] | 104 | int scsi_req_parse(SCSIRequest *req, uint8_t *buf); |
Gerd Hoffmann | ec76686 | 2009-11-26 15:34:01 +0100 | [diff] [blame] | 105 | void scsi_req_print(SCSIRequest *req); |
Gerd Hoffmann | ed3a34a | 2009-11-26 15:34:00 +0100 | [diff] [blame] | 106 | void scsi_req_complete(SCSIRequest *req); |
Gerd Hoffmann | 89b08ae | 2009-11-26 15:33:50 +0100 | [diff] [blame] | 107 | |
Gerd Hoffmann | 43b443b | 2009-10-30 09:54:00 +0100 | [diff] [blame] | 108 | #endif |