1 /* $NetBSD: scsipiconf.h,v 1.101 2005/12/11 12:23:50 christos 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 #ifdef __hppa__ 538 /* XXX temp hack until we fix the memory corruption bug */ 539 u_int8_t pad[32]; 540 #endif 541 }; 542 543 /* 544 * scsipi_xfer control flags 545 * 546 * To do: 547 * 548 * - figure out what to do with XS_CTL_ESCAPE 549 * 550 * - replace XS_CTL_URGENT with an `xs_priority' field? 551 */ 552 #define XS_CTL_NOSLEEP 0x00000001 /* don't sleep */ 553 #define XS_CTL_POLL 0x00000002 /* poll for completion */ 554 #define XS_CTL_DISCOVERY 0x00000004 /* doing device discovery */ 555 #define XS_CTL_ASYNC 0x00000008 /* command completes 556 asynchronously */ 557 #define XS_CTL_USERCMD 0x00000010 /* user issued command */ 558 #define XS_CTL_SILENT 0x00000020 /* don't print sense info */ 559 #define XS_CTL_IGNORE_NOT_READY 0x00000040 /* ignore NOT READY */ 560 #define XS_CTL_IGNORE_MEDIA_CHANGE \ 561 0x00000080 /* ignore media change */ 562 #define XS_CTL_IGNORE_ILLEGAL_REQUEST \ 563 0x00000100 /* ignore ILLEGAL REQUEST */ 564 #define XS_CTL_SILENT_NODEV 0x00000200 /* don't print sense info 565 if sense info is nodev */ 566 #define XS_CTL_RESET 0x00000400 /* reset the device */ 567 #define XS_CTL_DATA_UIO 0x00000800 /* xs_data points to uio */ 568 #define XS_CTL_DATA_IN 0x00001000 /* data coming into memory */ 569 #define XS_CTL_DATA_OUT 0x00002000 /* data going out of memory */ 570 #define XS_CTL_TARGET 0x00004000 /* target mode operation */ 571 #define XS_CTL_ESCAPE 0x00008000 /* escape operation */ 572 #define XS_CTL_URGENT 0x00010000 /* urgent (recovery) 573 operation */ 574 #define XS_CTL_SIMPLE_TAG 0x00020000 /* use a Simple Tag */ 575 #define XS_CTL_ORDERED_TAG 0x00040000 /* use an Ordered Tag */ 576 #define XS_CTL_HEAD_TAG 0x00080000 /* use a Head of Queue Tag */ 577 #define XS_CTL_THAW_PERIPH 0x00100000 /* thaw periph once enqueued */ 578 #define XS_CTL_FREEZE_PERIPH 0x00200000 /* freeze periph when done */ 579 #define XS_CTL_DATA_ONSTACK 0x00400000 /* data is alloc'ed on stack */ 580 #define XS_CTL_REQSENSE 0x00800000 /* xfer is a request sense */ 581 582 #define XS_CTL_TAGMASK (XS_CTL_SIMPLE_TAG|XS_CTL_ORDERED_TAG|XS_CTL_HEAD_TAG) 583 584 #define XS_CTL_TAGTYPE(xs) ((xs)->xs_control & XS_CTL_TAGMASK) 585 586 /* 587 * scsipi_xfer status flags 588 */ 589 #define XS_STS_DONE 0x00000001 /* scsipi_xfer is done */ 590 #define XS_STS_PRIVATE 0xf0000000 /* reserved for HBA's use */ 591 592 /* 593 * This describes matching information for scsipi_inqmatch(). The more things 594 * match, the higher the configuration priority. 595 */ 596 struct scsipi_inquiry_pattern { 597 u_int8_t type; 598 boolean removable; 599 const char *vendor; 600 const char *product; 601 const char *revision; 602 }; 603 604 /* 605 * This is used to pass information from the high-level configuration code 606 * to the device-specific drivers. 607 */ 608 struct scsipibus_attach_args { 609 struct scsipi_periph *sa_periph; 610 struct scsipi_inquiry_pattern sa_inqbuf; 611 struct scsipi_inquiry_data *sa_inqptr; 612 union { /* bus-type specific infos */ 613 u_int8_t scsi_version; /* SCSI version */ 614 } scsipi_info; 615 }; 616 617 /* 618 * this describes a quirk entry 619 */ 620 struct scsi_quirk_inquiry_pattern { 621 struct scsipi_inquiry_pattern pattern; 622 int quirks; 623 }; 624 625 /* 626 * Default number of retries, used for generic routines. 627 */ 628 #define SCSIPIRETRIES 4 629 630 631 #ifdef _KERNEL 632 void scsipi_init(void); 633 int scsipi_command(struct scsipi_periph *, struct scsipi_generic *, int, 634 u_char *, int, int, int, struct buf *, int); 635 void scsipi_create_completion_thread(void *); 636 const void *scsipi_inqmatch(struct scsipi_inquiry_pattern *, const void *, 637 size_t, size_t, int *); 638 const char *scsipi_dtype(int); 639 void scsipi_strvis(u_char *, int, const u_char *, int); 640 int scsipi_execute_xs(struct scsipi_xfer *); 641 u_int64_t scsipi_size(struct scsipi_periph *, int); 642 int scsipi_test_unit_ready(struct scsipi_periph *, int); 643 int scsipi_prevent(struct scsipi_periph *, int, int); 644 int scsipi_inquire(struct scsipi_periph *, 645 struct scsipi_inquiry_data *, int); 646 int scsipi_mode_select(struct scsipi_periph *, int, 647 struct scsi_mode_parameter_header_6 *, int, int, int, int); 648 int scsipi_mode_select_big(struct scsipi_periph *, int, 649 struct scsi_mode_parameter_header_10 *, int, int, int, int); 650 int scsipi_mode_sense(struct scsipi_periph *, int, int, 651 struct scsi_mode_parameter_header_6 *, int, int, int, int); 652 int scsipi_mode_sense_big(struct scsipi_periph *, int, int, 653 struct scsi_mode_parameter_header_10 *, int, int, int, int); 654 int scsipi_start(struct scsipi_periph *, int, int); 655 void scsipi_done(struct scsipi_xfer *); 656 void scsipi_user_done(struct scsipi_xfer *); 657 int scsipi_interpret_sense(struct scsipi_xfer *); 658 void scsipi_wait_drain(struct scsipi_periph *); 659 void scsipi_kill_pending(struct scsipi_periph *); 660 struct scsipi_periph *scsipi_alloc_periph(int); 661 #ifdef SCSIVERBOSE 662 void scsipi_print_sense(struct scsipi_xfer *, int); 663 void scsipi_print_sense_data(struct scsi_sense_data *, int); 664 char *scsipi_decode_sense(void *, int); 665 #endif 666 void scsipi_print_cdb(struct scsipi_generic *cmd); 667 int scsipi_thread_call_callback(struct scsipi_channel *, 668 void (*callback)(struct scsipi_channel *, void *), 669 void *); 670 void scsipi_async_event(struct scsipi_channel *, 671 scsipi_async_event_t, void *); 672 int scsipi_do_ioctl(struct scsipi_periph *, dev_t, u_long, caddr_t, 673 int, struct lwp *); 674 675 void scsipi_print_xfer_mode(struct scsipi_periph *); 676 void scsipi_set_xfer_mode(struct scsipi_channel *, int, int); 677 678 int scsipi_channel_init(struct scsipi_channel *); 679 void scsipi_channel_shutdown(struct scsipi_channel *); 680 681 void scsipi_insert_periph(struct scsipi_channel *, 682 struct scsipi_periph *); 683 void scsipi_remove_periph(struct scsipi_channel *, 684 struct scsipi_periph *); 685 struct scsipi_periph *scsipi_lookup_periph(struct scsipi_channel *, 686 int, int); 687 int scsipi_target_detach(struct scsipi_channel *, int, int, int); 688 689 int scsipi_adapter_addref(struct scsipi_adapter *); 690 void scsipi_adapter_delref(struct scsipi_adapter *); 691 692 void scsipi_channel_freeze(struct scsipi_channel *, int); 693 void scsipi_channel_thaw(struct scsipi_channel *, int); 694 void scsipi_channel_timed_thaw(void *); 695 696 void scsipi_periph_freeze(struct scsipi_periph *, int); 697 void scsipi_periph_thaw(struct scsipi_periph *, int); 698 void scsipi_periph_timed_thaw(void *); 699 700 int scsipi_sync_period_to_factor(int); 701 int scsipi_sync_factor_to_period(int); 702 int scsipi_sync_factor_to_freq(int); 703 704 void show_scsipi_xs(struct scsipi_xfer *); 705 void show_scsipi_cmd(struct scsipi_xfer *); 706 void show_mem(u_char *, int); 707 #endif /* _KERNEL */ 708 709 static __inline void __unused 710 _lto2b(u_int32_t val, u_int8_t *bytes) 711 { 712 713 bytes[0] = (val >> 8) & 0xff; 714 bytes[1] = val & 0xff; 715 } 716 717 static __inline void __unused 718 _lto3b(u_int32_t val, u_int8_t *bytes) 719 { 720 721 bytes[0] = (val >> 16) & 0xff; 722 bytes[1] = (val >> 8) & 0xff; 723 bytes[2] = val & 0xff; 724 } 725 726 static __inline void __unused 727 _lto4b(u_int32_t val, u_int8_t *bytes) 728 { 729 730 bytes[0] = (val >> 24) & 0xff; 731 bytes[1] = (val >> 16) & 0xff; 732 bytes[2] = (val >> 8) & 0xff; 733 bytes[3] = val & 0xff; 734 } 735 736 static __inline void __unused 737 _lto8b(u_int64_t val, u_int8_t *bytes) 738 { 739 740 bytes[0] = (val >> 56) & 0xff; 741 bytes[1] = (val >> 48) & 0xff; 742 bytes[2] = (val >> 40) & 0xff; 743 bytes[3] = (val >> 32) & 0xff; 744 bytes[4] = (val >> 24) & 0xff; 745 bytes[5] = (val >> 16) & 0xff; 746 bytes[6] = (val >> 8) & 0xff; 747 bytes[7] = val & 0xff; 748 } 749 750 static __inline u_int32_t __unused 751 _2btol(const u_int8_t *bytes) 752 { 753 u_int32_t rv; 754 755 rv = (bytes[0] << 8) | 756 bytes[1]; 757 return (rv); 758 } 759 760 static __inline u_int32_t __unused 761 _3btol(const u_int8_t *bytes) 762 { 763 u_int32_t rv; 764 765 rv = (bytes[0] << 16) | 766 (bytes[1] << 8) | 767 bytes[2]; 768 return (rv); 769 } 770 771 static __inline u_int32_t __unused 772 _4btol(const u_int8_t *bytes) 773 { 774 u_int32_t rv; 775 776 rv = (bytes[0] << 24) | 777 (bytes[1] << 16) | 778 (bytes[2] << 8) | 779 bytes[3]; 780 return (rv); 781 } 782 783 static __inline u_int64_t __unused 784 _5btol(const u_int8_t *bytes) 785 { 786 u_int64_t rv; 787 788 rv = ((u_int64_t)bytes[0] << 32) | 789 ((u_int64_t)bytes[1] << 24) | 790 ((u_int64_t)bytes[2] << 16) | 791 ((u_int64_t)bytes[3] << 8) | 792 (u_int64_t)bytes[4]; 793 return (rv); 794 } 795 796 static __inline u_int64_t __unused 797 _8btol(const u_int8_t *bytes) 798 { 799 u_int64_t rv; 800 801 rv = ((u_int64_t)bytes[0] << 56) | 802 ((u_int64_t)bytes[1] << 48) | 803 ((u_int64_t)bytes[2] << 40) | 804 ((u_int64_t)bytes[3] << 32) | 805 ((u_int64_t)bytes[4] << 24) | 806 ((u_int64_t)bytes[5] << 16) | 807 ((u_int64_t)bytes[6] << 8) | 808 (u_int64_t)bytes[7]; 809 return (rv); 810 } 811 812 static __inline void __unused 813 _lto2l(u_int32_t val, u_int8_t *bytes) 814 { 815 816 bytes[0] = val & 0xff; 817 bytes[1] = (val >> 8) & 0xff; 818 } 819 820 static __inline void __unused 821 _lto3l(u_int32_t val, u_int8_t *bytes) 822 { 823 824 bytes[0] = val & 0xff; 825 bytes[1] = (val >> 8) & 0xff; 826 bytes[2] = (val >> 16) & 0xff; 827 } 828 829 static __inline void __unused 830 _lto4l(u_int32_t val, u_int8_t *bytes) 831 { 832 833 bytes[0] = val & 0xff; 834 bytes[1] = (val >> 8) & 0xff; 835 bytes[2] = (val >> 16) & 0xff; 836 bytes[3] = (val >> 24) & 0xff; 837 } 838 839 static __inline u_int32_t __unused 840 _2ltol(const u_int8_t *bytes) 841 { 842 u_int32_t rv; 843 844 rv = bytes[0] | 845 (bytes[1] << 8); 846 return (rv); 847 } 848 849 static __inline u_int32_t __unused 850 _3ltol(const u_int8_t *bytes) 851 { 852 u_int32_t rv; 853 854 rv = bytes[0] | 855 (bytes[1] << 8) | 856 (bytes[2] << 16); 857 return (rv); 858 } 859 860 static __inline u_int32_t __unused 861 _4ltol(const u_int8_t *bytes) 862 { 863 u_int32_t rv; 864 865 rv = bytes[0] | 866 (bytes[1] << 8) | 867 (bytes[2] << 16) | 868 (bytes[3] << 24); 869 return (rv); 870 } 871 872 #endif /* _DEV_SCSIPI_SCSIPICONF_H_ */ 873