1/*	$NetBSD$	*/
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
53typedef	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
60struct buf;
61struct proc;
62struct device;
63struct scsipi_channel;
64struct scsipi_periph;
65struct scsipi_xfer;
66
67/*
68 * The following defines the scsipi_xfer queue.
69 */
70TAILQ_HEAD(scsipi_xfer_queue, scsipi_xfer);
71
72struct 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 */
94typedef 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 */
105struct 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 */
116struct 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 */
140typedef 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 */
163struct 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
171struct disk_parms;
172struct 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 */
188struct 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 */
232struct 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/* type is stored in the first byte */
243#define SCSIPI_BUSTYPE_TYPE_SHIFT 0
244#define SCSIPI_BUSTYPE_TYPE(x) (((x) >> SCSIPI_BUSTYPE_TYPE_SHIFT) & 0xff)
245#define	SCSIPI_BUSTYPE_SCSI	0 /* parallel SCSI */
246#define	SCSIPI_BUSTYPE_ATAPI	1
247/* #define SCSIPI_BUSTYPE_ATA	2 */
248/* subtype is stored in the second byte */
249#define SCSIPI_BUSTYPE_SUBTYPE_SHIFT 8
250#define SCSIPI_BUSTYPE_SUBTYPE(x) (((x) >> SCSIPI_BUSTYPE_SUBTYPE_SHIFT) & 0xff)
251
252#define SCSIPI_BUSTYPE_BUSTYPE(t, s) \
253    ((t) << SCSIPI_BUSTYPE_TYPE_SHIFT | (s) << SCSIPI_BUSTYPE_SUBTYPE_SHIFT)
254/* subtypes are defined in each bus type headers */
255/* XXX this should be in scsiconf.h but is used in scsipi_base.c */
256/* SCSI subtypes */
257#define SCSIPI_BUSTYPE_SCSI_PSCSI       0 /* parallel SCSI */
258#define SCSIPI_BUSTYPE_SCSI_FC          1 /* Fiber channel */
259#define SCSIPI_BUSTYPE_SCSI_SAS         2 /* SAS */
260#define SCSIPI_BUSTYPE_SCSI_USB         3 /* USB */
261
262/*
263 * scsipi_channel:
264 *
265 *	This structure describes a single channel of a SCSIPI adapter.
266 *	An adapter may have one or more channels.  See the comment above
267 *	regarding the resource counter.
268 *	Note: chan_bustype has to be first member, as its bustype_type member
269 * 	is shared with the aa_bustype member of struct ata_atapi_attach.
270 */
271
272#define	SCSIPI_CHAN_PERIPH_BUCKETS	16
273#define	SCSIPI_CHAN_PERIPH_HASHMASK	(SCSIPI_CHAN_PERIPH_BUCKETS - 1)
274
275#ifdef _KERNEL
276struct scsipi_channel {
277	const struct scsipi_bustype *chan_bustype; /* channel's bus type */
278	const char *chan_name;	/* this channel's name */
279
280	struct scsipi_adapter *chan_adapter; /* pointer to our adapter */
281
282	/* Periphs for this channel. */
283	LIST_HEAD(, scsipi_periph) chan_periphtab[SCSIPI_CHAN_PERIPH_BUCKETS];
284
285	int	chan_channel;		/* channel number */
286	int	chan_flags;		/* channel flags */
287	int	chan_openings;		/* number of command openings */
288	int	chan_max_periph;	/* max openings per periph */
289
290	int	chan_ntargets;		/* number of targets */
291	int	chan_nluns;		/* number of luns */
292	int	chan_id;		/* adapter's ID for this channel */
293
294	int	chan_defquirks;		/* default device's quirks */
295
296	struct lwp *chan_thread;	/* completion thread */
297	int	chan_tflags;		/* flags for the completion thread */
298
299	int	chan_qfreeze;		/* freeze count for queue */
300
301	/* Job queue for this channel. */
302	struct scsipi_xfer_queue chan_queue;
303
304	/* Completed (async) jobs. */
305	struct scsipi_xfer_queue chan_complete;
306
307	/* callback we may have to call from completion thread */
308	void (*chan_callback)(struct scsipi_channel *, void *);
309	void *chan_callback_arg;
310
311	/* callback we may have to call after forking the kthread */
312	void (*chan_init_cb)(struct scsipi_channel *, void *);
313	void *chan_init_cb_arg;
314};
315#endif
316
317/* chan_flags */
318#define	SCSIPI_CHAN_OPENINGS	0x01	/* use chan_openings */
319#define	SCSIPI_CHAN_CANGROW	0x02	/* channel can grow resources */
320#define	SCSIPI_CHAN_NOSETTLE	0x04	/* don't wait for devices to settle */
321#define	SCSIPI_CHAN_TACTIVE	0x08	/* completion thread is active */
322
323/* chan thread flags (chan_tflags) */
324#define	SCSIPI_CHANT_SHUTDOWN	0x01	/* channel is shutting down */
325#define	SCSIPI_CHANT_CALLBACK	0x02	/* has to call chan_callback() */
326#define	SCSIPI_CHANT_KICK	0x04	/* need to run queues */
327#define	SCSIPI_CHANT_GROWRES	0x08	/* call ADAPTER_REQ_GROW_RESOURCES */
328
329#define	SCSIPI_CHAN_MAX_PERIPH(chan)					\
330	(((chan)->chan_flags & SCSIPI_CHAN_OPENINGS) ?			\
331	 (chan)->chan_max_periph : (chan)->chan_adapter->adapt_max_periph)
332
333
334#define	scsipi_printaddr(periph)					\
335	(*(periph)->periph_channel->chan_bustype->bustype_printaddr)((periph))
336
337#define	scsipi_periph_bustype(periph)					\
338	(periph)->periph_channel->chan_bustype->bustype_type
339
340
341/*
342 * Number of tag words in a periph structure:
343 *
344 *	n_tag_words = ((256 / NBBY) / sizeof(u_int32_t))
345 */
346#define	PERIPH_NTAGWORDS	((256 / 8) / sizeof(u_int32_t))
347
348
349#ifdef _KERNEL
350/*
351 * scsipi_periph:
352 *
353 *	This structure describes the path between a peripherial device
354 *	and an adapter.  It contains a pointer to the adapter channel
355 *	which in turn contains a pointer to the adapter.
356 *
357 * XXX Given the way NetBSD's autoconfiguration works, this is ...
358 * XXX nasty.
359 *
360 *	Well, it's a lot nicer than it used to be, but there could
361 *	still be an improvement.
362 */
363struct scsipi_periph {
364	device_t periph_dev;	/* pointer to peripherial's device */
365	struct scsipi_channel *periph_channel; /* channel we're connected to */
366
367					/* link in channel's table of periphs */
368	LIST_ENTRY(scsipi_periph) periph_hash;
369
370	const struct scsipi_periphsw *periph_switch; /* peripherial's entry
371							points */
372	int	periph_openings;	/* max # of outstanding commands */
373	int	periph_active;		/* current # of outstanding commands */
374	int	periph_sent;		/* current # of commands sent to adapt*/
375
376	int	periph_mode;		/* operation modes, CAP bits */
377	int	periph_period;		/* sync period (factor) */
378	int	periph_offset;		/* sync offset */
379
380	/*
381	 * Information gleaned from the inquiry data.
382	 */
383	u_int8_t periph_type;		/* basic device type */
384	int	periph_cap;		/* capabilities */
385	int	periph_quirks;		/* device's quirks */
386
387	int	periph_flags;		/* misc. flags */
388	int	periph_dbflags;		/* debugging flags */
389
390	int	periph_target;		/* target ID (drive # on ATAPI) */
391	int	periph_lun;		/* LUN (not used on ATAPI) */
392
393	int	periph_version;		/* ANSI SCSI version */
394
395	int	periph_qfreeze;		/* queue freeze count */
396
397	/* Bitmap of free command tags. */
398	u_int32_t periph_freetags[PERIPH_NTAGWORDS];
399
400	/* Pending scsipi_xfers on this peripherial. */
401	struct scsipi_xfer_queue periph_xferq;
402
403	callout_t periph_callout;
404
405	/* xfer which has a pending CHECK_CONDITION */
406	struct scsipi_xfer *periph_xscheck;
407
408};
409#endif
410
411/*
412 * Macro to return the current xfer mode of a periph.
413 */
414#define	PERIPH_XFER_MODE(periph)					\
415	(((periph)->periph_flags & PERIPH_MODE_VALID) ?			\
416	 (periph)->periph_mode : 0)
417
418/* periph_cap */
419#define	PERIPH_CAP_ANEC		0x0001	/* async event notification */
420#define	PERIPH_CAP_TERMIOP	0x0002	/* terminate i/o proc. messages */
421#define	PERIPH_CAP_RELADR	0x0004	/* relative addressing */
422#define	PERIPH_CAP_WIDE32	0x0008	/* wide-32 transfers */
423#define	PERIPH_CAP_WIDE16	0x0010	/* wide-16 transfers */
424		/*	XXX	0x0020	   reserved for ATAPI_CFG_DRQ_MASK */
425		/*	XXX	0x0040	   reserved for ATAPI_CFG_DRQ_MASK */
426#define	PERIPH_CAP_SYNC		0x0080	/* synchronous transfers */
427#define	PERIPH_CAP_LINKCMDS	0x0100	/* linked commands */
428#define	PERIPH_CAP_TQING	0x0200	/* tagged queueing */
429#define	PERIPH_CAP_SFTRESET	0x0400	/* soft RESET condition response */
430#define	PERIPH_CAP_CMD16	0x0800	/* 16 byte commands (ATAPI) */
431#define	PERIPH_CAP_DT		0x1000	/* supports DT clock */
432#define	PERIPH_CAP_QAS		0x2000	/* supports quick arbit. and select. */
433#define	PERIPH_CAP_IUS		0x4000	/* supports information unit xfers */
434
435/* periph_flags */
436#define	PERIPH_REMOVABLE	0x0001	/* media is removable */
437#define	PERIPH_MEDIA_LOADED	0x0002	/* media is loaded */
438#define	PERIPH_WAITING		0x0004	/* process waiting for opening */
439#define	PERIPH_OPEN		0x0008	/* device is open */
440#define	PERIPH_WAITDRAIN	0x0010	/* waiting for pending xfers to drain */
441#define	PERIPH_GROW_OPENINGS	0x0020	/* allow openings to grow */
442#define	PERIPH_MODE_VALID	0x0040	/* periph_mode is valid */
443#define	PERIPH_RECOVERING	0x0080	/* periph is recovering */
444#define	PERIPH_RECOVERY_ACTIVE	0x0100	/* a recovery command is active */
445#define PERIPH_KEEP_LABEL	0x0200	/* retain label after 'full' close */
446#define	PERIPH_SENSE		0x0400	/* periph has sense pending */
447#define PERIPH_UNTAG		0x0800	/* untagged command running */
448
449/* periph_quirks */
450#define	PQUIRK_AUTOSAVE		0x00000001	/* do implicit SAVE POINTERS */
451#define	PQUIRK_NOSYNC		0x00000002	/* does not grok SDTR */
452#define	PQUIRK_NOWIDE		0x00000004	/* does not grok WDTR */
453#define	PQUIRK_NOTAG		0x00000008	/* does not grok tagged cmds */
454#define	PQUIRK_NOLUNS		0x00000010	/* DTWT with LUNs */
455#define	PQUIRK_FORCELUNS	0x00000020	/* prehistoric device groks
456						   LUNs */
457#define	PQUIRK_NOMODESENSE	0x00000040	/* device doesn't do MODE SENSE
458						   properly */
459#define	PQUIRK_NOSYNCCACHE	0x00000100	/* do not issue SYNC CACHE */
460#define	PQUIRK_LITTLETOC	0x00000400	/* audio TOC is little-endian */
461#define	PQUIRK_NOCAPACITY	0x00000800	/* no READ CD CAPACITY */
462#define	PQUIRK_NOTUR		0x00001000	/* no TEST UNIT READY */
463#define	PQUIRK_NODOORLOCK	0x00002000	/* can't lock door */
464#define	PQUIRK_NOSENSE		0x00004000	/* can't REQUEST SENSE */
465#define PQUIRK_ONLYBIG		0x00008000	/* only use SCSI_{R,W}_BIG */
466#define PQUIRK_NOBIGMODESENSE	0x00040000	/* has no big mode-sense op */
467#define PQUIRK_CAP_SYNC		0x00080000	/* SCSI device with ST sync op*/
468#define PQUIRK_CAP_WIDE16	0x00100000	/* SCSI device with ST wide op*/
469#define PQUIRK_CAP_NODT		0x00200000	/* signals DT, but can't. */
470
471
472/*
473 * Error values an adapter driver may return
474 */
475typedef enum {
476	XS_NOERROR,		/* there is no error, (sense is invalid)  */
477	XS_SENSE,		/* Check the returned sense for the error */
478	XS_SHORTSENSE,		/* Check the ATAPI sense for the error	  */
479	XS_DRIVER_STUFFUP,	/* Driver failed to perform operation     */
480	XS_RESOURCE_SHORTAGE,	/* adapter resource shortage		  */
481	XS_SELTIMEOUT,		/* The device timed out.. turned off?     */
482	XS_TIMEOUT,		/* The Timeout reported was caught by SW  */
483	XS_BUSY,		/* The device busy, try again later?      */
484	XS_RESET,		/* bus was reset; possible retry command  */
485	XS_REQUEUE		/* requeue this command */
486} scsipi_xfer_result_t;
487
488/*
489 * Each scsipi transaction is fully described by one of these structures
490 * It includes information about the source of the command and also the
491 * device and adapter for which the command is destined.
492 *
493 * Before the HBA is given this transaction, channel_q is the linkage on
494 * the related channel's chan_queue.
495 *
496 * When the this transaction is taken off the channel's chan_queue and
497 * the HBA's request entry point is called with this transaction, the
498 * HBA can use the channel_q tag for whatever it likes until it calls
499 * scsipi_done for this transaction, at which time it has to stop
500 * using channel_q.
501 *
502 * After scsipi_done is called with this transaction and if there was an
503 * error on it, channel_q then becomes the linkage on the related channel's
504 * chan_complete cqueue.
505 *
506 * The device_q member is maintained by the scsipi middle layer.  When
507 * a device issues a command, the xfer is placed on that device's
508 * pending commands queue.  When an xfer is done and freed, it is taken
509 * off the device's queue.  This allows for a device to wait for all of
510 * its pending commands to complete.
511 */
512struct scsipi_xfer {
513	TAILQ_ENTRY(scsipi_xfer) channel_q; /* entry on channel queue */
514	TAILQ_ENTRY(scsipi_xfer) device_q;  /* device's pending xfers */
515	callout_t xs_callout;		/* callout for adapter use */
516	int	xs_control;		/* control flags */
517	volatile int xs_status;		/* status flags */
518	struct scsipi_periph *xs_periph;/* peripherial doing the xfer */
519	int	xs_retries;		/* the number of times to retry */
520	int	xs_requeuecnt;		/* number of requeues */
521	int	timeout;		/* in milliseconds */
522	struct	scsipi_generic *cmd;	/* The scsipi command to execute */
523	int	cmdlen;			/* how long it is */
524	u_char	*data;			/* DMA address OR a uio address */
525	int	datalen;		/* data len (blank if uio) */
526	int	resid;			/* how much buffer was not touched */
527	scsipi_xfer_result_t error;	/* an error value */
528	struct	buf *bp;		/* If we need to associate with */
529					/* a buf */
530	union {
531		struct  scsi_sense_data scsi_sense; /* 32 bytes */
532		u_int32_t atapi_sense;
533	} sense;
534
535	struct scsipi_xfer *xs_sensefor;/* we are requesting sense for this */
536					/* xfer */
537
538	u_int8_t status;		/* SCSI status */
539
540	/*
541	 * Info for tagged command queueing.  This may or may not
542	 * be used by a given adapter driver.  These are the same
543	 * as the bytes in the tag message.
544	 */
545	u_int8_t xs_tag_type;		/* tag type */
546	u_int8_t xs_tag_id;		/* tag ID */
547
548	struct	scsipi_generic cmdstore
549	    __aligned(4);		/* stash the command in here */
550};
551
552/*
553 * scsipi_xfer control flags
554 *
555 * To do:
556 *
557 *	- figure out what to do with XS_CTL_ESCAPE
558 *
559 *	- replace XS_CTL_URGENT with an `xs_priority' field?
560 */
561#define	XS_CTL_NOSLEEP		0x00000001	/* don't sleep */
562#define	XS_CTL_POLL		0x00000002	/* poll for completion */
563#define	XS_CTL_DISCOVERY	0x00000004	/* doing device discovery */
564#define	XS_CTL_ASYNC		0x00000008	/* command completes
565						   asynchronously */
566#define	XS_CTL_USERCMD		0x00000010	/* user issued command */
567#define	XS_CTL_SILENT		0x00000020	/* don't print sense info */
568#define	XS_CTL_IGNORE_NOT_READY	0x00000040	/* ignore NOT READY */
569#define	XS_CTL_IGNORE_MEDIA_CHANGE 					\
570				0x00000080	/* ignore media change */
571#define	XS_CTL_IGNORE_ILLEGAL_REQUEST					\
572				0x00000100	/* ignore ILLEGAL REQUEST */
573#define	XS_CTL_SILENT_NODEV	0x00000200	/* don't print sense info
574						   if sense info is nodev */
575#define	XS_CTL_RESET		0x00000400	/* reset the device */
576#define	XS_CTL_DATA_UIO		0x00000800	/* xs_data points to uio */
577#define	XS_CTL_DATA_IN		0x00001000	/* data coming into memory */
578#define	XS_CTL_DATA_OUT		0x00002000	/* data going out of memory */
579#define	XS_CTL_TARGET		0x00004000	/* target mode operation */
580#define	XS_CTL_ESCAPE		0x00008000	/* escape operation */
581#define	XS_CTL_URGENT		0x00010000	/* urgent (recovery)
582						   operation */
583#define	XS_CTL_SIMPLE_TAG	0x00020000	/* use a Simple Tag */
584#define	XS_CTL_ORDERED_TAG	0x00040000	/* use an Ordered Tag */
585#define	XS_CTL_HEAD_TAG		0x00080000	/* use a Head of Queue Tag */
586#define	XS_CTL_THAW_PERIPH	0x00100000	/* thaw periph once enqueued */
587#define	XS_CTL_FREEZE_PERIPH	0x00200000	/* freeze periph when done */
588#define XS_CTL_REQSENSE		0x00800000	/* xfer is a request sense */
589
590#define	XS_CTL_TAGMASK	(XS_CTL_SIMPLE_TAG|XS_CTL_ORDERED_TAG|XS_CTL_HEAD_TAG)
591
592#define	XS_CTL_TAGTYPE(xs)	((xs)->xs_control & XS_CTL_TAGMASK)
593
594/*
595 * scsipi_xfer status flags
596 */
597#define	XS_STS_DONE		0x00000001	/* scsipi_xfer is done */
598#define	XS_STS_PRIVATE		0xf0000000	/* reserved for HBA's use */
599
600/*
601 * This describes matching information for scsipi_inqmatch().  The more things
602 * match, the higher the configuration priority.
603 */
604struct scsipi_inquiry_pattern {
605	u_int8_t type;
606	boolean removable;
607	const char *vendor;
608	const char *product;
609	const char *revision;
610};
611
612/*
613 * This is used to pass information from the high-level configuration code
614 * to the device-specific drivers.
615 */
616struct scsipibus_attach_args {
617	struct scsipi_periph *sa_periph;
618	struct scsipi_inquiry_pattern sa_inqbuf;
619	struct scsipi_inquiry_data *sa_inqptr;
620	union {				/* bus-type specific infos */
621		u_int8_t scsi_version;	/* SCSI version */
622	} scsipi_info;
623};
624
625/*
626 * this describes a quirk entry
627 */
628struct scsi_quirk_inquiry_pattern {
629	struct scsipi_inquiry_pattern pattern;
630	int quirks;
631};
632
633/*
634 * Default number of retries, used for generic routines.
635 */
636#define SCSIPIRETRIES 4
637
638
639#ifdef _KERNEL
640void	scsipi_init(void);
641void	scsipi_load_verbose(void);
642int	scsipi_command(struct scsipi_periph *, struct scsipi_generic *, int,
643	    u_char *, int, int, int, struct buf *, int);
644void	scsipi_create_completion_thread(void *);
645const void *scsipi_inqmatch(struct scsipi_inquiry_pattern *, const void *,
646	    size_t, size_t, int *);
647const char *scsipi_dtype(int);
648void	scsipi_strvis(u_char *, int, const u_char *, int);
649int	scsipi_execute_xs(struct scsipi_xfer *);
650int	scsipi_test_unit_ready(struct scsipi_periph *, int);
651int	scsipi_prevent(struct scsipi_periph *, int, int);
652int	scsipi_inquire(struct scsipi_periph *,
653	    struct scsipi_inquiry_data *, int);
654int	scsipi_mode_select(struct scsipi_periph *, int,
655	    struct scsi_mode_parameter_header_6 *, int, int, int, int);
656int	scsipi_mode_select_big(struct scsipi_periph *, int,
657	    struct scsi_mode_parameter_header_10 *, int, int, int, int);
658int	scsipi_mode_sense(struct scsipi_periph *, int, int,
659	    struct scsi_mode_parameter_header_6 *, int, int, int, int);
660int	scsipi_mode_sense_big(struct scsipi_periph *, int, int,
661	    struct scsi_mode_parameter_header_10 *, int, int, int, int);
662int	scsipi_start(struct scsipi_periph *, int, int);
663void	scsipi_done(struct scsipi_xfer *);
664void	scsipi_user_done(struct scsipi_xfer *);
665int	scsipi_interpret_sense(struct scsipi_xfer *);
666void	scsipi_wait_drain(struct scsipi_periph *);
667void	scsipi_kill_pending(struct scsipi_periph *);
668struct scsipi_periph *scsipi_alloc_periph(int);
669
670/* Function pointers for scsiverbose module */
671extern int	(*scsipi_print_sense)(struct scsipi_xfer *, int);
672extern void	(*scsipi_print_sense_data)(struct scsi_sense_data *, int);
673
674int     scsipi_print_sense_stub(struct scsipi_xfer *, int);
675void    scsipi_print_sense_data_stub(struct scsi_sense_data *, int);
676
677extern int	scsi_verbose_loaded;
678
679void	scsipi_print_cdb(struct scsipi_generic *cmd);
680int	scsipi_thread_call_callback(struct scsipi_channel *,
681	    void (*callback)(struct scsipi_channel *, void *),
682	    void *);
683void	scsipi_async_event(struct scsipi_channel *,
684	    scsipi_async_event_t, void *);
685int	scsipi_do_ioctl(struct scsipi_periph *, dev_t, u_long, void *,
686	    int, struct lwp *);
687
688void	scsipi_print_xfer_mode(struct scsipi_periph *);
689void	scsipi_set_xfer_mode(struct scsipi_channel *, int, int);
690
691int	scsipi_channel_init(struct scsipi_channel *);
692void	scsipi_channel_shutdown(struct scsipi_channel *);
693
694void	scsipi_insert_periph(struct scsipi_channel *,
695	    struct scsipi_periph *);
696void	scsipi_remove_periph(struct scsipi_channel *,
697	    struct scsipi_periph *);
698struct scsipi_periph *scsipi_lookup_periph(struct scsipi_channel *,
699	    int, int);
700int	scsipi_target_detach(struct scsipi_channel *, int, int, int);
701
702int	scsipi_adapter_addref(struct scsipi_adapter *);
703void	scsipi_adapter_delref(struct scsipi_adapter *);
704
705void	scsipi_channel_freeze(struct scsipi_channel *, int);
706void	scsipi_channel_thaw(struct scsipi_channel *, int);
707void	scsipi_channel_timed_thaw(void *);
708
709void	scsipi_periph_freeze(struct scsipi_periph *, int);
710void	scsipi_periph_thaw(struct scsipi_periph *, int);
711void	scsipi_periph_timed_thaw(void *);
712
713int	scsipi_sync_period_to_factor(int);
714int	scsipi_sync_factor_to_period(int);
715int	scsipi_sync_factor_to_freq(int);
716
717void	show_scsipi_xs(struct scsipi_xfer *);
718void	show_scsipi_cmd(struct scsipi_xfer *);
719void	show_mem(u_char *, int);
720#endif /* _KERNEL */
721
722static __inline void
723_lto2b(u_int32_t val, u_int8_t *bytes)
724{
725
726	bytes[0] = (val >> 8) & 0xff;
727	bytes[1] = val & 0xff;
728}
729
730static __inline void
731_lto3b(u_int32_t val, u_int8_t *bytes)
732{
733
734	bytes[0] = (val >> 16) & 0xff;
735	bytes[1] = (val >> 8) & 0xff;
736	bytes[2] = val & 0xff;
737}
738
739static __inline void
740_lto4b(u_int32_t val, u_int8_t *bytes)
741{
742
743	bytes[0] = (val >> 24) & 0xff;
744	bytes[1] = (val >> 16) & 0xff;
745	bytes[2] = (val >> 8) & 0xff;
746	bytes[3] = val & 0xff;
747}
748
749static __inline void
750_lto8b(u_int64_t val, u_int8_t *bytes)
751{
752
753	bytes[0] = (val >> 56) & 0xff;
754	bytes[1] = (val >> 48) & 0xff;
755	bytes[2] = (val >> 40) & 0xff;
756	bytes[3] = (val >> 32) & 0xff;
757	bytes[4] = (val >> 24) & 0xff;
758	bytes[5] = (val >> 16) & 0xff;
759	bytes[6] = (val >> 8)  & 0xff;
760	bytes[7] = val         & 0xff;
761}
762
763static __inline u_int32_t
764_2btol(const u_int8_t *bytes)
765{
766	u_int32_t rv;
767
768	rv = (bytes[0] << 8) |
769	     bytes[1];
770	return (rv);
771}
772
773static __inline u_int32_t
774_3btol(const u_int8_t *bytes)
775{
776	u_int32_t rv;
777
778	rv = (bytes[0] << 16) |
779	     (bytes[1] << 8) |
780	     bytes[2];
781	return (rv);
782}
783
784static __inline u_int32_t
785_4btol(const u_int8_t *bytes)
786{
787	u_int32_t rv;
788
789	rv = (bytes[0] << 24) |
790	     (bytes[1] << 16) |
791	     (bytes[2] << 8) |
792	     bytes[3];
793	return (rv);
794}
795
796static __inline u_int64_t
797_5btol(const u_int8_t *bytes)
798{
799	u_int64_t rv;
800
801	rv = ((u_int64_t)bytes[0] << 32) |
802	     ((u_int64_t)bytes[1] << 24) |
803	     ((u_int64_t)bytes[2] << 16) |
804	     ((u_int64_t)bytes[3] << 8) |
805	     (u_int64_t)bytes[4];
806	return (rv);
807}
808
809static __inline u_int64_t
810_8btol(const u_int8_t *bytes)
811{
812	u_int64_t rv;
813
814	rv = ((u_int64_t)bytes[0] << 56) |
815	     ((u_int64_t)bytes[1] << 48) |
816	     ((u_int64_t)bytes[2] << 40) |
817	     ((u_int64_t)bytes[3] << 32) |
818	     ((u_int64_t)bytes[4] << 24) |
819	     ((u_int64_t)bytes[5] << 16) |
820	     ((u_int64_t)bytes[6] << 8) |
821	     (u_int64_t)bytes[7];
822	return (rv);
823}
824
825static __inline void
826_lto2l(u_int32_t val, u_int8_t *bytes)
827{
828
829	bytes[0] = val & 0xff;
830	bytes[1] = (val >> 8) & 0xff;
831}
832
833static __inline void
834_lto3l(u_int32_t val, u_int8_t *bytes)
835{
836
837	bytes[0] = val & 0xff;
838	bytes[1] = (val >> 8) & 0xff;
839	bytes[2] = (val >> 16) & 0xff;
840}
841
842static __inline void
843_lto4l(u_int32_t val, u_int8_t *bytes)
844{
845
846	bytes[0] = val & 0xff;
847	bytes[1] = (val >> 8) & 0xff;
848	bytes[2] = (val >> 16) & 0xff;
849	bytes[3] = (val >> 24) & 0xff;
850}
851
852static __inline u_int32_t
853_2ltol(const u_int8_t *bytes)
854{
855	u_int32_t rv;
856
857	rv = bytes[0] |
858	     (bytes[1] << 8);
859	return (rv);
860}
861
862static __inline u_int32_t
863_3ltol(const u_int8_t *bytes)
864{
865	u_int32_t rv;
866
867	rv = bytes[0] |
868	     (bytes[1] << 8) |
869	     (bytes[2] << 16);
870	return (rv);
871}
872
873static __inline u_int32_t
874_4ltol(const u_int8_t *bytes)
875{
876	u_int32_t rv;
877
878	rv = bytes[0] |
879	     (bytes[1] << 8) |
880	     (bytes[2] << 16) |
881	     (bytes[3] << 24);
882	return (rv);
883}
884
885#endif /* _DEV_SCSIPI_SCSIPICONF_H_ */
886