1 |
1275 |
phoenix |
/* -*- mode: c; c-basic-offset: 8 -*- */
|
2 |
|
|
|
3 |
|
|
/* Driver for 53c700 and 53c700-66 chips from NCR and Symbios
|
4 |
|
|
*
|
5 |
|
|
* Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
#ifndef _53C700_H
|
9 |
|
|
#define _53C700_H
|
10 |
|
|
|
11 |
|
|
/* Turn on for general debugging---too verbose for normal use */
|
12 |
|
|
#undef NCR_700_DEBUG
|
13 |
|
|
/* Debug the tag queues, checking hash queue allocation and deallocation
|
14 |
|
|
* and search for duplicate tags */
|
15 |
|
|
#undef NCR_700_TAG_DEBUG
|
16 |
|
|
|
17 |
|
|
#ifdef NCR_700_DEBUG
|
18 |
|
|
#define DEBUG(x) printk x
|
19 |
|
|
#else
|
20 |
|
|
#define DEBUG(x)
|
21 |
|
|
#endif
|
22 |
|
|
|
23 |
|
|
/* The number of available command slots */
|
24 |
|
|
#define NCR_700_COMMAND_SLOTS_PER_HOST 64
|
25 |
|
|
/* The maximum number of Scatter Gathers we allow */
|
26 |
|
|
#define NCR_700_SG_SEGMENTS 32
|
27 |
|
|
/* The maximum number of luns (make this of the form 2^n) */
|
28 |
|
|
#define NCR_700_MAX_LUNS 32
|
29 |
|
|
#define NCR_700_LUN_MASK (NCR_700_MAX_LUNS - 1)
|
30 |
|
|
/* Alter this with care: too many tags won't give the elevator a chance to
|
31 |
|
|
* work; too few will cause the device to operate less efficiently */
|
32 |
|
|
#define NCR_700_MAX_TAGS 16
|
33 |
|
|
/* magic byte identifying an internally generated REQUEST_SENSE command */
|
34 |
|
|
#define NCR_700_INTERNAL_SENSE_MAGIC 0x42
|
35 |
|
|
|
36 |
|
|
/* WARNING: Leave this in for now: the dependency preprocessor doesn't
|
37 |
|
|
* pick up file specific flags, so must define here if they are not
|
38 |
|
|
* set */
|
39 |
|
|
#if !defined(CONFIG_53C700_IO_MAPPED) && !defined(CONFIG_53C700_MEM_MAPPED)
|
40 |
|
|
#error "Config.in must define either CONFIG_53C700_IO_MAPPED or CONFIG_53C700_MEM_MAPPED to use this scsi core."
|
41 |
|
|
#endif
|
42 |
|
|
|
43 |
|
|
/* macros for consistent memory allocation */
|
44 |
|
|
|
45 |
|
|
#ifdef CONFIG_53C700_USE_CONSISTENT
|
46 |
|
|
#define NCR_700_dma_cache_wback(mem, size) \
|
47 |
|
|
if(!hostdata->consistent) \
|
48 |
|
|
dma_cache_wback(mem, size)
|
49 |
|
|
#define NCR_700_dma_cache_inv(mem, size) \
|
50 |
|
|
if(!hostdata->consistent) \
|
51 |
|
|
dma_cache_inv(mem, size)
|
52 |
|
|
#define NCR_700_dma_cache_wback_inv(mem, size) \
|
53 |
|
|
if(!hostdata->consistent) \
|
54 |
|
|
dma_cache_wback_inv(mem, size)
|
55 |
|
|
#else
|
56 |
|
|
#define NCR_700_dma_cache_wback(mem, size) dma_cache_wback(mem,size)
|
57 |
|
|
#define NCR_700_dma_cache_inv(mem, size) dma_cache_inv(mem,size)
|
58 |
|
|
#define NCR_700_dma_cache_wback_inv(mem, size) dma_cache_wback_inv(mem,size)
|
59 |
|
|
#endif
|
60 |
|
|
|
61 |
|
|
|
62 |
|
|
struct NCR_700_Host_Parameters;
|
63 |
|
|
|
64 |
|
|
/* These are the externally used routines */
|
65 |
|
|
struct Scsi_Host *NCR_700_detect(Scsi_Host_Template *, struct NCR_700_Host_Parameters *);
|
66 |
|
|
int NCR_700_release(struct Scsi_Host *host);
|
67 |
|
|
void NCR_700_intr(int, void *, struct pt_regs *);
|
68 |
|
|
|
69 |
|
|
|
70 |
|
|
enum NCR_700_Host_State {
|
71 |
|
|
NCR_700_HOST_BUSY,
|
72 |
|
|
NCR_700_HOST_FREE,
|
73 |
|
|
};
|
74 |
|
|
|
75 |
|
|
struct NCR_700_SG_List {
|
76 |
|
|
/* The following is a script fragment to move the buffer onto the
|
77 |
|
|
* bus and then link the next fragment or return */
|
78 |
|
|
#define SCRIPT_MOVE_DATA_IN 0x09000000
|
79 |
|
|
#define SCRIPT_MOVE_DATA_OUT 0x08000000
|
80 |
|
|
__u32 ins;
|
81 |
|
|
__u32 pAddr;
|
82 |
|
|
#define SCRIPT_NOP 0x80000000
|
83 |
|
|
#define SCRIPT_RETURN 0x90080000
|
84 |
|
|
};
|
85 |
|
|
|
86 |
|
|
/* We use device->hostdata to store negotiated parameters. This is
|
87 |
|
|
* supposed to be a pointer to a device private area, but we cannot
|
88 |
|
|
* really use it as such since it will never be freed, so just use the
|
89 |
|
|
* 32 bits to cram the information. The SYNC negotiation sequence looks
|
90 |
|
|
* like:
|
91 |
|
|
*
|
92 |
|
|
* If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the
|
93 |
|
|
* initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION
|
94 |
|
|
* If we get an SDTR reply, work out the SXFER parameters, squirrel
|
95 |
|
|
* them away here, clear DEV_BEGIN_SYNC_NEGOTIATION and set
|
96 |
|
|
* DEV_NEGOTIATED_SYNC. If we get a REJECT msg, squirrel
|
97 |
|
|
*
|
98 |
|
|
*
|
99 |
|
|
* 0:7 SXFER_REG negotiated value for this device
|
100 |
|
|
* 8:15 Current queue depth
|
101 |
|
|
* 16 negotiated SYNC flag
|
102 |
|
|
* 17 begin SYNC negotiation flag
|
103 |
|
|
* 18 device supports tag queueing */
|
104 |
|
|
#define NCR_700_DEV_NEGOTIATED_SYNC (1<<16)
|
105 |
|
|
#define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17)
|
106 |
|
|
#define NCR_700_DEV_BEGIN_TAG_QUEUEING (1<<18)
|
107 |
|
|
#define NCR_700_DEV_TAG_STARVATION_WARNED (1<<19)
|
108 |
|
|
|
109 |
|
|
static inline void
|
110 |
|
|
NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer)
|
111 |
|
|
{
|
112 |
|
|
((unsigned long)SDp->hostdata) &= 0xffffff00;
|
113 |
|
|
((unsigned long)SDp->hostdata) |= sxfer & 0xff;
|
114 |
|
|
}
|
115 |
|
|
static inline __u8 NCR_700_get_SXFER(Scsi_Device *SDp)
|
116 |
|
|
{
|
117 |
|
|
return (((unsigned long)SDp->hostdata) & 0xff);
|
118 |
|
|
}
|
119 |
|
|
static inline void
|
120 |
|
|
NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
|
121 |
|
|
{
|
122 |
|
|
((unsigned long)SDp->hostdata) &= 0xffff00ff;
|
123 |
|
|
((unsigned long)SDp->hostdata) |= (0xff00 & (depth << 8));
|
124 |
|
|
}
|
125 |
|
|
static inline __u8
|
126 |
|
|
NCR_700_get_depth(Scsi_Device *SDp)
|
127 |
|
|
{
|
128 |
|
|
return ((((unsigned long)SDp->hostdata) & 0xff00)>>8);
|
129 |
|
|
}
|
130 |
|
|
static inline int
|
131 |
|
|
NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag)
|
132 |
|
|
{
|
133 |
|
|
return (((unsigned long)SDp->hostdata) & flag) == flag;
|
134 |
|
|
}
|
135 |
|
|
static inline int
|
136 |
|
|
NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag)
|
137 |
|
|
{
|
138 |
|
|
return (((unsigned long)SDp->hostdata) & flag) == 0;
|
139 |
|
|
}
|
140 |
|
|
static inline void
|
141 |
|
|
NCR_700_set_flag(Scsi_Device *SDp, __u32 flag)
|
142 |
|
|
{
|
143 |
|
|
((unsigned long)SDp->hostdata) |= (flag & 0xffff0000);
|
144 |
|
|
}
|
145 |
|
|
static inline void
|
146 |
|
|
NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag)
|
147 |
|
|
{
|
148 |
|
|
((unsigned long)SDp->hostdata) &= ~(flag & 0xffff0000);
|
149 |
|
|
}
|
150 |
|
|
|
151 |
|
|
/* These represent the Nexus hashing functions. A Nexus in SCSI terms
|
152 |
|
|
* just means the identification of an outstanding command, by ITL
|
153 |
|
|
* (Initiator Target Lun) or ITLQ (Initiator Target Lun Tag). I'm not
|
154 |
|
|
* very keen on XOR based hashes, so these are based on number theory
|
155 |
|
|
* instead. All you need to do is to fix your hash bucket size and
|
156 |
|
|
* then choose reasonable strides which are coprime with the chosen
|
157 |
|
|
* bucket size
|
158 |
|
|
*
|
159 |
|
|
* Note: this mathematical hash can be made very efficient, if the
|
160 |
|
|
* compiler is good at optimising: Choose the number of buckets to be
|
161 |
|
|
* 2^n and the modulo becomes a logical and with (2^n-1).
|
162 |
|
|
* Additionally, if you chose the coprimes of the form 2^n-2^n the
|
163 |
|
|
* multiplication can be done by a shift and an addition. */
|
164 |
|
|
#define MAX_ITL_HASH_BUCKETS 16
|
165 |
|
|
#define ITL_HASH_PRIME 7
|
166 |
|
|
|
167 |
|
|
#define MAX_ITLQ_HASH_BUCKETS 64
|
168 |
|
|
#define ITLQ_PUN_PRIME 7
|
169 |
|
|
#define ITLQ_LUN_PRIME 3
|
170 |
|
|
|
171 |
|
|
static inline int
|
172 |
|
|
hash_ITL(__u8 pun, __u8 lun)
|
173 |
|
|
{
|
174 |
|
|
return (pun*ITL_HASH_PRIME + lun) % MAX_ITL_HASH_BUCKETS;
|
175 |
|
|
}
|
176 |
|
|
|
177 |
|
|
static inline int
|
178 |
|
|
hash_ITLQ(__u8 pun, __u8 lun, __u8 tag)
|
179 |
|
|
{
|
180 |
|
|
return (pun*ITLQ_PUN_PRIME + lun*ITLQ_LUN_PRIME + tag) % MAX_ITLQ_HASH_BUCKETS;
|
181 |
|
|
}
|
182 |
|
|
|
183 |
|
|
struct NCR_700_command_slot {
|
184 |
|
|
struct NCR_700_SG_List SG[NCR_700_SG_SEGMENTS+1];
|
185 |
|
|
struct NCR_700_SG_List *pSG;
|
186 |
|
|
#define NCR_700_SLOT_MASK 0xFC
|
187 |
|
|
#define NCR_700_SLOT_MAGIC 0xb8
|
188 |
|
|
#define NCR_700_SLOT_FREE (0|NCR_700_SLOT_MAGIC) /* slot may be used */
|
189 |
|
|
#define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */
|
190 |
|
|
#define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */
|
191 |
|
|
__u8 state;
|
192 |
|
|
#define NCR_700_NO_TAG 0xdead
|
193 |
|
|
__u16 tag;
|
194 |
|
|
__u32 resume_offset;
|
195 |
|
|
Scsi_Cmnd *cmnd;
|
196 |
|
|
/* The pci_mapped address of the actual command in cmnd */
|
197 |
|
|
dma_addr_t pCmd;
|
198 |
|
|
__u32 temp;
|
199 |
|
|
/* if this command is a pci_single mapping, holds the dma address
|
200 |
|
|
* for later unmapping in the done routine */
|
201 |
|
|
dma_addr_t dma_handle;
|
202 |
|
|
/* Doubly linked ITL/ITLQ list kept in strict time order
|
203 |
|
|
* (latest at the back) */
|
204 |
|
|
struct NCR_700_command_slot *ITL_forw;
|
205 |
|
|
struct NCR_700_command_slot *ITL_back;
|
206 |
|
|
struct NCR_700_command_slot *ITLQ_forw;
|
207 |
|
|
struct NCR_700_command_slot *ITLQ_back;
|
208 |
|
|
};
|
209 |
|
|
|
210 |
|
|
struct NCR_700_Host_Parameters {
|
211 |
|
|
/* These must be filled in by the calling driver */
|
212 |
|
|
int clock; /* board clock speed in MHz */
|
213 |
|
|
unsigned long base; /* the base for the port (copied to host) */
|
214 |
|
|
struct pci_dev *pci_dev;
|
215 |
|
|
__u32 dmode_extra; /* adjustable bus settings */
|
216 |
|
|
__u32 differential:1; /* if we are differential */
|
217 |
|
|
#ifdef CONFIG_53C700_LE_ON_BE
|
218 |
|
|
/* This option is for HP only. Set it if your chip is wired for
|
219 |
|
|
* little endian on this platform (which is big endian) */
|
220 |
|
|
__u32 force_le_on_be:1;
|
221 |
|
|
#endif
|
222 |
|
|
__u32 chip710:1; /* set if really a 710 not 700 */
|
223 |
|
|
__u32 burst_disable:1; /* set to 1 to disable 710 bursting */
|
224 |
|
|
|
225 |
|
|
/* NOTHING BELOW HERE NEEDS ALTERING */
|
226 |
|
|
__u32 fast:1; /* if we can alter the SCSI bus clock
|
227 |
|
|
speed (so can negiotiate sync) */
|
228 |
|
|
#ifdef CONFIG_53C700_USE_CONSISTENT
|
229 |
|
|
__u32 consistent:1;
|
230 |
|
|
#endif
|
231 |
|
|
|
232 |
|
|
int sync_clock; /* The speed of the SYNC core */
|
233 |
|
|
|
234 |
|
|
__u32 *script; /* pointer to script location */
|
235 |
|
|
__u32 pScript; /* physical mem addr of script */
|
236 |
|
|
|
237 |
|
|
/* This will be the host lock. Unfortunately, we can't use it
|
238 |
|
|
* at the moment because of the necessity of holding the
|
239 |
|
|
* io_request_lock */
|
240 |
|
|
spinlock_t lock;
|
241 |
|
|
enum NCR_700_Host_State state; /* protected by state lock */
|
242 |
|
|
Scsi_Cmnd *cmd;
|
243 |
|
|
/* Note: pScript contains the single consistent block of
|
244 |
|
|
* memory. All the msgin, msgout and status are allocated in
|
245 |
|
|
* this memory too (at separate cache lines). TOTAL_MEM_SIZE
|
246 |
|
|
* represents the total size of this area */
|
247 |
|
|
#define MSG_ARRAY_SIZE 8
|
248 |
|
|
#define MSGOUT_OFFSET (L1_CACHE_ALIGN(sizeof(SCRIPT)))
|
249 |
|
|
__u8 *msgout;
|
250 |
|
|
#define MSGIN_OFFSET (MSGOUT_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
|
251 |
|
|
__u8 *msgin;
|
252 |
|
|
#define STATUS_OFFSET (MSGIN_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
|
253 |
|
|
__u8 *status;
|
254 |
|
|
#define SLOTS_OFFSET (STATUS_OFFSET + L1_CACHE_ALIGN(MSG_ARRAY_SIZE))
|
255 |
|
|
struct NCR_700_command_slot *slots;
|
256 |
|
|
#define TOTAL_MEM_SIZE (SLOTS_OFFSET + L1_CACHE_ALIGN(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST))
|
257 |
|
|
int saved_slot_position;
|
258 |
|
|
int command_slot_count; /* protected by state lock */
|
259 |
|
|
__u8 tag_negotiated;
|
260 |
|
|
__u8 rev;
|
261 |
|
|
__u8 reselection_id;
|
262 |
|
|
/* flags for the host */
|
263 |
|
|
|
264 |
|
|
/* ITL list. ALL outstanding commands are hashed here in strict
|
265 |
|
|
* order, latest at the back */
|
266 |
|
|
struct NCR_700_command_slot *ITL_Hash_forw[MAX_ITL_HASH_BUCKETS];
|
267 |
|
|
struct NCR_700_command_slot *ITL_Hash_back[MAX_ITL_HASH_BUCKETS];
|
268 |
|
|
|
269 |
|
|
/* Only tagged outstanding commands are hashed here (also latest
|
270 |
|
|
* at the back) */
|
271 |
|
|
struct NCR_700_command_slot *ITLQ_Hash_forw[MAX_ITLQ_HASH_BUCKETS];
|
272 |
|
|
struct NCR_700_command_slot *ITLQ_Hash_back[MAX_ITLQ_HASH_BUCKETS];
|
273 |
|
|
|
274 |
|
|
/* Free list, singly linked by ITL_forw elements */
|
275 |
|
|
struct NCR_700_command_slot *free_list;
|
276 |
|
|
};
|
277 |
|
|
|
278 |
|
|
/*
|
279 |
|
|
* 53C700 Register Interface - the offset from the Selected base
|
280 |
|
|
* I/O address */
|
281 |
|
|
#ifdef CONFIG_53C700_LE_ON_BE
|
282 |
|
|
#define bE (hostdata->force_le_on_be ? 0 : 3)
|
283 |
|
|
#define bSWAP (hostdata->force_le_on_be)
|
284 |
|
|
#elif defined(__BIG_ENDIAN)
|
285 |
|
|
#define bE 3
|
286 |
|
|
#define bSWAP 0
|
287 |
|
|
#elif defined(__LITTLE_ENDIAN)
|
288 |
|
|
#define bE 0
|
289 |
|
|
#define bSWAP 0
|
290 |
|
|
#else
|
291 |
|
|
#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined, did you include byteorder.h?"
|
292 |
|
|
#endif
|
293 |
|
|
#define bS_to_cpu(x) (bSWAP ? le32_to_cpu(x) : (x))
|
294 |
|
|
#define bS_to_host(x) (bSWAP ? cpu_to_le32(x) : (x))
|
295 |
|
|
|
296 |
|
|
/* NOTE: These registers are in the LE register space only, the required byte
|
297 |
|
|
* swapping is done by the NCR_700_{read|write}[b] functions */
|
298 |
|
|
#define SCNTL0_REG 0x00
|
299 |
|
|
#define FULL_ARBITRATION 0xc0
|
300 |
|
|
#define PARITY 0x08
|
301 |
|
|
#define ENABLE_PARITY 0x04
|
302 |
|
|
#define AUTO_ATN 0x02
|
303 |
|
|
#define SCNTL1_REG 0x01
|
304 |
|
|
#define SLOW_BUS 0x80
|
305 |
|
|
#define ENABLE_SELECT 0x20
|
306 |
|
|
#define ASSERT_RST 0x08
|
307 |
|
|
#define ASSERT_EVEN_PARITY 0x04
|
308 |
|
|
#define SDID_REG 0x02
|
309 |
|
|
#define SIEN_REG 0x03
|
310 |
|
|
#define PHASE_MM_INT 0x80
|
311 |
|
|
#define FUNC_COMP_INT 0x40
|
312 |
|
|
#define SEL_TIMEOUT_INT 0x20
|
313 |
|
|
#define SELECT_INT 0x10
|
314 |
|
|
#define GROSS_ERR_INT 0x08
|
315 |
|
|
#define UX_DISC_INT 0x04
|
316 |
|
|
#define RST_INT 0x02
|
317 |
|
|
#define PAR_ERR_INT 0x01
|
318 |
|
|
#define SCID_REG 0x04
|
319 |
|
|
#define SXFER_REG 0x05
|
320 |
|
|
#define ASYNC_OPERATION 0x00
|
321 |
|
|
#define SODL_REG 0x06
|
322 |
|
|
#define SOCL_REG 0x07
|
323 |
|
|
#define SFBR_REG 0x08
|
324 |
|
|
#define SIDL_REG 0x09
|
325 |
|
|
#define SBDL_REG 0x0A
|
326 |
|
|
#define SBCL_REG 0x0B
|
327 |
|
|
/* read bits */
|
328 |
|
|
#define SBCL_IO 0x01
|
329 |
|
|
/*write bits */
|
330 |
|
|
#define SYNC_DIV_AS_ASYNC 0x00
|
331 |
|
|
#define SYNC_DIV_1_0 0x01
|
332 |
|
|
#define SYNC_DIV_1_5 0x02
|
333 |
|
|
#define SYNC_DIV_2_0 0x03
|
334 |
|
|
#define DSTAT_REG 0x0C
|
335 |
|
|
#define ILGL_INST_DETECTED 0x01
|
336 |
|
|
#define WATCH_DOG_INTERRUPT 0x02
|
337 |
|
|
#define SCRIPT_INT_RECEIVED 0x04
|
338 |
|
|
#define ABORTED 0x10
|
339 |
|
|
#define SSTAT0_REG 0x0D
|
340 |
|
|
#define PARITY_ERROR 0x01
|
341 |
|
|
#define SCSI_RESET_DETECTED 0x02
|
342 |
|
|
#define UNEXPECTED_DISCONNECT 0x04
|
343 |
|
|
#define SCSI_GROSS_ERROR 0x08
|
344 |
|
|
#define SELECTED 0x10
|
345 |
|
|
#define SELECTION_TIMEOUT 0x20
|
346 |
|
|
#define FUNCTION_COMPLETE 0x40
|
347 |
|
|
#define PHASE_MISMATCH 0x80
|
348 |
|
|
#define SSTAT1_REG 0x0E
|
349 |
|
|
#define SIDL_REG_FULL 0x80
|
350 |
|
|
#define SODR_REG_FULL 0x40
|
351 |
|
|
#define SODL_REG_FULL 0x20
|
352 |
|
|
#define SSTAT2_REG 0x0F
|
353 |
|
|
#define CTEST0_REG 0x14
|
354 |
|
|
#define BTB_TIMER_DISABLE 0x40
|
355 |
|
|
#define CTEST1_REG 0x15
|
356 |
|
|
#define CTEST2_REG 0x16
|
357 |
|
|
#define CTEST3_REG 0x17
|
358 |
|
|
#define CTEST4_REG 0x18
|
359 |
|
|
#define DISABLE_FIFO 0x00
|
360 |
|
|
#define SLBE 0x10
|
361 |
|
|
#define SFWR 0x08
|
362 |
|
|
#define BYTE_LANE0 0x04
|
363 |
|
|
#define BYTE_LANE1 0x05
|
364 |
|
|
#define BYTE_LANE2 0x06
|
365 |
|
|
#define BYTE_LANE3 0x07
|
366 |
|
|
#define SCSI_ZMODE 0x20
|
367 |
|
|
#define ZMODE 0x40
|
368 |
|
|
#define CTEST5_REG 0x19
|
369 |
|
|
#define MASTER_CONTROL 0x10
|
370 |
|
|
#define DMA_DIRECTION 0x08
|
371 |
|
|
#define CTEST7_REG 0x1B
|
372 |
|
|
#define BURST_DISABLE 0x80 /* 710 only */
|
373 |
|
|
#define SEL_TIMEOUT_DISABLE 0x10 /* 710 only */
|
374 |
|
|
#define DFP 0x08
|
375 |
|
|
#define EVP 0x04
|
376 |
|
|
#define DIFF 0x01
|
377 |
|
|
#define CTEST6_REG 0x1A
|
378 |
|
|
#define TEMP_REG 0x1C
|
379 |
|
|
#define DFIFO_REG 0x20
|
380 |
|
|
#define FLUSH_DMA_FIFO 0x80
|
381 |
|
|
#define CLR_FIFO 0x40
|
382 |
|
|
#define ISTAT_REG 0x21
|
383 |
|
|
#define ABORT_OPERATION 0x80
|
384 |
|
|
#define SOFTWARE_RESET_710 0x40
|
385 |
|
|
#define DMA_INT_PENDING 0x01
|
386 |
|
|
#define SCSI_INT_PENDING 0x02
|
387 |
|
|
#define CONNECTED 0x08
|
388 |
|
|
#define CTEST8_REG 0x22
|
389 |
|
|
#define LAST_DIS_ENBL 0x01
|
390 |
|
|
#define SHORTEN_FILTERING 0x04
|
391 |
|
|
#define ENABLE_ACTIVE_NEGATION 0x10
|
392 |
|
|
#define GENERATE_RECEIVE_PARITY 0x20
|
393 |
|
|
#define CLR_FIFO_710 0x04
|
394 |
|
|
#define FLUSH_DMA_FIFO_710 0x08
|
395 |
|
|
#define CTEST9_REG 0x23
|
396 |
|
|
#define DBC_REG 0x24
|
397 |
|
|
#define DCMD_REG 0x27
|
398 |
|
|
#define DNAD_REG 0x28
|
399 |
|
|
#define DIEN_REG 0x39
|
400 |
|
|
#define BUS_FAULT 0x20
|
401 |
|
|
#define ABORT_INT 0x10
|
402 |
|
|
#define INT_INST_INT 0x04
|
403 |
|
|
#define WD_INT 0x02
|
404 |
|
|
#define ILGL_INST_INT 0x01
|
405 |
|
|
#define DCNTL_REG 0x3B
|
406 |
|
|
#define SOFTWARE_RESET 0x01
|
407 |
|
|
#define COMPAT_700_MODE 0x01
|
408 |
|
|
#define SCRPTS_16BITS 0x20
|
409 |
|
|
#define ASYNC_DIV_2_0 0x00
|
410 |
|
|
#define ASYNC_DIV_1_5 0x40
|
411 |
|
|
#define ASYNC_DIV_1_0 0x80
|
412 |
|
|
#define ASYNC_DIV_3_0 0xc0
|
413 |
|
|
#define DMODE_710_REG 0x38
|
414 |
|
|
#define DMODE_700_REG 0x34
|
415 |
|
|
#define BURST_LENGTH_1 0x00
|
416 |
|
|
#define BURST_LENGTH_2 0x40
|
417 |
|
|
#define BURST_LENGTH_4 0x80
|
418 |
|
|
#define BURST_LENGTH_8 0xC0
|
419 |
|
|
#define DMODE_FC1 0x10
|
420 |
|
|
#define DMODE_FC2 0x20
|
421 |
|
|
#define BW16 32
|
422 |
|
|
#define MODE_286 16
|
423 |
|
|
#define IO_XFER 8
|
424 |
|
|
#define FIXED_ADDR 4
|
425 |
|
|
|
426 |
|
|
#define DSP_REG 0x2C
|
427 |
|
|
#define DSPS_REG 0x30
|
428 |
|
|
|
429 |
|
|
/* Parameters to begin SDTR negotiations. Empirically, I find that
|
430 |
|
|
* the 53c700-66 cannot handle an offset >8, so don't change this */
|
431 |
|
|
#define NCR_700_MAX_OFFSET 8
|
432 |
|
|
/* Was hoping the max offset would be greater for the 710, but
|
433 |
|
|
* empirically it seems to be 8 also */
|
434 |
|
|
#define NCR_710_MAX_OFFSET 8
|
435 |
|
|
#define NCR_700_MIN_XFERP 1
|
436 |
|
|
#define NCR_710_MIN_XFERP 0
|
437 |
|
|
#define NCR_700_MIN_PERIOD 25 /* for SDTR message, 100ns */
|
438 |
|
|
|
439 |
|
|
#define script_patch_32(script, symbol, value) \
|
440 |
|
|
{ \
|
441 |
|
|
int i; \
|
442 |
|
|
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
|
443 |
|
|
__u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]) + value; \
|
444 |
|
|
(script)[A_##symbol##_used[i]] = bS_to_host(val); \
|
445 |
|
|
dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
|
446 |
|
|
DEBUG((" script, patching %s at %d to 0x%lx\n", \
|
447 |
|
|
#symbol, A_##symbol##_used[i], (value))); \
|
448 |
|
|
} \
|
449 |
|
|
}
|
450 |
|
|
|
451 |
|
|
#define script_patch_32_abs(script, symbol, value) \
|
452 |
|
|
{ \
|
453 |
|
|
int i; \
|
454 |
|
|
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
|
455 |
|
|
(script)[A_##symbol##_used[i]] = bS_to_host(value); \
|
456 |
|
|
dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
|
457 |
|
|
DEBUG((" script, patching %s at %d to 0x%lx\n", \
|
458 |
|
|
#symbol, A_##symbol##_used[i], (value))); \
|
459 |
|
|
} \
|
460 |
|
|
}
|
461 |
|
|
|
462 |
|
|
/* Used for patching the SCSI ID in the SELECT instruction */
|
463 |
|
|
#define script_patch_ID(script, symbol, value) \
|
464 |
|
|
{ \
|
465 |
|
|
int i; \
|
466 |
|
|
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
|
467 |
|
|
__u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]); \
|
468 |
|
|
val &= 0xff00ffff; \
|
469 |
|
|
val |= ((value) & 0xff) << 16; \
|
470 |
|
|
(script)[A_##symbol##_used[i]] = bS_to_host(val); \
|
471 |
|
|
dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
|
472 |
|
|
DEBUG((" script, patching ID field %s at %d to 0x%x\n", \
|
473 |
|
|
#symbol, A_##symbol##_used[i], val)); \
|
474 |
|
|
} \
|
475 |
|
|
}
|
476 |
|
|
|
477 |
|
|
#define script_patch_16(script, symbol, value) \
|
478 |
|
|
{ \
|
479 |
|
|
int i; \
|
480 |
|
|
for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \
|
481 |
|
|
__u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]); \
|
482 |
|
|
val &= 0xffff0000; \
|
483 |
|
|
val |= ((value) & 0xffff); \
|
484 |
|
|
(script)[A_##symbol##_used[i]] = bS_to_host(val); \
|
485 |
|
|
dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
|
486 |
|
|
DEBUG((" script, patching short field %s at %d to 0x%x\n", \
|
487 |
|
|
#symbol, A_##symbol##_used[i], val)); \
|
488 |
|
|
} \
|
489 |
|
|
}
|
490 |
|
|
|
491 |
|
|
#endif
|
492 |
|
|
|
493 |
|
|
#ifdef CONFIG_53C700_MEM_MAPPED
|
494 |
|
|
static inline __u8
|
495 |
|
|
NCR_700_readb(struct Scsi_Host *host, __u32 reg)
|
496 |
|
|
{
|
497 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
498 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
499 |
|
|
|
500 |
|
|
return readb(host->base + (reg^bE));
|
501 |
|
|
}
|
502 |
|
|
|
503 |
|
|
static inline __u32
|
504 |
|
|
NCR_700_readl(struct Scsi_Host *host, __u32 reg)
|
505 |
|
|
{
|
506 |
|
|
__u32 value = __raw_readl(host->base + reg);
|
507 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
508 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
509 |
|
|
#if 1
|
510 |
|
|
/* sanity check the register */
|
511 |
|
|
if((reg & 0x3) != 0)
|
512 |
|
|
BUG();
|
513 |
|
|
#endif
|
514 |
|
|
|
515 |
|
|
return bS_to_cpu(value);
|
516 |
|
|
}
|
517 |
|
|
|
518 |
|
|
static inline void
|
519 |
|
|
NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
|
520 |
|
|
{
|
521 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
522 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
523 |
|
|
|
524 |
|
|
writeb(value, host->base + (reg^bE));
|
525 |
|
|
}
|
526 |
|
|
|
527 |
|
|
static inline void
|
528 |
|
|
NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
|
529 |
|
|
{
|
530 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
531 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
532 |
|
|
|
533 |
|
|
#if 1
|
534 |
|
|
/* sanity check the register */
|
535 |
|
|
if((reg & 0x3) != 0)
|
536 |
|
|
BUG();
|
537 |
|
|
#endif
|
538 |
|
|
|
539 |
|
|
__raw_writel(bS_to_host(value), host->base + reg);
|
540 |
|
|
}
|
541 |
|
|
#elif defined(CONFIG_53C700_IO_MAPPED)
|
542 |
|
|
static inline __u8
|
543 |
|
|
NCR_700_readb(struct Scsi_Host *host, __u32 reg)
|
544 |
|
|
{
|
545 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
546 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
547 |
|
|
|
548 |
|
|
return inb(host->base + (reg^bE));
|
549 |
|
|
}
|
550 |
|
|
|
551 |
|
|
static inline __u32
|
552 |
|
|
NCR_700_readl(struct Scsi_Host *host, __u32 reg)
|
553 |
|
|
{
|
554 |
|
|
__u32 value = inl(host->base + reg);
|
555 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
556 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
557 |
|
|
|
558 |
|
|
#if 1
|
559 |
|
|
/* sanity check the register */
|
560 |
|
|
if((reg & 0x3) != 0)
|
561 |
|
|
BUG();
|
562 |
|
|
#endif
|
563 |
|
|
|
564 |
|
|
return bS_to_cpu(value);
|
565 |
|
|
}
|
566 |
|
|
|
567 |
|
|
static inline void
|
568 |
|
|
NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
|
569 |
|
|
{
|
570 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
571 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
572 |
|
|
|
573 |
|
|
outb(value, host->base + (reg^bE));
|
574 |
|
|
}
|
575 |
|
|
|
576 |
|
|
static inline void
|
577 |
|
|
NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
|
578 |
|
|
{
|
579 |
|
|
const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
|
580 |
|
|
= (struct NCR_700_Host_Parameters *)host->hostdata[0];
|
581 |
|
|
|
582 |
|
|
#if 1
|
583 |
|
|
/* sanity check the register */
|
584 |
|
|
if((reg & 0x3) != 0)
|
585 |
|
|
BUG();
|
586 |
|
|
#endif
|
587 |
|
|
|
588 |
|
|
outl(bS_to_host(value), host->base + reg);
|
589 |
|
|
}
|
590 |
|
|
#endif
|