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