18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 48c2ecf20Sopenharmony_ci * of PCI-SCSI IO processors. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This driver is derived from the Linux sym53c8xx driver. 98c2ecf20Sopenharmony_ci * Copyright (C) 1998-2000 Gerard Roudier 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 128c2ecf20Sopenharmony_ci * a port of the FreeBSD ncr driver to Linux-1.2.13. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * The original ncr driver has been written for 386bsd and FreeBSD by 158c2ecf20Sopenharmony_ci * Wolfgang Stanglmeier <wolf@cologne.de> 168c2ecf20Sopenharmony_ci * Stefan Esser <se@mi.Uni-Koeln.de> 178c2ecf20Sopenharmony_ci * Copyright (C) 1994 Wolfgang Stanglmeier 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * Other major contributions: 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * NVRAM detection and reading. 228c2ecf20Sopenharmony_ci * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci *----------------------------------------------------------------------------- 258c2ecf20Sopenharmony_ci */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include <linux/gfp.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#ifndef SYM_HIPD_H 308c2ecf20Sopenharmony_ci#define SYM_HIPD_H 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* 338c2ecf20Sopenharmony_ci * Generic driver options. 348c2ecf20Sopenharmony_ci * 358c2ecf20Sopenharmony_ci * They may be defined in platform specific headers, if they 368c2ecf20Sopenharmony_ci * are useful. 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * SYM_OPT_HANDLE_DEVICE_QUEUEING 398c2ecf20Sopenharmony_ci * When this option is set, the driver will use a queue per 408c2ecf20Sopenharmony_ci * device and handle QUEUE FULL status requeuing internally. 418c2ecf20Sopenharmony_ci * 428c2ecf20Sopenharmony_ci * SYM_OPT_LIMIT_COMMAND_REORDERING 438c2ecf20Sopenharmony_ci * When this option is set, the driver tries to limit tagged 448c2ecf20Sopenharmony_ci * command reordering to some reasonable value. 458c2ecf20Sopenharmony_ci * (set for Linux) 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci#if 0 488c2ecf20Sopenharmony_ci#define SYM_OPT_HANDLE_DEVICE_QUEUEING 498c2ecf20Sopenharmony_ci#define SYM_OPT_LIMIT_COMMAND_REORDERING 508c2ecf20Sopenharmony_ci#endif 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* 538c2ecf20Sopenharmony_ci * Active debugging tags and verbosity. 548c2ecf20Sopenharmony_ci * Both DEBUG_FLAGS and sym_verbose can be redefined 558c2ecf20Sopenharmony_ci * by the platform specific code to something else. 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_ci#define DEBUG_ALLOC (0x0001) 588c2ecf20Sopenharmony_ci#define DEBUG_PHASE (0x0002) 598c2ecf20Sopenharmony_ci#define DEBUG_POLL (0x0004) 608c2ecf20Sopenharmony_ci#define DEBUG_QUEUE (0x0008) 618c2ecf20Sopenharmony_ci#define DEBUG_RESULT (0x0010) 628c2ecf20Sopenharmony_ci#define DEBUG_SCATTER (0x0020) 638c2ecf20Sopenharmony_ci#define DEBUG_SCRIPT (0x0040) 648c2ecf20Sopenharmony_ci#define DEBUG_TINY (0x0080) 658c2ecf20Sopenharmony_ci#define DEBUG_TIMING (0x0100) 668c2ecf20Sopenharmony_ci#define DEBUG_NEGO (0x0200) 678c2ecf20Sopenharmony_ci#define DEBUG_TAGS (0x0400) 688c2ecf20Sopenharmony_ci#define DEBUG_POINTER (0x0800) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#ifndef DEBUG_FLAGS 718c2ecf20Sopenharmony_ci#define DEBUG_FLAGS (0x0000) 728c2ecf20Sopenharmony_ci#endif 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci#ifndef sym_verbose 758c2ecf20Sopenharmony_ci#define sym_verbose (np->verbose) 768c2ecf20Sopenharmony_ci#endif 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/* 798c2ecf20Sopenharmony_ci * These ones should have been already defined. 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ci#ifndef assert 828c2ecf20Sopenharmony_ci#define assert(expression) { \ 838c2ecf20Sopenharmony_ci if (!(expression)) { \ 848c2ecf20Sopenharmony_ci (void)panic( \ 858c2ecf20Sopenharmony_ci "assertion \"%s\" failed: file \"%s\", line %d\n", \ 868c2ecf20Sopenharmony_ci #expression, \ 878c2ecf20Sopenharmony_ci __FILE__, __LINE__); \ 888c2ecf20Sopenharmony_ci } \ 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci#endif 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci/* 938c2ecf20Sopenharmony_ci * Number of tasks per device we want to handle. 948c2ecf20Sopenharmony_ci */ 958c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_TAG_ORDER > 8 968c2ecf20Sopenharmony_ci#error "more than 256 tags per logical unit not allowed." 978c2ecf20Sopenharmony_ci#endif 988c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_TASK (1<<SYM_CONF_MAX_TAG_ORDER) 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci/* 1018c2ecf20Sopenharmony_ci * Donnot use more tasks that we can handle. 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_ci#ifndef SYM_CONF_MAX_TAG 1048c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_TAG SYM_CONF_MAX_TASK 1058c2ecf20Sopenharmony_ci#endif 1068c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_TAG > SYM_CONF_MAX_TASK 1078c2ecf20Sopenharmony_ci#undef SYM_CONF_MAX_TAG 1088c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_TAG SYM_CONF_MAX_TASK 1098c2ecf20Sopenharmony_ci#endif 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/* 1128c2ecf20Sopenharmony_ci * This one means 'NO TAG for this job' 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_ci#define NO_TAG (256) 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci/* 1178c2ecf20Sopenharmony_ci * Number of SCSI targets. 1188c2ecf20Sopenharmony_ci */ 1198c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_TARGET > 16 1208c2ecf20Sopenharmony_ci#error "more than 16 targets not allowed." 1218c2ecf20Sopenharmony_ci#endif 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci/* 1248c2ecf20Sopenharmony_ci * Number of logical units per target. 1258c2ecf20Sopenharmony_ci */ 1268c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_LUN > 64 1278c2ecf20Sopenharmony_ci#error "more than 64 logical units per target not allowed." 1288c2ecf20Sopenharmony_ci#endif 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/* 1318c2ecf20Sopenharmony_ci * Asynchronous pre-scaler (ns). Shall be 40 for 1328c2ecf20Sopenharmony_ci * the SCSI timings to be compliant. 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci#define SYM_CONF_MIN_ASYNC (40) 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci/* 1388c2ecf20Sopenharmony_ci * MEMORY ALLOCATOR. 1398c2ecf20Sopenharmony_ci */ 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci#define SYM_MEM_WARN 1 /* Warn on failed operations */ 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci#define SYM_MEM_PAGE_ORDER 0 /* 1 PAGE maximum */ 1448c2ecf20Sopenharmony_ci#define SYM_MEM_CLUSTER_SHIFT (PAGE_SHIFT+SYM_MEM_PAGE_ORDER) 1458c2ecf20Sopenharmony_ci#define SYM_MEM_FREE_UNUSED /* Free unused pages immediately */ 1468c2ecf20Sopenharmony_ci/* 1478c2ecf20Sopenharmony_ci * Shortest memory chunk is (1<<SYM_MEM_SHIFT), currently 16. 1488c2ecf20Sopenharmony_ci * Actual allocations happen as SYM_MEM_CLUSTER_SIZE sized. 1498c2ecf20Sopenharmony_ci * (1 PAGE at a time is just fine). 1508c2ecf20Sopenharmony_ci */ 1518c2ecf20Sopenharmony_ci#define SYM_MEM_SHIFT 4 1528c2ecf20Sopenharmony_ci#define SYM_MEM_CLUSTER_SIZE (1UL << SYM_MEM_CLUSTER_SHIFT) 1538c2ecf20Sopenharmony_ci#define SYM_MEM_CLUSTER_MASK (SYM_MEM_CLUSTER_SIZE-1) 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/* 1568c2ecf20Sopenharmony_ci * Number of entries in the START and DONE queues. 1578c2ecf20Sopenharmony_ci * 1588c2ecf20Sopenharmony_ci * We limit to 1 PAGE in order to succeed allocation of 1598c2ecf20Sopenharmony_ci * these queues. Each entry is 8 bytes long (2 DWORDS). 1608c2ecf20Sopenharmony_ci */ 1618c2ecf20Sopenharmony_ci#ifdef SYM_CONF_MAX_START 1628c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_QUEUE (SYM_CONF_MAX_START+2) 1638c2ecf20Sopenharmony_ci#else 1648c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_QUEUE (7*SYM_CONF_MAX_TASK+2) 1658c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_START (SYM_CONF_MAX_QUEUE-2) 1668c2ecf20Sopenharmony_ci#endif 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_QUEUE > SYM_MEM_CLUSTER_SIZE/8 1698c2ecf20Sopenharmony_ci#undef SYM_CONF_MAX_QUEUE 1708c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_QUEUE (SYM_MEM_CLUSTER_SIZE/8) 1718c2ecf20Sopenharmony_ci#undef SYM_CONF_MAX_START 1728c2ecf20Sopenharmony_ci#define SYM_CONF_MAX_START (SYM_CONF_MAX_QUEUE-2) 1738c2ecf20Sopenharmony_ci#endif 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci/* 1768c2ecf20Sopenharmony_ci * For this one, we want a short name :-) 1778c2ecf20Sopenharmony_ci */ 1788c2ecf20Sopenharmony_ci#define MAX_QUEUE SYM_CONF_MAX_QUEUE 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci/* 1818c2ecf20Sopenharmony_ci * Common definitions for both bus space based and legacy IO methods. 1828c2ecf20Sopenharmony_ci */ 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci#define INB_OFF(np, o) ioread8(np->s.ioaddr + (o)) 1858c2ecf20Sopenharmony_ci#define INW_OFF(np, o) ioread16(np->s.ioaddr + (o)) 1868c2ecf20Sopenharmony_ci#define INL_OFF(np, o) ioread32(np->s.ioaddr + (o)) 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci#define OUTB_OFF(np, o, val) iowrite8((val), np->s.ioaddr + (o)) 1898c2ecf20Sopenharmony_ci#define OUTW_OFF(np, o, val) iowrite16((val), np->s.ioaddr + (o)) 1908c2ecf20Sopenharmony_ci#define OUTL_OFF(np, o, val) iowrite32((val), np->s.ioaddr + (o)) 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci#define INB(np, r) INB_OFF(np, offsetof(struct sym_reg, r)) 1938c2ecf20Sopenharmony_ci#define INW(np, r) INW_OFF(np, offsetof(struct sym_reg, r)) 1948c2ecf20Sopenharmony_ci#define INL(np, r) INL_OFF(np, offsetof(struct sym_reg, r)) 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci#define OUTB(np, r, v) OUTB_OFF(np, offsetof(struct sym_reg, r), (v)) 1978c2ecf20Sopenharmony_ci#define OUTW(np, r, v) OUTW_OFF(np, offsetof(struct sym_reg, r), (v)) 1988c2ecf20Sopenharmony_ci#define OUTL(np, r, v) OUTL_OFF(np, offsetof(struct sym_reg, r), (v)) 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci#define OUTONB(np, r, m) OUTB(np, r, INB(np, r) | (m)) 2018c2ecf20Sopenharmony_ci#define OUTOFFB(np, r, m) OUTB(np, r, INB(np, r) & ~(m)) 2028c2ecf20Sopenharmony_ci#define OUTONW(np, r, m) OUTW(np, r, INW(np, r) | (m)) 2038c2ecf20Sopenharmony_ci#define OUTOFFW(np, r, m) OUTW(np, r, INW(np, r) & ~(m)) 2048c2ecf20Sopenharmony_ci#define OUTONL(np, r, m) OUTL(np, r, INL(np, r) | (m)) 2058c2ecf20Sopenharmony_ci#define OUTOFFL(np, r, m) OUTL(np, r, INL(np, r) & ~(m)) 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci/* 2088c2ecf20Sopenharmony_ci * We normally want the chip to have a consistent view 2098c2ecf20Sopenharmony_ci * of driver internal data structures when we restart it. 2108c2ecf20Sopenharmony_ci * Thus these macros. 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_ci#define OUTL_DSP(np, v) \ 2138c2ecf20Sopenharmony_ci do { \ 2148c2ecf20Sopenharmony_ci MEMORY_WRITE_BARRIER(); \ 2158c2ecf20Sopenharmony_ci OUTL(np, nc_dsp, (v)); \ 2168c2ecf20Sopenharmony_ci } while (0) 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci#define OUTONB_STD() \ 2198c2ecf20Sopenharmony_ci do { \ 2208c2ecf20Sopenharmony_ci MEMORY_WRITE_BARRIER(); \ 2218c2ecf20Sopenharmony_ci OUTONB(np, nc_dcntl, (STD|NOCOM)); \ 2228c2ecf20Sopenharmony_ci } while (0) 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/* 2258c2ecf20Sopenharmony_ci * Command control block states. 2268c2ecf20Sopenharmony_ci */ 2278c2ecf20Sopenharmony_ci#define HS_IDLE (0) 2288c2ecf20Sopenharmony_ci#define HS_BUSY (1) 2298c2ecf20Sopenharmony_ci#define HS_NEGOTIATE (2) /* sync/wide data transfer*/ 2308c2ecf20Sopenharmony_ci#define HS_DISCONNECT (3) /* Disconnected by target */ 2318c2ecf20Sopenharmony_ci#define HS_WAIT (4) /* waiting for resource */ 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci#define HS_DONEMASK (0x80) 2348c2ecf20Sopenharmony_ci#define HS_COMPLETE (4|HS_DONEMASK) 2358c2ecf20Sopenharmony_ci#define HS_SEL_TIMEOUT (5|HS_DONEMASK) /* Selection timeout */ 2368c2ecf20Sopenharmony_ci#define HS_UNEXPECTED (6|HS_DONEMASK) /* Unexpected disconnect */ 2378c2ecf20Sopenharmony_ci#define HS_COMP_ERR (7|HS_DONEMASK) /* Completed with error */ 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci/* 2408c2ecf20Sopenharmony_ci * Software Interrupt Codes 2418c2ecf20Sopenharmony_ci */ 2428c2ecf20Sopenharmony_ci#define SIR_BAD_SCSI_STATUS (1) 2438c2ecf20Sopenharmony_ci#define SIR_SEL_ATN_NO_MSG_OUT (2) 2448c2ecf20Sopenharmony_ci#define SIR_MSG_RECEIVED (3) 2458c2ecf20Sopenharmony_ci#define SIR_MSG_WEIRD (4) 2468c2ecf20Sopenharmony_ci#define SIR_NEGO_FAILED (5) 2478c2ecf20Sopenharmony_ci#define SIR_NEGO_PROTO (6) 2488c2ecf20Sopenharmony_ci#define SIR_SCRIPT_STOPPED (7) 2498c2ecf20Sopenharmony_ci#define SIR_REJECT_TO_SEND (8) 2508c2ecf20Sopenharmony_ci#define SIR_SWIDE_OVERRUN (9) 2518c2ecf20Sopenharmony_ci#define SIR_SODL_UNDERRUN (10) 2528c2ecf20Sopenharmony_ci#define SIR_RESEL_NO_MSG_IN (11) 2538c2ecf20Sopenharmony_ci#define SIR_RESEL_NO_IDENTIFY (12) 2548c2ecf20Sopenharmony_ci#define SIR_RESEL_BAD_LUN (13) 2558c2ecf20Sopenharmony_ci#define SIR_TARGET_SELECTED (14) 2568c2ecf20Sopenharmony_ci#define SIR_RESEL_BAD_I_T_L (15) 2578c2ecf20Sopenharmony_ci#define SIR_RESEL_BAD_I_T_L_Q (16) 2588c2ecf20Sopenharmony_ci#define SIR_ABORT_SENT (17) 2598c2ecf20Sopenharmony_ci#define SIR_RESEL_ABORTED (18) 2608c2ecf20Sopenharmony_ci#define SIR_MSG_OUT_DONE (19) 2618c2ecf20Sopenharmony_ci#define SIR_COMPLETE_ERROR (20) 2628c2ecf20Sopenharmony_ci#define SIR_DATA_OVERRUN (21) 2638c2ecf20Sopenharmony_ci#define SIR_BAD_PHASE (22) 2648c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 2 2658c2ecf20Sopenharmony_ci#define SIR_DMAP_DIRTY (23) 2668c2ecf20Sopenharmony_ci#define SIR_MAX (23) 2678c2ecf20Sopenharmony_ci#else 2688c2ecf20Sopenharmony_ci#define SIR_MAX (22) 2698c2ecf20Sopenharmony_ci#endif 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/* 2728c2ecf20Sopenharmony_ci * Extended error bit codes. 2738c2ecf20Sopenharmony_ci * xerr_status field of struct sym_ccb. 2748c2ecf20Sopenharmony_ci */ 2758c2ecf20Sopenharmony_ci#define XE_EXTRA_DATA (1) /* unexpected data phase */ 2768c2ecf20Sopenharmony_ci#define XE_BAD_PHASE (1<<1) /* illegal phase (4/5) */ 2778c2ecf20Sopenharmony_ci#define XE_PARITY_ERR (1<<2) /* unrecovered SCSI parity error */ 2788c2ecf20Sopenharmony_ci#define XE_SODL_UNRUN (1<<3) /* ODD transfer in DATA OUT phase */ 2798c2ecf20Sopenharmony_ci#define XE_SWIDE_OVRUN (1<<4) /* ODD transfer in DATA IN phase */ 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci/* 2828c2ecf20Sopenharmony_ci * Negotiation status. 2838c2ecf20Sopenharmony_ci * nego_status field of struct sym_ccb. 2848c2ecf20Sopenharmony_ci */ 2858c2ecf20Sopenharmony_ci#define NS_SYNC (1) 2868c2ecf20Sopenharmony_ci#define NS_WIDE (2) 2878c2ecf20Sopenharmony_ci#define NS_PPR (3) 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci/* 2908c2ecf20Sopenharmony_ci * A CCB hashed table is used to retrieve CCB address 2918c2ecf20Sopenharmony_ci * from DSA value. 2928c2ecf20Sopenharmony_ci */ 2938c2ecf20Sopenharmony_ci#define CCB_HASH_SHIFT 8 2948c2ecf20Sopenharmony_ci#define CCB_HASH_SIZE (1UL << CCB_HASH_SHIFT) 2958c2ecf20Sopenharmony_ci#define CCB_HASH_MASK (CCB_HASH_SIZE-1) 2968c2ecf20Sopenharmony_ci#if 1 2978c2ecf20Sopenharmony_ci#define CCB_HASH_CODE(dsa) \ 2988c2ecf20Sopenharmony_ci (((dsa) >> (_LGRU16_(sizeof(struct sym_ccb)))) & CCB_HASH_MASK) 2998c2ecf20Sopenharmony_ci#else 3008c2ecf20Sopenharmony_ci#define CCB_HASH_CODE(dsa) (((dsa) >> 9) & CCB_HASH_MASK) 3018c2ecf20Sopenharmony_ci#endif 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 2 3048c2ecf20Sopenharmony_ci/* 3058c2ecf20Sopenharmony_ci * We may want to use segment registers for 64 bit DMA. 3068c2ecf20Sopenharmony_ci * 16 segments registers -> up to 64 GB addressable. 3078c2ecf20Sopenharmony_ci */ 3088c2ecf20Sopenharmony_ci#define SYM_DMAP_SHIFT (4) 3098c2ecf20Sopenharmony_ci#define SYM_DMAP_SIZE (1u<<SYM_DMAP_SHIFT) 3108c2ecf20Sopenharmony_ci#define SYM_DMAP_MASK (SYM_DMAP_SIZE-1) 3118c2ecf20Sopenharmony_ci#endif 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci/* 3148c2ecf20Sopenharmony_ci * Device flags. 3158c2ecf20Sopenharmony_ci */ 3168c2ecf20Sopenharmony_ci#define SYM_DISC_ENABLED (1) 3178c2ecf20Sopenharmony_ci#define SYM_TAGS_ENABLED (1<<1) 3188c2ecf20Sopenharmony_ci#define SYM_SCAN_BOOT_DISABLED (1<<2) 3198c2ecf20Sopenharmony_ci#define SYM_SCAN_LUNS_DISABLED (1<<3) 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* 3228c2ecf20Sopenharmony_ci * Host adapter miscellaneous flags. 3238c2ecf20Sopenharmony_ci */ 3248c2ecf20Sopenharmony_ci#define SYM_AVOID_BUS_RESET (1) 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci/* 3278c2ecf20Sopenharmony_ci * Misc. 3288c2ecf20Sopenharmony_ci */ 3298c2ecf20Sopenharmony_ci#define SYM_SNOOP_TIMEOUT (10000000) 3308c2ecf20Sopenharmony_ci#define BUS_8_BIT 0 3318c2ecf20Sopenharmony_ci#define BUS_16_BIT 1 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci/* 3348c2ecf20Sopenharmony_ci * Gather negotiable parameters value 3358c2ecf20Sopenharmony_ci */ 3368c2ecf20Sopenharmony_cistruct sym_trans { 3378c2ecf20Sopenharmony_ci u8 period; 3388c2ecf20Sopenharmony_ci u8 offset; 3398c2ecf20Sopenharmony_ci unsigned int width:1; 3408c2ecf20Sopenharmony_ci unsigned int iu:1; 3418c2ecf20Sopenharmony_ci unsigned int dt:1; 3428c2ecf20Sopenharmony_ci unsigned int qas:1; 3438c2ecf20Sopenharmony_ci unsigned int check_nego:1; 3448c2ecf20Sopenharmony_ci unsigned int renego:2; 3458c2ecf20Sopenharmony_ci}; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci/* 3488c2ecf20Sopenharmony_ci * Global TCB HEADER. 3498c2ecf20Sopenharmony_ci * 3508c2ecf20Sopenharmony_ci * Due to lack of indirect addressing on earlier NCR chips, 3518c2ecf20Sopenharmony_ci * this substructure is copied from the TCB to a global 3528c2ecf20Sopenharmony_ci * address after selection. 3538c2ecf20Sopenharmony_ci * For SYMBIOS chips that support LOAD/STORE this copy is 3548c2ecf20Sopenharmony_ci * not needed and thus not performed. 3558c2ecf20Sopenharmony_ci */ 3568c2ecf20Sopenharmony_cistruct sym_tcbh { 3578c2ecf20Sopenharmony_ci /* 3588c2ecf20Sopenharmony_ci * Scripts bus addresses of LUN table accessed from scripts. 3598c2ecf20Sopenharmony_ci * LUN #0 is a special case, since multi-lun devices are rare, 3608c2ecf20Sopenharmony_ci * and we we want to speed-up the general case and not waste 3618c2ecf20Sopenharmony_ci * resources. 3628c2ecf20Sopenharmony_ci */ 3638c2ecf20Sopenharmony_ci u32 luntbl_sa; /* bus address of this table */ 3648c2ecf20Sopenharmony_ci u32 lun0_sa; /* bus address of LCB #0 */ 3658c2ecf20Sopenharmony_ci /* 3668c2ecf20Sopenharmony_ci * Actual SYNC/WIDE IO registers value for this target. 3678c2ecf20Sopenharmony_ci * 'sval', 'wval' and 'uval' are read from SCRIPTS and 3688c2ecf20Sopenharmony_ci * so have alignment constraints. 3698c2ecf20Sopenharmony_ci */ 3708c2ecf20Sopenharmony_ci/*0*/ u_char uval; /* -> SCNTL4 register */ 3718c2ecf20Sopenharmony_ci/*1*/ u_char sval; /* -> SXFER io register */ 3728c2ecf20Sopenharmony_ci/*2*/ u_char filler1; 3738c2ecf20Sopenharmony_ci/*3*/ u_char wval; /* -> SCNTL3 io register */ 3748c2ecf20Sopenharmony_ci}; 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci/* 3778c2ecf20Sopenharmony_ci * Target Control Block 3788c2ecf20Sopenharmony_ci */ 3798c2ecf20Sopenharmony_cistruct sym_tcb { 3808c2ecf20Sopenharmony_ci /* 3818c2ecf20Sopenharmony_ci * TCB header. 3828c2ecf20Sopenharmony_ci * Assumed at offset 0. 3838c2ecf20Sopenharmony_ci */ 3848c2ecf20Sopenharmony_ci/*0*/ struct sym_tcbh head; 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci /* 3878c2ecf20Sopenharmony_ci * LUN table used by the SCRIPTS processor. 3888c2ecf20Sopenharmony_ci * An array of bus addresses is used on reselection. 3898c2ecf20Sopenharmony_ci */ 3908c2ecf20Sopenharmony_ci u32 *luntbl; /* LCBs bus address table */ 3918c2ecf20Sopenharmony_ci int nlcb; /* Number of valid LCBs (including LUN #0) */ 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* 3948c2ecf20Sopenharmony_ci * LUN table used by the C code. 3958c2ecf20Sopenharmony_ci */ 3968c2ecf20Sopenharmony_ci struct sym_lcb *lun0p; /* LCB of LUN #0 (usual case) */ 3978c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_LUN > 1 3988c2ecf20Sopenharmony_ci struct sym_lcb **lunmp; /* Other LCBs [1..MAX_LUN] */ 3998c2ecf20Sopenharmony_ci#endif 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci#ifdef SYM_HAVE_STCB 4028c2ecf20Sopenharmony_ci /* 4038c2ecf20Sopenharmony_ci * O/S specific data structure. 4048c2ecf20Sopenharmony_ci */ 4058c2ecf20Sopenharmony_ci struct sym_stcb s; 4068c2ecf20Sopenharmony_ci#endif 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci /* Transfer goal */ 4098c2ecf20Sopenharmony_ci struct sym_trans tgoal; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci /* Last printed transfer speed */ 4128c2ecf20Sopenharmony_ci struct sym_trans tprint; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci /* 4158c2ecf20Sopenharmony_ci * Keep track of the CCB used for the negotiation in order 4168c2ecf20Sopenharmony_ci * to ensure that only 1 negotiation is queued at a time. 4178c2ecf20Sopenharmony_ci */ 4188c2ecf20Sopenharmony_ci struct sym_ccb * nego_cp; /* CCB used for the nego */ 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci /* 4218c2ecf20Sopenharmony_ci * Set when we want to reset the device. 4228c2ecf20Sopenharmony_ci */ 4238c2ecf20Sopenharmony_ci u_char to_reset; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci /* 4268c2ecf20Sopenharmony_ci * Other user settable limits and options. 4278c2ecf20Sopenharmony_ci * These limits are read from the NVRAM if present. 4288c2ecf20Sopenharmony_ci */ 4298c2ecf20Sopenharmony_ci unsigned char usrflags; 4308c2ecf20Sopenharmony_ci unsigned char usr_period; 4318c2ecf20Sopenharmony_ci unsigned char usr_width; 4328c2ecf20Sopenharmony_ci unsigned short usrtags; 4338c2ecf20Sopenharmony_ci struct scsi_target *starget; 4348c2ecf20Sopenharmony_ci}; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci/* 4378c2ecf20Sopenharmony_ci * Global LCB HEADER. 4388c2ecf20Sopenharmony_ci * 4398c2ecf20Sopenharmony_ci * Due to lack of indirect addressing on earlier NCR chips, 4408c2ecf20Sopenharmony_ci * this substructure is copied from the LCB to a global 4418c2ecf20Sopenharmony_ci * address after selection. 4428c2ecf20Sopenharmony_ci * For SYMBIOS chips that support LOAD/STORE this copy is 4438c2ecf20Sopenharmony_ci * not needed and thus not performed. 4448c2ecf20Sopenharmony_ci */ 4458c2ecf20Sopenharmony_cistruct sym_lcbh { 4468c2ecf20Sopenharmony_ci /* 4478c2ecf20Sopenharmony_ci * SCRIPTS address jumped by SCRIPTS on reselection. 4488c2ecf20Sopenharmony_ci * For not probed logical units, this address points to 4498c2ecf20Sopenharmony_ci * SCRIPTS that deal with bad LU handling (must be at 4508c2ecf20Sopenharmony_ci * offset zero of the LCB for that reason). 4518c2ecf20Sopenharmony_ci */ 4528c2ecf20Sopenharmony_ci/*0*/ u32 resel_sa; 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci /* 4558c2ecf20Sopenharmony_ci * Task (bus address of a CCB) read from SCRIPTS that points 4568c2ecf20Sopenharmony_ci * to the unique ITL nexus allowed to be disconnected. 4578c2ecf20Sopenharmony_ci */ 4588c2ecf20Sopenharmony_ci u32 itl_task_sa; 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci /* 4618c2ecf20Sopenharmony_ci * Task table bus address (read from SCRIPTS). 4628c2ecf20Sopenharmony_ci */ 4638c2ecf20Sopenharmony_ci u32 itlq_tbl_sa; 4648c2ecf20Sopenharmony_ci}; 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci/* 4678c2ecf20Sopenharmony_ci * Logical Unit Control Block 4688c2ecf20Sopenharmony_ci */ 4698c2ecf20Sopenharmony_cistruct sym_lcb { 4708c2ecf20Sopenharmony_ci /* 4718c2ecf20Sopenharmony_ci * TCB header. 4728c2ecf20Sopenharmony_ci * Assumed at offset 0. 4738c2ecf20Sopenharmony_ci */ 4748c2ecf20Sopenharmony_ci/*0*/ struct sym_lcbh head; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci /* 4778c2ecf20Sopenharmony_ci * Task table read from SCRIPTS that contains pointers to 4788c2ecf20Sopenharmony_ci * ITLQ nexuses. The bus address read from SCRIPTS is 4798c2ecf20Sopenharmony_ci * inside the header. 4808c2ecf20Sopenharmony_ci */ 4818c2ecf20Sopenharmony_ci u32 *itlq_tbl; /* Kernel virtual address */ 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci /* 4848c2ecf20Sopenharmony_ci * Busy CCBs management. 4858c2ecf20Sopenharmony_ci */ 4868c2ecf20Sopenharmony_ci u_short busy_itlq; /* Number of busy tagged CCBs */ 4878c2ecf20Sopenharmony_ci u_short busy_itl; /* Number of busy untagged CCBs */ 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci /* 4908c2ecf20Sopenharmony_ci * Circular tag allocation buffer. 4918c2ecf20Sopenharmony_ci */ 4928c2ecf20Sopenharmony_ci u_short ia_tag; /* Tag allocation index */ 4938c2ecf20Sopenharmony_ci u_short if_tag; /* Tag release index */ 4948c2ecf20Sopenharmony_ci u_char *cb_tags; /* Circular tags buffer */ 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci /* 4978c2ecf20Sopenharmony_ci * O/S specific data structure. 4988c2ecf20Sopenharmony_ci */ 4998c2ecf20Sopenharmony_ci#ifdef SYM_HAVE_SLCB 5008c2ecf20Sopenharmony_ci struct sym_slcb s; 5018c2ecf20Sopenharmony_ci#endif 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING 5048c2ecf20Sopenharmony_ci /* 5058c2ecf20Sopenharmony_ci * Optionnaly the driver can handle device queueing, 5068c2ecf20Sopenharmony_ci * and requeues internally command to redo. 5078c2ecf20Sopenharmony_ci */ 5088c2ecf20Sopenharmony_ci SYM_QUEHEAD waiting_ccbq; 5098c2ecf20Sopenharmony_ci SYM_QUEHEAD started_ccbq; 5108c2ecf20Sopenharmony_ci int num_sgood; 5118c2ecf20Sopenharmony_ci u_short started_tags; 5128c2ecf20Sopenharmony_ci u_short started_no_tag; 5138c2ecf20Sopenharmony_ci u_short started_max; 5148c2ecf20Sopenharmony_ci u_short started_limit; 5158c2ecf20Sopenharmony_ci#endif 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING 5188c2ecf20Sopenharmony_ci /* 5198c2ecf20Sopenharmony_ci * Optionally the driver can try to prevent SCSI 5208c2ecf20Sopenharmony_ci * IOs from being reordered too much. 5218c2ecf20Sopenharmony_ci */ 5228c2ecf20Sopenharmony_ci u_char tags_si; /* Current index to tags sum */ 5238c2ecf20Sopenharmony_ci u_short tags_sum[2]; /* Tags sum counters */ 5248c2ecf20Sopenharmony_ci u_short tags_since; /* # of tags since last switch */ 5258c2ecf20Sopenharmony_ci#endif 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci /* 5288c2ecf20Sopenharmony_ci * Set when we want to clear all tasks. 5298c2ecf20Sopenharmony_ci */ 5308c2ecf20Sopenharmony_ci u_char to_clear; 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci /* 5338c2ecf20Sopenharmony_ci * Capabilities. 5348c2ecf20Sopenharmony_ci */ 5358c2ecf20Sopenharmony_ci u_char user_flags; 5368c2ecf20Sopenharmony_ci u_char curr_flags; 5378c2ecf20Sopenharmony_ci}; 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci/* 5408c2ecf20Sopenharmony_ci * Action from SCRIPTS on a task. 5418c2ecf20Sopenharmony_ci * Is part of the CCB, but is also used separately to plug 5428c2ecf20Sopenharmony_ci * error handling action to perform from SCRIPTS. 5438c2ecf20Sopenharmony_ci */ 5448c2ecf20Sopenharmony_cistruct sym_actscr { 5458c2ecf20Sopenharmony_ci u32 start; /* Jumped by SCRIPTS after selection */ 5468c2ecf20Sopenharmony_ci u32 restart; /* Jumped by SCRIPTS on relection */ 5478c2ecf20Sopenharmony_ci}; 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci/* 5508c2ecf20Sopenharmony_ci * Phase mismatch context. 5518c2ecf20Sopenharmony_ci * 5528c2ecf20Sopenharmony_ci * It is part of the CCB and is used as parameters for the 5538c2ecf20Sopenharmony_ci * DATA pointer. We need two contexts to handle correctly the 5548c2ecf20Sopenharmony_ci * SAVED DATA POINTER. 5558c2ecf20Sopenharmony_ci */ 5568c2ecf20Sopenharmony_cistruct sym_pmc { 5578c2ecf20Sopenharmony_ci struct sym_tblmove sg; /* Updated interrupted SG block */ 5588c2ecf20Sopenharmony_ci u32 ret; /* SCRIPT return address */ 5598c2ecf20Sopenharmony_ci}; 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci/* 5628c2ecf20Sopenharmony_ci * LUN control block lookup. 5638c2ecf20Sopenharmony_ci * We use a direct pointer for LUN #0, and a table of 5648c2ecf20Sopenharmony_ci * pointers which is only allocated for devices that support 5658c2ecf20Sopenharmony_ci * LUN(s) > 0. 5668c2ecf20Sopenharmony_ci */ 5678c2ecf20Sopenharmony_ci#if SYM_CONF_MAX_LUN <= 1 5688c2ecf20Sopenharmony_ci#define sym_lp(tp, lun) (!lun) ? (tp)->lun0p : NULL 5698c2ecf20Sopenharmony_ci#else 5708c2ecf20Sopenharmony_ci#define sym_lp(tp, lun) \ 5718c2ecf20Sopenharmony_ci (!lun) ? (tp)->lun0p : (tp)->lunmp ? (tp)->lunmp[((u8)lun)] : NULL 5728c2ecf20Sopenharmony_ci#endif 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci/* 5758c2ecf20Sopenharmony_ci * Status are used by the host and the script processor. 5768c2ecf20Sopenharmony_ci * 5778c2ecf20Sopenharmony_ci * The last four bytes (status[4]) are copied to the 5788c2ecf20Sopenharmony_ci * scratchb register (declared as scr0..scr3) just after the 5798c2ecf20Sopenharmony_ci * select/reselect, and copied back just after disconnecting. 5808c2ecf20Sopenharmony_ci * Inside the script the XX_REG are used. 5818c2ecf20Sopenharmony_ci */ 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci/* 5848c2ecf20Sopenharmony_ci * Last four bytes (script) 5858c2ecf20Sopenharmony_ci */ 5868c2ecf20Sopenharmony_ci#define HX_REG scr0 5878c2ecf20Sopenharmony_ci#define HX_PRT nc_scr0 5888c2ecf20Sopenharmony_ci#define HS_REG scr1 5898c2ecf20Sopenharmony_ci#define HS_PRT nc_scr1 5908c2ecf20Sopenharmony_ci#define SS_REG scr2 5918c2ecf20Sopenharmony_ci#define SS_PRT nc_scr2 5928c2ecf20Sopenharmony_ci#define HF_REG scr3 5938c2ecf20Sopenharmony_ci#define HF_PRT nc_scr3 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci/* 5968c2ecf20Sopenharmony_ci * Last four bytes (host) 5978c2ecf20Sopenharmony_ci */ 5988c2ecf20Sopenharmony_ci#define host_xflags phys.head.status[0] 5998c2ecf20Sopenharmony_ci#define host_status phys.head.status[1] 6008c2ecf20Sopenharmony_ci#define ssss_status phys.head.status[2] 6018c2ecf20Sopenharmony_ci#define host_flags phys.head.status[3] 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci/* 6048c2ecf20Sopenharmony_ci * Host flags 6058c2ecf20Sopenharmony_ci */ 6068c2ecf20Sopenharmony_ci#define HF_IN_PM0 1u 6078c2ecf20Sopenharmony_ci#define HF_IN_PM1 (1u<<1) 6088c2ecf20Sopenharmony_ci#define HF_ACT_PM (1u<<2) 6098c2ecf20Sopenharmony_ci#define HF_DP_SAVED (1u<<3) 6108c2ecf20Sopenharmony_ci#define HF_SENSE (1u<<4) 6118c2ecf20Sopenharmony_ci#define HF_EXT_ERR (1u<<5) 6128c2ecf20Sopenharmony_ci#define HF_DATA_IN (1u<<6) 6138c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 6148c2ecf20Sopenharmony_ci#define HF_HINT_IARB (1u<<7) 6158c2ecf20Sopenharmony_ci#endif 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci/* 6188c2ecf20Sopenharmony_ci * More host flags 6198c2ecf20Sopenharmony_ci */ 6208c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 2 6218c2ecf20Sopenharmony_ci#define HX_DMAP_DIRTY (1u<<7) 6228c2ecf20Sopenharmony_ci#endif 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci/* 6258c2ecf20Sopenharmony_ci * Global CCB HEADER. 6268c2ecf20Sopenharmony_ci * 6278c2ecf20Sopenharmony_ci * Due to lack of indirect addressing on earlier NCR chips, 6288c2ecf20Sopenharmony_ci * this substructure is copied from the ccb to a global 6298c2ecf20Sopenharmony_ci * address after selection (or reselection) and copied back 6308c2ecf20Sopenharmony_ci * before disconnect. 6318c2ecf20Sopenharmony_ci * For SYMBIOS chips that support LOAD/STORE this copy is 6328c2ecf20Sopenharmony_ci * not needed and thus not performed. 6338c2ecf20Sopenharmony_ci */ 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_cistruct sym_ccbh { 6368c2ecf20Sopenharmony_ci /* 6378c2ecf20Sopenharmony_ci * Start and restart SCRIPTS addresses (must be at 0). 6388c2ecf20Sopenharmony_ci */ 6398c2ecf20Sopenharmony_ci/*0*/ struct sym_actscr go; 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci /* 6428c2ecf20Sopenharmony_ci * SCRIPTS jump address that deal with data pointers. 6438c2ecf20Sopenharmony_ci * 'savep' points to the position in the script responsible 6448c2ecf20Sopenharmony_ci * for the actual transfer of data. 6458c2ecf20Sopenharmony_ci * It's written on reception of a SAVE_DATA_POINTER message. 6468c2ecf20Sopenharmony_ci */ 6478c2ecf20Sopenharmony_ci u32 savep; /* Jump address to saved data pointer */ 6488c2ecf20Sopenharmony_ci u32 lastp; /* SCRIPTS address at end of data */ 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci /* 6518c2ecf20Sopenharmony_ci * Status fields. 6528c2ecf20Sopenharmony_ci */ 6538c2ecf20Sopenharmony_ci u8 status[4]; 6548c2ecf20Sopenharmony_ci}; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci/* 6578c2ecf20Sopenharmony_ci * GET/SET the value of the data pointer used by SCRIPTS. 6588c2ecf20Sopenharmony_ci * 6598c2ecf20Sopenharmony_ci * We must distinguish between the LOAD/STORE-based SCRIPTS 6608c2ecf20Sopenharmony_ci * that use directly the header in the CCB, and the NCR-GENERIC 6618c2ecf20Sopenharmony_ci * SCRIPTS that use the copy of the header in the HCB. 6628c2ecf20Sopenharmony_ci */ 6638c2ecf20Sopenharmony_ci#if SYM_CONF_GENERIC_SUPPORT 6648c2ecf20Sopenharmony_ci#define sym_set_script_dp(np, cp, dp) \ 6658c2ecf20Sopenharmony_ci do { \ 6668c2ecf20Sopenharmony_ci if (np->features & FE_LDSTR) \ 6678c2ecf20Sopenharmony_ci cp->phys.head.lastp = cpu_to_scr(dp); \ 6688c2ecf20Sopenharmony_ci else \ 6698c2ecf20Sopenharmony_ci np->ccb_head.lastp = cpu_to_scr(dp); \ 6708c2ecf20Sopenharmony_ci } while (0) 6718c2ecf20Sopenharmony_ci#define sym_get_script_dp(np, cp) \ 6728c2ecf20Sopenharmony_ci scr_to_cpu((np->features & FE_LDSTR) ? \ 6738c2ecf20Sopenharmony_ci cp->phys.head.lastp : np->ccb_head.lastp) 6748c2ecf20Sopenharmony_ci#else 6758c2ecf20Sopenharmony_ci#define sym_set_script_dp(np, cp, dp) \ 6768c2ecf20Sopenharmony_ci do { \ 6778c2ecf20Sopenharmony_ci cp->phys.head.lastp = cpu_to_scr(dp); \ 6788c2ecf20Sopenharmony_ci } while (0) 6798c2ecf20Sopenharmony_ci 6808c2ecf20Sopenharmony_ci#define sym_get_script_dp(np, cp) (cp->phys.head.lastp) 6818c2ecf20Sopenharmony_ci#endif 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci/* 6848c2ecf20Sopenharmony_ci * Data Structure Block 6858c2ecf20Sopenharmony_ci * 6868c2ecf20Sopenharmony_ci * During execution of a ccb by the script processor, the 6878c2ecf20Sopenharmony_ci * DSA (data structure address) register points to this 6888c2ecf20Sopenharmony_ci * substructure of the ccb. 6898c2ecf20Sopenharmony_ci */ 6908c2ecf20Sopenharmony_cistruct sym_dsb { 6918c2ecf20Sopenharmony_ci /* 6928c2ecf20Sopenharmony_ci * CCB header. 6938c2ecf20Sopenharmony_ci * Also assumed at offset 0 of the sym_ccb structure. 6948c2ecf20Sopenharmony_ci */ 6958c2ecf20Sopenharmony_ci/*0*/ struct sym_ccbh head; 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci /* 6988c2ecf20Sopenharmony_ci * Phase mismatch contexts. 6998c2ecf20Sopenharmony_ci * We need two to handle correctly the SAVED DATA POINTER. 7008c2ecf20Sopenharmony_ci * MUST BOTH BE AT OFFSET < 256, due to using 8 bit arithmetic 7018c2ecf20Sopenharmony_ci * for address calculation from SCRIPTS. 7028c2ecf20Sopenharmony_ci */ 7038c2ecf20Sopenharmony_ci struct sym_pmc pm0; 7048c2ecf20Sopenharmony_ci struct sym_pmc pm1; 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci /* 7078c2ecf20Sopenharmony_ci * Table data for Script 7088c2ecf20Sopenharmony_ci */ 7098c2ecf20Sopenharmony_ci struct sym_tblsel select; 7108c2ecf20Sopenharmony_ci struct sym_tblmove smsg; 7118c2ecf20Sopenharmony_ci struct sym_tblmove smsg_ext; 7128c2ecf20Sopenharmony_ci struct sym_tblmove cmd; 7138c2ecf20Sopenharmony_ci struct sym_tblmove sense; 7148c2ecf20Sopenharmony_ci struct sym_tblmove wresid; 7158c2ecf20Sopenharmony_ci struct sym_tblmove data [SYM_CONF_MAX_SG]; 7168c2ecf20Sopenharmony_ci}; 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_ci/* 7198c2ecf20Sopenharmony_ci * Our Command Control Block 7208c2ecf20Sopenharmony_ci */ 7218c2ecf20Sopenharmony_cistruct sym_ccb { 7228c2ecf20Sopenharmony_ci /* 7238c2ecf20Sopenharmony_ci * This is the data structure which is pointed by the DSA 7248c2ecf20Sopenharmony_ci * register when it is executed by the script processor. 7258c2ecf20Sopenharmony_ci * It must be the first entry. 7268c2ecf20Sopenharmony_ci */ 7278c2ecf20Sopenharmony_ci struct sym_dsb phys; 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci /* 7308c2ecf20Sopenharmony_ci * Pointer to CAM ccb and related stuff. 7318c2ecf20Sopenharmony_ci */ 7328c2ecf20Sopenharmony_ci struct scsi_cmnd *cmd; /* CAM scsiio ccb */ 7338c2ecf20Sopenharmony_ci u8 cdb_buf[16]; /* Copy of CDB */ 7348c2ecf20Sopenharmony_ci#define SYM_SNS_BBUF_LEN 32 7358c2ecf20Sopenharmony_ci u8 sns_bbuf[SYM_SNS_BBUF_LEN]; /* Bounce buffer for sense data */ 7368c2ecf20Sopenharmony_ci int data_len; /* Total data length */ 7378c2ecf20Sopenharmony_ci int segments; /* Number of SG segments */ 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci u8 order; /* Tag type (if tagged command) */ 7408c2ecf20Sopenharmony_ci unsigned char odd_byte_adjustment; /* odd-sized req on wide bus */ 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci u_char nego_status; /* Negotiation status */ 7438c2ecf20Sopenharmony_ci u_char xerr_status; /* Extended error flags */ 7448c2ecf20Sopenharmony_ci u32 extra_bytes; /* Extraneous bytes transferred */ 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci /* 7478c2ecf20Sopenharmony_ci * Message areas. 7488c2ecf20Sopenharmony_ci * We prepare a message to be sent after selection. 7498c2ecf20Sopenharmony_ci * We may use a second one if the command is rescheduled 7508c2ecf20Sopenharmony_ci * due to CHECK_CONDITION or COMMAND TERMINATED. 7518c2ecf20Sopenharmony_ci * Contents are IDENTIFY and SIMPLE_TAG. 7528c2ecf20Sopenharmony_ci * While negotiating sync or wide transfer, 7538c2ecf20Sopenharmony_ci * a SDTR or WDTR message is appended. 7548c2ecf20Sopenharmony_ci */ 7558c2ecf20Sopenharmony_ci u_char scsi_smsg [12]; 7568c2ecf20Sopenharmony_ci u_char scsi_smsg2[12]; 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_ci /* 7598c2ecf20Sopenharmony_ci * Auto request sense related fields. 7608c2ecf20Sopenharmony_ci */ 7618c2ecf20Sopenharmony_ci u_char sensecmd[6]; /* Request Sense command */ 7628c2ecf20Sopenharmony_ci u_char sv_scsi_status; /* Saved SCSI status */ 7638c2ecf20Sopenharmony_ci u_char sv_xerr_status; /* Saved extended status */ 7648c2ecf20Sopenharmony_ci int sv_resid; /* Saved residual */ 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_ci /* 7678c2ecf20Sopenharmony_ci * Other fields. 7688c2ecf20Sopenharmony_ci */ 7698c2ecf20Sopenharmony_ci u32 ccb_ba; /* BUS address of this CCB */ 7708c2ecf20Sopenharmony_ci u_short tag; /* Tag for this transfer */ 7718c2ecf20Sopenharmony_ci /* NO_TAG means no tag */ 7728c2ecf20Sopenharmony_ci u_char target; 7738c2ecf20Sopenharmony_ci u_char lun; 7748c2ecf20Sopenharmony_ci struct sym_ccb *link_ccbh; /* Host adapter CCB hash chain */ 7758c2ecf20Sopenharmony_ci SYM_QUEHEAD link_ccbq; /* Link to free/busy CCB queue */ 7768c2ecf20Sopenharmony_ci u32 startp; /* Initial data pointer */ 7778c2ecf20Sopenharmony_ci u32 goalp; /* Expected last data pointer */ 7788c2ecf20Sopenharmony_ci int ext_sg; /* Extreme data pointer, used */ 7798c2ecf20Sopenharmony_ci int ext_ofs; /* to calculate the residual. */ 7808c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING 7818c2ecf20Sopenharmony_ci SYM_QUEHEAD link2_ccbq; /* Link for device queueing */ 7828c2ecf20Sopenharmony_ci u_char started; /* CCB queued to the squeue */ 7838c2ecf20Sopenharmony_ci#endif 7848c2ecf20Sopenharmony_ci u_char to_abort; /* Want this IO to be aborted */ 7858c2ecf20Sopenharmony_ci#ifdef SYM_OPT_LIMIT_COMMAND_REORDERING 7868c2ecf20Sopenharmony_ci u_char tags_si; /* Lun tags sum index (0,1) */ 7878c2ecf20Sopenharmony_ci#endif 7888c2ecf20Sopenharmony_ci}; 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci#define CCB_BA(cp,lbl) cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl)) 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_citypedef struct device *m_pool_ident_t; 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci/* 7958c2ecf20Sopenharmony_ci * Host Control Block 7968c2ecf20Sopenharmony_ci */ 7978c2ecf20Sopenharmony_cistruct sym_hcb { 7988c2ecf20Sopenharmony_ci /* 7998c2ecf20Sopenharmony_ci * Global headers. 8008c2ecf20Sopenharmony_ci * Due to poorness of addressing capabilities, earlier 8018c2ecf20Sopenharmony_ci * chips (810, 815, 825) copy part of the data structures 8028c2ecf20Sopenharmony_ci * (CCB, TCB and LCB) in fixed areas. 8038c2ecf20Sopenharmony_ci */ 8048c2ecf20Sopenharmony_ci#if SYM_CONF_GENERIC_SUPPORT 8058c2ecf20Sopenharmony_ci struct sym_ccbh ccb_head; 8068c2ecf20Sopenharmony_ci struct sym_tcbh tcb_head; 8078c2ecf20Sopenharmony_ci struct sym_lcbh lcb_head; 8088c2ecf20Sopenharmony_ci#endif 8098c2ecf20Sopenharmony_ci /* 8108c2ecf20Sopenharmony_ci * Idle task and invalid task actions and 8118c2ecf20Sopenharmony_ci * their bus addresses. 8128c2ecf20Sopenharmony_ci */ 8138c2ecf20Sopenharmony_ci struct sym_actscr idletask, notask, bad_itl, bad_itlq; 8148c2ecf20Sopenharmony_ci u32 idletask_ba, notask_ba, bad_itl_ba, bad_itlq_ba; 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ci /* 8178c2ecf20Sopenharmony_ci * Dummy lun table to protect us against target 8188c2ecf20Sopenharmony_ci * returning bad lun number on reselection. 8198c2ecf20Sopenharmony_ci */ 8208c2ecf20Sopenharmony_ci u32 *badluntbl; /* Table physical address */ 8218c2ecf20Sopenharmony_ci u32 badlun_sa; /* SCRIPT handler BUS address */ 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_ci /* 8248c2ecf20Sopenharmony_ci * Bus address of this host control block. 8258c2ecf20Sopenharmony_ci */ 8268c2ecf20Sopenharmony_ci u32 hcb_ba; 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci /* 8298c2ecf20Sopenharmony_ci * Bit 32-63 of the on-chip RAM bus address in LE format. 8308c2ecf20Sopenharmony_ci * The START_RAM64 script loads the MMRS and MMWS from this 8318c2ecf20Sopenharmony_ci * field. 8328c2ecf20Sopenharmony_ci */ 8338c2ecf20Sopenharmony_ci u32 scr_ram_seg; 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_ci /* 8368c2ecf20Sopenharmony_ci * Initial value of some IO register bits. 8378c2ecf20Sopenharmony_ci * These values are assumed to have been set by BIOS, and may 8388c2ecf20Sopenharmony_ci * be used to probe adapter implementation differences. 8398c2ecf20Sopenharmony_ci */ 8408c2ecf20Sopenharmony_ci u_char sv_scntl0, sv_scntl3, sv_dmode, sv_dcntl, sv_ctest3, sv_ctest4, 8418c2ecf20Sopenharmony_ci sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4, sv_scntl4, 8428c2ecf20Sopenharmony_ci sv_stest1; 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci /* 8458c2ecf20Sopenharmony_ci * Actual initial value of IO register bits used by the 8468c2ecf20Sopenharmony_ci * driver. They are loaded at initialisation according to 8478c2ecf20Sopenharmony_ci * features that are to be enabled/disabled. 8488c2ecf20Sopenharmony_ci */ 8498c2ecf20Sopenharmony_ci u_char rv_scntl0, rv_scntl3, rv_dmode, rv_dcntl, rv_ctest3, rv_ctest4, 8508c2ecf20Sopenharmony_ci rv_ctest5, rv_stest2, rv_ccntl0, rv_ccntl1, rv_scntl4; 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci /* 8538c2ecf20Sopenharmony_ci * Target data. 8548c2ecf20Sopenharmony_ci */ 8558c2ecf20Sopenharmony_ci struct sym_tcb target[SYM_CONF_MAX_TARGET]; 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci /* 8588c2ecf20Sopenharmony_ci * Target control block bus address array used by the SCRIPT 8598c2ecf20Sopenharmony_ci * on reselection. 8608c2ecf20Sopenharmony_ci */ 8618c2ecf20Sopenharmony_ci u32 *targtbl; 8628c2ecf20Sopenharmony_ci u32 targtbl_ba; 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci /* 8658c2ecf20Sopenharmony_ci * DMA pool handle for this HBA. 8668c2ecf20Sopenharmony_ci */ 8678c2ecf20Sopenharmony_ci m_pool_ident_t bus_dmat; 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci /* 8708c2ecf20Sopenharmony_ci * O/S specific data structure 8718c2ecf20Sopenharmony_ci */ 8728c2ecf20Sopenharmony_ci struct sym_shcb s; 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_ci /* 8758c2ecf20Sopenharmony_ci * Physical bus addresses of the chip. 8768c2ecf20Sopenharmony_ci */ 8778c2ecf20Sopenharmony_ci u32 mmio_ba; /* MMIO 32 bit BUS address */ 8788c2ecf20Sopenharmony_ci u32 ram_ba; /* RAM 32 bit BUS address */ 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_ci /* 8818c2ecf20Sopenharmony_ci * SCRIPTS virtual and physical bus addresses. 8828c2ecf20Sopenharmony_ci * 'script' is loaded in the on-chip RAM if present. 8838c2ecf20Sopenharmony_ci * 'scripth' stays in main memory for all chips except the 8848c2ecf20Sopenharmony_ci * 53C895A, 53C896 and 53C1010 that provide 8K on-chip RAM. 8858c2ecf20Sopenharmony_ci */ 8868c2ecf20Sopenharmony_ci u_char *scripta0; /* Copy of scripts A, B, Z */ 8878c2ecf20Sopenharmony_ci u_char *scriptb0; 8888c2ecf20Sopenharmony_ci u_char *scriptz0; 8898c2ecf20Sopenharmony_ci u32 scripta_ba; /* Actual scripts A, B, Z */ 8908c2ecf20Sopenharmony_ci u32 scriptb_ba; /* 32 bit bus addresses. */ 8918c2ecf20Sopenharmony_ci u32 scriptz_ba; 8928c2ecf20Sopenharmony_ci u_short scripta_sz; /* Actual size of script A, B, Z*/ 8938c2ecf20Sopenharmony_ci u_short scriptb_sz; 8948c2ecf20Sopenharmony_ci u_short scriptz_sz; 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_ci /* 8978c2ecf20Sopenharmony_ci * Bus addresses, setup and patch methods for 8988c2ecf20Sopenharmony_ci * the selected firmware. 8998c2ecf20Sopenharmony_ci */ 9008c2ecf20Sopenharmony_ci struct sym_fwa_ba fwa_bas; /* Useful SCRIPTA bus addresses */ 9018c2ecf20Sopenharmony_ci struct sym_fwb_ba fwb_bas; /* Useful SCRIPTB bus addresses */ 9028c2ecf20Sopenharmony_ci struct sym_fwz_ba fwz_bas; /* Useful SCRIPTZ bus addresses */ 9038c2ecf20Sopenharmony_ci void (*fw_setup)(struct sym_hcb *np, struct sym_fw *fw); 9048c2ecf20Sopenharmony_ci void (*fw_patch)(struct Scsi_Host *); 9058c2ecf20Sopenharmony_ci char *fw_name; 9068c2ecf20Sopenharmony_ci 9078c2ecf20Sopenharmony_ci /* 9088c2ecf20Sopenharmony_ci * General controller parameters and configuration. 9098c2ecf20Sopenharmony_ci */ 9108c2ecf20Sopenharmony_ci u_int features; /* Chip features map */ 9118c2ecf20Sopenharmony_ci u_char myaddr; /* SCSI id of the adapter */ 9128c2ecf20Sopenharmony_ci u_char maxburst; /* log base 2 of dwords burst */ 9138c2ecf20Sopenharmony_ci u_char maxwide; /* Maximum transfer width */ 9148c2ecf20Sopenharmony_ci u_char minsync; /* Min sync period factor (ST) */ 9158c2ecf20Sopenharmony_ci u_char maxsync; /* Max sync period factor (ST) */ 9168c2ecf20Sopenharmony_ci u_char maxoffs; /* Max scsi offset (ST) */ 9178c2ecf20Sopenharmony_ci u_char minsync_dt; /* Min sync period factor (DT) */ 9188c2ecf20Sopenharmony_ci u_char maxsync_dt; /* Max sync period factor (DT) */ 9198c2ecf20Sopenharmony_ci u_char maxoffs_dt; /* Max scsi offset (DT) */ 9208c2ecf20Sopenharmony_ci u_char multiplier; /* Clock multiplier (1,2,4) */ 9218c2ecf20Sopenharmony_ci u_char clock_divn; /* Number of clock divisors */ 9228c2ecf20Sopenharmony_ci u32 clock_khz; /* SCSI clock frequency in KHz */ 9238c2ecf20Sopenharmony_ci u32 pciclk_khz; /* Estimated PCI clock in KHz */ 9248c2ecf20Sopenharmony_ci /* 9258c2ecf20Sopenharmony_ci * Start queue management. 9268c2ecf20Sopenharmony_ci * It is filled up by the host processor and accessed by the 9278c2ecf20Sopenharmony_ci * SCRIPTS processor in order to start SCSI commands. 9288c2ecf20Sopenharmony_ci */ 9298c2ecf20Sopenharmony_ci volatile /* Prevent code optimizations */ 9308c2ecf20Sopenharmony_ci u32 *squeue; /* Start queue virtual address */ 9318c2ecf20Sopenharmony_ci u32 squeue_ba; /* Start queue BUS address */ 9328c2ecf20Sopenharmony_ci u_short squeueput; /* Next free slot of the queue */ 9338c2ecf20Sopenharmony_ci u_short actccbs; /* Number of allocated CCBs */ 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_ci /* 9368c2ecf20Sopenharmony_ci * Command completion queue. 9378c2ecf20Sopenharmony_ci * It is the same size as the start queue to avoid overflow. 9388c2ecf20Sopenharmony_ci */ 9398c2ecf20Sopenharmony_ci u_short dqueueget; /* Next position to scan */ 9408c2ecf20Sopenharmony_ci volatile /* Prevent code optimizations */ 9418c2ecf20Sopenharmony_ci u32 *dqueue; /* Completion (done) queue */ 9428c2ecf20Sopenharmony_ci u32 dqueue_ba; /* Done queue BUS address */ 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_ci /* 9458c2ecf20Sopenharmony_ci * Miscellaneous buffers accessed by the scripts-processor. 9468c2ecf20Sopenharmony_ci * They shall be DWORD aligned, because they may be read or 9478c2ecf20Sopenharmony_ci * written with a script command. 9488c2ecf20Sopenharmony_ci */ 9498c2ecf20Sopenharmony_ci u_char msgout[8]; /* Buffer for MESSAGE OUT */ 9508c2ecf20Sopenharmony_ci u_char msgin [8]; /* Buffer for MESSAGE IN */ 9518c2ecf20Sopenharmony_ci u32 lastmsg; /* Last SCSI message sent */ 9528c2ecf20Sopenharmony_ci u32 scratch; /* Scratch for SCSI receive */ 9538c2ecf20Sopenharmony_ci /* Also used for cache test */ 9548c2ecf20Sopenharmony_ci /* 9558c2ecf20Sopenharmony_ci * Miscellaneous configuration and status parameters. 9568c2ecf20Sopenharmony_ci */ 9578c2ecf20Sopenharmony_ci u_char usrflags; /* Miscellaneous user flags */ 9588c2ecf20Sopenharmony_ci u_char scsi_mode; /* Current SCSI BUS mode */ 9598c2ecf20Sopenharmony_ci u_char verbose; /* Verbosity for this controller*/ 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci /* 9628c2ecf20Sopenharmony_ci * CCB lists and queue. 9638c2ecf20Sopenharmony_ci */ 9648c2ecf20Sopenharmony_ci struct sym_ccb **ccbh; /* CCBs hashed by DSA value */ 9658c2ecf20Sopenharmony_ci /* CCB_HASH_SIZE lists of CCBs */ 9668c2ecf20Sopenharmony_ci SYM_QUEHEAD free_ccbq; /* Queue of available CCBs */ 9678c2ecf20Sopenharmony_ci SYM_QUEHEAD busy_ccbq; /* Queue of busy CCBs */ 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci /* 9708c2ecf20Sopenharmony_ci * During error handling and/or recovery, 9718c2ecf20Sopenharmony_ci * active CCBs that are to be completed with 9728c2ecf20Sopenharmony_ci * error or requeued are moved from the busy_ccbq 9738c2ecf20Sopenharmony_ci * to the comp_ccbq prior to completion. 9748c2ecf20Sopenharmony_ci */ 9758c2ecf20Sopenharmony_ci SYM_QUEHEAD comp_ccbq; 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING 9788c2ecf20Sopenharmony_ci SYM_QUEHEAD dummy_ccbq; 9798c2ecf20Sopenharmony_ci#endif 9808c2ecf20Sopenharmony_ci 9818c2ecf20Sopenharmony_ci /* 9828c2ecf20Sopenharmony_ci * IMMEDIATE ARBITRATION (IARB) control. 9838c2ecf20Sopenharmony_ci * 9848c2ecf20Sopenharmony_ci * We keep track in 'last_cp' of the last CCB that has been 9858c2ecf20Sopenharmony_ci * queued to the SCRIPTS processor and clear 'last_cp' when 9868c2ecf20Sopenharmony_ci * this CCB completes. If last_cp is not zero at the moment 9878c2ecf20Sopenharmony_ci * we queue a new CCB, we set a flag in 'last_cp' that is 9888c2ecf20Sopenharmony_ci * used by the SCRIPTS as a hint for setting IARB. 9898c2ecf20Sopenharmony_ci * We donnot set more than 'iarb_max' consecutive hints for 9908c2ecf20Sopenharmony_ci * IARB in order to leave devices a chance to reselect. 9918c2ecf20Sopenharmony_ci * By the way, any non zero value of 'iarb_max' is unfair. :) 9928c2ecf20Sopenharmony_ci */ 9938c2ecf20Sopenharmony_ci#ifdef SYM_CONF_IARB_SUPPORT 9948c2ecf20Sopenharmony_ci u_short iarb_max; /* Max. # consecutive IARB hints*/ 9958c2ecf20Sopenharmony_ci u_short iarb_count; /* Actual # of these hints */ 9968c2ecf20Sopenharmony_ci struct sym_ccb * last_cp; 9978c2ecf20Sopenharmony_ci#endif 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci /* 10008c2ecf20Sopenharmony_ci * Command abort handling. 10018c2ecf20Sopenharmony_ci * We need to synchronize tightly with the SCRIPTS 10028c2ecf20Sopenharmony_ci * processor in order to handle things correctly. 10038c2ecf20Sopenharmony_ci */ 10048c2ecf20Sopenharmony_ci u_char abrt_msg[4]; /* Message to send buffer */ 10058c2ecf20Sopenharmony_ci struct sym_tblmove abrt_tbl; /* Table for the MOV of it */ 10068c2ecf20Sopenharmony_ci struct sym_tblsel abrt_sel; /* Sync params for selection */ 10078c2ecf20Sopenharmony_ci u_char istat_sem; /* Tells the chip to stop (SEM) */ 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci /* 10108c2ecf20Sopenharmony_ci * 64 bit DMA handling. 10118c2ecf20Sopenharmony_ci */ 10128c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE != 0 10138c2ecf20Sopenharmony_ci u_char use_dac; /* Use PCI DAC cycles */ 10148c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 2 10158c2ecf20Sopenharmony_ci u_char dmap_dirty; /* Dma segments registers dirty */ 10168c2ecf20Sopenharmony_ci u32 dmap_bah[SYM_DMAP_SIZE];/* Segment registers map */ 10178c2ecf20Sopenharmony_ci#endif 10188c2ecf20Sopenharmony_ci#endif 10198c2ecf20Sopenharmony_ci}; 10208c2ecf20Sopenharmony_ci 10218c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 0 10228c2ecf20Sopenharmony_ci#define use_dac(np) 0 10238c2ecf20Sopenharmony_ci#define set_dac(np) do { } while (0) 10248c2ecf20Sopenharmony_ci#else 10258c2ecf20Sopenharmony_ci#define use_dac(np) (np)->use_dac 10268c2ecf20Sopenharmony_ci#define set_dac(np) (np)->use_dac = 1 10278c2ecf20Sopenharmony_ci#endif 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_ci#define HCB_BA(np, lbl) (np->hcb_ba + offsetof(struct sym_hcb, lbl)) 10308c2ecf20Sopenharmony_ci 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_ci/* 10338c2ecf20Sopenharmony_ci * FIRMWARES (sym_fw.c) 10348c2ecf20Sopenharmony_ci */ 10358c2ecf20Sopenharmony_cistruct sym_fw * sym_find_firmware(struct sym_chip *chip); 10368c2ecf20Sopenharmony_civoid sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len); 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci/* 10398c2ecf20Sopenharmony_ci * Driver methods called from O/S specific code. 10408c2ecf20Sopenharmony_ci */ 10418c2ecf20Sopenharmony_cichar *sym_driver_name(void); 10428c2ecf20Sopenharmony_civoid sym_print_xerr(struct scsi_cmnd *cmd, int x_status); 10438c2ecf20Sopenharmony_ciint sym_reset_scsi_bus(struct sym_hcb *np, int enab_int); 10448c2ecf20Sopenharmony_cistruct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision); 10458c2ecf20Sopenharmony_ci#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING 10468c2ecf20Sopenharmony_civoid sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn); 10478c2ecf20Sopenharmony_ci#else 10488c2ecf20Sopenharmony_civoid sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); 10498c2ecf20Sopenharmony_ci#endif 10508c2ecf20Sopenharmony_civoid sym_start_up(struct Scsi_Host *, int reason); 10518c2ecf20Sopenharmony_ciirqreturn_t sym_interrupt(struct Scsi_Host *); 10528c2ecf20Sopenharmony_ciint sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task); 10538c2ecf20Sopenharmony_cistruct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order); 10548c2ecf20Sopenharmony_civoid sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp); 10558c2ecf20Sopenharmony_cistruct sym_lcb *sym_alloc_lcb(struct sym_hcb *np, u_char tn, u_char ln); 10568c2ecf20Sopenharmony_ciint sym_free_lcb(struct sym_hcb *np, u_char tn, u_char ln); 10578c2ecf20Sopenharmony_ciint sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); 10588c2ecf20Sopenharmony_ciint sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out); 10598c2ecf20Sopenharmony_ciint sym_reset_scsi_target(struct sym_hcb *np, int target); 10608c2ecf20Sopenharmony_civoid sym_hcb_free(struct sym_hcb *np); 10618c2ecf20Sopenharmony_ciint sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram *nvram); 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_ci/* 10648c2ecf20Sopenharmony_ci * Build a scatter/gather entry. 10658c2ecf20Sopenharmony_ci * 10668c2ecf20Sopenharmony_ci * For 64 bit systems, we use the 8 upper bits of the size field 10678c2ecf20Sopenharmony_ci * to provide bus address bits 32-39 to the SCRIPTS processor. 10688c2ecf20Sopenharmony_ci * This allows the 895A, 896, 1010 to address up to 1 TB of memory. 10698c2ecf20Sopenharmony_ci */ 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci#if SYM_CONF_DMA_ADDRESSING_MODE == 0 10728c2ecf20Sopenharmony_ci#define DMA_DAC_MASK DMA_BIT_MASK(32) 10738c2ecf20Sopenharmony_ci#define sym_build_sge(np, data, badd, len) \ 10748c2ecf20Sopenharmony_cido { \ 10758c2ecf20Sopenharmony_ci (data)->addr = cpu_to_scr(badd); \ 10768c2ecf20Sopenharmony_ci (data)->size = cpu_to_scr(len); \ 10778c2ecf20Sopenharmony_ci} while (0) 10788c2ecf20Sopenharmony_ci#elif SYM_CONF_DMA_ADDRESSING_MODE == 1 10798c2ecf20Sopenharmony_ci#define DMA_DAC_MASK DMA_BIT_MASK(40) 10808c2ecf20Sopenharmony_ci#define sym_build_sge(np, data, badd, len) \ 10818c2ecf20Sopenharmony_cido { \ 10828c2ecf20Sopenharmony_ci (data)->addr = cpu_to_scr(badd); \ 10838c2ecf20Sopenharmony_ci (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len); \ 10848c2ecf20Sopenharmony_ci} while (0) 10858c2ecf20Sopenharmony_ci#elif SYM_CONF_DMA_ADDRESSING_MODE == 2 10868c2ecf20Sopenharmony_ci#define DMA_DAC_MASK DMA_BIT_MASK(64) 10878c2ecf20Sopenharmony_ciint sym_lookup_dmap(struct sym_hcb *np, u32 h, int s); 10888c2ecf20Sopenharmony_cistatic inline void 10898c2ecf20Sopenharmony_cisym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len) 10908c2ecf20Sopenharmony_ci{ 10918c2ecf20Sopenharmony_ci u32 h = (badd>>32); 10928c2ecf20Sopenharmony_ci int s = (h&SYM_DMAP_MASK); 10938c2ecf20Sopenharmony_ci 10948c2ecf20Sopenharmony_ci if (h != np->dmap_bah[s]) 10958c2ecf20Sopenharmony_ci goto bad; 10968c2ecf20Sopenharmony_cigood: 10978c2ecf20Sopenharmony_ci (data)->addr = cpu_to_scr(badd); 10988c2ecf20Sopenharmony_ci (data)->size = cpu_to_scr((s<<24) + len); 10998c2ecf20Sopenharmony_ci return; 11008c2ecf20Sopenharmony_cibad: 11018c2ecf20Sopenharmony_ci s = sym_lookup_dmap(np, h, s); 11028c2ecf20Sopenharmony_ci goto good; 11038c2ecf20Sopenharmony_ci} 11048c2ecf20Sopenharmony_ci#else 11058c2ecf20Sopenharmony_ci#error "Unsupported DMA addressing mode" 11068c2ecf20Sopenharmony_ci#endif 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_ci/* 11098c2ecf20Sopenharmony_ci * MEMORY ALLOCATOR. 11108c2ecf20Sopenharmony_ci */ 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_ci#define sym_get_mem_cluster() \ 11138c2ecf20Sopenharmony_ci (void *) __get_free_pages(GFP_ATOMIC, SYM_MEM_PAGE_ORDER) 11148c2ecf20Sopenharmony_ci#define sym_free_mem_cluster(p) \ 11158c2ecf20Sopenharmony_ci free_pages((unsigned long)p, SYM_MEM_PAGE_ORDER) 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci/* 11188c2ecf20Sopenharmony_ci * Link between free memory chunks of a given size. 11198c2ecf20Sopenharmony_ci */ 11208c2ecf20Sopenharmony_citypedef struct sym_m_link { 11218c2ecf20Sopenharmony_ci struct sym_m_link *next; 11228c2ecf20Sopenharmony_ci} *m_link_p; 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci/* 11258c2ecf20Sopenharmony_ci * Virtual to bus physical translation for a given cluster. 11268c2ecf20Sopenharmony_ci * Such a structure is only useful with DMA abstraction. 11278c2ecf20Sopenharmony_ci */ 11288c2ecf20Sopenharmony_citypedef struct sym_m_vtob { /* Virtual to Bus address translation */ 11298c2ecf20Sopenharmony_ci struct sym_m_vtob *next; 11308c2ecf20Sopenharmony_ci void *vaddr; /* Virtual address */ 11318c2ecf20Sopenharmony_ci dma_addr_t baddr; /* Bus physical address */ 11328c2ecf20Sopenharmony_ci} *m_vtob_p; 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_ci/* Hash this stuff a bit to speed up translations */ 11358c2ecf20Sopenharmony_ci#define VTOB_HASH_SHIFT 5 11368c2ecf20Sopenharmony_ci#define VTOB_HASH_SIZE (1UL << VTOB_HASH_SHIFT) 11378c2ecf20Sopenharmony_ci#define VTOB_HASH_MASK (VTOB_HASH_SIZE-1) 11388c2ecf20Sopenharmony_ci#define VTOB_HASH_CODE(m) \ 11398c2ecf20Sopenharmony_ci ((((unsigned long)(m)) >> SYM_MEM_CLUSTER_SHIFT) & VTOB_HASH_MASK) 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_ci/* 11428c2ecf20Sopenharmony_ci * Memory pool of a given kind. 11438c2ecf20Sopenharmony_ci * Ideally, we want to use: 11448c2ecf20Sopenharmony_ci * 1) 1 pool for memory we donnot need to involve in DMA. 11458c2ecf20Sopenharmony_ci * 2) The same pool for controllers that require same DMA 11468c2ecf20Sopenharmony_ci * constraints and features. 11478c2ecf20Sopenharmony_ci * The OS specific m_pool_id_t thing and the sym_m_pool_match() 11488c2ecf20Sopenharmony_ci * method are expected to tell the driver about. 11498c2ecf20Sopenharmony_ci */ 11508c2ecf20Sopenharmony_citypedef struct sym_m_pool { 11518c2ecf20Sopenharmony_ci m_pool_ident_t dev_dmat; /* Identifies the pool (see above) */ 11528c2ecf20Sopenharmony_ci void * (*get_mem_cluster)(struct sym_m_pool *); 11538c2ecf20Sopenharmony_ci#ifdef SYM_MEM_FREE_UNUSED 11548c2ecf20Sopenharmony_ci void (*free_mem_cluster)(struct sym_m_pool *, void *); 11558c2ecf20Sopenharmony_ci#endif 11568c2ecf20Sopenharmony_ci#define M_GET_MEM_CLUSTER() mp->get_mem_cluster(mp) 11578c2ecf20Sopenharmony_ci#define M_FREE_MEM_CLUSTER(p) mp->free_mem_cluster(mp, p) 11588c2ecf20Sopenharmony_ci int nump; 11598c2ecf20Sopenharmony_ci m_vtob_p vtob[VTOB_HASH_SIZE]; 11608c2ecf20Sopenharmony_ci struct sym_m_pool *next; 11618c2ecf20Sopenharmony_ci struct sym_m_link h[SYM_MEM_CLUSTER_SHIFT - SYM_MEM_SHIFT + 1]; 11628c2ecf20Sopenharmony_ci} *m_pool_p; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci/* 11658c2ecf20Sopenharmony_ci * Alloc, free and translate addresses to bus physical 11668c2ecf20Sopenharmony_ci * for DMAable memory. 11678c2ecf20Sopenharmony_ci */ 11688c2ecf20Sopenharmony_civoid *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name); 11698c2ecf20Sopenharmony_civoid __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name); 11708c2ecf20Sopenharmony_cidma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m); 11718c2ecf20Sopenharmony_ci 11728c2ecf20Sopenharmony_ci/* 11738c2ecf20Sopenharmony_ci * Verbs used by the driver code for DMAable memory handling. 11748c2ecf20Sopenharmony_ci * The _uvptv_ macro avoids a nasty warning about pointer to volatile 11758c2ecf20Sopenharmony_ci * being discarded. 11768c2ecf20Sopenharmony_ci */ 11778c2ecf20Sopenharmony_ci#define _uvptv_(p) ((void *)((u_long)(p))) 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_ci#define _sym_calloc_dma(np, l, n) __sym_calloc_dma(np->bus_dmat, l, n) 11808c2ecf20Sopenharmony_ci#define _sym_mfree_dma(np, p, l, n) \ 11818c2ecf20Sopenharmony_ci __sym_mfree_dma(np->bus_dmat, _uvptv_(p), l, n) 11828c2ecf20Sopenharmony_ci#define sym_calloc_dma(l, n) _sym_calloc_dma(np, l, n) 11838c2ecf20Sopenharmony_ci#define sym_mfree_dma(p, l, n) _sym_mfree_dma(np, p, l, n) 11848c2ecf20Sopenharmony_ci#define vtobus(p) __vtobus(np->bus_dmat, _uvptv_(p)) 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci/* 11878c2ecf20Sopenharmony_ci * We have to provide the driver memory allocator with methods for 11888c2ecf20Sopenharmony_ci * it to maintain virtual to bus physical address translations. 11898c2ecf20Sopenharmony_ci */ 11908c2ecf20Sopenharmony_ci 11918c2ecf20Sopenharmony_ci#define sym_m_pool_match(mp_id1, mp_id2) (mp_id1 == mp_id2) 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_cistatic inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp) 11948c2ecf20Sopenharmony_ci{ 11958c2ecf20Sopenharmony_ci void *vaddr = NULL; 11968c2ecf20Sopenharmony_ci dma_addr_t baddr = 0; 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci vaddr = dma_alloc_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, &baddr, 11998c2ecf20Sopenharmony_ci GFP_ATOMIC); 12008c2ecf20Sopenharmony_ci if (vaddr) { 12018c2ecf20Sopenharmony_ci vbp->vaddr = vaddr; 12028c2ecf20Sopenharmony_ci vbp->baddr = baddr; 12038c2ecf20Sopenharmony_ci } 12048c2ecf20Sopenharmony_ci return vaddr; 12058c2ecf20Sopenharmony_ci} 12068c2ecf20Sopenharmony_ci 12078c2ecf20Sopenharmony_cistatic inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp) 12088c2ecf20Sopenharmony_ci{ 12098c2ecf20Sopenharmony_ci dma_free_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, vbp->vaddr, 12108c2ecf20Sopenharmony_ci vbp->baddr); 12118c2ecf20Sopenharmony_ci} 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ci#endif /* SYM_HIPD_H */ 1214