1 /*        $NetBSD: scsipiconf.h,v 1.133 2024/10/29 15:50:07 nat 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 <sys/condvar.h>
58 #include <dev/scsipi/scsi_spc.h>
59 #include <dev/scsipi/scsipi_debug.h>
60 
61 struct buf;
62 struct proc;
63 struct device;
64 struct scsipi_channel;
65 struct scsipi_periph;
66 struct scsipi_xfer;
67 
68 /*
69  * The following defines the scsipi_xfer queue.
70  */
71 TAILQ_HEAD(scsipi_xfer_queue, scsipi_xfer);
72 
73 struct scsipi_generic {
74           u_int8_t opcode;
75           u_int8_t bytes[15];
76 };
77 
78 
79 /*
80  * scsipi_async_event_t:
81  *
82  *        Asynchronous events from the adapter to the mid-layer and
83  *        peripheral.
84  *
85  *        Arguments:
86  *
87  *        ASYNC_EVENT_MAX_OPENINGS      scsipi_max_openings * -- max
88  *                                                openings, device specified in
89  *                                                parameters
90  *
91  *        ASYNC_EVENT_XFER_MODE                   scsipi_xfer_mode * -- xfer mode
92  *                                                parameters changed for I_T Nexus
93  *        ASYNC_EVENT_RESET             NULL - channel has been reset
94  */
95 typedef enum {
96           ASYNC_EVENT_MAX_OPENINGS,     /* set max openings on periph */
97           ASYNC_EVENT_XFER_MODE,                  /* xfer mode update for I_T */
98           ASYNC_EVENT_RESET             /* channel reset */
99 } scsipi_async_event_t;
100 
101 /*
102  * scsipi_max_openings:
103  *
104  *        Argument for an ASYNC_EVENT_MAX_OPENINGS event.
105  */
106 struct scsipi_max_openings {
107           int       mo_target;                    /* openings are for this target... */
108           int       mo_lun;                       /* ...and this lun */
109           int       mo_openings;                  /* openings value */
110 };
111 
112 /*
113  * scsipi_xfer_mode:
114  *
115  *        Argument for an ASYNC_EVENT_XFER_MODE event.
116  */
117 struct scsipi_xfer_mode {
118           int       xm_target;                    /* target, for I_T Nexus */
119           int       xm_mode;            /* PERIPH_CAP* bits */
120           int       xm_period;                    /* sync period */
121           int       xm_offset;                    /* sync offset */
122 };
123 
124 
125 /*
126  * scsipi_adapter_req_t:
127  *
128  *        Requests that can be made of an adapter.
129  *
130  *        Arguments:
131  *
132  *        ADAPTER_REQ_RUN_XFER                    scsipi_xfer * -- the xfer which
133  *                                                is to be run
134  *
135  *        ADAPTER_REQ_GROW_RESOURCES    no argument
136  *
137  *        ADAPTER_REQ_SET_XFER_MODE     scsipi_xfer_mode * -- set the xfer
138  *                                                mode for the I_T Nexus according to
139  *                                                this
140  */
141 typedef enum {
142           ADAPTER_REQ_RUN_XFER,                   /* run a scsipi_xfer */
143           ADAPTER_REQ_GROW_RESOURCES,   /* grow xfer execution resources */
144           ADAPTER_REQ_SET_XFER_MODE     /* set xfer mode */
145 } scsipi_adapter_req_t;
146 
147 #ifdef _KERNEL
148 /*
149  * scsipi_periphsw:
150  *
151  *        Callbacks into periph driver from midlayer.
152  *
153  *        psw_error Called by the bustype's interpret-sense routine
154  *                            to do periph-specific sense handling.
155  *
156  *        psw_start Called by midlayer to restart a device once
157  *                            more command openings become available.
158  *
159  *        psw_async Called by midlayer when an asynchronous event
160  *                            from the adapter occurs.
161  *
162  *        psw_done  Called by the midlayer when an xfer has completed.
163  */
164 struct scsipi_periphsw {
165           int       (*psw_error)(struct scsipi_xfer *);
166           void      (*psw_start)(struct scsipi_periph *);
167           int       (*psw_async)(struct scsipi_periph *,
168                         scsipi_async_event_t, void *);
169           void      (*psw_done)(struct scsipi_xfer *, int);
170 };
171 
172 struct disk_parms;
173 struct scsipi_inquiry_pattern;
174 
175 /*
176  * scsipi_adapter:
177  *
178  *        This structure describes an instance of a SCSIPI adapter.
179  *
180  *        Note that `adapt_openings' is used by (the common case of) adapters
181  *        which have per-adapter resources.  If an adapter's command resources
182  *        are associated with a channel, then the `chan_openings' below will
183  *        be used instead.
184  *
185  *        Note that all adapter entry points take a pointer to a channel,
186  *        as an adapter may have more than one channel, and the channel
187  *        structure contains the channel number.
188  */
189 struct scsipi_adapter {
190           device_t adapt_dev; /* pointer to adapter's device */
191           int       adapt_nchannels;    /* number of adapter channels */
192           volatile int        adapt_refcnt;                 /* adapter's reference count */
193           int       adapt_openings;               /* total # of command openings */
194           int       adapt_max_periph;   /* max openings per periph */
195           int       adapt_flags;
196 
197           void      (*adapt_request)(struct scsipi_channel *,
198                         scsipi_adapter_req_t, void *);
199           void      (*adapt_minphys)(struct buf *);
200           int       (*adapt_ioctl)(struct scsipi_channel *, u_long,
201                         void *, int, struct proc *);
202           int       (*adapt_enable)(device_t, int);
203           int       (*adapt_getgeom)(struct scsipi_periph *,
204                               struct disk_parms *, u_long);
205           int       (*adapt_accesschk)(struct scsipi_periph *,
206                               struct scsipi_inquiry_pattern *);
207 
208           kmutex_t adapt_mtx;
209           volatile int        adapt_running;      /* how many users of mutex */
210 };
211 
212 /* adapt_flags */
213 #define SCSIPI_ADAPT_POLL_ONLY          0x01 /* Adaptor can't do interrupts. */
214 #define SCSIPI_ADAPT_MPSAFE     0x02 /* Adaptor doesn't need kernel lock */
215 
216 void scsipi_adapter_minphys(struct scsipi_channel *, struct buf *);
217 void scsipi_adapter_request(struct scsipi_channel *,
218           scsipi_adapter_req_t, void *);
219 int scsipi_adapter_ioctl(struct scsipi_channel *, u_long,
220           void *, int, struct proc *);
221 int scsipi_adapter_enable(struct scsipi_adapter *, int);
222 #endif
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           void      (*bustype_async_event_xfer_mode)(struct scsipi_channel *,
240                         void *);
241 };
242 
243 /* bustype_type */
244 /* type is stored in the first byte */
245 #define SCSIPI_BUSTYPE_TYPE_SHIFT 0
246 #define SCSIPI_BUSTYPE_TYPE(x) (((x) >> SCSIPI_BUSTYPE_TYPE_SHIFT) & 0xff)
247 #define   SCSIPI_BUSTYPE_SCSI 0 /* parallel SCSI */
248 #define   SCSIPI_BUSTYPE_ATAPI          1
249 /* #define SCSIPI_BUSTYPE_ATA 2 */
250 /* subtype is stored in the second byte */
251 #define SCSIPI_BUSTYPE_SUBTYPE_SHIFT 8
252 #define SCSIPI_BUSTYPE_SUBTYPE(x) (((x) >> SCSIPI_BUSTYPE_SUBTYPE_SHIFT) & 0xff)
253 
254 #define SCSIPI_BUSTYPE_BUSTYPE(t, s) \
255     ((t) << SCSIPI_BUSTYPE_TYPE_SHIFT | (s) << SCSIPI_BUSTYPE_SUBTYPE_SHIFT)
256 /* subtypes are defined in each bus type headers */
257 
258 /*
259  * scsipi_channel:
260  *
261  *        This structure describes a single channel of a SCSIPI adapter.
262  *        An adapter may have one or more channels.  See the comment above
263  *        regarding the resource counter.
264  *        Note: chan_bustype has to be first member, as its bustype_type member
265  *        is shared with the aa_bustype member of struct ata_atapi_attach.
266  */
267 
268 #define   SCSIPI_CHAN_PERIPH_BUCKETS    16
269 #define   SCSIPI_CHAN_PERIPH_HASHMASK   (SCSIPI_CHAN_PERIPH_BUCKETS - 1)
270 
271 #ifdef _KERNEL
272 struct scsipi_channel {
273           const struct scsipi_bustype *chan_bustype; /* channel's bus type */
274           const char *chan_name;        /* this channel's name */
275 
276           struct scsipi_adapter *chan_adapter; /* pointer to our adapter */
277 
278           /* Periphs for this channel. */
279           LIST_HEAD(, scsipi_periph) chan_periphtab[SCSIPI_CHAN_PERIPH_BUCKETS];
280 
281           int       chan_channel;                 /* channel number */
282           int       chan_flags;                   /* channel flags */
283           int       chan_openings;                /* number of command openings */
284           int       chan_max_periph;    /* max openings per periph */
285 
286           int       chan_ntargets;                /* number of targets */
287           int       chan_nluns;                   /* number of luns */
288           int       chan_id;            /* adapter's ID for this channel */
289 
290           int       chan_defquirks;               /* default device's quirks */
291 
292           struct lwp *chan_dthread;     /* discovery thread */
293           struct lwp *chan_thread;      /* completion thread */
294           int       chan_tflags;                  /* flags for the completion thread */
295 
296           int       chan_qfreeze;                 /* freeze count for queue */
297 
298           /* Job queue for this channel. */
299           struct scsipi_xfer_queue chan_queue;
300 
301           /* Completed (async) jobs. */
302           struct scsipi_xfer_queue chan_complete;
303 
304           /* callback we may have to call from completion thread */
305           void (*chan_callback)(struct scsipi_channel *, void *);
306           void *chan_callback_arg;
307 
308           /* callback we may have to call after forking the kthread */
309           void (*chan_init_cb)(struct scsipi_channel *, void *);
310           void *chan_init_cb_arg;
311 
312           kcondvar_t chan_cv_comp;
313           kcondvar_t chan_cv_thr;
314           kcondvar_t chan_cv_xs;
315 
316 #define chan_cv_complete(ch) (&(ch)->chan_cv_comp)
317 #define chan_cv_thread(ch) (&(ch)->chan_cv_thr)
318 };
319 
320 #define chan_running(ch) ((ch)->chan_adapter->adapt_running)
321 #define chan_mtx(ch) (&(ch)->chan_adapter->adapt_mtx)
322 #endif
323 
324 /* chan_flags */
325 #define   SCSIPI_CHAN_OPENINGS          0x01      /* use chan_openings */
326 #define   SCSIPI_CHAN_CANGROW 0x02      /* channel can grow resources */
327 #define   SCSIPI_CHAN_NOSETTLE          0x04      /* don't wait for devices to settle */
328 #define   SCSIPI_CHAN_TACTIVE 0x08      /* completion thread is active */
329 
330 /* chan thread flags (chan_tflags) */
331 #define   SCSIPI_CHANT_SHUTDOWN         0x01      /* channel is shutting down */
332 #define   SCSIPI_CHANT_CALLBACK         0x02      /* has to call chan_callback() */
333 #define   SCSIPI_CHANT_KICK   0x04      /* need to run queues */
334 #define   SCSIPI_CHANT_GROWRES          0x08      /* call ADAPTER_REQ_GROW_RESOURCES */
335 
336 #define   SCSIPI_CHAN_MAX_PERIPH(chan)                                          \
337           (((chan)->chan_flags & SCSIPI_CHAN_OPENINGS) ?                        \
338            (chan)->chan_max_periph : (chan)->chan_adapter->adapt_max_periph)
339 
340 
341 #define   scsipi_printaddr(periph)                                              \
342           (*(periph)->periph_channel->chan_bustype->bustype_printaddr)((periph))
343 
344 #define   scsipi_periph_bustype(periph)                                         \
345           (periph)->periph_channel->chan_bustype->bustype_type
346 
347 
348 /*
349  * Number of tag words in a periph structure:
350  *
351  *        n_tag_words = ((256 / NBBY) / sizeof(u_int32_t))
352  */
353 #define   PERIPH_NTAGWORDS    ((256 / 8) / sizeof(u_int32_t))
354 
355 #ifdef _KERNEL
356 /*
357  * scsipi_opcodes:
358  *      This optionally allocated structure documents
359  *      valid opcodes and timeout values for the respective
360  *      opcodes overriding the requested timeouts.
361  *      It is created when SCSI_MAINTENANCE_IN/
362  *      RSOC_REPORT_SUPPORTED_OPCODES can provide information
363  *      at attach time.
364  */
365 struct scsipi_opcodes
366 {
367           struct scsipi_opinfo
368           {
369                     long          ti_timeout;     /* timeout in seconds (> 0 => VALID) */
370                     unsigned long ti_flags;
371 #define SCSIPI_TI_VALID  0x0001                 /* valid op code */
372 #define SCSIPI_TI_LOGGED 0x8000                 /* override logged during debug */
373           } opcode_info[0x100];
374 };
375 
376 /*
377  * scsipi_periph:
378  *
379  *        This structure describes the path between a peripheral device
380  *        and an adapter.  It contains a pointer to the adapter channel
381  *        which in turn contains a pointer to the adapter.
382  *
383  * XXX Given the way NetBSD's autoconfiguration works, this is ...
384  * XXX nasty.
385  *
386  *        Well, it's a lot nicer than it used to be, but there could
387  *        still be an improvement.
388  */
389 struct scsipi_periph {
390           device_t periph_dev;          /* pointer to peripheral's device */
391           struct scsipi_channel *periph_channel; /* channel we're connected to */
392 
393                                                   /* link in channel's table of periphs */
394           LIST_ENTRY(scsipi_periph) periph_hash;
395 
396           const struct scsipi_periphsw *periph_switch; /* peripheral's entry
397                                                                       points */
398           int       periph_openings;    /* max # of outstanding commands */
399           int       periph_active;                /* current # of outstanding commands */
400           int       periph_sent;                  /* current # of commands sent to adapt*/
401 
402           int       periph_mode;                  /* operation modes, CAP bits */
403           int       periph_period;                /* sync period (factor) */
404           int       periph_offset;                /* sync offset */
405 
406           /*
407            * Information gleaned from the inquiry data.
408            */
409           u_int8_t periph_type;                   /* basic device type */
410           int       periph_cap;                   /* capabilities */
411           int       periph_quirks;                /* device's quirks */
412 
413           int       periph_flags;                 /* misc. flags */
414           int       periph_dbflags;               /* debugging flags */
415 
416           int       periph_target;                /* target ID (drive # on ATAPI) */
417           int       periph_lun;                   /* LUN (not used on ATAPI) */
418 
419           int       periph_version;               /* ANSI SCSI version */
420 
421           int       periph_qfreeze;               /* queue freeze count */
422 
423           /* available opcodes and timeout information */
424           struct scsipi_opcodes *periph_opcs;
425 
426           /* Bitmap of free command tags. */
427           u_int32_t periph_freetags[PERIPH_NTAGWORDS];
428 
429           /* Pending scsipi_xfers on this peripheral. */
430           struct scsipi_xfer_queue periph_xferq;
431 
432           callout_t periph_callout;
433 
434           /* xfer which has a pending CHECK_CONDITION */
435           struct scsipi_xfer *periph_xscheck;
436 
437           kcondvar_t periph_cv;
438 #define periph_cv_periph(p) (&(p)->periph_cv)
439 #define periph_cv_active(p) (&(p)->periph_cv)
440 };
441 #endif
442 
443 /*
444  * Macro to return the current xfer mode of a periph.
445  */
446 #define   PERIPH_XFER_MODE(periph)                                              \
447           (((periph)->periph_flags & PERIPH_MODE_VALID) ?                       \
448            (periph)->periph_mode : 0)
449 
450 /* periph_cap */
451 #define   PERIPH_CAP_ANEC               0x0001    /* async event notification */
452 #define   PERIPH_CAP_TERMIOP  0x0002    /* terminate i/o proc. messages */
453 #define   PERIPH_CAP_RELADR   0x0004    /* relative addressing */
454 #define   PERIPH_CAP_WIDE32   0x0008    /* wide-32 transfers */
455 #define   PERIPH_CAP_WIDE16   0x0010    /* wide-16 transfers */
456                     /*        XXX       0x0020       reserved for ATAPI_CFG_DRQ_MASK */
457                     /*        XXX       0x0040       reserved for ATAPI_CFG_DRQ_MASK */
458 #define   PERIPH_CAP_SYNC               0x0080    /* synchronous transfers */
459 #define   PERIPH_CAP_LINKCMDS 0x0100    /* linked commands */
460 #define   PERIPH_CAP_TQING    0x0200    /* tagged queueing */
461 #define   PERIPH_CAP_SFTRESET 0x0400    /* soft RESET condition response */
462 #define   PERIPH_CAP_CMD16    0x0800    /* 16 byte commands (ATAPI) */
463 #define   PERIPH_CAP_DT                 0x1000    /* supports DT clock */
464 #define   PERIPH_CAP_QAS                0x2000    /* supports quick arbit. and select. */
465 #define   PERIPH_CAP_IUS                0x4000    /* supports information unit xfers */
466 
467 /* periph_flags */
468 #define   PERIPH_REMOVABLE    0x0001    /* media is removable */
469 #define   PERIPH_MEDIA_LOADED 0x0002    /* media is loaded */
470 #define   PERIPH_WAITING                0x0004    /* process waiting for opening */
471 #define   PERIPH_OPEN                   0x0008    /* device is open */
472 #define   PERIPH_WAITDRAIN    0x0010    /* waiting for pending xfers to drain */
473 #define   PERIPH_GROW_OPENINGS          0x0020    /* allow openings to grow */
474 #define   PERIPH_MODE_VALID   0x0040    /* periph_mode is valid */
475 #define   PERIPH_RECOVERING   0x0080    /* periph is recovering */
476 #define   PERIPH_RECOVERY_ACTIVE        0x0100    /* a recovery command is active */
477 #define PERIPH_KEEP_LABEL     0x0200    /* retain label after 'full' close */
478 #define   PERIPH_SENSE                  0x0400    /* periph has sense pending */
479 #define PERIPH_UNTAG                    0x0800    /* untagged command running */
480 
481 /* periph_quirks */
482 #define   PQUIRK_AUTOSAVE               0x00000001          /* do implicit SAVE POINTERS */
483 #define   PQUIRK_NOSYNC                 0x00000002          /* does not grok SDTR */
484 #define   PQUIRK_NOWIDE                 0x00000004          /* does not grok WDTR */
485 #define   PQUIRK_NOTAG                  0x00000008          /* does not grok tagged cmds */
486 #define   PQUIRK_NOLUNS                 0x00000010          /* DTWT with LUNs */
487 #define   PQUIRK_FORCELUNS    0x00000020          /* prehistoric device groks
488                                                                LUNs */
489 #define   PQUIRK_NOMODESENSE  0x00000040          /* device doesn't do MODE SENSE
490                                                                properly */
491 #define   PQUIRK_NOSYNCCACHE  0x00000100          /* do not issue SYNC CACHE */
492 #define   PQUIRK_LITTLETOC    0x00000400          /* audio TOC is little-endian */
493 #define   PQUIRK_NOCAPACITY   0x00000800          /* no READ CD CAPACITY */
494 #define   PQUIRK_NOTUR                  0x00001000          /* no TEST UNIT READY */
495 #define   PQUIRK_NODOORLOCK   0x00002000          /* can't lock door */
496 #define   PQUIRK_NOSENSE                0x00004000          /* can't REQUEST SENSE */
497 #define PQUIRK_ONLYBIG                  0x00008000          /* only use SCSI_{R,W}_BIG */
498 #define PQUIRK_NOBIGMODESENSE 0x00040000          /* has no big mode-sense op */
499 #define PQUIRK_CAP_SYNC                 0x00080000          /* SCSI device with ST sync op*/
500 #define PQUIRK_CAP_WIDE16     0x00100000          /* SCSI device with ST wide op*/
501 #define PQUIRK_CAP_NODT                 0x00200000          /* signals DT, but can't. */
502 #define PQUIRK_START                    0x00400000          /* needs start before tur */
503 #define   PQUIRK_NOFUA                  0x00800000          /* does not grok FUA */
504 #define PQUIRK_NOREPSUPPOPC     0x01000000      /* does not grok
505                                                                REPORT SUPPORTED OPCODES
506                                                                to fetch device timeouts */
507 #define PQUIRK_NOREADDISCINFO   0x02000000      /* device doesn't do
508                                                                READ_DISCINFO properly */
509 /*
510  * Error values an adapter driver may return
511  */
512 typedef enum {
513           XS_NOERROR,                   /* there is no error, (sense is invalid)  */
514           XS_SENSE,           /* Check the returned sense for the error */
515           XS_SHORTSENSE,                /* Check the ATAPI sense for the error    */
516           XS_DRIVER_STUFFUP,  /* Driver failed to perform operation     */
517           XS_RESOURCE_SHORTAGE,         /* adapter resource shortage              */
518           XS_SELTIMEOUT,                /* The device timed out.. turned off?     */
519           XS_TIMEOUT,                   /* The Timeout reported was caught by SW  */
520           XS_BUSY,            /* The device busy, try again later?      */
521           XS_RESET,           /* bus was reset; possible retry command  */
522           XS_REQUEUE                    /* requeue this command */
523 } scsipi_xfer_result_t;
524 
525 #ifdef _KERNEL
526 /*
527  * Each scsipi transaction is fully described by one of these structures
528  * It includes information about the source of the command and also the
529  * device and adapter for which the command is destined.
530  *
531  * Before the HBA is given this transaction, channel_q is the linkage on
532  * the related channel's chan_queue.
533  *
534  * When the this transaction is taken off the channel's chan_queue and
535  * the HBA's request entry point is called with this transaction, the
536  * HBA can use the channel_q tag for whatever it likes until it calls
537  * scsipi_done for this transaction, at which time it has to stop
538  * using channel_q.
539  *
540  * After scsipi_done is called with this transaction and if there was an
541  * error on it, channel_q then becomes the linkage on the related channel's
542  * chan_complete cqueue.
543  *
544  * The device_q member is maintained by the scsipi middle layer.  When
545  * a device issues a command, the xfer is placed on that device's
546  * pending commands queue.  When an xfer is done and freed, it is taken
547  * off the device's queue.  This allows for a device to wait for all of
548  * its pending commands to complete.
549  */
550 struct scsipi_xfer {
551           TAILQ_ENTRY(scsipi_xfer) channel_q; /* entry on channel queue */
552           TAILQ_ENTRY(scsipi_xfer) device_q;  /* device's pending xfers */
553           callout_t xs_callout;                   /* callout for adapter use */
554           int       xs_control;                   /* control flags */
555           volatile int xs_status;                 /* status flags */
556           struct scsipi_periph *xs_periph;/* peripheral doing the xfer */
557           int       xs_retries;                   /* the number of times to retry */
558           int       xs_requeuecnt;                /* number of requeues */
559           int       timeout;            /* in milliseconds */
560           struct    scsipi_generic *cmd;          /* The scsipi command to execute */
561           int       cmdlen;                       /* how long it is */
562           u_char    *data;                        /* DMA address OR a uio address */
563           int       datalen;            /* data len (blank if uio) */
564           int       resid;                        /* how much buffer was not touched */
565           scsipi_xfer_result_t error;   /* an error value */
566           struct    buf *bp;            /* If we need to associate with */
567                                                   /* a buf */
568           union {
569                     struct  scsi_sense_data scsi_sense; /* 32 bytes */
570                     u_int32_t atapi_sense;
571           } sense;
572 
573           struct scsipi_xfer *xs_sensefor;/* we are requesting sense for this */
574                                                   /* xfer */
575 
576           u_int8_t status;              /* SCSI status */
577 
578           /*
579            * Info for tagged command queueing.  This may or may not
580            * be used by a given adapter driver.  These are the same
581            * as the bytes in the tag message.
582            */
583           u_int8_t xs_tag_type;                   /* tag type */
584           u_int8_t xs_tag_id;           /* tag ID */
585 
586           struct    scsipi_generic cmdstore
587               __aligned(4);             /* stash the command in here */
588 
589 #define xs_cv(xs) (&(xs)->xs_periph->periph_channel->chan_cv_xs)
590 };
591 #endif
592 
593 /*
594  * scsipi_xfer control flags
595  *
596  * To do:
597  *
598  *        - figure out what to do with XS_CTL_ESCAPE
599  *
600  *        - replace XS_CTL_URGENT with an `xs_priority' field?
601  */
602 #define   XS_CTL_NOSLEEP                0x00000001          /* don't sleep */
603 #define   XS_CTL_POLL                   0x00000002          /* poll for completion */
604 #define   XS_CTL_DISCOVERY    0x00000004          /* doing device discovery */
605 #define   XS_CTL_ASYNC                  0x00000008          /* command completes
606                                                                asynchronously */
607 #define   XS_CTL_USERCMD                0x00000010          /* user issued command */
608 #define   XS_CTL_SILENT                 0x00000020          /* don't print sense info */
609 #define   XS_CTL_IGNORE_NOT_READY       0x00000040          /* ignore NOT READY */
610 #define   XS_CTL_IGNORE_MEDIA_CHANGE                                            \
611                                         0x00000080          /* ignore media change */
612 #define   XS_CTL_IGNORE_ILLEGAL_REQUEST                                         \
613                                         0x00000100          /* ignore ILLEGAL REQUEST */
614 #define   XS_CTL_SILENT_NODEV 0x00000200          /* don't print sense info
615                                                                if sense info is nodev */
616 #define   XS_CTL_RESET                  0x00000400          /* reset the device */
617 #define   XS_CTL_DATA_UIO               0x00000800          /* xs_data points to uio */
618 #define   XS_CTL_DATA_IN                0x00001000          /* data coming into memory */
619 #define   XS_CTL_DATA_OUT               0x00002000          /* data going out of memory */
620 #define   XS_CTL_TARGET                 0x00004000          /* target mode operation */
621 #define   XS_CTL_ESCAPE                 0x00008000          /* escape operation */
622 #define   XS_CTL_URGENT                 0x00010000          /* urgent (recovery)
623                                                                operation */
624 #define   XS_CTL_SIMPLE_TAG   0x00020000          /* use a Simple Tag */
625 #define   XS_CTL_ORDERED_TAG  0x00040000          /* use an Ordered Tag */
626 #define   XS_CTL_HEAD_TAG               0x00080000          /* use a Head of Queue Tag */
627 #define   XS_CTL_THAW_PERIPH  0x00100000          /* thaw periph once enqueued */
628 #define   XS_CTL_FREEZE_PERIPH          0x00200000          /* freeze periph when done */
629 #define XS_CTL_REQSENSE                 0x00800000          /* xfer is a request sense */
630 
631 #define   XS_CTL_TAGMASK      (XS_CTL_SIMPLE_TAG|XS_CTL_ORDERED_TAG|XS_CTL_HEAD_TAG)
632 
633 #define   XS_CTL_TAGTYPE(xs)  ((xs)->xs_control & XS_CTL_TAGMASK)
634 
635 /*
636  * scsipi_xfer status flags
637  */
638 #define   XS_STS_DONE                   0x00000001          /* scsipi_xfer is done */
639 #define   XS_STS_PRIVATE                0xf0000000          /* reserved for HBA's use */
640 
641 /*
642  * This describes matching information for scsipi_inqmatch().  The more things
643  * match, the higher the configuration priority.
644  */
645 struct scsipi_inquiry_pattern {
646           u_int8_t type;
647           boolean removable;
648           const char *vendor;
649           const char *product;
650           const char *revision;
651 };
652 
653 /*
654  * This is used to pass information from the high-level configuration code
655  * to the device-specific drivers.
656  */
657 struct scsipibus_attach_args {
658           struct scsipi_periph *sa_periph;
659           struct scsipi_inquiry_pattern sa_inqbuf;
660           struct scsipi_inquiry_data *sa_inqptr;
661           union {                                 /* bus-type specific infos */
662                     u_int8_t scsi_version;        /* SCSI version */
663           } scsipi_info;
664 };
665 
666 /*
667  * this describes a quirk entry
668  */
669 struct scsi_quirk_inquiry_pattern {
670           struct scsipi_inquiry_pattern pattern;
671           int quirks;
672 };
673 
674 /*
675  * Default number of retries, used for generic routines.
676  */
677 #define SCSIPIRETRIES 4
678 
679 
680 #ifdef _KERNEL
681 void      scsipi_init(void);
682 void      scsipi_ioctl_init(void);
683 void      scsipi_load_verbose(void);
684 int       scsipi_command(struct scsipi_periph *, struct scsipi_generic *, int,
685               u_char *, int, int, int, struct buf *, int);
686 void      scsipi_create_completion_thread(void *);
687 const void *scsipi_inqmatch(struct scsipi_inquiry_pattern *, const void *,
688               size_t, size_t, int *);
689 const char *scsipi_dtype(int);
690 int       scsipi_execute_xs(struct scsipi_xfer *);
691 int       scsipi_test_unit_ready(struct scsipi_periph *, int);
692 int       scsipi_prevent(struct scsipi_periph *, int, int);
693 int       scsipi_inquire(struct scsipi_periph *,
694               struct scsipi_inquiry_data *, int);
695 int       scsipi_mode_select(struct scsipi_periph *, int,
696               struct scsi_mode_parameter_header_6 *, int, int, int, int);
697 int       scsipi_mode_select_big(struct scsipi_periph *, int,
698               struct scsi_mode_parameter_header_10 *, int, int, int, int);
699 int       scsipi_mode_sense(struct scsipi_periph *, int, int,
700               struct scsi_mode_parameter_header_6 *, int, int, int, int);
701 int       scsipi_mode_sense_big(struct scsipi_periph *, int, int,
702               struct scsi_mode_parameter_header_10 *, int, int, int, int);
703 int       scsipi_start(struct scsipi_periph *, int, int);
704 void      scsipi_done(struct scsipi_xfer *);
705 void      scsipi_user_done(struct scsipi_xfer *);
706 int       scsipi_interpret_sense(struct scsipi_xfer *);
707 void      scsipi_wait_drain(struct scsipi_periph *);
708 void      scsipi_kill_pending(struct scsipi_periph *);
709 void    scsipi_get_opcodeinfo(struct scsipi_periph *periph);
710 void    scsipi_free_opcodeinfo(struct scsipi_periph *periph);
711 struct scsipi_periph *scsipi_alloc_periph(int);
712 void      scsipi_free_periph(struct scsipi_periph *);
713 
714 /* Function pointers for scsiverbose module */
715 extern int          (*scsipi_print_sense)(struct scsipi_xfer *, int);
716 extern void         (*scsipi_print_sense_data)(struct scsi_sense_data *, int);
717 
718 int     scsipi_print_sense_stub(struct scsipi_xfer *, int);
719 void    scsipi_print_sense_data_stub(struct scsi_sense_data *, int);
720 
721 extern int          scsi_verbose_loaded;
722 
723 void      scsipi_print_cdb(struct scsipi_generic *cmd);
724 int       scsipi_thread_call_callback(struct scsipi_channel *,
725               void (*callback)(struct scsipi_channel *, void *),
726               void *);
727 void      scsipi_async_event(struct scsipi_channel *,
728               scsipi_async_event_t, void *);
729 int       scsipi_do_ioctl(struct scsipi_periph *, dev_t, u_long, void *,
730               int, struct lwp *);
731 
732 void      scsipi_set_xfer_mode(struct scsipi_channel *, int, int);
733 
734 int       scsipi_channel_init(struct scsipi_channel *);
735 void      scsipi_channel_shutdown(struct scsipi_channel *);
736 
737 void      scsipi_insert_periph(struct scsipi_channel *,
738               struct scsipi_periph *);
739 void      scsipi_remove_periph(struct scsipi_channel *,
740               struct scsipi_periph *);
741 struct scsipi_periph *scsipi_lookup_periph(struct scsipi_channel *,
742               int, int);
743 struct scsipi_periph *scsipi_lookup_periph_locked(struct scsipi_channel *,
744               int, int);
745 int       scsipi_target_detach(struct scsipi_channel *, int, int, int);
746 
747 int       scsipi_adapter_addref(struct scsipi_adapter *);
748 void      scsipi_adapter_delref(struct scsipi_adapter *);
749 
750 void      scsipi_channel_freeze(struct scsipi_channel *, int);
751 void      scsipi_channel_thaw(struct scsipi_channel *, int);
752 void      scsipi_channel_timed_thaw(void *);
753 
754 void      scsipi_periph_freeze(struct scsipi_periph *, int);
755 void      scsipi_periph_thaw(struct scsipi_periph *, int);
756 void      scsipi_periph_timed_thaw(void *);
757 
758 void      scsipi_periph_freeze_locked(struct scsipi_periph *, int);
759 void      scsipi_periph_thaw_locked(struct scsipi_periph *, int);
760 
761 int       scsipi_sync_period_to_factor(int);
762 int       scsipi_sync_factor_to_period(int);
763 int       scsipi_sync_factor_to_freq(int);
764 
765 void      show_scsipi_xs(struct scsipi_xfer *);
766 void      show_scsipi_cmd(struct scsipi_xfer *);
767 void      show_mem(u_char *, int);
768 #endif /* _KERNEL */
769 
770 static __inline void
_lto2b(u_int32_t val,u_int8_t * bytes)771 _lto2b(u_int32_t val, u_int8_t *bytes)
772 {
773 
774           bytes[0] = (val >> 8) & 0xff;
775           bytes[1] = val & 0xff;
776 }
777 
778 static __inline void
_lto3b(u_int32_t val,u_int8_t * bytes)779 _lto3b(u_int32_t val, u_int8_t *bytes)
780 {
781 
782           bytes[0] = (val >> 16) & 0xff;
783           bytes[1] = (val >> 8) & 0xff;
784           bytes[2] = val & 0xff;
785 }
786 
787 static __inline void
_lto4b(u_int32_t val,u_int8_t * bytes)788 _lto4b(u_int32_t val, u_int8_t *bytes)
789 {
790 
791           bytes[0] = (val >> 24) & 0xff;
792           bytes[1] = (val >> 16) & 0xff;
793           bytes[2] = (val >> 8) & 0xff;
794           bytes[3] = val & 0xff;
795 }
796 
797 static __inline void
_lto8b(u_int64_t val,u_int8_t * bytes)798 _lto8b(u_int64_t val, u_int8_t *bytes)
799 {
800 
801           bytes[0] = (val >> 56) & 0xff;
802           bytes[1] = (val >> 48) & 0xff;
803           bytes[2] = (val >> 40) & 0xff;
804           bytes[3] = (val >> 32) & 0xff;
805           bytes[4] = (val >> 24) & 0xff;
806           bytes[5] = (val >> 16) & 0xff;
807           bytes[6] = (val >> 8)  & 0xff;
808           bytes[7] = val         & 0xff;
809 }
810 
811 static __inline u_int32_t
_2btol(const u_int8_t * bytes)812 _2btol(const u_int8_t *bytes)
813 {
814           u_int32_t rv;
815 
816           rv = (bytes[0] << 8) |
817                bytes[1];
818           return (rv);
819 }
820 
821 static __inline u_int32_t
_3btol(const u_int8_t * bytes)822 _3btol(const u_int8_t *bytes)
823 {
824           u_int32_t rv;
825 
826           rv = (bytes[0] << 16) |
827                (bytes[1] << 8) |
828                bytes[2];
829           return (rv);
830 }
831 
832 static __inline u_int32_t
_4btol(const u_int8_t * bytes)833 _4btol(const u_int8_t *bytes)
834 {
835           u_int32_t rv;
836 
837           rv = ((u_int32_t)bytes[0] << 24) |
838                ((u_int32_t)bytes[1] << 16) |
839                ((u_int32_t)bytes[2] << 8) |
840                (u_int32_t)bytes[3];
841           return (rv);
842 }
843 
844 static __inline u_int64_t
_5btol(const u_int8_t * bytes)845 _5btol(const u_int8_t *bytes)
846 {
847           u_int64_t rv;
848 
849           rv = ((u_int64_t)bytes[0] << 32) |
850                ((u_int64_t)bytes[1] << 24) |
851                ((u_int64_t)bytes[2] << 16) |
852                ((u_int64_t)bytes[3] << 8) |
853                (u_int64_t)bytes[4];
854           return (rv);
855 }
856 
857 static __inline u_int64_t
_8btol(const u_int8_t * bytes)858 _8btol(const u_int8_t *bytes)
859 {
860           u_int64_t rv;
861 
862           rv = ((u_int64_t)bytes[0] << 56) |
863                ((u_int64_t)bytes[1] << 48) |
864                ((u_int64_t)bytes[2] << 40) |
865                ((u_int64_t)bytes[3] << 32) |
866                ((u_int64_t)bytes[4] << 24) |
867                ((u_int64_t)bytes[5] << 16) |
868                ((u_int64_t)bytes[6] << 8) |
869                (u_int64_t)bytes[7];
870           return (rv);
871 }
872 
873 static __inline void
_lto2l(u_int32_t val,u_int8_t * bytes)874 _lto2l(u_int32_t val, u_int8_t *bytes)
875 {
876 
877           bytes[0] = val & 0xff;
878           bytes[1] = (val >> 8) & 0xff;
879 }
880 
881 static __inline void
_lto3l(u_int32_t val,u_int8_t * bytes)882 _lto3l(u_int32_t val, u_int8_t *bytes)
883 {
884 
885           bytes[0] = val & 0xff;
886           bytes[1] = (val >> 8) & 0xff;
887           bytes[2] = (val >> 16) & 0xff;
888 }
889 
890 static __inline void
_lto4l(u_int32_t val,u_int8_t * bytes)891 _lto4l(u_int32_t val, u_int8_t *bytes)
892 {
893 
894           bytes[0] = val & 0xff;
895           bytes[1] = (val >> 8) & 0xff;
896           bytes[2] = (val >> 16) & 0xff;
897           bytes[3] = (val >> 24) & 0xff;
898 }
899 
900 static __inline u_int32_t
_2ltol(const u_int8_t * bytes)901 _2ltol(const u_int8_t *bytes)
902 {
903           u_int32_t rv;
904 
905           rv = bytes[0] |
906                (bytes[1] << 8);
907           return (rv);
908 }
909 
910 static __inline u_int32_t
_3ltol(const u_int8_t * bytes)911 _3ltol(const u_int8_t *bytes)
912 {
913           u_int32_t rv;
914 
915           rv = bytes[0] |
916                (bytes[1] << 8) |
917                (bytes[2] << 16);
918           return (rv);
919 }
920 
921 static __inline u_int32_t
_4ltol(const u_int8_t * bytes)922 _4ltol(const u_int8_t *bytes)
923 {
924           u_int32_t rv;
925 
926           rv = (u_int32_t)bytes[0] |
927                ((u_int32_t)bytes[1] << 8) |
928                ((u_int32_t)bytes[2] << 16) |
929                ((u_int32_t)bytes[3] << 24);
930           return (rv);
931 }
932 
933 #endif /* _DEV_SCSIPI_SCSIPICONF_H_ */
934