xref: /netbsd-src/sys/dev/scsipi/scsipiconf.h (revision 5e4c038a45edbc7d63b7c2daa76e29f88b64a4e3)
1 /*	$NetBSD: scsipiconf.h,v 1.69 2002/05/16 02:54:21 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Charles M. Hannum; by Jason R. Thorpe of the Numerical Aerospace
9  * Simulation Facility, NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *        This product includes software developed by the NetBSD
22  *        Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Originally written by Julian Elischer (julian@tfs.com)
42  * for TRW Financial Systems for use under the MACH(2.5) operating system.
43  *
44  * TRW Financial Systems, in accordance with their agreement with Carnegie
45  * Mellon University, makes this software available to CMU to distribute
46  * or use in any manner that they see fit as long as this message is kept with
47  * the software. For this reason TFS also grants any other persons or
48  * organisations permission to use or modify this software.
49  *
50  * TFS supplies this software to be publicly redistributed
51  * on the understanding that TFS is not responsible for the correct
52  * functioning of this software in any circumstances.
53  *
54  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
55  */
56 
57 #ifndef _DEV_SCSIPI_SCSIPICONF_H_
58 #define _DEV_SCSIPI_SCSIPICONF_H_
59 
60 typedef	int	boolean;
61 
62 #include <sys/callout.h>
63 #include <sys/queue.h>
64 #include <dev/scsipi/scsipi_debug.h>
65 
66 struct buf;
67 struct proc;
68 struct device;
69 struct scsipi_channel;
70 struct scsipi_periph;
71 struct scsipi_xfer;
72 
73 /*
74  * The following defines the scsipi_xfer queue.
75  */
76 TAILQ_HEAD(scsipi_xfer_queue, scsipi_xfer);
77 
78 struct scsipi_generic {
79 	u_int8_t opcode;
80 	u_int8_t bytes[15];
81 };
82 
83 
84 /*
85  * scsipi_async_event_t:
86  *
87  *	Asynchronous events from the adapter to the mid-layer and
88  *	peripherial.
89  *
90  *	Arguments:
91  *
92  *	ASYNC_EVENT_MAX_OPENINGS	scsipi_max_openings * -- max
93  *					openings, device specified in
94  *					parameters
95  *
96  *	ASYNC_EVENT_XFER_MODE		scsipi_xfer_mode * -- xfer mode
97  *					parameters changed for I_T Nexus
98  *	ASYNC_EVENT_RESET		NULL - channel has been reset
99  */
100 typedef enum {
101 	ASYNC_EVENT_MAX_OPENINGS,	/* set max openings on periph */
102 	ASYNC_EVENT_XFER_MODE,		/* xfer mode update for I_T */
103 	ASYNC_EVENT_RESET		/* channel reset */
104 } scsipi_async_event_t;
105 
106 /*
107  * scsipi_max_openings:
108  *
109  *	Argument for an ASYNC_EVENT_MAX_OPENINGS event.
110  */
111 struct scsipi_max_openings {
112 	int	mo_target;		/* openings are for this target... */
113 	int	mo_lun;			/* ...and this lun */
114 	int	mo_openings;		/* openings value */
115 };
116 
117 /*
118  * scsipi_xfer_mode:
119  *
120  *	Argument for an ASYNC_EVENT_XFER_MODE event.
121  */
122 struct scsipi_xfer_mode {
123 	int	xm_target;		/* target, for I_T Nexus */
124 	int	xm_mode;		/* PERIPH_CAP* bits */
125 	int	xm_period;		/* sync period */
126 	int	xm_offset;		/* sync offset */
127 };
128 
129 
130 /*
131  * scsipi_adapter_req_t:
132  *
133  *	Requests that can be made of an adapter.
134  *
135  *	Arguments:
136  *
137  *	ADAPTER_REQ_RUN_XFER		scsipi_xfer * -- the xfer which
138  *					is to be run
139  *
140  *	ADAPTER_REQ_GROW_RESOURCES	no argument
141  *
142  *	ADAPTER_REQ_SET_XFER_MODE	scsipi_xfer_mode * -- set the xfer
143  *					mode for the I_T Nexus according to
144  *					this
145  */
146 typedef enum {
147 	ADAPTER_REQ_RUN_XFER,		/* run a scsipi_xfer */
148 	ADAPTER_REQ_GROW_RESOURCES,	/* grow xfer execution resources */
149 	ADAPTER_REQ_SET_XFER_MODE	/* set xfer mode */
150 } scsipi_adapter_req_t;
151 
152 
153 /*
154  * scsipi_periphsw:
155  *
156  *	Callbacks into periph driver from midlayer.
157  *
158  *	psw_error	Called by the bustype's interpret-sense routine
159  *			to do periph-specific sense handling.
160  *
161  *	psw_start	Called by midlayer to restart a device once
162  *			more command openings become available.
163  *
164  *	psw_async	Called by midlayer when an asynchronous event
165  *			from the adapter occurs.
166  *
167  *	psw_done	Called by the midlayer when an xfer has completed.
168  */
169 struct scsipi_periphsw {
170 	int	(*psw_error) __P((struct scsipi_xfer *));
171 	void	(*psw_start) __P((struct scsipi_periph *));
172 	int	(*psw_async) __P((struct scsipi_periph *,
173 		    scsipi_async_event_t, void *));
174 	void	(*psw_done) __P((struct scsipi_xfer *));
175 };
176 
177 struct disk_parms;
178 struct scsipi_inquiry_pattern;
179 
180 /*
181  * scsipi_adapter:
182  *
183  *	This structure describes an instance of a SCSIPI adapter.
184  *
185  *	Note that `adapt_openings' is used by (the common case of) adapters
186  *	which have per-adapter resources.  If an adapter's command resources
187  *	are associated with a channel, the the 	`chan_openings' below will
188  *	be used instead.
189  *
190  *	Note that all adapter entry points take a pointer to a channel,
191  *	as an adapter may have more than one channel, and the channel
192  *	structure contains the channel number.
193  */
194 struct scsipi_adapter {
195 	struct device *adapt_dev;	/* pointer to adapter's device */
196 	int	adapt_nchannels;	/* numnber of adapter channels */
197 	int	adapt_refcnt;		/* adapter's reference count */
198 	int	adapt_openings;		/* total # of command openings */
199 	int	adapt_max_periph;	/* max openings per periph */
200 	int	adapt_flags;
201 
202 	void	(*adapt_request) __P((struct scsipi_channel *,
203 		    scsipi_adapter_req_t, void *));
204 	void	(*adapt_minphys) __P((struct buf *));
205 	int	(*adapt_ioctl) __P((struct scsipi_channel *, u_long,
206 		    caddr_t, int, struct proc *));
207 	int	(*adapt_enable) __P((struct device *, int));
208 	int	(*adapt_getgeom) __P((struct scsipi_periph *,
209 			struct disk_parms *, u_long));
210 	int	(*adapt_accesschk) __P((struct scsipi_periph *,
211 			struct scsipi_inquiry_pattern *));
212 };
213 
214 /* adapt_flags */
215 #define SCSIPI_ADAPT_POLL_ONLY	0x01 /* Adaptor can't do interrupts. */
216 
217 #define	scsipi_adapter_minphys(chan, bp)				\
218 	(*(chan)->chan_adapter->adapt_minphys)((bp))
219 
220 #define	scsipi_adapter_request(chan, req, arg)				\
221 	(*(chan)->chan_adapter->adapt_request)((chan), (req), (arg))
222 
223 #define	scsipi_adapter_ioctl(chan, cmd, data, flag, p)			\
224 	(*(chan)->chan_adapter->adapt_ioctl)((chan), (cmd), (data), (flag), (p))
225 
226 #define	scsipi_adapter_enable(chan, enable)				\
227 	(*(chan)->chan_adapt->adapt_enable)((chan), (enable))
228 
229 
230 /*
231  * scsipi_bustype:
232  *
233  *	This structure describes a SCSIPI bus type.
234  *	The bustype_type member is shared with struct ata_bustype
235  *	(because we can ata, atapi or scsi busses to the same controller)
236  */
237 struct scsipi_bustype {
238 	int	bustype_type;		/* symbolic name of type */
239 
240 	int	(*bustype_cmd) __P((struct scsipi_periph *,
241 		    struct scsipi_generic *, int, void *, size_t, int,
242 		    int, struct buf *, int));
243 	int	(*bustype_interpret_sense) __P((struct scsipi_xfer *));
244 	void	(*bustype_printaddr) __P((struct scsipi_periph *));
245 	void	(*bustype_kill_pending) __P((struct scsipi_periph *));
246 };
247 
248 /* bustype_type */
249 #define	SCSIPI_BUSTYPE_SCSI	0
250 #define	SCSIPI_BUSTYPE_ATAPI	1
251 /* #define SCSIPI_BUSTYPE_ATA	2 */
252 
253 
254 /*
255  * scsipi_channel:
256  *
257  *	This structure describes a single channel of a SCSIPI adapter.
258  *	An adapter may have one or more channels.  See the comment above
259  *	regarding the resource counter.
260  *	Note: chan_bustype has to be first member, as its bustype_type member
261  * 	is shared with the aa_bustype member of struct ata_atapi_attach.
262  */
263 
264 #define	SCSIPI_CHAN_PERIPH_BUCKETS	16
265 #define	SCSIPI_CHAN_PERIPH_HASHMASK	(SCSIPI_CHAN_PERIPH_BUCKETS - 1)
266 
267 struct scsipi_channel {
268 	const struct scsipi_bustype *chan_bustype; /* channel's bus type */
269 	const char *chan_name;	/* this channel's name */
270 
271 	struct scsipi_adapter *chan_adapter; /* pointer to our adapter */
272 
273 	/* Periphs for this channel. */
274 	LIST_HEAD(, scsipi_periph) chan_periphtab[SCSIPI_CHAN_PERIPH_BUCKETS];
275 
276 	int	chan_channel;		/* channel number */
277 	int	chan_flags;		/* channel flags */
278 	int	chan_openings;		/* number of command openings */
279 	int	chan_max_periph;	/* max openings per periph */
280 
281 	int	chan_ntargets;		/* number of targets */
282 	int	chan_nluns;		/* number of luns */
283 	int	chan_id;		/* adapter's ID for this channel */
284 
285 	int	chan_defquirks;		/* default device's quirks */
286 
287 	struct proc *chan_thread;	/* completion thread */
288 	int	chan_tflags;		/* flags for the completion thread */
289 
290 	int	chan_qfreeze;		/* freeze count for queue */
291 
292 	/* Job queue for this channel. */
293 	struct scsipi_xfer_queue chan_queue;
294 
295 	/* Completed (async) jobs. */
296 	struct scsipi_xfer_queue chan_complete;
297 
298 	/* callback we may have to call from completion thread */
299 	void (*chan_callback) __P((struct scsipi_channel *, void *));
300 	void *chan_callback_arg;
301 };
302 
303 /* chan_flags */
304 #define	SCSIPI_CHAN_OPENINGS	0x01	/* use chan_openings */
305 #define	SCSIPI_CHAN_CANGROW	0x02	/* channel can grow resources */
306 #define	SCSIPI_CHAN_NOSETTLE	0x04	/* don't wait for devices to settle */
307 #define	SCSIPI_CHAN_TACTIVE	0x08	/* completion thread is active */
308 
309 /* chan thread flags (chan_tflags) */
310 #define	SCSIPI_CHANT_SHUTDOWN	0x01	/* channel is shutting down */
311 #define	SCSIPI_CHANT_CALLBACK	0x02	/* has to call chan_callback() */
312 #define	SCSIPI_CHANT_KICK	0x04	/* need to run queues */
313 #define	SCSIPI_CHANT_GROWRES	0x08	/* call ADAPTER_REQ_GROW_RESOURCES */
314 
315 #define	SCSIPI_CHAN_MAX_PERIPH(chan)					\
316 	(((chan)->chan_flags & SCSIPI_CHAN_OPENINGS) ?			\
317 	 (chan)->chan_max_periph : (chan)->chan_adapter->adapt_max_periph)
318 
319 
320 #define	scsipi_printaddr(periph)					\
321 	(*(periph)->periph_channel->chan_bustype->bustype_printaddr)((periph))
322 
323 #define	scsipi_periph_bustype(periph)					\
324 	(periph)->periph_channel->chan_bustype->bustype_type
325 
326 
327 /*
328  * Number of tag words in a periph structure:
329  *
330  *	n_tag_words = ((256 / NBBY) / sizeof(u_int32_t))
331  */
332 #define	PERIPH_NTAGWORDS	((256 / 8) / sizeof(u_int32_t))
333 
334 
335 /*
336  * scsipi_periph:
337  *
338  *	This structure describes the path between a peripherial device
339  *	and an adapter.  It contains a pointer to the adapter channel
340  *	which in turn contains a pointer to the adapter.
341  *
342  * XXX Given the way NetBSD's autoconfiguration works, this is ...
343  * XXX nasty.
344  *
345  *	Well, it's a lot nicer than it used to be, but there could
346  *	still be an improvement.
347  */
348 struct scsipi_periph {
349 	struct device *periph_dev;	/* pointer to peripherial's device */
350 	struct scsipi_channel *periph_channel; /* channel we're connected to */
351 
352 					/* link in channel's table of periphs */
353 	LIST_ENTRY(scsipi_periph) periph_hash;
354 
355 	const struct scsipi_periphsw *periph_switch; /* peripherial's entry
356 							points */
357 	int	periph_openings;	/* max # of outstanding commands */
358 	int	periph_active;		/* current # of outstanding commands */
359 	int	periph_sent;		/* current # of commands sent to adapt*/
360 
361 	int	periph_mode;		/* operation modes, CAP bits */
362 	int	periph_period;		/* sync period (factor) */
363 	int	periph_offset;		/* sync offset */
364 
365 	/*
366 	 * Information gleaned from the inquiry data.
367 	 */
368 	u_int8_t periph_type;		/* basic device type */
369 	int	periph_cap;		/* capabilities */
370 	int	periph_quirks;		/* device's quirks */
371 
372 	int	periph_flags;		/* misc. flags */
373 	int	periph_dbflags;		/* debugging flags */
374 
375 	int	periph_target;		/* target ID (drive # on ATAPI) */
376 	int	periph_lun;		/* LUN (not used on ATAPI) */
377 
378 	int	periph_version;		/* ANSI SCSI version */
379 
380 	int	periph_qfreeze;		/* queue freeze count */
381 
382 	/* Bitmap of free command tags. */
383 	u_int32_t periph_freetags[PERIPH_NTAGWORDS];
384 
385 	/* Pending scsipi_xfers on this peripherial. */
386 	struct scsipi_xfer_queue periph_xferq;
387 
388 	struct callout periph_callout;
389 
390 	/* xfer which has a pending CHECK_CONDITION */
391 	struct scsipi_xfer *periph_xscheck;
392 
393 };
394 
395 /*
396  * Macro to return the current xfer mode of a periph.
397  */
398 #define	PERIPH_XFER_MODE(periph)					\
399 	(((periph)->periph_flags & PERIPH_MODE_VALID) ?			\
400 	 (periph)->periph_mode : 0)
401 
402 /* periph_cap */
403 #define	PERIPH_CAP_ANEC		0x0001	/* async event notification */
404 #define	PERIPH_CAP_TERMIOP	0x0002	/* terminate i/o proc. messages */
405 #define	PERIPH_CAP_RELADR	0x0004	/* relative addressing */
406 #define	PERIPH_CAP_WIDE32	0x0008	/* wide-32 transfers */
407 #define	PERIPH_CAP_WIDE16	0x0010	/* wide-16 transfers */
408 		/*	XXX	0x0020	   reserved for ATAPI_CFG_DRQ_MASK */
409 		/*	XXX	0x0040	   reserved for ATAPI_CFG_DRQ_MASK */
410 #define	PERIPH_CAP_SYNC		0x0080	/* synchronous transfers */
411 #define	PERIPH_CAP_LINKCMDS	0x0100	/* linked commands */
412 #define	PERIPH_CAP_TQING	0x0200	/* tagged queueing */
413 #define	PERIPH_CAP_SFTRESET	0x0400	/* soft RESET condition response */
414 #define	PERIPH_CAP_CMD16	0x0800	/* 16 byte commands (ATAPI) */
415 #define	PERIPH_CAP_DT		0x1000	/* supports DT clock */
416 #define	PERIPH_CAP_QAS		0x2000	/* supports quick arbit. and select. */
417 #define	PERIPH_CAP_IUS		0x4000	/* supports information unit xfers */
418 
419 /* periph_flags */
420 #define	PERIPH_REMOVABLE	0x0001	/* media is removable */
421 #define	PERIPH_MEDIA_LOADED	0x0002	/* media is loaded */
422 #define	PERIPH_WAITING		0x0004	/* process waiting for opening */
423 #define	PERIPH_OPEN		0x0008	/* device is open */
424 #define	PERIPH_WAITDRAIN	0x0010	/* waiting for pending xfers to drain */
425 #define	PERIPH_GROW_OPENINGS	0x0020	/* allow openings to grow */
426 #define	PERIPH_MODE_VALID	0x0040	/* periph_mode is valid */
427 #define	PERIPH_RECOVERING	0x0080	/* periph is recovering */
428 #define	PERIPH_RECOVERY_ACTIVE	0x0100	/* a recovery command is active */
429 #define PERIPH_KEEP_LABEL	0x0200	/* retain label after 'full' close */
430 #define	PERIPH_SENSE		0x0400	/* periph has sense pending */
431 #define PERIPH_UNTAG		0x0800	/* untagged command running */
432 
433 /* periph_quirks */
434 #define	PQUIRK_AUTOSAVE		0x00000001	/* do implicit SAVE POINTERS */
435 #define	PQUIRK_NOSYNC		0x00000002	/* does not grok SDTR */
436 #define	PQUIRK_NOWIDE		0x00000004	/* does not grok WDTR */
437 #define	PQUIRK_NOTAG		0x00000008	/* does not grok tagged cmds */
438 #define	PQUIRK_NOLUNS		0x00000010	/* DTWT with LUNs */
439 #define	PQUIRK_FORCELUNS	0x00000020	/* prehistoric device groks
440 						   LUNs */
441 #define	PQUIRK_NOMODESENSE	0x00000040	/* device doesn't do MODE SENSE
442 						   properly */
443 #define	PQUIRK_NOSTARTUNIT	0x00000080	/* do not issue START UNIT */
444 #define	PQUIRK_NOSYNCCACHE	0x00000100	/* do not issue SYNC CACHE */
445 #define	PQUIRK_CDROM		0x00000200	/* device is a CD-ROM, no
446 						   matter what else it claims */
447 #define	PQUIRK_LITTLETOC	0x00000400	/* audio TOC is little-endian */
448 #define	PQUIRK_NOCAPACITY	0x00000800	/* no READ CD CAPACITY */
449 #define	PQUIRK_NOTUR		0x00001000	/* no TEST UNIT READY */
450 #define	PQUIRK_NODOORLOCK	0x00002000	/* can't lock door */
451 #define	PQUIRK_NOSENSE		0x00004000	/* can't REQUEST SENSE */
452 #define PQUIRK_ONLYBIG		0x00008000	/* only use SCSI_{R,W}_BIG */
453 #define PQUIRK_BYTE5_ZERO	0x00010000	/* byte5 in capacity is wrong */
454 #define PQUIRK_NO_FLEX_PAGE	0x00020000	/* does not support flex geom
455 						   page */
456 #define PQUIRK_NOBIGMODESENSE	0x00040000	/* has no big mode-sense op */
457 #define PQUIRK_CAP_SYNC		0x00080000	/* SCSI device with ST sync op*/
458 #define PQUIRK_CAP_WIDE16	0x00100000	/* SCSI device with ST wide op*/
459 
460 
461 /*
462  * Error values an adapter driver may return
463  */
464 typedef enum {
465 	XS_NOERROR,		/* there is no error, (sense is invalid)  */
466 	XS_SENSE,		/* Check the returned sense for the error */
467 	XS_SHORTSENSE,		/* Check the ATAPI sense for the error	  */
468 	XS_DRIVER_STUFFUP,	/* Driver failed to perform operation     */
469 	XS_RESOURCE_SHORTAGE,	/* adapter resource shortage		  */
470 	XS_SELTIMEOUT,		/* The device timed out.. turned off?     */
471 	XS_TIMEOUT,		/* The Timeout reported was caught by SW  */
472 	XS_BUSY,		/* The device busy, try again later?      */
473 	XS_RESET,		/* bus was reset; possible retry command  */
474 	XS_REQUEUE		/* requeue this command */
475 } scsipi_xfer_result_t;
476 
477 /*
478  * Each scsipi transaction is fully described by one of these structures
479  * It includes information about the source of the command and also the
480  * device and adapter for which the command is destined.
481  *
482  * Before the HBA is given this transaction, channel_q is the linkage on
483  * the related channel's chan_queue.
484  *
485  * When the this transaction is taken off the channel's chan_queue and
486  * the HBA's request entry point is called with this transaction, the
487  * HBA can use the channel_q tag for whatever it likes until it calls
488  * scsipi_done for this transaction, at which time it has to stop
489  * using channel_q.
490  *
491  * After scsipi_done is called with this transaction and if there was an
492  * error on it, channel_q then becomes the linkage on the related channel's
493  * chan_complete cqueue.
494  *
495  * The device_q member is maintained by the scsipi middle layer.  When
496  * a device issues a command, the xfer is placed on that device's
497  * pending commands queue.  When an xfer is done and freed, it is taken
498  * off the device's queue.  This allows for a device to wait for all of
499  * its pending commands to complete.
500  */
501 struct scsipi_xfer {
502 	TAILQ_ENTRY(scsipi_xfer) channel_q; /* entry on channel queue */
503 	TAILQ_ENTRY(scsipi_xfer) device_q;  /* device's pending xfers */
504 	struct callout xs_callout;	/* callout for adapter use */
505 	int	xs_control;		/* control flags */
506 	__volatile int xs_status;	/* status flags */
507 	struct scsipi_periph *xs_periph;/* peripherial doing the xfer */
508 	int	xs_retries;		/* the number of times to retry */
509 	int	xs_requeuecnt;		/* number of requeues */
510 	int	timeout;		/* in milliseconds */
511 	struct	scsipi_generic *cmd;	/* The scsipi command to execute */
512 	int	cmdlen;			/* how long it is */
513 	u_char	*data;			/* dma address OR a uio address */
514 	int	datalen;		/* data len (blank if uio) */
515 	int	resid;			/* how much buffer was not touched */
516 	scsipi_xfer_result_t error;	/* an error value */
517 	struct	buf *bp;		/* If we need to associate with */
518 					/* a buf */
519 	union {
520 		struct  scsipi_sense_data scsi_sense; /* 32 bytes */
521 		u_int32_t atapi_sense;
522 	} sense;
523 
524 	struct scsipi_xfer *xs_sensefor;/* we are requesting sense for this */
525 					/* xfer */
526 
527 	u_int8_t status;		/* SCSI status */
528 
529 	/*
530 	 * Info for tagged command queueing.  This may or may not
531 	 * be used by a given adapter driver.  These are the same
532 	 * as the bytes in the tag message.
533 	 */
534 	u_int8_t xs_tag_type;		/* tag type */
535 	u_int8_t xs_tag_id;		/* tag ID */
536 
537 	struct	scsipi_generic cmdstore
538 	    __attribute__ ((aligned (4)));/* stash the command in here */
539 };
540 
541 /*
542  * scsipi_xfer control flags
543  *
544  * To do:
545  *
546  *	- figure out what to do with XS_CTL_ESCAPE
547  *
548  *	- replace XS_CTL_URGENT with an `xs_priority' field?
549  */
550 #define	XS_CTL_NOSLEEP		0x00000001	/* don't sleep */
551 #define	XS_CTL_POLL		0x00000002	/* poll for completion */
552 #define	XS_CTL_DISCOVERY	0x00000004	/* doing device discovery */
553 #define	XS_CTL_ASYNC		0x00000008	/* command completes
554 						   asynchronously */
555 #define	XS_CTL_USERCMD		0x00000010	/* user issued command */
556 #define	XS_CTL_SILENT		0x00000020	/* don't print sense info */
557 #define	XS_CTL_IGNORE_NOT_READY	0x00000040	/* ignore NOT READY */
558 #define	XS_CTL_IGNORE_MEDIA_CHANGE 					\
559 				0x00000080	/* ignore media change */
560 #define	XS_CTL_IGNORE_ILLEGAL_REQUEST					\
561 				0x00000100	/* ignore ILLEGAL REQUEST */
562 #define	XS_CTL_SILENT_NODEV	0x00000200	/* don't print sense info
563 						   if sense info is nodev */
564 #define	XS_CTL_RESET		0x00000400	/* reset the device */
565 #define	XS_CTL_DATA_UIO		0x00000800	/* xs_data points to uio */
566 #define	XS_CTL_DATA_IN		0x00001000	/* data coming into memory */
567 #define	XS_CTL_DATA_OUT		0x00002000	/* data going out of memory */
568 #define	XS_CTL_TARGET		0x00004000	/* target mode operation */
569 #define	XS_CTL_ESCAPE		0x00008000	/* escape operation */
570 #define	XS_CTL_URGENT		0x00010000	/* urgent (recovery)
571 						   operation */
572 #define	XS_CTL_SIMPLE_TAG	0x00020000	/* use a Simple Tag */
573 #define	XS_CTL_ORDERED_TAG	0x00040000	/* use an Ordered Tag */
574 #define	XS_CTL_HEAD_TAG		0x00080000	/* use a Head of Queue Tag */
575 #define	XS_CTL_THAW_PERIPH	0x00100000	/* thaw periph once enqueued */
576 #define	XS_CTL_FREEZE_PERIPH	0x00200000	/* freeze periph when done */
577 #define XS_CTL_DATA_ONSTACK	0x00400000	/* data is alloc'ed on stack */
578 #define XS_CTL_REQSENSE		0x00800000	/* xfer is a request sense */
579 
580 #define	XS_CTL_TAGMASK	(XS_CTL_SIMPLE_TAG|XS_CTL_ORDERED_TAG|XS_CTL_HEAD_TAG)
581 
582 #define	XS_CTL_TAGTYPE(xs)	((xs)->xs_control & XS_CTL_TAGMASK)
583 
584 /*
585  * scsipi_xfer status flags
586  */
587 #define	XS_STS_DONE		0x00000001	/* scsipi_xfer is done */
588 #define	XS_STS_PRIVATE		0xf0000000	/* reserved for HBA's use */
589 
590 /*
591  * This describes matching information for scsipi_inqmatch().  The more things
592  * match, the higher the configuration priority.
593  */
594 struct scsipi_inquiry_pattern {
595 	u_int8_t type;
596 	boolean removable;
597 	char *vendor;
598 	char *product;
599 	char *revision;
600 };
601 
602 /*
603  * This is used to pass information from the high-level configuration code
604  * to the device-specific drivers.
605  */
606 struct scsipibus_attach_args {
607 	struct scsipi_periph *sa_periph;
608 	struct scsipi_inquiry_pattern sa_inqbuf;
609 	struct scsipi_inquiry_data *sa_inqptr;
610 	union {				/* bus-type specific infos */
611 		u_int8_t scsi_version;	/* SCSI version */
612 	} scsipi_info;
613 };
614 
615 /*
616  * this describes a quirk entry
617  */
618 struct scsi_quirk_inquiry_pattern {
619 	struct scsipi_inquiry_pattern pattern;
620 	int quirks;
621 };
622 
623 /*
624  * Default number of retries, used for generic routines.
625  */
626 #define SCSIPIRETRIES 4
627 
628 
629 #ifdef _KERNEL
630 void	scsipi_init __P((void));
631 int	scsipi_command __P((struct scsipi_periph *,
632 	    struct scsipi_generic *, int, u_char *, int,
633 	    int, int, struct buf *, int));
634 void	scsipi_create_completion_thread __P((void *));
635 caddr_t	scsipi_inqmatch __P((struct scsipi_inquiry_pattern *, caddr_t,
636 	    int, int, int *));
637 char	*scsipi_dtype __P((int));
638 void	scsipi_strvis __P((u_char *, int, u_char *, int));
639 int	scsipi_execute_xs __P((struct scsipi_xfer *));
640 u_long	scsipi_size __P((struct scsipi_periph *, int));
641 int	scsipi_test_unit_ready __P((struct scsipi_periph *, int));
642 int	scsipi_prevent __P((struct scsipi_periph *, int, int));
643 int	scsipi_inquire __P((struct scsipi_periph *,
644 	    struct scsipi_inquiry_data *, int));
645 int	scsipi_mode_select __P((struct scsipi_periph *, int,
646 	    struct scsipi_mode_header *, int, int, int, int));
647 int	scsipi_mode_select_big __P((struct scsipi_periph *, int,
648 	    struct scsipi_mode_header_big *, int, int, int, int));
649 int	scsipi_mode_sense __P((struct scsipi_periph *, int, int,
650 	    struct scsipi_mode_header *, int, int, int, int));
651 int	scsipi_mode_sense_big __P((struct scsipi_periph *, int, int,
652 	    struct scsipi_mode_header_big *, int, int, int, int));
653 int	scsipi_start __P((struct scsipi_periph *, int, int));
654 void	scsipi_done __P((struct scsipi_xfer *));
655 void	scsipi_user_done __P((struct scsipi_xfer *));
656 int	scsipi_interpret_sense __P((struct scsipi_xfer *));
657 void	scsipi_wait_drain __P((struct scsipi_periph *));
658 void	scsipi_kill_pending __P((struct scsipi_periph *));
659 struct scsipi_periph *scsipi_alloc_periph __P((int));
660 #ifdef SCSIVERBOSE
661 void	scsipi_print_sense __P((struct scsipi_xfer *, int));
662 void	scsipi_print_sense_data __P((struct scsipi_sense_data *, int));
663 char   *scsipi_decode_sense __P((void *, int));
664 #endif
665 int	scsipi_thread_call_callback __P((struct scsipi_channel *,
666 	    void (*callback) __P((struct scsipi_channel *, void *)),
667 	    void *));
668 void	scsipi_async_event __P((struct scsipi_channel *,
669 	    scsipi_async_event_t, void *));
670 int	scsipi_do_ioctl __P((struct scsipi_periph *, dev_t, u_long, caddr_t,
671 	    int, struct proc *));
672 
673 void	scsipi_print_xfer_mode __P((struct scsipi_periph *));
674 void	scsipi_set_xfer_mode __P((struct scsipi_channel *, int, int));
675 
676 int	scsipi_channel_init __P((struct scsipi_channel *));
677 void	scsipi_channel_shutdown __P((struct scsipi_channel *));
678 
679 void	scsipi_insert_periph __P((struct scsipi_channel *,
680 	    struct scsipi_periph *));
681 void	scsipi_remove_periph __P((struct scsipi_channel *,
682 	    struct scsipi_periph *));
683 struct scsipi_periph *scsipi_lookup_periph __P((struct scsipi_channel *,
684 	    int, int));
685 int	scsipi_target_detach __P((struct scsipi_channel *, int, int, int));
686 
687 int	scsipi_adapter_addref __P((struct scsipi_adapter *));
688 void	scsipi_adapter_delref __P((struct scsipi_adapter *));
689 
690 void	scsipi_channel_freeze __P((struct scsipi_channel *, int));
691 void	scsipi_channel_thaw __P((struct scsipi_channel *, int));
692 void	scsipi_channel_timed_thaw __P((void *));
693 
694 void	scsipi_periph_freeze __P((struct scsipi_periph *, int));
695 void	scsipi_periph_thaw __P((struct scsipi_periph *, int));
696 void	scsipi_periph_timed_thaw __P((void *));
697 
698 int	scsipi_sync_period_to_factor __P((int));
699 int	scsipi_sync_factor_to_period __P((int));
700 int	scsipi_sync_factor_to_freq __P((int));
701 
702 void	show_scsipi_xs __P((struct scsipi_xfer *));
703 void	show_scsipi_cmd __P((struct scsipi_xfer *));
704 void	show_mem __P((u_char *, int));
705 #endif /* _KERNEL */
706 
707 static __inline void _lto2b __P((u_int32_t val, u_int8_t *bytes))
708 	__attribute__ ((unused));
709 static __inline void _lto3b __P((u_int32_t val, u_int8_t *bytes))
710 	__attribute__ ((unused));
711 static __inline void _lto4b __P((u_int32_t val, u_int8_t *bytes))
712 	__attribute__ ((unused));
713 static __inline u_int32_t _2btol __P((const u_int8_t *bytes))
714 	__attribute__ ((unused));
715 static __inline u_int32_t _3btol __P((const u_int8_t *bytes))
716 	__attribute__ ((unused));
717 static __inline u_int32_t _4btol __P((const u_int8_t *bytes))
718 	__attribute__ ((unused));
719 
720 static __inline void _lto2l __P((u_int32_t val, u_int8_t *bytes))
721 	__attribute__ ((unused));
722 static __inline void _lto3l __P((u_int32_t val, u_int8_t *bytes))
723 	__attribute__ ((unused));
724 static __inline void _lto4l __P((u_int32_t val, u_int8_t *bytes))
725 	__attribute__ ((unused));
726 static __inline u_int32_t _2ltol __P((const u_int8_t *bytes))
727 	__attribute__ ((unused));
728 static __inline u_int32_t _3ltol __P((const u_int8_t *bytes))
729 	__attribute__ ((unused));
730 static __inline u_int32_t _4ltol __P((const u_int8_t *bytes))
731 	__attribute__ ((unused));
732 
733 static __inline void
734 _lto2b(val, bytes)
735 	u_int32_t val;
736 	u_int8_t *bytes;
737 {
738 
739 	bytes[0] = (val >> 8) & 0xff;
740 	bytes[1] = val & 0xff;
741 }
742 
743 static __inline void
744 _lto3b(val, bytes)
745 	u_int32_t val;
746 	u_int8_t *bytes;
747 {
748 
749 	bytes[0] = (val >> 16) & 0xff;
750 	bytes[1] = (val >> 8) & 0xff;
751 	bytes[2] = val & 0xff;
752 }
753 
754 static __inline void
755 _lto4b(val, bytes)
756 	u_int32_t val;
757 	u_int8_t *bytes;
758 {
759 
760 	bytes[0] = (val >> 24) & 0xff;
761 	bytes[1] = (val >> 16) & 0xff;
762 	bytes[2] = (val >> 8) & 0xff;
763 	bytes[3] = val & 0xff;
764 }
765 
766 static __inline u_int32_t
767 _2btol(bytes)
768 	const u_int8_t *bytes;
769 {
770 	u_int32_t rv;
771 
772 	rv = (bytes[0] << 8) |
773 	     bytes[1];
774 	return (rv);
775 }
776 
777 static __inline u_int32_t
778 _3btol(bytes)
779 	const u_int8_t *bytes;
780 {
781 	u_int32_t rv;
782 
783 	rv = (bytes[0] << 16) |
784 	     (bytes[1] << 8) |
785 	     bytes[2];
786 	return (rv);
787 }
788 
789 static __inline u_int32_t
790 _4btol(bytes)
791 	const u_int8_t *bytes;
792 {
793 	u_int32_t rv;
794 
795 	rv = (bytes[0] << 24) |
796 	     (bytes[1] << 16) |
797 	     (bytes[2] << 8) |
798 	     bytes[3];
799 	return (rv);
800 }
801 
802 static __inline void
803 _lto2l(val, bytes)
804 	u_int32_t val;
805 	u_int8_t *bytes;
806 {
807 
808 	bytes[0] = val & 0xff;
809 	bytes[1] = (val >> 8) & 0xff;
810 }
811 
812 static __inline void
813 _lto3l(val, bytes)
814 	u_int32_t val;
815 	u_int8_t *bytes;
816 {
817 
818 	bytes[0] = val & 0xff;
819 	bytes[1] = (val >> 8) & 0xff;
820 	bytes[2] = (val >> 16) & 0xff;
821 }
822 
823 static __inline void
824 _lto4l(val, bytes)
825 	u_int32_t val;
826 	u_int8_t *bytes;
827 {
828 
829 	bytes[0] = val & 0xff;
830 	bytes[1] = (val >> 8) & 0xff;
831 	bytes[2] = (val >> 16) & 0xff;
832 	bytes[3] = (val >> 24) & 0xff;
833 }
834 
835 static __inline u_int32_t
836 _2ltol(bytes)
837 	const u_int8_t *bytes;
838 {
839 	u_int32_t rv;
840 
841 	rv = bytes[0] |
842 	     (bytes[1] << 8);
843 	return (rv);
844 }
845 
846 static __inline u_int32_t
847 _3ltol(bytes)
848 	const u_int8_t *bytes;
849 {
850 	u_int32_t rv;
851 
852 	rv = bytes[0] |
853 	     (bytes[1] << 8) |
854 	     (bytes[2] << 16);
855 	return (rv);
856 }
857 
858 static __inline u_int32_t
859 _4ltol(bytes)
860 	const u_int8_t *bytes;
861 {
862 	u_int32_t rv;
863 
864 	rv = bytes[0] |
865 	     (bytes[1] << 8) |
866 	     (bytes[2] << 16) |
867 	     (bytes[3] << 24);
868 	return (rv);
869 }
870 
871 #endif /* _DEV_SCSIPI_SCSIPICONF_H_ */
872