1 /* $FreeBSD: src/sys/dev/isp/isp_freebsd.h,v 1.120 2011/11/06 00:44:40 mjacob Exp $ */ 2 /*- 3 * Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions 4 * 5 * Copyright (c) 1997-2008 by Matthew Jacob 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice immediately at the beginning of the file, without modification, 13 * this list of conditions, and the following disclaimer. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 #ifndef _ISP_FREEBSD_H 30 #define _ISP_FREEBSD_H 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/endian.h> 35 #include <sys/lock.h> 36 #include <sys/kernel.h> 37 #include <sys/queue.h> 38 #include <sys/malloc.h> 39 #include <sys/mutex.h> 40 #include <sys/condvar.h> 41 #include <sys/sysctl.h> 42 43 #include <sys/proc.h> 44 #include <sys/bus.h> 45 #include <sys/taskqueue.h> 46 47 #include <machine/cpu.h> 48 #include <machine/stdarg.h> 49 50 #include <bus/cam/cam.h> 51 #include <bus/cam/cam_debug.h> 52 #include <bus/cam/cam_ccb.h> 53 #include <bus/cam/cam_sim.h> 54 #include <bus/cam/cam_xpt.h> 55 #include <bus/cam/cam_xpt_sim.h> 56 #include <bus/cam/scsi/scsi_all.h> 57 #include <bus/cam/scsi/scsi_message.h> 58 59 #include "opt_isp.h" 60 61 #define ISP_PLATFORM_VERSION_MAJOR 7 62 #define ISP_PLATFORM_VERSION_MINOR 0 63 64 /* 65 * Efficiency- get rid of SBus code && tests unless we need them. 66 */ 67 #define ISP_SBUS_SUPPORTED 0 68 69 #define ISP_IFLAGS INTR_MPSAFE 70 71 #ifdef ISP_TARGET_MODE 72 #define ISP_TARGET_FUNCTIONS 1 73 #define ATPDPSIZE 4096 74 75 #include <dev/disk/isp/isp_target.h> 76 77 typedef struct { 78 void * next; 79 uint32_t orig_datalen; 80 uint32_t bytes_xfered; 81 uint32_t last_xframt; 82 uint32_t tag; 83 uint32_t lun; 84 uint32_t nphdl; 85 uint32_t sid; 86 uint32_t portid; 87 uint32_t 88 oxid : 16, 89 cdb0 : 8, 90 : 1, 91 dead : 1, 92 tattr : 3, 93 state : 3; 94 } atio_private_data_t; 95 #define ATPD_STATE_FREE 0 96 #define ATPD_STATE_ATIO 1 97 #define ATPD_STATE_CAM 2 98 #define ATPD_STATE_CTIO 3 99 #define ATPD_STATE_LAST_CTIO 4 100 #define ATPD_STATE_PDON 5 101 102 typedef union inot_private_data inot_private_data_t; 103 union inot_private_data { 104 inot_private_data_t *next; 105 struct { 106 isp_notify_t nt; /* must be first! */ 107 uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */ 108 uint32_t tag_id, seq_id; 109 } rd; 110 }; 111 112 typedef struct tstate { 113 SLIST_ENTRY(tstate) next; 114 struct cam_path *owner; 115 struct ccb_hdr_slist atios; 116 struct ccb_hdr_slist inots; 117 uint32_t hold; 118 int atio_count; 119 int inot_count; 120 inot_private_data_t * restart_queue; 121 inot_private_data_t * ntfree; 122 inot_private_data_t ntpool[ATPDPSIZE]; 123 atio_private_data_t * atfree; 124 atio_private_data_t atpool[ATPDPSIZE]; 125 } tstate_t; 126 127 #define LUN_HASH_SIZE 32 128 #define LUN_HASH_FUNC(lun) ((lun) & (LUN_HASH_SIZE - 1)) 129 130 #endif 131 132 /* 133 * Per command info. 134 */ 135 struct isp_pcmd { 136 struct isp_pcmd * next; 137 bus_dmamap_t dmap; /* dma map for this command */ 138 struct ispsoftc * isp; /* containing isp */ 139 struct callout wdog; /* watchdog timer */ 140 }; 141 #define ISP_PCMD(ccb) (ccb)->ccb_h.spriv_ptr1 142 #define PISP_PCMD(ccb) ((struct isp_pcmd *)ISP_PCMD(ccb)) 143 144 /* 145 * Per channel information 146 */ 147 SLIST_HEAD(tslist, tstate); 148 149 struct isp_fc { 150 struct cam_sim *sim; 151 struct cam_path *path; 152 struct ispsoftc *isp; 153 struct thread *kthread; 154 bus_dma_tag_t tdmat; 155 bus_dmamap_t tdmap; 156 uint64_t def_wwpn; 157 uint64_t def_wwnn; 158 uint32_t loop_down_time; 159 uint32_t loop_down_limit; 160 uint32_t gone_device_time; 161 uint32_t 162 #ifdef ISP_TARGET_MODE 163 #ifdef ISP_INTERNAL_TARGET 164 proc_active : 1, 165 #endif 166 tm_luns_enabled : 1, 167 tm_enable_defer : 1, 168 tm_enabled : 1, 169 #endif 170 simqfrozen : 3, 171 default_id : 8, 172 hysteresis : 8, 173 def_role : 2, /* default role */ 174 gdt_running : 1, 175 loop_dead : 1, 176 fcbsy : 1, 177 ready : 1; 178 struct callout ldt; /* loop down timer */ 179 struct callout gdt; /* gone device timer */ 180 struct task ltask; 181 struct task gtask; 182 #ifdef ISP_TARGET_MODE 183 struct tslist lun_hash[LUN_HASH_SIZE]; 184 #ifdef ISP_INTERNAL_TARGET 185 struct proc * target_proc; 186 #endif 187 #endif 188 }; 189 190 struct isp_spi { 191 struct cam_sim *sim; 192 struct cam_path *path; 193 uint32_t 194 #ifdef ISP_TARGET_MODE 195 #ifdef ISP_INTERNAL_TARGET 196 proc_active : 1, 197 #endif 198 tm_luns_enabled : 1, 199 tm_enable_defer : 1, 200 tm_enabled : 1, 201 #endif 202 simqfrozen : 3, 203 def_role : 2, 204 iid : 4; 205 #ifdef ISP_TARGET_MODE 206 struct tslist lun_hash[LUN_HASH_SIZE]; 207 #ifdef ISP_INTERNAL_TARGET 208 struct proc * target_proc; 209 #endif 210 #endif 211 }; 212 213 struct isposinfo { 214 /* 215 * Linkage, locking, and identity 216 */ 217 struct lock lock; 218 device_t dev; 219 struct cdev * cdev; 220 struct intr_config_hook ehook; 221 struct cam_devq * devq; 222 223 /* 224 * Firmware pointer 225 */ 226 const struct firmware * fw; 227 228 /* 229 * DMA related sdtuff 230 */ 231 bus_space_tag_t bus_tag; 232 bus_dma_tag_t dmat; 233 bus_space_handle_t bus_handle; 234 bus_dma_tag_t cdmat; 235 bus_dmamap_t cdmap; 236 237 /* 238 * Command and transaction related related stuff 239 */ 240 struct isp_pcmd * pcmd_pool; 241 struct isp_pcmd * pcmd_free; 242 243 uint32_t 244 #ifdef ISP_TARGET_MODE 245 tmwanted : 1, 246 tmbusy : 1, 247 #else 248 : 2, 249 #endif 250 forcemulti : 1, 251 timer_active : 1, 252 autoconf : 1, 253 ehook_active : 1, 254 disabled : 1, 255 mbox_sleeping : 1, 256 mbox_sleep_ok : 1, 257 mboxcmd_done : 1, 258 mboxbsy : 1; 259 260 struct callout tmo; /* general timer */ 261 262 /* 263 * misc- needs to be sorted better XXXXXX 264 */ 265 int framesize; 266 int exec_throttle; 267 int cont_max; 268 269 #ifdef ISP_TARGET_MODE 270 cam_status * rptr; 271 #endif 272 273 /* 274 * Per-type private storage... 275 */ 276 union { 277 struct isp_fc *fc; 278 struct isp_spi *spi; 279 void *ptr; 280 } pc; 281 }; 282 #define ISP_FC_PC(isp, chan) (&(isp)->isp_osinfo.pc.fc[(chan)]) 283 #define ISP_SPI_PC(isp, chan) (&(isp)->isp_osinfo.pc.spi[(chan)]) 284 #define ISP_GET_PC(isp, chan, tag, rslt) \ 285 if (IS_SCSI(isp)) { \ 286 rslt = ISP_SPI_PC(isp, chan)-> tag; \ 287 } else { \ 288 rslt = ISP_FC_PC(isp, chan)-> tag; \ 289 } 290 #define ISP_GET_PC_ADDR(isp, chan, tag, rp) \ 291 if (IS_SCSI(isp)) { \ 292 rp = &ISP_SPI_PC(isp, chan)-> tag; \ 293 } else { \ 294 rp = &ISP_FC_PC(isp, chan)-> tag; \ 295 } 296 #define ISP_SET_PC(isp, chan, tag, val) \ 297 if (IS_SCSI(isp)) { \ 298 ISP_SPI_PC(isp, chan)-> tag = val; \ 299 } else { \ 300 ISP_FC_PC(isp, chan)-> tag = val; \ 301 } 302 303 #define isp_lock isp_osinfo.lock 304 #define isp_bus_tag isp_osinfo.bus_tag 305 #define isp_bus_handle isp_osinfo.bus_handle 306 307 /* 308 * Locking macros... 309 */ 310 #define ISP_LOCK(isp) lockmgr(&isp->isp_osinfo.lock, LK_EXCLUSIVE) 311 #define ISP_UNLOCK(isp) lockmgr(&isp->isp_osinfo.lock, LK_RELEASE) 312 313 /* 314 * Required Macros/Defines 315 */ 316 317 #define ISP_FC_SCRLEN 0x1000 318 319 #define ISP_MEMZERO(a, b) memset(a, 0, b) 320 #define ISP_MEMCPY memcpy 321 #define ISP_SNPRINTF ksnprintf 322 #define ISP_DELAY DELAY 323 #define ISP_SLEEP(isp, x) DELAY(x) 324 325 #define ISP_MIN imin 326 327 #ifndef DIAGNOSTIC 328 #define ISP_INLINE __inline 329 #else 330 #define ISP_INLINE 331 #endif 332 333 #define NANOTIME_T struct timespec 334 #define GET_NANOTIME nanotime 335 #define GET_NANOSEC(x) ((x)->tv_sec * 1000000000 + (x)->tv_nsec) 336 #define NANOTIME_SUB isp_nanotime_sub 337 338 #define MAXISPREQUEST(isp) ((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256) 339 340 #define MEMORYBARRIER(isp, type, offset, size, chan) \ 341 switch (type) { \ 342 case SYNC_SFORDEV: \ 343 { \ 344 struct isp_fc *fc = ISP_FC_PC(isp, chan); \ 345 bus_dmamap_sync(fc->tdmat, fc->tdmap, \ 346 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); \ 347 break; \ 348 } \ 349 case SYNC_REQUEST: \ 350 bus_dmamap_sync(isp->isp_osinfo.cdmat, \ 351 isp->isp_osinfo.cdmap, \ 352 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); \ 353 break; \ 354 case SYNC_SFORCPU: \ 355 { \ 356 struct isp_fc *fc = ISP_FC_PC(isp, chan); \ 357 bus_dmamap_sync(fc->tdmat, fc->tdmap, \ 358 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); \ 359 break; \ 360 } \ 361 case SYNC_RESULT: \ 362 bus_dmamap_sync(isp->isp_osinfo.cdmat, \ 363 isp->isp_osinfo.cdmap, \ 364 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); \ 365 break; \ 366 case SYNC_REG: \ 367 bus_space_barrier(isp->isp_osinfo.bus_tag, \ 368 isp->isp_osinfo.bus_handle, offset, size, \ 369 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); \ 370 break; \ 371 default: \ 372 break; \ 373 } 374 375 #define MBOX_ACQUIRE isp_mbox_acquire 376 #define MBOX_WAIT_COMPLETE isp_mbox_wait_complete 377 #define MBOX_NOTIFY_COMPLETE isp_mbox_notify_done 378 #define MBOX_RELEASE isp_mbox_release 379 380 #define FC_SCRATCH_ACQUIRE isp_fc_scratch_acquire 381 #define FC_SCRATCH_RELEASE(isp, chan) isp->isp_osinfo.pc.fc[chan].fcbsy = 0 382 383 #ifndef SCSI_GOOD 384 #define SCSI_GOOD SCSI_STATUS_OK 385 #endif 386 #ifndef SCSI_CHECK 387 #define SCSI_CHECK SCSI_STATUS_CHECK_COND 388 #endif 389 #ifndef SCSI_BUSY 390 #define SCSI_BUSY SCSI_STATUS_BUSY 391 #endif 392 #ifndef SCSI_QFULL 393 #define SCSI_QFULL SCSI_STATUS_QUEUE_FULL 394 #endif 395 396 #define XS_T struct ccb_scsiio 397 #define XS_DMA_ADDR_T bus_addr_t 398 #define XS_GET_DMA64_SEG(a, b, c) \ 399 { \ 400 ispds64_t *d = a; \ 401 bus_dma_segment_t *e = b; \ 402 uint32_t f = c; \ 403 e += f; \ 404 d->ds_base = DMA_LO32(e->ds_addr); \ 405 d->ds_basehi = DMA_HI32(e->ds_addr); \ 406 d->ds_count = e->ds_len; \ 407 } 408 #define XS_GET_DMA_SEG(a, b, c) \ 409 { \ 410 ispds_t *d = a; \ 411 bus_dma_segment_t *e = b; \ 412 uint32_t f = c; \ 413 e += f; \ 414 d->ds_base = DMA_LO32(e->ds_addr); \ 415 d->ds_count = e->ds_len; \ 416 } 417 #define XS_ISP(ccb) cam_sim_softc(xpt_path_sim((ccb)->ccb_h.path)) 418 #define XS_CHANNEL(ccb) cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path)) 419 #define XS_TGT(ccb) (ccb)->ccb_h.target_id 420 #define XS_LUN(ccb) (ccb)->ccb_h.target_lun 421 422 #define XS_CDBP(ccb) \ 423 (((ccb)->ccb_h.flags & CAM_CDB_POINTER)? \ 424 (ccb)->cdb_io.cdb_ptr : (ccb)->cdb_io.cdb_bytes) 425 426 #define XS_CDBLEN(ccb) (ccb)->cdb_len 427 #define XS_XFRLEN(ccb) (ccb)->dxfer_len 428 #define XS_TIME(ccb) (ccb)->ccb_h.timeout 429 #define XS_GET_RESID(ccb) (ccb)->resid 430 #define XS_SET_RESID(ccb, r) (ccb)->resid = r 431 #define XS_STSP(ccb) (&(ccb)->scsi_status) 432 #define XS_SNSP(ccb) (&(ccb)->sense_data) 433 434 #define XS_SNSLEN(ccb) \ 435 imin((sizeof((ccb)->sense_data)), ccb->sense_len - ccb->sense_resid) 436 437 #define XS_SNSKEY(ccb) (scsi_get_sense_key(&(ccb)->sense_data, \ 438 ccb->sense_len - ccb->sense_resid, \ 439 /*show_errors*/ 1)) 440 441 #define XS_SNSASC(ccb) (scsi_get_asc(&(ccb)->sense_data, \ 442 ccb->sense_len - ccb->sense_resid, \ 443 /*show_errors*/ 1)) 444 445 #define XS_SNSASCQ(ccb) (scsi_get_ascq(&(ccb)->sense_data, \ 446 ccb->sense_len - ccb->sense_resid, \ 447 /*show_errors*/ 1)) 448 #define XS_TAG_P(ccb) \ 449 (((ccb)->ccb_h.flags & CAM_TAG_ACTION_VALID) && \ 450 (ccb)->tag_action != CAM_TAG_ACTION_NONE) 451 452 #define XS_TAG_TYPE(ccb) \ 453 ((ccb->tag_action == MSG_SIMPLE_Q_TAG)? REQFLAG_STAG : \ 454 ((ccb->tag_action == MSG_HEAD_OF_Q_TAG)? REQFLAG_HTAG : REQFLAG_OTAG)) 455 456 457 #define XS_SETERR(ccb, v) (ccb)->ccb_h.status &= ~CAM_STATUS_MASK, \ 458 (ccb)->ccb_h.status |= v, \ 459 (ccb)->ccb_h.spriv_field0 |= ISP_SPRIV_ERRSET 460 461 # define HBA_NOERROR CAM_REQ_INPROG 462 # define HBA_BOTCH CAM_UNREC_HBA_ERROR 463 # define HBA_CMDTIMEOUT CAM_CMD_TIMEOUT 464 # define HBA_SELTIMEOUT CAM_SEL_TIMEOUT 465 # define HBA_TGTBSY CAM_SCSI_STATUS_ERROR 466 # define HBA_BUSRESET CAM_SCSI_BUS_RESET 467 # define HBA_ABORTED CAM_REQ_ABORTED 468 # define HBA_DATAOVR CAM_DATA_RUN_ERR 469 # define HBA_ARQFAIL CAM_AUTOSENSE_FAIL 470 471 472 #define XS_ERR(ccb) ((ccb)->ccb_h.status & CAM_STATUS_MASK) 473 474 #define XS_NOERR(ccb) \ 475 (((ccb)->ccb_h.spriv_field0 & ISP_SPRIV_ERRSET) == 0 || \ 476 ((ccb)->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) 477 478 #define XS_INITERR(ccb) \ 479 XS_SETERR(ccb, CAM_REQ_INPROG), (ccb)->ccb_h.spriv_field0 = 0 480 481 #define XS_SAVE_SENSE(xs, sense_ptr, slen) do { \ 482 (xs)->ccb_h.status |= CAM_AUTOSNS_VALID; \ 483 memset(&(xs)->sense_data, 0, sizeof((xs)->sense_data)); \ 484 memcpy(&(xs)->sense_data, sense_ptr, imin(XS_SNSLEN(xs),\ 485 slen)); \ 486 if (slen < (xs)->sense_len) \ 487 (xs)->sense_resid = (xs)->sense_len - slen; \ 488 } while (0); 489 490 #define XS_SENSE_VALID(xs) (((xs)->ccb_h.status & CAM_AUTOSNS_VALID) != 0) 491 492 #define DEFAULT_FRAMESIZE(isp) isp->isp_osinfo.framesize 493 #define DEFAULT_EXEC_THROTTLE(isp) isp->isp_osinfo.exec_throttle 494 495 #define GET_DEFAULT_ROLE(isp, chan) \ 496 (IS_FC(isp)? ISP_FC_PC(isp, chan)->def_role : ISP_SPI_PC(isp, chan)->def_role) 497 #define SET_DEFAULT_ROLE(isp, chan, val) \ 498 if (IS_FC(isp)) { \ 499 ISP_FC_PC(isp, chan)->def_role = val; \ 500 } else { \ 501 ISP_SPI_PC(isp, chan)->def_role = val; \ 502 } 503 504 #define DEFAULT_IID(isp, chan) isp->isp_osinfo.pc.spi[chan].iid 505 506 #define DEFAULT_LOOPID(x, chan) isp->isp_osinfo.pc.fc[chan].default_id 507 508 #define DEFAULT_NODEWWN(isp, chan) isp_default_wwn(isp, chan, 0, 1) 509 #define DEFAULT_PORTWWN(isp, chan) isp_default_wwn(isp, chan, 0, 0) 510 #define ACTIVE_NODEWWN(isp, chan) isp_default_wwn(isp, chan, 1, 1) 511 #define ACTIVE_PORTWWN(isp, chan) isp_default_wwn(isp, chan, 1, 0) 512 513 514 #if BYTE_ORDER == BIG_ENDIAN 515 #ifdef ISP_SBUS_SUPPORTED 516 #define ISP_IOXPUT_8(isp, s, d) *(d) = s 517 #define ISP_IOXPUT_16(isp, s, d) \ 518 *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap16(s) 519 #define ISP_IOXPUT_32(isp, s, d) \ 520 *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap32(s) 521 #define ISP_IOXGET_8(isp, s, d) d = (*((uint8_t *)s)) 522 #define ISP_IOXGET_16(isp, s, d) \ 523 d = (isp->isp_bustype == ISP_BT_SBUS)? \ 524 *((uint16_t *)s) : bswap16(*((uint16_t *)s)) 525 #define ISP_IOXGET_32(isp, s, d) \ 526 d = (isp->isp_bustype == ISP_BT_SBUS)? \ 527 *((uint32_t *)s) : bswap32(*((uint32_t *)s)) 528 529 #else /* ISP_SBUS_SUPPORTED */ 530 #define ISP_IOXPUT_8(isp, s, d) *(d) = s 531 #define ISP_IOXPUT_16(isp, s, d) *(d) = bswap16(s) 532 #define ISP_IOXPUT_32(isp, s, d) *(d) = bswap32(s) 533 #define ISP_IOXGET_8(isp, s, d) d = (*((uint8_t *)s)) 534 #define ISP_IOXGET_16(isp, s, d) d = bswap16(*((uint16_t *)s)) 535 #define ISP_IOXGET_32(isp, s, d) d = bswap32(*((uint32_t *)s)) 536 #endif 537 #define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = bswap16(*rp) 538 #define ISP_SWIZZLE_NVRAM_LONG(isp, rp) *rp = bswap32(*rp) 539 540 #define ISP_IOZGET_8(isp, s, d) d = (*((uint8_t *)s)) 541 #define ISP_IOZGET_16(isp, s, d) d = (*((uint16_t *)s)) 542 #define ISP_IOZGET_32(isp, s, d) d = (*((uint32_t *)s)) 543 #define ISP_IOZPUT_8(isp, s, d) *(d) = s 544 #define ISP_IOZPUT_16(isp, s, d) *(d) = s 545 #define ISP_IOZPUT_32(isp, s, d) *(d) = s 546 547 548 #else 549 #define ISP_IOXPUT_8(isp, s, d) *(d) = s 550 #define ISP_IOXPUT_16(isp, s, d) *(d) = s 551 #define ISP_IOXPUT_32(isp, s, d) *(d) = s 552 #define ISP_IOXGET_8(isp, s, d) d = *(s) 553 #define ISP_IOXGET_16(isp, s, d) d = *(s) 554 #define ISP_IOXGET_32(isp, s, d) d = *(s) 555 #define ISP_SWIZZLE_NVRAM_WORD(isp, rp) 556 #define ISP_SWIZZLE_NVRAM_LONG(isp, rp) 557 558 #define ISP_IOZPUT_8(isp, s, d) *(d) = s 559 #define ISP_IOZPUT_16(isp, s, d) *(d) = bswap16(s) 560 #define ISP_IOZPUT_32(isp, s, d) *(d) = bswap32(s) 561 562 #define ISP_IOZGET_8(isp, s, d) d = (*((uint8_t *)(s))) 563 #define ISP_IOZGET_16(isp, s, d) d = bswap16(*((uint16_t *)(s))) 564 #define ISP_IOZGET_32(isp, s, d) d = bswap32(*((uint32_t *)(s))) 565 566 #endif 567 568 #define ISP_SWAP16(isp, s) bswap16(s) 569 #define ISP_SWAP32(isp, s) bswap32(s) 570 571 /* 572 * Includes of common header files 573 */ 574 575 #include <dev/disk/isp/ispreg.h> 576 #include <dev/disk/isp/ispvar.h> 577 #include <dev/disk/isp/ispmbox.h> 578 579 /* 580 * isp_osinfo definiitions && shorthand 581 */ 582 #define SIMQFRZ_RESOURCE 0x1 583 #define SIMQFRZ_LOOPDOWN 0x2 584 #define SIMQFRZ_TIMED 0x4 585 586 #define isp_dev isp_osinfo.dev 587 588 /* 589 * prototypes for isp_pci && isp_freebsd to share 590 */ 591 extern int isp_attach(ispsoftc_t *); 592 extern int isp_detach(ispsoftc_t *); 593 extern void isp_uninit(ispsoftc_t *); 594 extern uint64_t isp_default_wwn(ispsoftc_t *, int, int, int); 595 596 /* 597 * driver global data 598 */ 599 extern int isp_announced; 600 extern int isp_fabric_hysteresis; 601 extern int isp_loop_down_limit; 602 extern int isp_gone_device_time; 603 extern int isp_quickboot_time; 604 extern int isp_autoconfig; 605 606 /* 607 * Platform private flags 608 */ 609 #define ISP_SPRIV_ERRSET 0x1 610 #define ISP_SPRIV_TACTIVE 0x2 611 #define ISP_SPRIV_DONE 0x8 612 #define ISP_SPRIV_WPEND 0x10 613 614 #define XS_S_TACTIVE(sccb) (sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_TACTIVE 615 #define XS_C_TACTIVE(sccb) (sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_TACTIVE 616 #define XS_TACTIVE_P(sccb) ((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_TACTIVE) 617 618 #define XS_CMD_S_DONE(sccb) (sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_DONE 619 #define XS_CMD_C_DONE(sccb) (sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_DONE 620 #define XS_CMD_DONE_P(sccb) ((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_DONE) 621 622 #define XS_CMD_S_WPEND(sccb) (sccb)->ccb_h.spriv_field0 |= ISP_SPRIV_WPEND 623 #define XS_CMD_C_WPEND(sccb) (sccb)->ccb_h.spriv_field0 &= ~ISP_SPRIV_WPEND 624 #define XS_CMD_WPEND_P(sccb) ((sccb)->ccb_h.spriv_field0 & ISP_SPRIV_WPEND) 625 626 627 #define XS_CMD_S_CLEAR(sccb) (sccb)->ccb_h.spriv_field0 = 0 628 629 /* 630 * Platform Library Functions 631 */ 632 void isp_prt(ispsoftc_t *, int level, const char *, ...) __printflike(3, 4); 633 void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...) __printflike(4, 5); 634 uint64_t isp_nanotime_sub(struct timespec *, struct timespec *); 635 int isp_mbox_acquire(ispsoftc_t *); 636 void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *); 637 void isp_mbox_notify_done(ispsoftc_t *); 638 void isp_mbox_release(ispsoftc_t *); 639 int isp_fc_scratch_acquire(ispsoftc_t *, int); 640 int isp_mstohz(int); 641 void isp_platform_intr(void *); 642 void isp_common_dmateardown(ispsoftc_t *, struct ccb_scsiio *, uint32_t); 643 644 /* 645 * Platform Version specific defines 646 */ 647 #define BUS_DMA_ROOTARG(x) bus_get_dma_tag(x) 648 #define isp_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z) \ 649 bus_dma_tag_create(a, b, c, d, e, f, g, h, i, j, k, z) 650 651 #define isp_setup_intr bus_setup_intr 652 653 #define isp_sim_alloc(a, b, c, d, e, f, g, h) \ 654 cam_sim_alloc(a, b, c, d, e, &(d)->isp_osinfo.lock, f, g, h) 655 656 /* Should be BUS_SPACE_MAXSIZE, but MAXPHYS is larger than BUS_SPACE_MAXSIZE */ 657 #define ISP_NSEGS ((MAXPHYS / PAGE_SIZE) + 1) 658 659 #define ISP_PATH_PRT(i, l, p, ...) \ 660 if ((l) == ISP_LOGALL || ((l)& (i)->isp_dblev) != 0) { \ 661 xpt_print(p, __VA_ARGS__); \ 662 } 663 664 /* 665 * Platform specific inline functions 666 */ 667 668 /* 669 * ISP General Library functions 670 */ 671 672 #include <dev/disk/isp/isp_library.h> 673 674 #endif /* _ISP_FREEBSD_H */ 675