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