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