1 /* $NetBSD: scsipiconf.h,v 1.76 2003/06/29 22:30:41 fvdl 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_generic *, int, void *, size_t, int, 242 int, struct buf *, int)); 243 int (*bustype_interpret_sense) __P((struct scsipi_xfer *)); 244 void (*bustype_printaddr) __P((struct scsipi_periph *)); 245 void (*bustype_kill_pending) __P((struct scsipi_periph *)); 246 }; 247 248 /* bustype_type */ 249 #define SCSIPI_BUSTYPE_SCSI 0 250 #define SCSIPI_BUSTYPE_ATAPI 1 251 /* #define SCSIPI_BUSTYPE_ATA 2 */ 252 253 254 /* 255 * scsipi_channel: 256 * 257 * This structure describes a single channel of a SCSIPI adapter. 258 * An adapter may have one or more channels. See the comment above 259 * regarding the resource counter. 260 * Note: chan_bustype has to be first member, as its bustype_type member 261 * is shared with the aa_bustype member of struct ata_atapi_attach. 262 */ 263 264 #define SCSIPI_CHAN_PERIPH_BUCKETS 16 265 #define SCSIPI_CHAN_PERIPH_HASHMASK (SCSIPI_CHAN_PERIPH_BUCKETS - 1) 266 267 struct scsipi_channel { 268 const struct scsipi_bustype *chan_bustype; /* channel's bus type */ 269 const char *chan_name; /* this channel's name */ 270 271 struct scsipi_adapter *chan_adapter; /* pointer to our adapter */ 272 273 /* Periphs for this channel. */ 274 LIST_HEAD(, scsipi_periph) chan_periphtab[SCSIPI_CHAN_PERIPH_BUCKETS]; 275 276 int chan_channel; /* channel number */ 277 int chan_flags; /* channel flags */ 278 int chan_openings; /* number of command openings */ 279 int chan_max_periph; /* max openings per periph */ 280 281 int chan_ntargets; /* number of targets */ 282 int chan_nluns; /* number of luns */ 283 int chan_id; /* adapter's ID for this channel */ 284 285 int chan_defquirks; /* default device's quirks */ 286 287 struct proc *chan_thread; /* completion thread */ 288 int chan_tflags; /* flags for the completion thread */ 289 290 int chan_qfreeze; /* freeze count for queue */ 291 292 /* Job queue for this channel. */ 293 struct scsipi_xfer_queue chan_queue; 294 295 /* Completed (async) jobs. */ 296 struct scsipi_xfer_queue chan_complete; 297 298 /* callback we may have to call from completion thread */ 299 void (*chan_callback) __P((struct scsipi_channel *, void *)); 300 void *chan_callback_arg; 301 302 /* callback we may have to call after forking the kthread */ 303 void (*chan_init_cb) __P((struct scsipi_channel *, void *)); 304 void *chan_init_cb_arg; 305 }; 306 307 /* chan_flags */ 308 #define SCSIPI_CHAN_OPENINGS 0x01 /* use chan_openings */ 309 #define SCSIPI_CHAN_CANGROW 0x02 /* channel can grow resources */ 310 #define SCSIPI_CHAN_NOSETTLE 0x04 /* don't wait for devices to settle */ 311 #define SCSIPI_CHAN_TACTIVE 0x08 /* completion thread is active */ 312 313 /* chan thread flags (chan_tflags) */ 314 #define SCSIPI_CHANT_SHUTDOWN 0x01 /* channel is shutting down */ 315 #define SCSIPI_CHANT_CALLBACK 0x02 /* has to call chan_callback() */ 316 #define SCSIPI_CHANT_KICK 0x04 /* need to run queues */ 317 #define SCSIPI_CHANT_GROWRES 0x08 /* call ADAPTER_REQ_GROW_RESOURCES */ 318 319 #define SCSIPI_CHAN_MAX_PERIPH(chan) \ 320 (((chan)->chan_flags & SCSIPI_CHAN_OPENINGS) ? \ 321 (chan)->chan_max_periph : (chan)->chan_adapter->adapt_max_periph) 322 323 324 #define scsipi_printaddr(periph) \ 325 (*(periph)->periph_channel->chan_bustype->bustype_printaddr)((periph)) 326 327 #define scsipi_periph_bustype(periph) \ 328 (periph)->periph_channel->chan_bustype->bustype_type 329 330 331 /* 332 * Number of tag words in a periph structure: 333 * 334 * n_tag_words = ((256 / NBBY) / sizeof(u_int32_t)) 335 */ 336 #define PERIPH_NTAGWORDS ((256 / 8) / sizeof(u_int32_t)) 337 338 339 /* 340 * scsipi_periph: 341 * 342 * This structure describes the path between a peripherial device 343 * and an adapter. It contains a pointer to the adapter channel 344 * which in turn contains a pointer to the adapter. 345 * 346 * XXX Given the way NetBSD's autoconfiguration works, this is ... 347 * XXX nasty. 348 * 349 * Well, it's a lot nicer than it used to be, but there could 350 * still be an improvement. 351 */ 352 struct scsipi_periph { 353 struct device *periph_dev; /* pointer to peripherial's device */ 354 struct scsipi_channel *periph_channel; /* channel we're connected to */ 355 356 /* link in channel's table of periphs */ 357 LIST_ENTRY(scsipi_periph) periph_hash; 358 359 const struct scsipi_periphsw *periph_switch; /* peripherial's entry 360 points */ 361 int periph_openings; /* max # of outstanding commands */ 362 int periph_active; /* current # of outstanding commands */ 363 int periph_sent; /* current # of commands sent to adapt*/ 364 365 int periph_mode; /* operation modes, CAP bits */ 366 int periph_period; /* sync period (factor) */ 367 int periph_offset; /* sync offset */ 368 369 /* 370 * Information gleaned from the inquiry data. 371 */ 372 u_int8_t periph_type; /* basic device type */ 373 int periph_cap; /* capabilities */ 374 int periph_quirks; /* device's quirks */ 375 376 int periph_flags; /* misc. flags */ 377 int periph_dbflags; /* debugging flags */ 378 379 int periph_target; /* target ID (drive # on ATAPI) */ 380 int periph_lun; /* LUN (not used on ATAPI) */ 381 382 int periph_version; /* ANSI SCSI version */ 383 384 int periph_qfreeze; /* queue freeze count */ 385 386 /* Bitmap of free command tags. */ 387 u_int32_t periph_freetags[PERIPH_NTAGWORDS]; 388 389 /* Pending scsipi_xfers on this peripherial. */ 390 struct scsipi_xfer_queue periph_xferq; 391 392 struct callout periph_callout; 393 394 /* xfer which has a pending CHECK_CONDITION */ 395 struct scsipi_xfer *periph_xscheck; 396 397 }; 398 399 /* 400 * Macro to return the current xfer mode of a periph. 401 */ 402 #define PERIPH_XFER_MODE(periph) \ 403 (((periph)->periph_flags & PERIPH_MODE_VALID) ? \ 404 (periph)->periph_mode : 0) 405 406 /* periph_cap */ 407 #define PERIPH_CAP_ANEC 0x0001 /* async event notification */ 408 #define PERIPH_CAP_TERMIOP 0x0002 /* terminate i/o proc. messages */ 409 #define PERIPH_CAP_RELADR 0x0004 /* relative addressing */ 410 #define PERIPH_CAP_WIDE32 0x0008 /* wide-32 transfers */ 411 #define PERIPH_CAP_WIDE16 0x0010 /* wide-16 transfers */ 412 /* XXX 0x0020 reserved for ATAPI_CFG_DRQ_MASK */ 413 /* XXX 0x0040 reserved for ATAPI_CFG_DRQ_MASK */ 414 #define PERIPH_CAP_SYNC 0x0080 /* synchronous transfers */ 415 #define PERIPH_CAP_LINKCMDS 0x0100 /* linked commands */ 416 #define PERIPH_CAP_TQING 0x0200 /* tagged queueing */ 417 #define PERIPH_CAP_SFTRESET 0x0400 /* soft RESET condition response */ 418 #define PERIPH_CAP_CMD16 0x0800 /* 16 byte commands (ATAPI) */ 419 #define PERIPH_CAP_DT 0x1000 /* supports DT clock */ 420 #define PERIPH_CAP_QAS 0x2000 /* supports quick arbit. and select. */ 421 #define PERIPH_CAP_IUS 0x4000 /* supports information unit xfers */ 422 423 /* periph_flags */ 424 #define PERIPH_REMOVABLE 0x0001 /* media is removable */ 425 #define PERIPH_MEDIA_LOADED 0x0002 /* media is loaded */ 426 #define PERIPH_WAITING 0x0004 /* process waiting for opening */ 427 #define PERIPH_OPEN 0x0008 /* device is open */ 428 #define PERIPH_WAITDRAIN 0x0010 /* waiting for pending xfers to drain */ 429 #define PERIPH_GROW_OPENINGS 0x0020 /* allow openings to grow */ 430 #define PERIPH_MODE_VALID 0x0040 /* periph_mode is valid */ 431 #define PERIPH_RECOVERING 0x0080 /* periph is recovering */ 432 #define PERIPH_RECOVERY_ACTIVE 0x0100 /* a recovery command is active */ 433 #define PERIPH_KEEP_LABEL 0x0200 /* retain label after 'full' close */ 434 #define PERIPH_SENSE 0x0400 /* periph has sense pending */ 435 #define PERIPH_UNTAG 0x0800 /* untagged command running */ 436 437 /* periph_quirks */ 438 #define PQUIRK_AUTOSAVE 0x00000001 /* do implicit SAVE POINTERS */ 439 #define PQUIRK_NOSYNC 0x00000002 /* does not grok SDTR */ 440 #define PQUIRK_NOWIDE 0x00000004 /* does not grok WDTR */ 441 #define PQUIRK_NOTAG 0x00000008 /* does not grok tagged cmds */ 442 #define PQUIRK_NOLUNS 0x00000010 /* DTWT with LUNs */ 443 #define PQUIRK_FORCELUNS 0x00000020 /* prehistoric device groks 444 LUNs */ 445 #define PQUIRK_NOMODESENSE 0x00000040 /* device doesn't do MODE SENSE 446 properly */ 447 #define PQUIRK_NOSTARTUNIT 0x00000080 /* do not issue START UNIT */ 448 #define PQUIRK_NOSYNCCACHE 0x00000100 /* do not issue SYNC CACHE */ 449 #define PQUIRK_CDROM 0x00000200 /* device is a CD-ROM, no 450 matter what else it claims */ 451 #define PQUIRK_LITTLETOC 0x00000400 /* audio TOC is little-endian */ 452 #define PQUIRK_NOCAPACITY 0x00000800 /* no READ CD CAPACITY */ 453 #define PQUIRK_NOTUR 0x00001000 /* no TEST UNIT READY */ 454 #define PQUIRK_NODOORLOCK 0x00002000 /* can't lock door */ 455 #define PQUIRK_NOSENSE 0x00004000 /* can't REQUEST SENSE */ 456 #define PQUIRK_ONLYBIG 0x00008000 /* only use SCSI_{R,W}_BIG */ 457 #define PQUIRK_BYTE5_ZERO 0x00010000 /* byte5 in capacity is wrong */ 458 #define PQUIRK_NO_FLEX_PAGE 0x00020000 /* does not support flex geom 459 page */ 460 #define PQUIRK_NOBIGMODESENSE 0x00040000 /* has no big mode-sense op */ 461 #define PQUIRK_CAP_SYNC 0x00080000 /* SCSI device with ST sync op*/ 462 #define PQUIRK_CAP_WIDE16 0x00100000 /* SCSI device with ST wide op*/ 463 #define PQUIRK_CAP_NODT 0x00200000 /* signals DT, but can't. */ 464 465 466 /* 467 * Error values an adapter driver may return 468 */ 469 typedef enum { 470 XS_NOERROR, /* there is no error, (sense is invalid) */ 471 XS_SENSE, /* Check the returned sense for the error */ 472 XS_SHORTSENSE, /* Check the ATAPI sense for the error */ 473 XS_DRIVER_STUFFUP, /* Driver failed to perform operation */ 474 XS_RESOURCE_SHORTAGE, /* adapter resource shortage */ 475 XS_SELTIMEOUT, /* The device timed out.. turned off? */ 476 XS_TIMEOUT, /* The Timeout reported was caught by SW */ 477 XS_BUSY, /* The device busy, try again later? */ 478 XS_RESET, /* bus was reset; possible retry command */ 479 XS_REQUEUE /* requeue this command */ 480 } scsipi_xfer_result_t; 481 482 /* 483 * Each scsipi transaction is fully described by one of these structures 484 * It includes information about the source of the command and also the 485 * device and adapter for which the command is destined. 486 * 487 * Before the HBA is given this transaction, channel_q is the linkage on 488 * the related channel's chan_queue. 489 * 490 * When the this transaction is taken off the channel's chan_queue and 491 * the HBA's request entry point is called with this transaction, the 492 * HBA can use the channel_q tag for whatever it likes until it calls 493 * scsipi_done for this transaction, at which time it has to stop 494 * using channel_q. 495 * 496 * After scsipi_done is called with this transaction and if there was an 497 * error on it, channel_q then becomes the linkage on the related channel's 498 * chan_complete cqueue. 499 * 500 * The device_q member is maintained by the scsipi middle layer. When 501 * a device issues a command, the xfer is placed on that device's 502 * pending commands queue. When an xfer is done and freed, it is taken 503 * off the device's queue. This allows for a device to wait for all of 504 * its pending commands to complete. 505 */ 506 struct scsipi_xfer { 507 TAILQ_ENTRY(scsipi_xfer) channel_q; /* entry on channel queue */ 508 TAILQ_ENTRY(scsipi_xfer) device_q; /* device's pending xfers */ 509 struct callout xs_callout; /* callout for adapter use */ 510 int xs_control; /* control flags */ 511 __volatile int xs_status; /* status flags */ 512 struct scsipi_periph *xs_periph;/* peripherial doing the xfer */ 513 int xs_retries; /* the number of times to retry */ 514 int xs_requeuecnt; /* number of requeues */ 515 int timeout; /* in milliseconds */ 516 struct scsipi_generic *cmd; /* The scsipi command to execute */ 517 int cmdlen; /* how long it is */ 518 u_char *data; /* DMA address OR a uio address */ 519 int datalen; /* data len (blank if uio) */ 520 int resid; /* how much buffer was not touched */ 521 scsipi_xfer_result_t error; /* an error value */ 522 struct buf *bp; /* If we need to associate with */ 523 /* a buf */ 524 union { 525 struct scsipi_sense_data scsi_sense; /* 32 bytes */ 526 u_int32_t atapi_sense; 527 } sense; 528 529 struct scsipi_xfer *xs_sensefor;/* we are requesting sense for this */ 530 /* xfer */ 531 532 u_int8_t status; /* SCSI status */ 533 534 /* 535 * Info for tagged command queueing. This may or may not 536 * be used by a given adapter driver. These are the same 537 * as the bytes in the tag message. 538 */ 539 u_int8_t xs_tag_type; /* tag type */ 540 u_int8_t xs_tag_id; /* tag ID */ 541 542 struct scsipi_generic cmdstore 543 __attribute__ ((aligned (4)));/* stash the command in here */ 544 }; 545 546 /* 547 * scsipi_xfer control flags 548 * 549 * To do: 550 * 551 * - figure out what to do with XS_CTL_ESCAPE 552 * 553 * - replace XS_CTL_URGENT with an `xs_priority' field? 554 */ 555 #define XS_CTL_NOSLEEP 0x00000001 /* don't sleep */ 556 #define XS_CTL_POLL 0x00000002 /* poll for completion */ 557 #define XS_CTL_DISCOVERY 0x00000004 /* doing device discovery */ 558 #define XS_CTL_ASYNC 0x00000008 /* command completes 559 asynchronously */ 560 #define XS_CTL_USERCMD 0x00000010 /* user issued command */ 561 #define XS_CTL_SILENT 0x00000020 /* don't print sense info */ 562 #define XS_CTL_IGNORE_NOT_READY 0x00000040 /* ignore NOT READY */ 563 #define XS_CTL_IGNORE_MEDIA_CHANGE \ 564 0x00000080 /* ignore media change */ 565 #define XS_CTL_IGNORE_ILLEGAL_REQUEST \ 566 0x00000100 /* ignore ILLEGAL REQUEST */ 567 #define XS_CTL_SILENT_NODEV 0x00000200 /* don't print sense info 568 if sense info is nodev */ 569 #define XS_CTL_RESET 0x00000400 /* reset the device */ 570 #define XS_CTL_DATA_UIO 0x00000800 /* xs_data points to uio */ 571 #define XS_CTL_DATA_IN 0x00001000 /* data coming into memory */ 572 #define XS_CTL_DATA_OUT 0x00002000 /* data going out of memory */ 573 #define XS_CTL_TARGET 0x00004000 /* target mode operation */ 574 #define XS_CTL_ESCAPE 0x00008000 /* escape operation */ 575 #define XS_CTL_URGENT 0x00010000 /* urgent (recovery) 576 operation */ 577 #define XS_CTL_SIMPLE_TAG 0x00020000 /* use a Simple Tag */ 578 #define XS_CTL_ORDERED_TAG 0x00040000 /* use an Ordered Tag */ 579 #define XS_CTL_HEAD_TAG 0x00080000 /* use a Head of Queue Tag */ 580 #define XS_CTL_THAW_PERIPH 0x00100000 /* thaw periph once enqueued */ 581 #define XS_CTL_FREEZE_PERIPH 0x00200000 /* freeze periph when done */ 582 #define XS_CTL_DATA_ONSTACK 0x00400000 /* data is alloc'ed on stack */ 583 #define XS_CTL_REQSENSE 0x00800000 /* xfer is a request sense */ 584 585 #define XS_CTL_TAGMASK (XS_CTL_SIMPLE_TAG|XS_CTL_ORDERED_TAG|XS_CTL_HEAD_TAG) 586 587 #define XS_CTL_TAGTYPE(xs) ((xs)->xs_control & XS_CTL_TAGMASK) 588 589 /* 590 * scsipi_xfer status flags 591 */ 592 #define XS_STS_DONE 0x00000001 /* scsipi_xfer is done */ 593 #define XS_STS_PRIVATE 0xf0000000 /* reserved for HBA's use */ 594 595 /* 596 * This describes matching information for scsipi_inqmatch(). The more things 597 * match, the higher the configuration priority. 598 */ 599 struct scsipi_inquiry_pattern { 600 u_int8_t type; 601 boolean removable; 602 char *vendor; 603 char *product; 604 char *revision; 605 }; 606 607 /* 608 * This is used to pass information from the high-level configuration code 609 * to the device-specific drivers. 610 */ 611 struct scsipibus_attach_args { 612 struct scsipi_periph *sa_periph; 613 struct scsipi_inquiry_pattern sa_inqbuf; 614 struct scsipi_inquiry_data *sa_inqptr; 615 union { /* bus-type specific infos */ 616 u_int8_t scsi_version; /* SCSI version */ 617 } scsipi_info; 618 }; 619 620 /* 621 * this describes a quirk entry 622 */ 623 struct scsi_quirk_inquiry_pattern { 624 struct scsipi_inquiry_pattern pattern; 625 int quirks; 626 }; 627 628 /* 629 * Default number of retries, used for generic routines. 630 */ 631 #define SCSIPIRETRIES 4 632 633 634 #ifdef _KERNEL 635 void scsipi_init __P((void)); 636 int scsipi_command __P((struct scsipi_periph *, 637 struct scsipi_generic *, int, u_char *, int, 638 int, int, struct buf *, int)); 639 void scsipi_create_completion_thread __P((void *)); 640 caddr_t scsipi_inqmatch __P((struct scsipi_inquiry_pattern *, caddr_t, 641 int, int, int *)); 642 char *scsipi_dtype __P((int)); 643 void scsipi_strvis __P((u_char *, int, u_char *, int)); 644 int scsipi_execute_xs __P((struct scsipi_xfer *)); 645 u_int64_t scsipi_size __P((struct scsipi_periph *, int)); 646 int scsipi_test_unit_ready __P((struct scsipi_periph *, int)); 647 int scsipi_prevent __P((struct scsipi_periph *, int, int)); 648 int scsipi_inquire __P((struct scsipi_periph *, 649 struct scsipi_inquiry_data *, int)); 650 int scsipi_mode_select __P((struct scsipi_periph *, int, 651 struct scsipi_mode_header *, int, int, int, int)); 652 int scsipi_mode_select_big __P((struct scsipi_periph *, int, 653 struct scsipi_mode_header_big *, int, int, int, int)); 654 int scsipi_mode_sense __P((struct scsipi_periph *, int, int, 655 struct scsipi_mode_header *, int, int, int, int)); 656 int scsipi_mode_sense_big __P((struct scsipi_periph *, int, int, 657 struct scsipi_mode_header_big *, int, int, int, int)); 658 int scsipi_start __P((struct scsipi_periph *, int, int)); 659 void scsipi_done __P((struct scsipi_xfer *)); 660 void scsipi_user_done __P((struct scsipi_xfer *)); 661 int scsipi_interpret_sense __P((struct scsipi_xfer *)); 662 void scsipi_wait_drain __P((struct scsipi_periph *)); 663 void scsipi_kill_pending __P((struct scsipi_periph *)); 664 struct scsipi_periph *scsipi_alloc_periph __P((int)); 665 #ifdef SCSIVERBOSE 666 void scsipi_print_sense __P((struct scsipi_xfer *, int)); 667 void scsipi_print_sense_data __P((struct scsipi_sense_data *, int)); 668 char *scsipi_decode_sense __P((void *, int)); 669 #endif 670 int scsipi_thread_call_callback __P((struct scsipi_channel *, 671 void (*callback) __P((struct scsipi_channel *, void *)), 672 void *)); 673 void scsipi_async_event __P((struct scsipi_channel *, 674 scsipi_async_event_t, void *)); 675 int scsipi_do_ioctl __P((struct scsipi_periph *, dev_t, u_long, caddr_t, 676 int, struct proc *)); 677 678 void scsipi_print_xfer_mode __P((struct scsipi_periph *)); 679 void scsipi_set_xfer_mode __P((struct scsipi_channel *, int, int)); 680 681 int scsipi_channel_init __P((struct scsipi_channel *)); 682 void scsipi_channel_shutdown __P((struct scsipi_channel *)); 683 684 void scsipi_insert_periph __P((struct scsipi_channel *, 685 struct scsipi_periph *)); 686 void scsipi_remove_periph __P((struct scsipi_channel *, 687 struct scsipi_periph *)); 688 struct scsipi_periph *scsipi_lookup_periph __P((struct scsipi_channel *, 689 int, int)); 690 int scsipi_target_detach __P((struct scsipi_channel *, int, int, int)); 691 692 int scsipi_adapter_addref __P((struct scsipi_adapter *)); 693 void scsipi_adapter_delref __P((struct scsipi_adapter *)); 694 695 void scsipi_channel_freeze __P((struct scsipi_channel *, int)); 696 void scsipi_channel_thaw __P((struct scsipi_channel *, int)); 697 void scsipi_channel_timed_thaw __P((void *)); 698 699 void scsipi_periph_freeze __P((struct scsipi_periph *, int)); 700 void scsipi_periph_thaw __P((struct scsipi_periph *, int)); 701 void scsipi_periph_timed_thaw __P((void *)); 702 703 int scsipi_sync_period_to_factor __P((int)); 704 int scsipi_sync_factor_to_period __P((int)); 705 int scsipi_sync_factor_to_freq __P((int)); 706 707 void show_scsipi_xs __P((struct scsipi_xfer *)); 708 void show_scsipi_cmd __P((struct scsipi_xfer *)); 709 void show_mem __P((u_char *, int)); 710 #endif /* _KERNEL */ 711 712 static __inline void _lto2b __P((u_int32_t val, u_int8_t *bytes)) 713 __attribute__ ((unused)); 714 static __inline void _lto3b __P((u_int32_t val, u_int8_t *bytes)) 715 __attribute__ ((unused)); 716 static __inline void _lto4b __P((u_int32_t val, u_int8_t *bytes)) 717 __attribute__ ((unused)); 718 static __inline u_int32_t _2btol __P((const u_int8_t *bytes)) 719 __attribute__ ((unused)); 720 static __inline u_int32_t _3btol __P((const u_int8_t *bytes)) 721 __attribute__ ((unused)); 722 static __inline u_int32_t _4btol __P((const u_int8_t *bytes)) 723 __attribute__ ((unused)); 724 static __inline u_int64_t _5btol __P((const u_int8_t *bytes)) 725 __attribute__ ((unused)); 726 727 static __inline void _lto2l __P((u_int32_t val, u_int8_t *bytes)) 728 __attribute__ ((unused)); 729 static __inline void _lto3l __P((u_int32_t val, u_int8_t *bytes)) 730 __attribute__ ((unused)); 731 static __inline void _lto4l __P((u_int32_t val, u_int8_t *bytes)) 732 __attribute__ ((unused)); 733 static __inline u_int32_t _2ltol __P((const u_int8_t *bytes)) 734 __attribute__ ((unused)); 735 static __inline u_int32_t _3ltol __P((const u_int8_t *bytes)) 736 __attribute__ ((unused)); 737 static __inline u_int32_t _4ltol __P((const u_int8_t *bytes)) 738 __attribute__ ((unused)); 739 740 static __inline void 741 _lto2b(val, bytes) 742 u_int32_t val; 743 u_int8_t *bytes; 744 { 745 746 bytes[0] = (val >> 8) & 0xff; 747 bytes[1] = val & 0xff; 748 } 749 750 static __inline void 751 _lto3b(val, bytes) 752 u_int32_t val; 753 u_int8_t *bytes; 754 { 755 756 bytes[0] = (val >> 16) & 0xff; 757 bytes[1] = (val >> 8) & 0xff; 758 bytes[2] = val & 0xff; 759 } 760 761 static __inline void 762 _lto4b(val, bytes) 763 u_int32_t val; 764 u_int8_t *bytes; 765 { 766 767 bytes[0] = (val >> 24) & 0xff; 768 bytes[1] = (val >> 16) & 0xff; 769 bytes[2] = (val >> 8) & 0xff; 770 bytes[3] = val & 0xff; 771 } 772 773 static __inline u_int32_t 774 _2btol(bytes) 775 const u_int8_t *bytes; 776 { 777 u_int32_t rv; 778 779 rv = (bytes[0] << 8) | 780 bytes[1]; 781 return (rv); 782 } 783 784 static __inline u_int32_t 785 _3btol(bytes) 786 const u_int8_t *bytes; 787 { 788 u_int32_t rv; 789 790 rv = (bytes[0] << 16) | 791 (bytes[1] << 8) | 792 bytes[2]; 793 return (rv); 794 } 795 796 static __inline u_int32_t 797 _4btol(bytes) 798 const u_int8_t *bytes; 799 { 800 u_int32_t rv; 801 802 rv = (bytes[0] << 24) | 803 (bytes[1] << 16) | 804 (bytes[2] << 8) | 805 bytes[3]; 806 return (rv); 807 } 808 809 static __inline u_int64_t 810 _5btol(bytes) 811 const u_int8_t *bytes; 812 { 813 u_int64_t rv; 814 815 rv = ((u_int64_t)bytes[0] << 32) | 816 ((u_int64_t)bytes[1] << 24) | 817 ((u_int64_t)bytes[2] << 16) | 818 ((u_int64_t)bytes[3] << 8) | 819 (u_int64_t)bytes[4]; 820 return (rv); 821 } 822 823 static __inline void 824 _lto2l(val, bytes) 825 u_int32_t val; 826 u_int8_t *bytes; 827 { 828 829 bytes[0] = val & 0xff; 830 bytes[1] = (val >> 8) & 0xff; 831 } 832 833 static __inline void 834 _lto3l(val, bytes) 835 u_int32_t val; 836 u_int8_t *bytes; 837 { 838 839 bytes[0] = val & 0xff; 840 bytes[1] = (val >> 8) & 0xff; 841 bytes[2] = (val >> 16) & 0xff; 842 } 843 844 static __inline void 845 _lto4l(val, bytes) 846 u_int32_t val; 847 u_int8_t *bytes; 848 { 849 850 bytes[0] = val & 0xff; 851 bytes[1] = (val >> 8) & 0xff; 852 bytes[2] = (val >> 16) & 0xff; 853 bytes[3] = (val >> 24) & 0xff; 854 } 855 856 static __inline u_int32_t 857 _2ltol(bytes) 858 const u_int8_t *bytes; 859 { 860 u_int32_t rv; 861 862 rv = bytes[0] | 863 (bytes[1] << 8); 864 return (rv); 865 } 866 867 static __inline u_int32_t 868 _3ltol(bytes) 869 const u_int8_t *bytes; 870 { 871 u_int32_t rv; 872 873 rv = bytes[0] | 874 (bytes[1] << 8) | 875 (bytes[2] << 16); 876 return (rv); 877 } 878 879 static __inline u_int32_t 880 _4ltol(bytes) 881 const u_int8_t *bytes; 882 { 883 u_int32_t rv; 884 885 rv = bytes[0] | 886 (bytes[1] << 8) | 887 (bytes[2] << 16) | 888 (bytes[3] << 24); 889 return (rv); 890 } 891 892 #endif /* _DEV_SCSIPI_SCSIPICONF_H_ */ 893