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