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