1 /* $NetBSD: scsipiconf.h,v 1.46 2000/09/22 16:45:17 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 1999 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 /* 67 * The following documentation tries to describe the relationship between the 68 * various structures defined in this file: 69 * 70 * each adapter type has a scsipi_adapter struct. This describes the adapter 71 * and identifies routines that can be called to use the adapter. 72 * each device type has a scsipi_device struct. This describes the device and 73 * identifies routines that can be called to use the device. 74 * each existing device position (scsibus + target + lun or atapibus + drive) 75 * can be described by a scsipi_link struct. 76 * Only scsipi positions that actually have devices, have a scsipi_link 77 * structure assigned. so in effect each device has scsipi_link struct. 78 * The scsipi_link structure contains information identifying both the 79 * device driver and the adapter driver for that position on that scsipi 80 * bus, and can be said to 'link' the two. 81 * each individual scsipi bus has an array that points to all the scsipi_link 82 * structs associated with that scsipi bus. Slots with no device have 83 * a NULL pointer. 84 * each individual device also knows the address of it's own scsipi_link 85 * structure. 86 * 87 * ------------- 88 * 89 * The key to all this is the scsipi_link structure which associates all the 90 * other structures with each other in the correct configuration. The 91 * scsipi_link is the connecting information that allows each part of the 92 * scsipi system to find the associated other parts. 93 */ 94 95 struct buf; 96 struct proc; 97 struct scsipi_link; 98 struct scsipi_xfer; 99 100 /* 101 * The following defines the scsipi_xfer queue. 102 */ 103 TAILQ_HEAD(scsipi_xfer_queue, scsipi_xfer); 104 105 struct scsipi_generic { 106 u_int8_t opcode; 107 u_int8_t bytes[15]; 108 }; 109 110 111 /* 112 * return values for scsipi_cmd() 113 */ 114 #define SUCCESSFULLY_QUEUED 0 115 #define TRY_AGAIN_LATER 1 116 #define COMPLETE 2 117 #define ESCAPE_NOT_SUPPORTED 3 118 119 /* 120 * Device Specific Sense Handlers return either an errno 121 * or one of these three items. 122 */ 123 124 #define SCSIRET_NOERROR 0 /* No Error */ 125 #define SCSIRET_RETRY -1 /* Retry the command that got this sense */ 126 #define SCSIRET_CONTINUE -2 /* Continue with standard sense processing */ 127 128 /* 129 * These entry points are called by the low-end drivers to get services from 130 * whatever high-end drivers they are attached to. Each device type has one 131 * of these statically allocated. 132 */ 133 struct scsipi_device { 134 int (*err_handler) __P((struct scsipi_xfer *)); 135 /* returns -1 to say err processing done */ 136 void (*start) __P((void *)); 137 int (*async) __P((void)); 138 void (*done) __P((struct scsipi_xfer *)); 139 }; 140 141 /* 142 * These entrypoints are called by the high-end drivers to get services from 143 * whatever low-end drivers they are attached to. Each adapter instance has 144 * one of these. 145 * 146 * scsipi_cmd required 147 * scsipi_minphys required 148 * scsipi_ioctl optional 149 * scsipi_enable optional 150 * scsipi_getgeom optional 151 * scsipi_accesschk optional 152 */ 153 struct disk_parms; 154 struct scsipi_inquiry_pattern; 155 struct scsipi_adapter { 156 int scsipi_refcnt; /* adapter reference count */ 157 int (*scsipi_cmd) __P((struct scsipi_xfer *)); 158 void (*scsipi_minphys) __P((struct buf *)); 159 int (*scsipi_ioctl) __P((struct scsipi_link *, u_long, 160 caddr_t, int, struct proc *)); 161 int (*scsipi_enable) __P((void *, int)); 162 int (*scsipi_getgeom) __P((struct scsipi_link *, 163 struct disk_parms *, u_long)); 164 int (*scsipi_accesschk) __P((struct scsipi_link *, 165 struct scsipi_inquiry_pattern *)); 166 }; 167 168 /* 169 * This structure describes the connection between an adapter driver and 170 * a device driver, and is used by each to call services provided by 171 * the other, and to allow generic scsipi glue code to call these services 172 * as well. 173 * 174 * XXX Given the way NetBSD's autoconfiguration works, this is ... 175 * XXX nasty. 176 */ 177 178 /* 179 * XXX Small hack alert 180 * NOTE: The first field of struct scsipi_link is shared with 181 * dev/scspi/scsipiconf.h's struct ata_atapi_attach. This allows 182 * atapibus and scsibus to attach to the same device. 183 */ 184 struct scsipi_link { 185 u_int8_t type; /* device type, i.e. SCSI, ATAPI, ...*/ 186 #define BUS_SCSI 0 187 #define BUS_ATAPI 1 188 /*define BUS_ATA 2*/ 189 int openings; /* max # of outstanding commands */ 190 int active; /* current # of outstanding commands */ 191 int flags; /* flags that all devices have */ 192 #define SDEV_REMOVABLE 0x01 /* media is removable */ 193 #define SDEV_MEDIA_LOADED 0x02 /* device figures are still valid */ 194 #define SDEV_WAITING 0x04 /* a process is waiting for this */ 195 #define SDEV_OPEN 0x08 /* at least 1 open session */ 196 #define SDEV_DBX 0xf0 /* debuging flags (scsipi_debug.h) */ 197 #define SDEV_WAITDRAIN 0x100 /* waiting for pending_xfers to drain */ 198 #define SDEV_KEEP_LABEL 0x200 /* retain label after 'full' close */ 199 u_int16_t quirks; /* per-device oddities */ 200 #define SDEV_AUTOSAVE 0x0001 /* 201 * Do implicit SAVEDATAPOINTER on 202 * disconnect (ancient). 203 */ 204 #define SDEV_NOSYNC 0x0002 /* does not grok SDTR */ 205 #define SDEV_NOWIDE 0x0004 /* does not grok WDTR */ 206 #define SDEV_NOTAG 0x0008 /* does not do command tagging */ 207 #define SDEV_NOLUNS 0x0010 /* does not grok LUNs */ 208 #define SDEV_FORCELUNS 0x0020 /* prehistoric drive/ctlr groks LUNs */ 209 #define SDEV_NOMODESENSE 0x0040 /* removable media/optical drives */ 210 #define SDEV_NOSTARTUNIT 0x0080 /* Do not issue START UNIT requests */ 211 #define SDEV_NOSYNCCACHE 0x0100 /* does not grok SYNCHRONIZE CACHE */ 212 #define SDEV_CDROM 0x0200 /* device is a CD-ROM */ 213 #define ADEV_LITTLETOC 0x0400 /* Audio TOC uses wrong byte order */ 214 #define ADEV_NOCAPACITY 0x0800 /* no READ_CD_CAPACITY command */ 215 #define ADEV_NOTUR 0x1000 /* no TEST_UNIT_READY command */ 216 #define ADEV_NODOORLOCK 0x2000 /* device can't lock door */ 217 #define ADEV_NOSENSE 0x4000 /* device can't handle request sense */ 218 #define SDEV_ONLYBIG 0x8000 /* only use SCSI_{READ,WRITE}_BIG */ 219 220 struct scsipi_device *device; /* device entry points etc. */ 221 void *device_softc; /* needed for call to foo_start */ 222 struct scsipi_adapter *adapter;/* adapter entry points etc. */ 223 void *adapter_softc; /* needed for call to foo_scsipi_cmd */ 224 union { /* needed for call to foo_scsipi_cmd */ 225 struct scsi_link { 226 int channel; /* channel, i.e. bus # on controller */ 227 228 u_int8_t scsi_version; /* SCSI-I, SCSI-II, etc. */ 229 u_int8_t scsibus; /* the Nth scsibus */ 230 u_int8_t target; /* targ of this dev */ 231 u_int8_t lun; /* lun of this dev */ 232 u_int8_t adapter_target;/* what are we on the scsi 233 bus */ 234 int16_t max_target; /* XXX max target supported 235 by adapter (inclusive) */ 236 int16_t max_lun; /* XXX number of luns supported 237 by adapter (inclusive) */ 238 } scsipi_scsi; 239 struct atapi_link { 240 u_int8_t drive; /* drive number on the bus */ 241 u_int8_t channel; /* channel, i.e. bus # on 242 controller */ 243 u_int8_t atapibus; 244 u_int8_t cap; /* drive capability */ 245 /* 0x20-0x40 reserved for ATAPI_CFG_DRQ_MASK */ 246 #define ACAP_LEN 0x01 /* 16 bit commands */ 247 } scsipi_atapi; 248 } _scsipi_link; 249 struct scsipi_xfer_queue pending_xfers; 250 int (*scsipi_cmd) __P((struct scsipi_link *, struct scsipi_generic *, 251 int cmdlen, u_char *data_addr, int datalen, int retries, 252 int timeout, struct buf *bp, int flags)); 253 int (*scsipi_interpret_sense) __P((struct scsipi_xfer *)); 254 void (*sc_print_addr) __P((struct scsipi_link *sc_link)); 255 void (*scsipi_kill_pending) __P((struct scsipi_link *)); 256 }; 257 #define scsipi_scsi _scsipi_link.scsipi_scsi 258 #define scsipi_atapi _scsipi_link.scsipi_atapi 259 260 /* 261 * Each scsipi transaction is fully described by one of these structures 262 * It includes information about the source of the command and also the 263 * device and adapter for which the command is destined. 264 * (via the scsipi_link structure) 265 * 266 * The adapter_q member may be used by host adapter drivers to queue 267 * requests, if necessary. 268 * 269 * The device_q member is maintained by the scsipi middle layer. When 270 * a device issues a command, the xfer is placed on that device's 271 * pending commands queue. When an xfer is done and freed, it is taken 272 * off the device's queue. This allows for a device to wait for all of 273 * its pending commands to complete. 274 */ 275 struct scsipi_xfer { 276 TAILQ_ENTRY(scsipi_xfer) adapter_q; /* queue entry for use by adapter */ 277 TAILQ_ENTRY(scsipi_xfer) device_q; /* device's pending xfers */ 278 struct callout xs_callout; /* callout for adapter use */ 279 int xs_control; /* control flags */ 280 __volatile int xs_status; /* status flags */ 281 struct scsipi_link *sc_link; /* all about our device and adapter */ 282 int retries; /* the number of times to retry */ 283 int timeout; /* in milliseconds */ 284 struct scsipi_generic *cmd; /* The scsipi command to execute */ 285 int cmdlen; /* how long it is */ 286 u_char *data; /* dma address OR a uio address */ 287 int datalen; /* data len (blank if uio) */ 288 int resid; /* how much buffer was not touched */ 289 int error; /* an error value */ 290 struct buf *bp; /* If we need to associate with */ 291 /* a buf */ 292 union { 293 struct scsipi_sense_data scsi_sense; /* 32 bytes */ 294 u_int32_t atapi_sense; 295 } sense; 296 /* 297 * Believe it or not, Some targets fall on the ground with 298 * anything but a certain sense length. 299 */ 300 int req_sense_length; /* Explicit request sense length */ 301 u_int8_t status; /* SCSI status */ 302 struct scsipi_generic cmdstore 303 __attribute__ ((aligned (4)));/* stash the command in here */ 304 }; 305 306 /* 307 * scsipi_xfer control flags 308 * 309 * To do: 310 * 311 * - figure out what to do with XS_CTL_ESCAPE 312 * 313 * - replace XS_CTL_URGENT with an `xs_priority' field 314 */ 315 #define XS_CTL_NOSLEEP 0x00000001 /* don't sleep */ 316 #define XS_CTL_POLL 0x00000002 /* poll for completion */ 317 #define XS_CTL_DISCOVERY 0x00000004 /* doing device discovery */ 318 #define XS_CTL_ASYNC 0x00000008 /* command completes 319 asynchronously */ 320 #define XS_CTL_USERCMD 0x00000010 /* user issued command */ 321 #define XS_CTL_SILENT 0x00000020 /* don't print sense info */ 322 #define XS_CTL_IGNORE_NOT_READY 0x00000040 /* ignore NOT READY */ 323 #define XS_CTL_IGNORE_MEDIA_CHANGE \ 324 0x00000080 /* ignore media change */ 325 #define XS_CTL_IGNORE_ILLEGAL_REQUEST \ 326 0x00000100 /* ignore ILLEGAL REQUEST */ 327 #define XS_CTL_RESET 0x00000200 /* reset the device */ 328 #define XS_CTL_DATA_UIO 0x00000400 /* xs_data points to uio */ 329 #define XS_CTL_DATA_IN 0x00000800 /* data coming into memory */ 330 #define XS_CTL_DATA_OUT 0x00001000 /* data going out of memory */ 331 #define XS_CTL_TARGET 0x00002000 /* target mode operation */ 332 #define XS_CTL_ESCAPE 0x00004000 /* escape operation */ 333 #define XS_CTL_URGENT 0x00008000 /* urgent operation */ 334 #define XS_CTL_SIMPLE_TAG 0x00010000 /* use a Simple Tag */ 335 #define XS_CTL_ORDERED_TAG 0x00020000 /* use an Ordered Tag */ 336 #define XS_CTL_DATA_ONSTACK 0x00040000 /* data is alloc'ed on stack */ 337 338 /* 339 * scsipi_xfer status flags 340 */ 341 #define XS_STS_DONE 0x00000001 /* scsipi_xfer is done */ 342 #define XS_STS_PRIVATE 0xf0000000 /* reserved for HBA's use */ 343 344 /* 345 * Error values an adapter driver may return 346 */ 347 #define XS_NOERROR 0 /* there is no error, (sense is invalid) */ 348 #define XS_SENSE 1 /* Check the returned sense for the error */ 349 #define XS_SHORTSENSE 2 /* Check the ATAPI sense for the error */ 350 #define XS_DRIVER_STUFFUP 3 /* Driver failed to perform operation */ 351 #define XS_SELTIMEOUT 4 /* The device timed out.. turned off? */ 352 #define XS_TIMEOUT 5 /* The Timeout reported was caught by SW */ 353 #define XS_BUSY 7 /* The device busy, try again later? */ 354 #define XS_RESET 8 /* bus was reset; possible retry command */ 355 356 /* 357 * This describes matching information for scsipi_inqmatch(). The more things 358 * match, the higher the configuration priority. 359 */ 360 struct scsipi_inquiry_pattern { 361 u_int8_t type; 362 boolean removable; 363 char *vendor; 364 char *product; 365 char *revision; 366 }; 367 368 /* 369 * This is used to pass information from the high-level configuration code 370 * to the device-specific drivers. 371 */ 372 373 struct scsipibus_attach_args { 374 struct scsipi_link *sa_sc_link; 375 struct scsipi_inquiry_pattern sa_inqbuf; 376 struct scsipi_inquiry_data *sa_inqptr; 377 union { /* bus-type specific infos */ 378 u_int8_t scsi_version; /* SCSI version */ 379 } scsipi_info; 380 }; 381 382 /* 383 * this describes a quirk entry 384 */ 385 386 struct scsi_quirk_inquiry_pattern { 387 struct scsipi_inquiry_pattern pattern; 388 u_int16_t quirks; 389 }; 390 391 /* 392 * Default number of retries, used for generic routines. 393 */ 394 #define SCSIPIRETRIES 4 395 396 /* 397 * Similar, but invoke the controller directly with a scsipi_xfer. 398 */ 399 #define scsipi_command_direct(xs) \ 400 (*(xs)->sc_link->adapter->scsipi_cmd)((xs)) 401 402 #ifdef _KERNEL 403 void scsipi_init __P((void)); 404 int scsipi_command __P((struct scsipi_link *, 405 struct scsipi_generic *, int, u_char *, int, 406 int, int, struct buf *, int)); 407 caddr_t scsipi_inqmatch __P((struct scsipi_inquiry_pattern *, caddr_t, 408 int, int, int *)); 409 char *scsipi_dtype __P((int)); 410 void scsipi_strvis __P((u_char *, int, u_char *, int)); 411 int scsipi_execute_xs __P((struct scsipi_xfer *)); 412 u_long scsipi_size __P((struct scsipi_link *, int)); 413 int scsipi_test_unit_ready __P((struct scsipi_link *, int)); 414 int scsipi_prevent __P((struct scsipi_link *, int, int)); 415 int scsipi_inquire __P((struct scsipi_link *, 416 struct scsipi_inquiry_data *, int)); 417 int scsipi_start __P((struct scsipi_link *, int, int)); 418 void scsipi_done __P((struct scsipi_xfer *)); 419 void scsipi_user_done __P((struct scsipi_xfer *)); 420 int scsipi_interpret_sense __P((struct scsipi_xfer *)); 421 void scsipi_wait_drain __P((struct scsipi_link *)); 422 void scsipi_kill_pending __P((struct scsipi_link *)); 423 #ifdef SCSIVERBOSE 424 void scsipi_print_sense __P((struct scsipi_xfer *, int)); 425 void scsipi_print_sense_data __P((struct scsipi_sense_data *, int)); 426 char *scsipi_decode_sense __P((void *, int)); 427 #endif 428 int scsipi_do_ioctl __P((struct scsipi_link *, dev_t, u_long, caddr_t, 429 int, struct proc *)); 430 431 int scsipi_adapter_addref __P((struct scsipi_link *)); 432 void scsipi_adapter_delref __P((struct scsipi_link *)); 433 434 void show_scsipi_xs __P((struct scsipi_xfer *)); 435 void show_scsipi_cmd __P((struct scsipi_xfer *)); 436 void show_mem __P((u_char *, int)); 437 #endif /* _KERNEL */ 438 439 static __inline void _lto2b __P((u_int32_t val, u_int8_t *bytes)) 440 __attribute__ ((unused)); 441 static __inline void _lto3b __P((u_int32_t val, u_int8_t *bytes)) 442 __attribute__ ((unused)); 443 static __inline void _lto4b __P((u_int32_t val, u_int8_t *bytes)) 444 __attribute__ ((unused)); 445 static __inline u_int32_t _2btol __P((const u_int8_t *bytes)) 446 __attribute__ ((unused)); 447 static __inline u_int32_t _3btol __P((const u_int8_t *bytes)) 448 __attribute__ ((unused)); 449 static __inline u_int32_t _4btol __P((const u_int8_t *bytes)) 450 __attribute__ ((unused)); 451 452 static __inline void _lto2l __P((u_int32_t val, u_int8_t *bytes)) 453 __attribute__ ((unused)); 454 static __inline void _lto3l __P((u_int32_t val, u_int8_t *bytes)) 455 __attribute__ ((unused)); 456 static __inline void _lto4l __P((u_int32_t val, u_int8_t *bytes)) 457 __attribute__ ((unused)); 458 static __inline u_int32_t _2ltol __P((const u_int8_t *bytes)) 459 __attribute__ ((unused)); 460 static __inline u_int32_t _3ltol __P((const u_int8_t *bytes)) 461 __attribute__ ((unused)); 462 static __inline u_int32_t _4ltol __P((const u_int8_t *bytes)) 463 __attribute__ ((unused)); 464 static __inline void bswap __P((char *, int)) 465 __attribute__ ((unused)); 466 467 static __inline void 468 _lto2b(val, bytes) 469 u_int32_t val; 470 u_int8_t *bytes; 471 { 472 473 bytes[0] = (val >> 8) & 0xff; 474 bytes[1] = val & 0xff; 475 } 476 477 static __inline void 478 _lto3b(val, bytes) 479 u_int32_t val; 480 u_int8_t *bytes; 481 { 482 483 bytes[0] = (val >> 16) & 0xff; 484 bytes[1] = (val >> 8) & 0xff; 485 bytes[2] = val & 0xff; 486 } 487 488 static __inline void 489 _lto4b(val, bytes) 490 u_int32_t val; 491 u_int8_t *bytes; 492 { 493 494 bytes[0] = (val >> 24) & 0xff; 495 bytes[1] = (val >> 16) & 0xff; 496 bytes[2] = (val >> 8) & 0xff; 497 bytes[3] = val & 0xff; 498 } 499 500 static __inline u_int32_t 501 _2btol(bytes) 502 const u_int8_t *bytes; 503 { 504 u_int32_t rv; 505 506 rv = (bytes[0] << 8) | 507 bytes[1]; 508 return (rv); 509 } 510 511 static __inline u_int32_t 512 _3btol(bytes) 513 const u_int8_t *bytes; 514 { 515 u_int32_t rv; 516 517 rv = (bytes[0] << 16) | 518 (bytes[1] << 8) | 519 bytes[2]; 520 return (rv); 521 } 522 523 static __inline u_int32_t 524 _4btol(bytes) 525 const u_int8_t *bytes; 526 { 527 u_int32_t rv; 528 529 rv = (bytes[0] << 24) | 530 (bytes[1] << 16) | 531 (bytes[2] << 8) | 532 bytes[3]; 533 return (rv); 534 } 535 536 static __inline void 537 _lto2l(val, bytes) 538 u_int32_t val; 539 u_int8_t *bytes; 540 { 541 542 bytes[0] = val & 0xff; 543 bytes[1] = (val >> 8) & 0xff; 544 } 545 546 static __inline void 547 _lto3l(val, bytes) 548 u_int32_t val; 549 u_int8_t *bytes; 550 { 551 552 bytes[0] = val & 0xff; 553 bytes[1] = (val >> 8) & 0xff; 554 bytes[2] = (val >> 16) & 0xff; 555 } 556 557 static __inline void 558 _lto4l(val, bytes) 559 u_int32_t val; 560 u_int8_t *bytes; 561 { 562 563 bytes[0] = val & 0xff; 564 bytes[1] = (val >> 8) & 0xff; 565 bytes[2] = (val >> 16) & 0xff; 566 bytes[3] = (val >> 24) & 0xff; 567 } 568 569 static __inline u_int32_t 570 _2ltol(bytes) 571 const u_int8_t *bytes; 572 { 573 u_int32_t rv; 574 575 rv = bytes[0] | 576 (bytes[1] << 8); 577 return (rv); 578 } 579 580 static __inline u_int32_t 581 _3ltol(bytes) 582 const u_int8_t *bytes; 583 { 584 u_int32_t rv; 585 586 rv = bytes[0] | 587 (bytes[1] << 8) | 588 (bytes[2] << 16); 589 return (rv); 590 } 591 592 static __inline u_int32_t 593 _4ltol(bytes) 594 const u_int8_t *bytes; 595 { 596 u_int32_t rv; 597 598 rv = bytes[0] | 599 (bytes[1] << 8) | 600 (bytes[2] << 16) | 601 (bytes[3] << 24); 602 return (rv); 603 } 604 605 static __inline void 606 bswap (buf, len) 607 char *buf; 608 int len; 609 { 610 u_int16_t *p = (u_int16_t *)(buf + len); 611 612 while (--p >= (u_int16_t *)buf) 613 *p = (*p & 0xff) << 8 | (*p >> 8 & 0xff); 614 } 615 616 #endif /* _DEV_SCSIPI_SCSIPICONF_H_ */ 617