xref: /haiku/src/add-ons/kernel/bus_managers/scsi/scsi_internal.h (revision 60b39cd7416028e61e3d30bb3ba28bd3526e6001)
1 /*
2  * Copyright 2002/03, Thomas Kurschel. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _SCSI_INTERNAL_H
6 #define _SCSI_INTERNAL_H
7 
8 //!	Internal structures/definitions
9 
10 #include <sys/cdefs.h>
11 
12 #include <bus/SCSI.h>
13 #include <scsi_cmds.h>
14 #include <locked_pool.h>
15 #include <device_manager.h>
16 
17 #define debug_level_error 4
18 #define debug_level_info 4
19 #define debug_level_flow 4
20 
21 #define DEBUG_MSG_PREFIX "SCSI -- "
22 
23 #include "wrapper.h"
24 #include "scsi_lock.h"
25 
26 
27 #define MAX_PATH_ID 255
28 #define MAX_TARGET_ID 15
29 #define MAX_LUN_ID 7
30 
31 
32 // maximum number of fragments for temporary S/G lists
33 // for real SCSI controllers, there's no limit to transmission length
34 // but we need a limit - ATA transmits up to 128K, so we allow that
35 // (for massive data transmission, peripheral drivers should provide own
36 // SG list anyway)
37 // add one extra entry in case data is not page aligned
38 #define MAX_TEMP_SG_FRAGMENTS (128*1024 / B_PAGE_SIZE + 1)
39 
40 // maximum number of temporary S/G lists
41 #define MAX_TEMP_SG_LISTS 32
42 
43 // delay in µs before DMA buffer is cleaned up
44 #define SCSI_DMA_BUFFER_CLEANUP_DELAY 10*1000000
45 
46 // buffer size for emulated SCSI commands that ATAPI cannot handle;
47 // for MODE SELECT 6, maximum size is 255 + header,
48 // for MODE SENSE 6, we use MODE SENSE 10 which can return 64 K,
49 // but as the caller has to live with the 255 + header restriction,
50 // we hope that this buffer is large enough
51 #define SCSI_ATAPI_BUFFER_SIZE 512
52 
53 
54 // name of pnp generator of path ids
55 #define SCSI_PATHID_GENERATOR "scsi/path_id"
56 // true, if SCSI device needs ATAPI emulation (ui8)
57 #define SCSI_DEVICE_IS_ATAPI_ITEM "scsi/is_atapi"
58 // true, if device requires auto-sense emulation (ui8)
59 #define SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM "scsi/manual_autosense"
60 
61 // name of internal scsi_bus_raw device driver
62 #define SCSI_BUS_RAW_MODULE_NAME "bus_managers/scsi/bus/raw/device_v1"
63 
64 // info about DPC
65 typedef struct scsi_dpc_info {
66 	struct scsi_dpc_info *next;
67 	bool registered;			// true, if already/still in dpc list
68 
69 	void (*func)( void * );
70 	void *arg;
71 } scsi_dpc_info;
72 
73 
74 // controller restrictions (see blkman.h)
75 typedef struct dma_params {
76 	uint32 alignment;
77 	uint32 max_blocks;
78 	uint32 dma_boundary;
79 	uint32 max_sg_block_size;
80 	uint32 max_sg_blocks;
81 } dma_params;
82 
83 
84 // SCSI bus
85 typedef struct scsi_bus_info {
86 	int lock_count;				// sum of blocked[0..1] and sim_overflow
87 	int blocked[2];				// depth of nested locks by bus manager (0) and SIM (1)
88 	int left_slots;				// left command queuing slots on HBA
89 	bool sim_overflow;			// 1, if SIM refused req because of bus queue overflow
90 
91 	uchar path_id;				// SCSI path id
92 	uint32 max_target_count;	// maximum count of target_ids on the bus
93 	uint32 max_lun_count;		// maximum count of lun_ids on the bus
94 
95 	thread_id service_thread;	// service thread
96 	sem_id start_service;		// released whenever service thread has work to do
97 	bool shutting_down;			// set to true to tell service thread to shut down
98 
99 	struct mutex mutex;			// used to synchronize changes in queueing and blocking
100 
101 	sem_id scan_lun_lock;		// allocated whenever a lun is scanned
102 
103 	scsi_sim_interface *interface;	// SIM interface
104 	scsi_sim_cookie sim_cookie;	// internal SIM cookie
105 
106 	spinlock_irq dpc_lock;		// synchronizer for dpc list
107 	scsi_dpc_info *dpc_list;	// list of dpcs to execute
108 
109 	struct scsi_device_info *waiting_devices;	// devices ready to receive requests
110 
111 	locked_pool_cookie ccb_pool;	// ccb pool (one per bus)
112 
113 	device_node *node;		// pnp node of bus
114 
115 	struct dma_params dma_params;	// dma restrictions of controller
116 
117 	scsi_path_inquiry inquiry_data;	// inquiry data as read on init
118 } scsi_bus_info;
119 
120 
121 // DMA buffer
122 typedef struct dma_buffer {
123 	area_id area;			// area of DMA buffer
124 	uchar *address;			// address of DMA buffer
125 	size_t size;			// size of DMA buffer
126 	area_id sg_list_area;	// area of S/G list
127 	physical_entry *sg_list;	// address of S/G list
128 	size_t sg_count;			// number of entries in S/G list
129 	bool inuse;				// true, if in use
130 	bigtime_t last_use;		// timestamp of last usage
131 
132 	area_id sg_orig;					// area of S/G list to original data
133 	physical_entry *sg_list_orig;		// S/G list to original data
134 	size_t sg_count_max_orig;			// maximum size (in entries)
135 	size_t sg_count_orig;				// current size (in entries)
136 
137 	uchar *orig_data;					// pointer to original data
138 	const physical_entry *orig_sg_list;	// original S/G list
139 	size_t orig_sg_count;				// size of original S/G list
140 } dma_buffer;
141 
142 
143 // SCSI device
144 typedef struct scsi_device_info {
145 	struct scsi_device_info *waiting_next;
146 	struct scsi_device_info *waiting_prev;
147 
148 	bool manual_autosense : 1;	// no autosense support
149 	bool is_atapi : 1;			// ATAPI device - needs some commands emulated
150 
151 	int lock_count;				// sum of blocked[0..1] and sim_overflow
152 	int blocked[2];				// depth of nested locks by bus manager (0) and SIM (1)
153 	int sim_overflow;			// 1, if SIM returned a request because of device queue overflow
154 	int left_slots;				// left command queuing slots for device
155 	int total_slots;			// total number of command queuing slots for device
156 
157 	scsi_ccb *queued_reqs;		// queued requests, circularly doubly linked
158 								// (scsi_insert_new_request depends on circular)
159 
160 	int64 last_sort;			// last sort value (for elevator sort)
161 	int32 valid;				// access must be atomic!
162 
163 	scsi_bus_info *bus;
164 	uchar target_id;
165 	uchar target_lun;
166 
167 	scsi_ccb *auto_sense_request;		// auto-sense request
168 	scsi_ccb *auto_sense_originator;	// request that auto-sense is
169 										// currently requested for
170 	area_id auto_sense_area;			// area of auto-sense data and S/G list
171 
172 	uint8 emulation_map[256/8];		// bit field with index being command code:
173 								// 1 indicates that this command is not supported
174 								// and thus must be emulated
175 
176 	scsi_res_inquiry inquiry_data;
177 	device_node *node;	// device node
178 
179 	struct mutex dma_buffer_lock;	// lock between DMA buffer user and clean-up daemon
180 	sem_id dma_buffer_owner;	// to be acquired before using DMA buffer
181 	struct dma_buffer dma_buffer;	// DMA buffer
182 
183 	// buffer used for emulating SCSI commands
184 	char *buffer;
185 	physical_entry *buffer_sg_list;
186 	size_t buffer_sg_count;
187 	size_t buffer_size;
188 	area_id buffer_area;
189 	sem_id buffer_sem;
190 } scsi_device_info;
191 
192 enum {
193 	ev_scsi_requeue_request = 1,
194 	ev_scsi_resubmit_request,
195 	ev_scsi_submit_autosense,
196 	ev_scsi_finish_autosense,
197 	ev_scsi_device_queue_overflow,
198 	ev_scsi_request_finished,
199 	ev_scsi_async_io,
200 	ev_scsi_do_resend_request,
201 	ev_copy_sg_data
202 };
203 
204 // check whether device is in bus's wait queue
205 // we use the fact the queue is circular, so we don't need an explicit flag
206 #define DEVICE_IN_WAIT_QUEUE( device ) ((device)->waiting_next != NULL)
207 
208 
209 // state of ccb
210 enum {
211 	SCSI_STATE_FREE = 0,
212 	SCSI_STATE_INWORK = 1,
213 	SCSI_STATE_QUEUED = 2,
214 	SCSI_STATE_SENT = 3,
215 	SCSI_STATE_FINISHED = 5,
216 };
217 
218 
219 extern locked_pool_interface *locked_pool;
220 extern device_manager_info *pnp;
221 
222 extern scsi_for_sim_interface scsi_for_sim_module;
223 extern scsi_bus_interface scsi_bus_module;
224 extern scsi_device_interface scsi_device_module;
225 extern struct device_module_info gSCSIBusRawModule;
226 
227 
228 __BEGIN_DECLS
229 
230 
231 // busses.c
232 uchar scsi_inquiry_path(scsi_bus bus, scsi_path_inquiry *inquiry_data);
233 
234 
235 // ccb.c
236 scsi_ccb *scsi_alloc_ccb(scsi_device_info *device);
237 void scsi_free_ccb(scsi_ccb *ccb);
238 
239 status_t scsi_init_ccb_alloc(scsi_bus_info *bus);
240 void scsi_uninit_ccb_alloc(scsi_bus_info *bus);
241 
242 
243 // devices.c
244 status_t scsi_force_get_device(scsi_bus_info *bus,
245 	uchar target_id, uchar target_lun, scsi_device_info **res_device);
246 void scsi_put_forced_device(scsi_device_info *device);
247 status_t scsi_register_device(scsi_bus_info *bus, uchar target_id,
248 	uchar target_lun, scsi_res_inquiry *inquiry_data);
249 
250 
251 // device_scan.c
252 status_t scsi_scan_bus(scsi_bus_info *bus);
253 status_t scsi_scan_lun(scsi_bus_info *bus, uchar target_id, uchar target_lun);
254 
255 
256 // dpc.c
257 status_t scsi_alloc_dpc(scsi_dpc_info **dpc);
258 status_t scsi_free_dpc(scsi_dpc_info *dpc);
259 bool scsi_check_exec_dpc(scsi_bus_info *bus);
260 
261 status_t scsi_schedule_dpc(scsi_bus_info *bus, scsi_dpc_info *dpc, /*int flags,*/
262 	void (*func)( void *arg ), void *arg);
263 
264 
265 // scsi_io.c
266 void scsi_async_io(scsi_ccb *request);
267 void scsi_sync_io(scsi_ccb *request);
268 uchar scsi_term_io(scsi_ccb *ccb_to_terminate);
269 uchar scsi_abort(scsi_ccb *ccb_to_abort);
270 
271 bool scsi_check_exec_service(scsi_bus_info *bus);
272 
273 void scsi_done_io(scsi_ccb *ccb);
274 
275 void scsi_requeue_request(scsi_ccb *request, bool bus_overflow);
276 void scsi_resubmit_request(scsi_ccb *request);
277 void scsi_request_finished(scsi_ccb *request, uint num_requests);
278 
279 
280 // scatter_gather.c
281 bool create_temp_sg(scsi_ccb *ccb);
282 void cleanup_tmp_sg(scsi_ccb *ccb);
283 
284 int init_temp_sg(void);
285 void uninit_temp_sg(void);
286 
287 
288 // dma_buffer.c
289 void scsi_dma_buffer_daemon(void *dev, int counter);
290 void scsi_release_dma_buffer(scsi_ccb *request);
291 bool scsi_get_dma_buffer(scsi_ccb *request);
292 void scsi_dma_buffer_free(dma_buffer *buffer);
293 void scsi_dma_buffer_init(dma_buffer *buffer);
294 
295 
296 // queuing.c
297 
298 
299 // emulation.c
300 bool scsi_start_emulation(scsi_ccb *request);
301 void scsi_finish_emulation(scsi_ccb *request);
302 void scsi_free_emulation_buffer(scsi_device_info *device);
303 status_t scsi_init_emulation_buffer(scsi_device_info *device, size_t buffer_size);
304 
305 
306 __END_DECLS
307 
308 
309 #endif	/* _SCSI_INTERNAL_H */
310