1 /* 2 * Adaptec AIC79xx device driver for Linux. 3 * 4 * Copyright (c) 2000-2001 Adaptec Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * substantially similar to the "NO WARRANTY" disclaimer below 15 * ("Disclaimer") and any redistribution must be conditioned upon 16 * including a substantially similar Disclaimer requirement for further 17 * binary redistribution. 18 * 3. Neither the names of the above-listed copyright holders nor the names 19 * of any contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * Alternatively, this software may be distributed under the terms of the 23 * GNU General Public License ("GPL") version 2 as published by the Free 24 * Software Foundation. 25 * 26 * NO WARRANTY 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGES. 38 * 39 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#137 $ 40 * 41 */ 42 #ifndef _AIC79XX_LINUX_H_ 43 #define _AIC79XX_LINUX_H_ 44 45 #include <linux/types.h> 46 #include <linux/blkdev.h> 47 #include <linux/delay.h> 48 #include <linux/ioport.h> 49 #include <linux/pci.h> 50 #include <linux/smp_lock.h> 51 #include <linux/version.h> 52 #include <linux/module.h> 53 #include <asm/byteorder.h> 54 #include <asm/io.h> 55 56 #include <linux/interrupt.h> /* For tasklet support. */ 57 #include <linux/config.h> 58 #include <linux/slab.h> 59 60 /* Core SCSI definitions */ 61 #define AIC_LIB_PREFIX ahd 62 #include "scsi.h" 63 #include <scsi/scsi_host.h> 64 65 /* Name space conflict with BSD queue macros */ 66 #ifdef LIST_HEAD 67 #undef LIST_HEAD 68 #endif 69 70 #include "cam.h" 71 #include "queue.h" 72 #include "scsi_message.h" 73 #include "scsi_iu.h" 74 #include "aiclib.h" 75 76 /*********************************** Debugging ********************************/ 77 #ifdef CONFIG_AIC79XX_DEBUG_ENABLE 78 #ifdef CONFIG_AIC79XX_DEBUG_MASK 79 #define AHD_DEBUG 1 80 #define AHD_DEBUG_OPTS CONFIG_AIC79XX_DEBUG_MASK 81 #else 82 /* 83 * Compile in debugging code, but do not enable any printfs. 84 */ 85 #define AHD_DEBUG 1 86 #define AHD_DEBUG_OPTS 0 87 #endif 88 /* No debugging code. */ 89 #endif 90 91 /********************************** Misc Macros *******************************/ 92 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 93 #define powerof2(x) ((((x)-1)&(x))==0) 94 95 /************************* Forward Declarations *******************************/ 96 struct ahd_softc; 97 typedef struct pci_dev *ahd_dev_softc_t; 98 typedef Scsi_Cmnd *ahd_io_ctx_t; 99 100 /******************************* Byte Order ***********************************/ 101 #define ahd_htobe16(x) cpu_to_be16(x) 102 #define ahd_htobe32(x) cpu_to_be32(x) 103 #define ahd_htobe64(x) cpu_to_be64(x) 104 #define ahd_htole16(x) cpu_to_le16(x) 105 #define ahd_htole32(x) cpu_to_le32(x) 106 #define ahd_htole64(x) cpu_to_le64(x) 107 108 #define ahd_be16toh(x) be16_to_cpu(x) 109 #define ahd_be32toh(x) be32_to_cpu(x) 110 #define ahd_be64toh(x) be64_to_cpu(x) 111 #define ahd_le16toh(x) le16_to_cpu(x) 112 #define ahd_le32toh(x) le32_to_cpu(x) 113 #define ahd_le64toh(x) le64_to_cpu(x) 114 115 #ifndef LITTLE_ENDIAN 116 #define LITTLE_ENDIAN 1234 117 #endif 118 119 #ifndef BIG_ENDIAN 120 #define BIG_ENDIAN 4321 121 #endif 122 123 #ifndef BYTE_ORDER 124 #if defined(__BIG_ENDIAN) 125 #define BYTE_ORDER BIG_ENDIAN 126 #endif 127 #if defined(__LITTLE_ENDIAN) 128 #define BYTE_ORDER LITTLE_ENDIAN 129 #endif 130 #endif /* BYTE_ORDER */ 131 132 /************************* Configuration Data *********************************/ 133 extern uint32_t aic79xx_allow_memio; 134 extern int aic79xx_detect_complete; 135 extern Scsi_Host_Template aic79xx_driver_template; 136 137 /***************************** Bus Space/DMA **********************************/ 138 139 typedef uint32_t bus_size_t; 140 141 typedef enum { 142 BUS_SPACE_MEMIO, 143 BUS_SPACE_PIO 144 } bus_space_tag_t; 145 146 typedef union { 147 u_long ioport; 148 volatile uint8_t __iomem *maddr; 149 } bus_space_handle_t; 150 151 typedef struct bus_dma_segment 152 { 153 dma_addr_t ds_addr; 154 bus_size_t ds_len; 155 } bus_dma_segment_t; 156 157 struct ahd_linux_dma_tag 158 { 159 bus_size_t alignment; 160 bus_size_t boundary; 161 bus_size_t maxsize; 162 }; 163 typedef struct ahd_linux_dma_tag* bus_dma_tag_t; 164 165 struct ahd_linux_dmamap 166 { 167 dma_addr_t bus_addr; 168 }; 169 typedef struct ahd_linux_dmamap* bus_dmamap_t; 170 171 typedef int bus_dma_filter_t(void*, dma_addr_t); 172 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); 173 174 #define BUS_DMA_WAITOK 0x0 175 #define BUS_DMA_NOWAIT 0x1 176 #define BUS_DMA_ALLOCNOW 0x2 177 #define BUS_DMA_LOAD_SEGS 0x4 /* 178 * Argument is an S/G list not 179 * a single buffer. 180 */ 181 182 #define BUS_SPACE_MAXADDR 0xFFFFFFFF 183 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF 184 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF 185 186 int ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/, 187 bus_size_t /*alignment*/, bus_size_t /*boundary*/, 188 dma_addr_t /*lowaddr*/, dma_addr_t /*highaddr*/, 189 bus_dma_filter_t*/*filter*/, void */*filterarg*/, 190 bus_size_t /*maxsize*/, int /*nsegments*/, 191 bus_size_t /*maxsegsz*/, int /*flags*/, 192 bus_dma_tag_t */*dma_tagp*/); 193 194 void ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/); 195 196 int ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t /*dmat*/, 197 void** /*vaddr*/, int /*flags*/, 198 bus_dmamap_t* /*mapp*/); 199 200 void ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t /*dmat*/, 201 void* /*vaddr*/, bus_dmamap_t /*map*/); 202 203 void ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/, 204 bus_dmamap_t /*map*/); 205 206 int ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t /*dmat*/, 207 bus_dmamap_t /*map*/, void * /*buf*/, 208 bus_size_t /*buflen*/, bus_dmamap_callback_t *, 209 void */*callback_arg*/, int /*flags*/); 210 211 int ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t); 212 213 /* 214 * Operations performed by ahd_dmamap_sync(). 215 */ 216 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ 217 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ 218 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ 219 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ 220 221 /* 222 * XXX 223 * ahd_dmamap_sync is only used on buffers allocated with 224 * the pci_alloc_consistent() API. Although I'm not sure how 225 * this works on architectures with a write buffer, Linux does 226 * not have an API to sync "coherent" memory. Perhaps we need 227 * to do an mb()? 228 */ 229 #define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op) 230 231 /************************** Timer DataStructures ******************************/ 232 typedef struct timer_list ahd_timer_t; 233 234 /********************************** Includes **********************************/ 235 #ifdef CONFIG_AIC79XX_REG_PRETTY_PRINT 236 #define AIC_DEBUG_REGISTERS 1 237 #else 238 #define AIC_DEBUG_REGISTERS 0 239 #endif 240 #include "aic79xx.h" 241 242 /***************************** Timer Facilities *******************************/ 243 #define ahd_timer_init init_timer 244 #define ahd_timer_stop del_timer_sync 245 typedef void ahd_linux_callback_t (u_long); 246 static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec, 247 ahd_callback_t *func, void *arg); 248 static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec); 249 250 static __inline void 251 ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg) 252 { 253 struct ahd_softc *ahd; 254 255 ahd = (struct ahd_softc *)arg; 256 del_timer(timer); 257 timer->data = (u_long)arg; 258 timer->expires = jiffies + (usec * HZ)/1000000; 259 timer->function = (ahd_linux_callback_t*)func; 260 add_timer(timer); 261 } 262 263 static __inline void 264 ahd_scb_timer_reset(struct scb *scb, u_int usec) 265 { 266 mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000); 267 } 268 269 /***************************** SMP support ************************************/ 270 #include <linux/spinlock.h> 271 272 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) 273 #define AHD_SCSI_HAS_HOST_LOCK 1 274 #else 275 #define AHD_SCSI_HAS_HOST_LOCK 0 276 #endif 277 278 #define AIC79XX_DRIVER_VERSION "1.3.11" 279 280 /**************************** Front End Queues ********************************/ 281 /* 282 * Data structure used to cast the Linux struct scsi_cmnd to something 283 * that allows us to use the queue macros. The linux structure has 284 * plenty of space to hold the links fields as required by the queue 285 * macros, but the queue macors require them to have the correct type. 286 */ 287 struct ahd_cmd_internal { 288 /* Area owned by the Linux scsi layer. */ 289 uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)]; 290 union { 291 STAILQ_ENTRY(ahd_cmd) ste; 292 LIST_ENTRY(ahd_cmd) le; 293 TAILQ_ENTRY(ahd_cmd) tqe; 294 } links; 295 uint32_t end; 296 }; 297 298 struct ahd_cmd { 299 union { 300 struct ahd_cmd_internal icmd; 301 struct scsi_cmnd scsi_cmd; 302 } un; 303 }; 304 305 #define acmd_icmd(cmd) ((cmd)->un.icmd) 306 #define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd) 307 #define acmd_links un.icmd.links 308 309 /*************************** Device Data Structures ***************************/ 310 /* 311 * A per probed device structure used to deal with some error recovery 312 * scenarios that the Linux mid-layer code just doesn't know how to 313 * handle. The structure allocated for a device only becomes persistent 314 * after a successfully completed inquiry command to the target when 315 * that inquiry data indicates a lun is present. 316 */ 317 TAILQ_HEAD(ahd_busyq, ahd_cmd); 318 typedef enum { 319 AHD_DEV_UNCONFIGURED = 0x01, 320 AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ 321 AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ 322 AHD_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ 323 AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ 324 AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ 325 AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ 326 AHD_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ 327 } ahd_linux_dev_flags; 328 329 struct ahd_linux_target; 330 struct ahd_linux_device { 331 TAILQ_ENTRY(ahd_linux_device) links; 332 struct ahd_busyq busyq; 333 334 /* 335 * The number of transactions currently 336 * queued to the device. 337 */ 338 int active; 339 340 /* 341 * The currently allowed number of 342 * transactions that can be queued to 343 * the device. Must be signed for 344 * conversion from tagged to untagged 345 * mode where the device may have more 346 * than one outstanding active transaction. 347 */ 348 int openings; 349 350 /* 351 * A positive count indicates that this 352 * device's queue is halted. 353 */ 354 u_int qfrozen; 355 356 /* 357 * Cumulative command counter. 358 */ 359 u_long commands_issued; 360 361 /* 362 * The number of tagged transactions when 363 * running at our current opening level 364 * that have been successfully received by 365 * this device since the last QUEUE FULL. 366 */ 367 u_int tag_success_count; 368 #define AHD_TAG_SUCCESS_INTERVAL 50 369 370 ahd_linux_dev_flags flags; 371 372 /* 373 * Per device timer. 374 */ 375 struct timer_list timer; 376 377 /* 378 * The high limit for the tags variable. 379 */ 380 u_int maxtags; 381 382 /* 383 * The computed number of tags outstanding 384 * at the time of the last QUEUE FULL event. 385 */ 386 u_int tags_on_last_queuefull; 387 388 /* 389 * How many times we have seen a queue full 390 * with the same number of tags. This is used 391 * to stop our adaptive queue depth algorithm 392 * on devices with a fixed number of tags. 393 */ 394 u_int last_queuefull_same_count; 395 #define AHD_LOCK_TAGS_COUNT 50 396 397 /* 398 * How many transactions have been queued 399 * without the device going idle. We use 400 * this statistic to determine when to issue 401 * an ordered tag to prevent transaction 402 * starvation. This statistic is only updated 403 * if the AHD_DEV_PERIODIC_OTAG flag is set 404 * on this device. 405 */ 406 u_int commands_since_idle_or_otag; 407 #define AHD_OTAG_THRESH 500 408 409 int lun; 410 Scsi_Device *scsi_device; 411 struct ahd_linux_target *target; 412 }; 413 414 typedef enum { 415 AHD_DV_REQUIRED = 0x01, 416 AHD_INQ_VALID = 0x02, 417 AHD_BASIC_DV = 0x04, 418 AHD_ENHANCED_DV = 0x08 419 } ahd_linux_targ_flags; 420 421 /* DV States */ 422 typedef enum { 423 AHD_DV_STATE_EXIT = 0, 424 AHD_DV_STATE_INQ_SHORT_ASYNC, 425 AHD_DV_STATE_INQ_ASYNC, 426 AHD_DV_STATE_INQ_ASYNC_VERIFY, 427 AHD_DV_STATE_TUR, 428 AHD_DV_STATE_REBD, 429 AHD_DV_STATE_INQ_VERIFY, 430 AHD_DV_STATE_WEB, 431 AHD_DV_STATE_REB, 432 AHD_DV_STATE_SU, 433 AHD_DV_STATE_BUSY 434 } ahd_dv_state; 435 436 struct ahd_linux_target { 437 struct ahd_linux_device *devices[AHD_NUM_LUNS]; 438 int channel; 439 int target; 440 int refcount; 441 struct ahd_transinfo last_tinfo; 442 struct ahd_softc *ahd; 443 ahd_linux_targ_flags flags; 444 struct scsi_inquiry_data *inq_data; 445 /* 446 * The next "fallback" period to use for narrow/wide transfers. 447 */ 448 uint8_t dv_next_narrow_period; 449 uint8_t dv_next_wide_period; 450 uint8_t dv_max_width; 451 uint8_t dv_max_ppr_options; 452 uint8_t dv_last_ppr_options; 453 u_int dv_echo_size; 454 ahd_dv_state dv_state; 455 u_int dv_state_retry; 456 uint8_t *dv_buffer; 457 uint8_t *dv_buffer1; 458 459 /* 460 * Cumulative counter of errors. 461 */ 462 u_long errors_detected; 463 u_long cmds_since_error; 464 }; 465 466 /********************* Definitions Required by the Core ***********************/ 467 /* 468 * Number of SG segments we require. So long as the S/G segments for 469 * a particular transaction are allocated in a physically contiguous 470 * manner and are allocated below 4GB, the number of S/G segments is 471 * unrestricted. 472 */ 473 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 474 /* 475 * We dynamically adjust the number of segments in pre-2.5 kernels to 476 * avoid fragmentation issues in the SCSI mid-layer's private memory 477 * allocator. See aic79xx_osm.c ahd_linux_size_nseg() for details. 478 */ 479 extern u_int ahd_linux_nseg; 480 #define AHD_NSEG ahd_linux_nseg 481 #define AHD_LINUX_MIN_NSEG 64 482 #else 483 #define AHD_NSEG 128 484 #endif 485 486 /* 487 * Per-SCB OSM storage. 488 */ 489 typedef enum { 490 AHD_SCB_UP_EH_SEM = 0x1 491 } ahd_linux_scb_flags; 492 493 struct scb_platform_data { 494 struct ahd_linux_device *dev; 495 dma_addr_t buf_busaddr; 496 uint32_t xfer_len; 497 uint32_t sense_resid; /* Auto-Sense residual */ 498 ahd_linux_scb_flags flags; 499 }; 500 501 /* 502 * Define a structure used for each host adapter. All members are 503 * aligned on a boundary >= the size of the member to honor the 504 * alignment restrictions of the various platforms supported by 505 * this driver. 506 */ 507 typedef enum { 508 AHD_DV_WAIT_SIMQ_EMPTY = 0x01, 509 AHD_DV_WAIT_SIMQ_RELEASE = 0x02, 510 AHD_DV_ACTIVE = 0x04, 511 AHD_DV_SHUTDOWN = 0x08, 512 AHD_RUN_CMPLT_Q_TIMER = 0x10 513 } ahd_linux_softc_flags; 514 515 TAILQ_HEAD(ahd_completeq, ahd_cmd); 516 517 struct ahd_platform_data { 518 /* 519 * Fields accessed from interrupt context. 520 */ 521 struct ahd_linux_target *targets[AHD_NUM_TARGETS]; 522 TAILQ_HEAD(, ahd_linux_device) device_runq; 523 struct ahd_completeq completeq; 524 525 spinlock_t spin_lock; 526 struct tasklet_struct runq_tasklet; 527 u_int qfrozen; 528 pid_t dv_pid; 529 struct timer_list completeq_timer; 530 struct timer_list reset_timer; 531 struct timer_list stats_timer; 532 struct semaphore eh_sem; 533 struct semaphore dv_sem; 534 struct semaphore dv_cmd_sem; /* XXX This needs to be in 535 * the target struct 536 */ 537 struct scsi_device *dv_scsi_dev; 538 struct Scsi_Host *host; /* pointer to scsi host */ 539 #define AHD_LINUX_NOIRQ ((uint32_t)~0) 540 uint32_t irq; /* IRQ for this adapter */ 541 uint32_t bios_address; 542 uint32_t mem_busaddr; /* Mem Base Addr */ 543 uint64_t hw_dma_mask; 544 ahd_linux_softc_flags flags; 545 }; 546 547 /************************** OS Utility Wrappers *******************************/ 548 #define printf printk 549 #define M_NOWAIT GFP_ATOMIC 550 #define M_WAITOK 0 551 #define malloc(size, type, flags) kmalloc(size, flags) 552 #define free(ptr, type) kfree(ptr) 553 554 static __inline void ahd_delay(long); 555 static __inline void 556 ahd_delay(long usec) 557 { 558 /* 559 * udelay on Linux can have problems for 560 * multi-millisecond waits. Wait at most 561 * 1024us per call. 562 */ 563 while (usec > 0) { 564 udelay(usec % 1024); 565 usec -= 1024; 566 } 567 } 568 569 570 /***************************** Low Level I/O **********************************/ 571 static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port); 572 static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port); 573 static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val); 574 static __inline void ahd_outw_atomic(struct ahd_softc * ahd, 575 long port, uint16_t val); 576 static __inline void ahd_outsb(struct ahd_softc * ahd, long port, 577 uint8_t *, int count); 578 static __inline void ahd_insb(struct ahd_softc * ahd, long port, 579 uint8_t *, int count); 580 581 static __inline uint8_t 582 ahd_inb(struct ahd_softc * ahd, long port) 583 { 584 uint8_t x; 585 586 if (ahd->tags[0] == BUS_SPACE_MEMIO) { 587 x = readb(ahd->bshs[0].maddr + port); 588 } else { 589 x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); 590 } 591 mb(); 592 return (x); 593 } 594 595 static __inline uint16_t 596 ahd_inw_atomic(struct ahd_softc * ahd, long port) 597 { 598 uint8_t x; 599 600 if (ahd->tags[0] == BUS_SPACE_MEMIO) { 601 x = readw(ahd->bshs[0].maddr + port); 602 } else { 603 x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF)); 604 } 605 mb(); 606 return (x); 607 } 608 609 static __inline void 610 ahd_outb(struct ahd_softc * ahd, long port, uint8_t val) 611 { 612 if (ahd->tags[0] == BUS_SPACE_MEMIO) { 613 writeb(val, ahd->bshs[0].maddr + port); 614 } else { 615 outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); 616 } 617 mb(); 618 } 619 620 static __inline void 621 ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val) 622 { 623 if (ahd->tags[0] == BUS_SPACE_MEMIO) { 624 writew(val, ahd->bshs[0].maddr + port); 625 } else { 626 outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF)); 627 } 628 mb(); 629 } 630 631 static __inline void 632 ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count) 633 { 634 int i; 635 636 /* 637 * There is probably a more efficient way to do this on Linux 638 * but we don't use this for anything speed critical and this 639 * should work. 640 */ 641 for (i = 0; i < count; i++) 642 ahd_outb(ahd, port, *array++); 643 } 644 645 static __inline void 646 ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count) 647 { 648 int i; 649 650 /* 651 * There is probably a more efficient way to do this on Linux 652 * but we don't use this for anything speed critical and this 653 * should work. 654 */ 655 for (i = 0; i < count; i++) 656 *array++ = ahd_inb(ahd, port); 657 } 658 659 /**************************** Initialization **********************************/ 660 int ahd_linux_register_host(struct ahd_softc *, 661 Scsi_Host_Template *); 662 663 uint64_t ahd_linux_get_memsize(void); 664 665 /*************************** Pretty Printing **********************************/ 666 struct info_str { 667 char *buffer; 668 int length; 669 off_t offset; 670 int pos; 671 }; 672 673 void ahd_format_transinfo(struct info_str *info, 674 struct ahd_transinfo *tinfo); 675 676 /******************************** Locking *************************************/ 677 /* Lock protecting internal data structures */ 678 static __inline void ahd_lockinit(struct ahd_softc *); 679 static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags); 680 static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags); 681 682 /* Lock acquisition and release of the above lock in midlayer entry points. */ 683 static __inline void ahd_midlayer_entrypoint_lock(struct ahd_softc *, 684 unsigned long *flags); 685 static __inline void ahd_midlayer_entrypoint_unlock(struct ahd_softc *, 686 unsigned long *flags); 687 688 /* Lock held during command compeletion to the upper layer */ 689 static __inline void ahd_done_lockinit(struct ahd_softc *); 690 static __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags); 691 static __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags); 692 693 /* Lock held during ahd_list manipulation and ahd softc frees */ 694 extern spinlock_t ahd_list_spinlock; 695 static __inline void ahd_list_lockinit(void); 696 static __inline void ahd_list_lock(unsigned long *flags); 697 static __inline void ahd_list_unlock(unsigned long *flags); 698 699 static __inline void 700 ahd_lockinit(struct ahd_softc *ahd) 701 { 702 spin_lock_init(&ahd->platform_data->spin_lock); 703 } 704 705 static __inline void 706 ahd_lock(struct ahd_softc *ahd, unsigned long *flags) 707 { 708 spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags); 709 } 710 711 static __inline void 712 ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) 713 { 714 spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags); 715 } 716 717 static __inline void 718 ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags) 719 { 720 /* 721 * In 2.5.X and some 2.4.X versions, the midlayer takes our 722 * lock just before calling us, so we avoid locking again. 723 * For other kernel versions, the io_request_lock is taken 724 * just before our entry point is called. In this case, we 725 * trade the io_request_lock for our per-softc lock. 726 */ 727 #if AHD_SCSI_HAS_HOST_LOCK == 0 728 spin_unlock(&io_request_lock); 729 spin_lock(&ahd->platform_data->spin_lock); 730 #endif 731 } 732 733 static __inline void 734 ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags) 735 { 736 #if AHD_SCSI_HAS_HOST_LOCK == 0 737 spin_unlock(&ahd->platform_data->spin_lock); 738 spin_lock(&io_request_lock); 739 #endif 740 } 741 742 static __inline void 743 ahd_done_lockinit(struct ahd_softc *ahd) 744 { 745 /* 746 * In 2.5.X, our own lock is held during completions. 747 * In previous versions, the io_request_lock is used. 748 * In either case, we can't initialize this lock again. 749 */ 750 } 751 752 static __inline void 753 ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags) 754 { 755 #if AHD_SCSI_HAS_HOST_LOCK == 0 756 spin_lock(&io_request_lock); 757 #endif 758 } 759 760 static __inline void 761 ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags) 762 { 763 #if AHD_SCSI_HAS_HOST_LOCK == 0 764 spin_unlock(&io_request_lock); 765 #endif 766 } 767 768 static __inline void 769 ahd_list_lockinit(void) 770 { 771 spin_lock_init(&ahd_list_spinlock); 772 } 773 774 static __inline void 775 ahd_list_lock(unsigned long *flags) 776 { 777 spin_lock_irqsave(&ahd_list_spinlock, *flags); 778 } 779 780 static __inline void 781 ahd_list_unlock(unsigned long *flags) 782 { 783 spin_unlock_irqrestore(&ahd_list_spinlock, *flags); 784 } 785 786 /******************************* PCI Definitions ******************************/ 787 /* 788 * PCIM_xxx: mask to locate subfield in register 789 * PCIR_xxx: config register offset 790 * PCIC_xxx: device class 791 * PCIS_xxx: device subclass 792 * PCIP_xxx: device programming interface 793 * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) 794 * PCID_xxx: device ID 795 */ 796 #define PCIR_DEVVENDOR 0x00 797 #define PCIR_VENDOR 0x00 798 #define PCIR_DEVICE 0x02 799 #define PCIR_COMMAND 0x04 800 #define PCIM_CMD_PORTEN 0x0001 801 #define PCIM_CMD_MEMEN 0x0002 802 #define PCIM_CMD_BUSMASTEREN 0x0004 803 #define PCIM_CMD_MWRICEN 0x0010 804 #define PCIM_CMD_PERRESPEN 0x0040 805 #define PCIM_CMD_SERRESPEN 0x0100 806 #define PCIR_STATUS 0x06 807 #define PCIR_REVID 0x08 808 #define PCIR_PROGIF 0x09 809 #define PCIR_SUBCLASS 0x0a 810 #define PCIR_CLASS 0x0b 811 #define PCIR_CACHELNSZ 0x0c 812 #define PCIR_LATTIMER 0x0d 813 #define PCIR_HEADERTYPE 0x0e 814 #define PCIM_MFDEV 0x80 815 #define PCIR_BIST 0x0f 816 #define PCIR_CAP_PTR 0x34 817 818 /* config registers for header type 0 devices */ 819 #define PCIR_MAPS 0x10 820 #define PCIR_SUBVEND_0 0x2c 821 #define PCIR_SUBDEV_0 0x2e 822 823 /****************************** PCI-X definitions *****************************/ 824 #define PCIXR_COMMAND 0x96 825 #define PCIXR_DEVADDR 0x98 826 #define PCIXM_DEVADDR_FNUM 0x0003 /* Function Number */ 827 #define PCIXM_DEVADDR_DNUM 0x00F8 /* Device Number */ 828 #define PCIXM_DEVADDR_BNUM 0xFF00 /* Bus Number */ 829 #define PCIXR_STATUS 0x9A 830 #define PCIXM_STATUS_64BIT 0x0001 /* Active 64bit connection to device. */ 831 #define PCIXM_STATUS_133CAP 0x0002 /* Device is 133MHz capable */ 832 #define PCIXM_STATUS_SCDISC 0x0004 /* Split Completion Discarded */ 833 #define PCIXM_STATUS_UNEXPSC 0x0008 /* Unexpected Split Completion */ 834 #define PCIXM_STATUS_CMPLEXDEV 0x0010 /* Device Complexity (set == bridge) */ 835 #define PCIXM_STATUS_MAXMRDBC 0x0060 /* Maximum Burst Read Count */ 836 #define PCIXM_STATUS_MAXSPLITS 0x0380 /* Maximum Split Transactions */ 837 #define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ 838 #define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ 839 840 extern struct pci_driver aic79xx_pci_driver; 841 842 typedef enum 843 { 844 AHD_POWER_STATE_D0, 845 AHD_POWER_STATE_D1, 846 AHD_POWER_STATE_D2, 847 AHD_POWER_STATE_D3 848 } ahd_power_state; 849 850 void ahd_power_state_change(struct ahd_softc *ahd, 851 ahd_power_state new_state); 852 853 /******************************* PCI Routines *********************************/ 854 int ahd_linux_pci_init(void); 855 void ahd_linux_pci_exit(void); 856 int ahd_pci_map_registers(struct ahd_softc *ahd); 857 int ahd_pci_map_int(struct ahd_softc *ahd); 858 859 static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci, 860 int reg, int width); 861 862 static __inline uint32_t 863 ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width) 864 { 865 switch (width) { 866 case 1: 867 { 868 uint8_t retval; 869 870 pci_read_config_byte(pci, reg, &retval); 871 return (retval); 872 } 873 case 2: 874 { 875 uint16_t retval; 876 pci_read_config_word(pci, reg, &retval); 877 return (retval); 878 } 879 case 4: 880 { 881 uint32_t retval; 882 pci_read_config_dword(pci, reg, &retval); 883 return (retval); 884 } 885 default: 886 panic("ahd_pci_read_config: Read size too big"); 887 /* NOTREACHED */ 888 return (0); 889 } 890 } 891 892 static __inline void ahd_pci_write_config(ahd_dev_softc_t pci, 893 int reg, uint32_t value, 894 int width); 895 896 static __inline void 897 ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width) 898 { 899 switch (width) { 900 case 1: 901 pci_write_config_byte(pci, reg, value); 902 break; 903 case 2: 904 pci_write_config_word(pci, reg, value); 905 break; 906 case 4: 907 pci_write_config_dword(pci, reg, value); 908 break; 909 default: 910 panic("ahd_pci_write_config: Write size too big"); 911 /* NOTREACHED */ 912 } 913 } 914 915 static __inline int ahd_get_pci_function(ahd_dev_softc_t); 916 static __inline int 917 ahd_get_pci_function(ahd_dev_softc_t pci) 918 { 919 return (PCI_FUNC(pci->devfn)); 920 } 921 922 static __inline int ahd_get_pci_slot(ahd_dev_softc_t); 923 static __inline int 924 ahd_get_pci_slot(ahd_dev_softc_t pci) 925 { 926 return (PCI_SLOT(pci->devfn)); 927 } 928 929 static __inline int ahd_get_pci_bus(ahd_dev_softc_t); 930 static __inline int 931 ahd_get_pci_bus(ahd_dev_softc_t pci) 932 { 933 return (pci->bus->number); 934 } 935 936 static __inline void ahd_flush_device_writes(struct ahd_softc *); 937 static __inline void 938 ahd_flush_device_writes(struct ahd_softc *ahd) 939 { 940 /* XXX Is this sufficient for all architectures??? */ 941 ahd_inb(ahd, INTSTAT); 942 } 943 944 /**************************** Proc FS Support *********************************/ 945 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 946 int ahd_linux_proc_info(char *, char **, off_t, int, int, int); 947 #else 948 int ahd_linux_proc_info(struct Scsi_Host *, char *, char **, 949 off_t, int, int); 950 #endif 951 952 /*************************** Domain Validation ********************************/ 953 #define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete) 954 #define AHD_DV_SIMQ_FROZEN(ahd) \ 955 ((((ahd)->platform_data->flags & AHD_DV_ACTIVE) != 0) \ 956 && (ahd)->platform_data->qfrozen == 1) 957 958 /*********************** Transaction Access Wrappers **************************/ 959 static __inline void ahd_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); 960 static __inline void ahd_set_transaction_status(struct scb *, uint32_t); 961 static __inline void ahd_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); 962 static __inline void ahd_set_scsi_status(struct scb *, uint32_t); 963 static __inline uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd); 964 static __inline uint32_t ahd_get_transaction_status(struct scb *); 965 static __inline uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd); 966 static __inline uint32_t ahd_get_scsi_status(struct scb *); 967 static __inline void ahd_set_transaction_tag(struct scb *, int, u_int); 968 static __inline u_long ahd_get_transfer_length(struct scb *); 969 static __inline int ahd_get_transfer_dir(struct scb *); 970 static __inline void ahd_set_residual(struct scb *, u_long); 971 static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid); 972 static __inline u_long ahd_get_residual(struct scb *); 973 static __inline u_long ahd_get_sense_residual(struct scb *); 974 static __inline int ahd_perform_autosense(struct scb *); 975 static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *, 976 struct scb *); 977 static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *, 978 struct ahd_devinfo *); 979 static __inline void ahd_platform_scb_free(struct ahd_softc *ahd, 980 struct scb *scb); 981 static __inline void ahd_freeze_scb(struct scb *scb); 982 983 static __inline 984 void ahd_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) 985 { 986 cmd->result &= ~(CAM_STATUS_MASK << 16); 987 cmd->result |= status << 16; 988 } 989 990 static __inline 991 void ahd_set_transaction_status(struct scb *scb, uint32_t status) 992 { 993 ahd_cmd_set_transaction_status(scb->io_ctx,status); 994 } 995 996 static __inline 997 void ahd_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) 998 { 999 cmd->result &= ~0xFFFF; 1000 cmd->result |= status; 1001 } 1002 1003 static __inline 1004 void ahd_set_scsi_status(struct scb *scb, uint32_t status) 1005 { 1006 ahd_cmd_set_scsi_status(scb->io_ctx, status); 1007 } 1008 1009 static __inline 1010 uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd) 1011 { 1012 return ((cmd->result >> 16) & CAM_STATUS_MASK); 1013 } 1014 1015 static __inline 1016 uint32_t ahd_get_transaction_status(struct scb *scb) 1017 { 1018 return (ahd_cmd_get_transaction_status(scb->io_ctx)); 1019 } 1020 1021 static __inline 1022 uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd) 1023 { 1024 return (cmd->result & 0xFFFF); 1025 } 1026 1027 static __inline 1028 uint32_t ahd_get_scsi_status(struct scb *scb) 1029 { 1030 return (ahd_cmd_get_scsi_status(scb->io_ctx)); 1031 } 1032 1033 static __inline 1034 void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type) 1035 { 1036 /* 1037 * Nothing to do for linux as the incoming transaction 1038 * has no concept of tag/non tagged, etc. 1039 */ 1040 } 1041 1042 static __inline 1043 u_long ahd_get_transfer_length(struct scb *scb) 1044 { 1045 return (scb->platform_data->xfer_len); 1046 } 1047 1048 static __inline 1049 int ahd_get_transfer_dir(struct scb *scb) 1050 { 1051 return (scb->io_ctx->sc_data_direction); 1052 } 1053 1054 static __inline 1055 void ahd_set_residual(struct scb *scb, u_long resid) 1056 { 1057 scb->io_ctx->resid = resid; 1058 } 1059 1060 static __inline 1061 void ahd_set_sense_residual(struct scb *scb, u_long resid) 1062 { 1063 scb->platform_data->sense_resid = resid; 1064 } 1065 1066 static __inline 1067 u_long ahd_get_residual(struct scb *scb) 1068 { 1069 return (scb->io_ctx->resid); 1070 } 1071 1072 static __inline 1073 u_long ahd_get_sense_residual(struct scb *scb) 1074 { 1075 return (scb->platform_data->sense_resid); 1076 } 1077 1078 static __inline 1079 int ahd_perform_autosense(struct scb *scb) 1080 { 1081 /* 1082 * We always perform autosense in Linux. 1083 * On other platforms this is set on a 1084 * per-transaction basis. 1085 */ 1086 return (1); 1087 } 1088 1089 static __inline uint32_t 1090 ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb) 1091 { 1092 return (sizeof(struct scsi_sense_data)); 1093 } 1094 1095 static __inline void 1096 ahd_notify_xfer_settings_change(struct ahd_softc *ahd, 1097 struct ahd_devinfo *devinfo) 1098 { 1099 /* Nothing to do here for linux */ 1100 } 1101 1102 static __inline void 1103 ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb) 1104 { 1105 ahd->flags &= ~AHD_RESOURCE_SHORTAGE; 1106 } 1107 1108 int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); 1109 void ahd_platform_free(struct ahd_softc *ahd); 1110 void ahd_platform_init(struct ahd_softc *ahd); 1111 void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb); 1112 void ahd_freeze_simq(struct ahd_softc *ahd); 1113 void ahd_release_simq(struct ahd_softc *ahd); 1114 1115 static __inline void 1116 ahd_freeze_scb(struct scb *scb) 1117 { 1118 if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) { 1119 scb->io_ctx->result |= CAM_DEV_QFRZN << 16; 1120 scb->platform_data->dev->qfrozen++; 1121 } 1122 } 1123 1124 void ahd_platform_set_tags(struct ahd_softc *ahd, 1125 struct ahd_devinfo *devinfo, ahd_queue_alg); 1126 int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, 1127 char channel, int lun, u_int tag, 1128 role_t role, uint32_t status); 1129 irqreturn_t 1130 ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); 1131 void ahd_platform_flushwork(struct ahd_softc *ahd); 1132 int ahd_softc_comp(struct ahd_softc *, struct ahd_softc *); 1133 void ahd_done(struct ahd_softc*, struct scb*); 1134 void ahd_send_async(struct ahd_softc *, char channel, 1135 u_int target, u_int lun, ac_code, void *); 1136 void ahd_print_path(struct ahd_softc *, struct scb *); 1137 void ahd_platform_dump_card_state(struct ahd_softc *ahd); 1138 1139 #ifdef CONFIG_PCI 1140 #define AHD_PCI_CONFIG 1 1141 #else 1142 #define AHD_PCI_CONFIG 0 1143 #endif 1144 #define bootverbose aic79xx_verbose 1145 extern uint32_t aic79xx_verbose; 1146 1147 #endif /* _AIC79XX_LINUX_H_ */ 1148