1 ///////////////////////////////////////////////////////////////////////// 2 // $Id: scsi_device.h 14117 2021-02-01 12:42:12Z vruppert $ 3 ///////////////////////////////////////////////////////////////////////// 4 // 5 // SCSI emulation layer (ported from QEMU) 6 // 7 // Copyright (C) 2006 CodeSourcery. 8 // Based on code by Fabrice Bellard 9 // 10 // Written by Paul Brook 11 // 12 // Copyright (C) 2007-2021 The Bochs Project 13 // 14 // This library is free software; you can redistribute it and/or 15 // modify it under the terms of the GNU Lesser General Public 16 // License as published by the Free Software Foundation; either 17 // version 2 of the License, or (at your option) any later version. 18 // 19 // This library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 // Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public 25 // License along with this library; if not, write to the Free Software 26 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 28 #ifndef BX_IODEV_SCSI_DEVICE_H 29 #define BX_IODEV_SCSI_DEVICE_H 30 31 typedef void (*scsi_completionfn)(void *opaque, int reason, Bit32u tag, 32 Bit32u arg); 33 class cdrom_base_c; 34 35 enum scsidev_type { 36 SCSIDEV_TYPE_DISK, 37 SCSIDEV_TYPE_CDROM 38 }; 39 40 enum scsi_reason { 41 SCSI_REASON_DONE, 42 SCSI_REASON_DATA 43 }; 44 45 #define SENSE_NO_SENSE 0 46 #define SENSE_NOT_READY 2 47 #define SENSE_MEDIUM_ERROR 3 48 #define SENSE_HARDWARE_ERROR 4 49 #define SENSE_ILLEGAL_REQUEST 5 50 51 #define STATUS_GOOD 0 52 #define STATUS_CHECK_CONDITION 2 53 54 #define SCSI_DMA_BUF_SIZE 131072 55 #define SCSI_MAX_INQUIRY_LEN 256 56 57 typedef struct SCSIRequest { 58 Bit32u tag; 59 Bit64u sector; 60 Bit32u sector_count; 61 int buf_len; 62 Bit8u *dma_buf; 63 Bit32u status; 64 bool write_cmd; 65 bool async_mode; 66 Bit8u seek_pending; 67 struct SCSIRequest *next; 68 } SCSIRequest; 69 70 71 class scsi_device_t : public logfunctions { 72 public: 73 scsi_device_t(device_image_t *_hdimage, int _tcq, 74 scsi_completionfn _completion, void *_dev); 75 scsi_device_t(cdrom_base_c *_cdrom, int _tcq, 76 scsi_completionfn _completion, void *_dev); 77 virtual ~scsi_device_t(void); 78 79 void register_state(bx_list_c *parent, const char *name); 80 Bit32s scsi_send_command(Bit32u tag, Bit8u *buf, int lun, bool async); 81 void scsi_command_complete(SCSIRequest *r, int status, int sense); 82 void scsi_cancel_io(Bit32u tag); 83 void scsi_read_complete(void *req, int ret); 84 void scsi_read_data(Bit32u tag); 85 void scsi_write_complete(void *req, int ret); 86 void scsi_write_data(Bit32u tag); 87 Bit8u* scsi_get_buf(Bit32u tag); get_serial_number()88 const char *get_serial_number() {return drive_serial_str;} 89 void set_inserted(bool value); get_inserted()90 bool get_inserted() {return inserted;} get_locked()91 bool get_locked() {return locked;} 92 static void seek_timer_handler(void *); 93 bool save_requests(const char *path); 94 void restore_requests(const char *path); 95 void set_debug_mode(); 96 97 protected: 98 SCSIRequest* scsi_new_request(Bit32u tag); 99 void scsi_remove_request(SCSIRequest *r); 100 SCSIRequest *scsi_find_request(Bit32u tag); 101 102 private: 103 void start_seek(SCSIRequest *r); 104 void seek_timer(void); 105 void seek_complete(SCSIRequest *r); 106 107 // members set in constructor 108 enum scsidev_type type; 109 device_image_t *hdimage; 110 cdrom_base_c *cdrom; 111 int block_size; 112 int tcq; 113 scsi_completionfn completion; 114 void *dev; 115 char drive_serial_str[21]; 116 int seek_timer_index; 117 int statusbar_id; 118 // members set in constructor / runtime config 119 Bit64u max_lba; 120 bool inserted; 121 // members handled by save/restore 122 Bit64u curr_lba; 123 int sense; 124 bool locked; 125 SCSIRequest *requests; 126 }; 127 128 #endif 129