1 #ifndef UAE_SCSI_H
2 #define UAE_SCSI_H
3 
4 #include "uae/types.h"
5 #include "uae/memory.h"
6 #ifdef FSUAE
7 #include "uae/limits.h"
8 #endif
9 
10 #define SCSI_DEFAULT_DATA_BUFFER_SIZE (256 * 512)
11 
12 struct scsi_data_tape
13 {
14 	TCHAR tape_dir[MAX_DPATH];
15 	int file_number;
16 	uae_s64 file_offset;
17 	int blocksize;
18 	bool realdir;
19 	struct zdirectory *zd;
20 	struct my_opendir_s *od;
21 	struct zfile *zf;
22 	struct zfile *index;
23 	int beom;
24 	bool wp;
25 	bool nomedia;
26 	bool unloaded;
27 };
28 
29 struct scsi_data
30 {
31 	int id;
32 	void *privdata;
33 	int cmd_len;
34 	uae_u8 *data;
35 	int data_len;
36 	int status;
37 	uae_u8 sense[256];
38 	int sense_len;
39 	uae_u8 reply[256];
40 	uae_u8 cmd[16];
41 	uae_u8 msgout[4];
42 	int reply_len;
43 	int direction;
44 	uae_u8 message[1];
45 	int blocksize;
46 
47 	int offset;
48 	uae_u8 *buffer;
49 	int buffer_size;
50 	struct hd_hardfiledata *hfd;
51 	struct scsi_data_tape *tape;
52 	int device_type;
53 	int nativescsiunit;
54 	int cd_emu_unit;
55 	bool atapi;
56 	uae_u32 unit_attention;
57 };
58 
59 extern struct scsi_data *scsi_alloc_hd(int, struct hd_hardfiledata*);
60 extern struct scsi_data *scsi_alloc_cd(int, int, bool);
61 extern struct scsi_data *scsi_alloc_tape(int id, const TCHAR *tape_directory, bool readonly);
62 extern struct scsi_data *scsi_alloc_native(int, int);
63 extern void scsi_free(struct scsi_data*);
64 extern void scsi_reset(void);
65 
66 extern void scsi_start_transfer(struct scsi_data*);
67 extern int scsi_send_data(struct scsi_data*, uae_u8);
68 extern int scsi_receive_data(struct scsi_data*, uae_u8*, bool next);
69 extern void scsi_emulate_cmd(struct scsi_data *sd);
70 extern void scsi_illegal_lun(struct scsi_data *sd);
71 extern void scsi_clear_sense(struct scsi_data *sd);
72 
73 extern int scsi_hd_emulate(struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, uae_u8 *cmdbuf, int scsi_cmd_len,
74 		uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len);
75 extern int scsi_tape_emulate(struct scsi_data_tape *sd, uae_u8 *cmdbuf, int scsi_cmd_len,
76 		uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len);
77 extern bool scsi_emulate_analyze (struct scsi_data*);
78 
79 extern bool tape_get_info (int, struct device_info*);
80 extern struct scsi_data_tape *tape_alloc (int unitnum, const TCHAR *tape_directory, bool readonly);
81 extern void tape_free (struct scsi_data_tape*);
82 extern void tape_media_change (int unitnum, struct uaedev_config_info*);
83 
84 int add_scsi_device(struct scsi_data **sd, int ch, struct uaedev_config_info *ci, struct romconfig *rc);
85 int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci);
86 int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum);
87 int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly);
88 void free_scsi (struct scsi_data *sd);
89 
90 void scsi_freenative(struct scsi_data **sd, int max);
91 void scsi_addnative(struct scsi_data **sd);
92 
93 #define SCSI_NO_SENSE_DATA		0x00
94 #define SCSI_NOT_READY			0x04
95 #define SCSI_NOT_LOADED			0x09
96 #define SCSI_INSUF_CAPACITY		0x0a
97 #define SCSI_HARD_DATA_ERROR	0x11
98 #define SCSI_WRITE_PROTECT		0x17
99 #define SCSI_CORRECTABLE_ERROR	0x18
100 #define SCSI_FILE_MARK			0x1c
101 #define SCSI_INVALID_COMMAND	0x20
102 #define SCSI_INVALID_FIELD		0x24
103 #define SCSI_INVALID_LUN		0x25
104 #define SCSI_UNIT_ATTENTION		0x30
105 #define SCSI_END_OF_MEDIA		0x34
106 #define SCSI_MEDIUM_NOT_PRESENT	0x3a
107 
108 #define SCSI_SK_NO_SENSE        0x0
109 #define SCSI_SK_REC_ERR         0x1     /* recovered error */
110 #define SCSI_SK_NOT_READY       0x2
111 #define SCSI_SK_MED_ERR         0x3     /* medium error */
112 #define SCSI_SK_HW_ERR          0x4     /* hardware error */
113 #define SCSI_SK_ILLEGAL_REQ     0x5
114 #define SCSI_SK_UNIT_ATT        0x6     /* unit attention */
115 #define SCSI_SK_DATA_PROTECT    0x7
116 #define SCSI_SK_BLANK_CHECK     0x8
117 #define SCSI_SK_VENDOR_SPEC     0x9
118 #define SCSI_SK_COPY_ABORTED    0xA
119 #define SCSI_SK_ABORTED_CMND    0xB
120 #define SCSI_SK_VOL_OVERFLOW    0xD
121 #define SCSI_SK_MISCOMPARE      0xE
122 
123 #define SCSI_STATUS_GOOD                   0x00
124 #define SCSI_STATUS_CHECK_CONDITION        0x02
125 #define SCSI_STATUS_CONDITION_MET          0x04
126 #define SCSI_STATUS_BUSY                   0x08
127 #define SCSI_STATUS_INTERMEDIATE           0x10
128 #define SCSI_STATUS_ICM                    0x14 /* intermediate condition met */
129 #define SCSI_STATUS_RESERVATION_CONFLICT   0x18
130 #define SCSI_STATUS_COMMAND_TERMINATED     0x22
131 #define SCSI_STATUS_QUEUE_FULL             0x28
132 #define SCSI_STATUS_ACA_ACTIVE             0x30
133 
134 #define SCSI_MEMORY_FUNCTIONS(x, y, z) \
135 static void REGPARAM2 x ## _bput(uaecptr addr, uae_u32 b) \
136 { \
137 	y ## _bput(&z, addr, b); \
138 } \
139 static void REGPARAM2 x ## _wput(uaecptr addr, uae_u32 b) \
140 { \
141 	y ## _wput(&z, addr, b); \
142 } \
143 static void REGPARAM2 x ## _lput(uaecptr addr, uae_u32 b) \
144 { \
145 	y ## _lput(&z, addr, b); \
146 } \
147 static uae_u32 REGPARAM2 x ## _bget(uaecptr addr) \
148 { \
149 return y ## _bget(&z, addr); \
150 } \
151 static uae_u32 REGPARAM2 x ## _wget(uaecptr addr) \
152 { \
153 return y ## _wget(&z, addr); \
154 } \
155 static uae_u32 REGPARAM2 x ## _lget(uaecptr addr) \
156 { \
157 return y ## _lget(&z, addr); \
158 }
159 
160 void soft_scsi_put(uaecptr addr, int size, uae_u32 v);
161 uae_u32 soft_scsi_get(uaecptr addr, int size);
162 
163 void ncr80_rethink(void);
164 
165 void apollo_scsi_bput(uaecptr addr, uae_u8 v);
166 uae_u8 apollo_scsi_bget(uaecptr addr);
167 void apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
168 
169 void soft_scsi_free(void);
170 void soft_scsi_reset(void);
171 
172 uae_u8 parallel_port_scsi_read(int reg, uae_u8 data, uae_u8 dir);
173 void parallel_port_scsi_write(int reg, uae_u8 v, uae_u8 dir);
174 extern bool parallel_port_scsi;
175 
176 addrbank *supra_init(struct romconfig*);
177 void supra_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
178 
179 addrbank *golem_init(struct romconfig*);
180 void golem_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
181 
182 addrbank *stardrive_init(struct romconfig*);
183 void stardrive_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
184 
185 addrbank *kommos_init(struct romconfig*);
186 void kommos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
187 
188 addrbank *vector_init(struct romconfig*);
189 void vector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
190 
191 addrbank *protar_init(struct romconfig *rc);
192 void protar_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
193 
194 addrbank *add500_init(struct romconfig *rc);
195 void add500_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
196 
197 addrbank *kronos_init(struct romconfig *rc);
198 void kronos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
199 
200 addrbank *adscsi_init(struct romconfig *rc);
201 void adscsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
202 
203 void rochard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
204 bool rochard_scsi_init(struct romconfig *rc, uaecptr baseaddress);
205 uae_u8 rochard_scsi_get(uaecptr addr);
206 void rochard_scsi_put(uaecptr addr, uae_u8 v);
207 
208 addrbank *cltda1000scsi_init(struct romconfig *rc);
209 void cltda1000scsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
210 
211 addrbank *ptnexus_init(struct romconfig *rc);
212 void ptnexus_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
213 
214 addrbank *dataflyer_init(struct romconfig *rc);
215 void dataflyer_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
216 
217 addrbank *tecmar_init(struct romconfig *rc);
218 void tecmar_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
219 
220 addrbank *xebec_init(struct romconfig *rc);
221 void xebec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
222 
223 addrbank *microforge_init(struct romconfig *rc);
224 void microforge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
225 
226 addrbank *paradox_init(struct romconfig *rc);
227 void paradox_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
228 
229 addrbank *hda506_init(struct romconfig *rc);
230 void hda506_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
231 
232 addrbank *alf1_init(struct romconfig *rc);
233 void alf1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
234 
235 addrbank *promigos_init(struct romconfig *rc);
236 void promigos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
237 
238 addrbank *system2000_init(struct romconfig *rc);
239 void system2000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
240 
241 addrbank *omtiadapter_init(struct romconfig *rc);
242 void omtiadapter_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
243 
244 addrbank *phoenixboard_init(struct romconfig *rc);
245 void phoenixboard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
246 
247 void x86_xt_hd_bput(int, uae_u8);
248 uae_u8 x86_xt_hd_bget(int);
249 addrbank *x86_xt_hd_init(struct romconfig *rc);
250 void x86_add_xt_hd_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
251 
252 #endif /* UAE_SCSI_H */
253