2 * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
3 * of PCI-SCSI IO processors.
5 * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>
7 * This driver is derived from the Linux sym53c8xx driver.
8 * Copyright (C) 1998-2000 Gerard Roudier
10 * The sym53c8xx driver is derived from the ncr53c8xx driver that had been
11 * a port of the FreeBSD ncr driver to Linux-1.2.13.
13 * The original ncr driver has been written for 386bsd and FreeBSD by
14 * Wolfgang Stanglmeier <wolf@cologne.de>
15 * Stefan Esser <se@mi.Uni-Koeln.de>
16 * Copyright (C) 1994 Wolfgang Stanglmeier
18 * Other major contributions:
20 * NVRAM detection and reading.
21 * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
23 *-----------------------------------------------------------------------------
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation; either version 2 of the License, or
28 * (at your option) any later version.
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 #include <dev/sym/sym_glue.h>
47 * Macros used for all firmwares.
49 #define SYM_GEN_A(s, label) ((short) offsetof(s, label)),
50 #define SYM_GEN_B(s, label) ((short) offsetof(s, label)),
51 #define SYM_GEN_Z(s, label) ((short) offsetof(s, label)),
52 #define PADDR_A(label) SYM_GEN_PADDR_A(struct SYM_FWA_SCR, label)
53 #define PADDR_B(label) SYM_GEN_PADDR_B(struct SYM_FWB_SCR, label)
56 #if SYM_CONF_GENERIC_SUPPORT
58 * Allocate firmware #1 script area.
60 #define SYM_FWA_SCR sym_fw1a_scr
61 #define SYM_FWB_SCR sym_fw1b_scr
62 #define SYM_FWZ_SCR sym_fw1z_scr
64 #include <dev/sym/sym_fw1.h>
68 static struct sym_fwa_ofs sym_fw1a_ofs
= {
69 SYM_GEN_FW_A(struct SYM_FWA_SCR
)
71 static struct sym_fwb_ofs sym_fw1b_ofs
= {
72 SYM_GEN_FW_B(struct SYM_FWB_SCR
)
73 #ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
74 SYM_GEN_B(struct SYM_FWB_SCR
, data_io
)
77 static struct sym_fwz_ofs sym_fw1z_ofs
= {
78 SYM_GEN_FW_Z(struct SYM_FWZ_SCR
)
83 #endif /* SYM_CONF_GENERIC_SUPPORT */
86 * Allocate firmware #2 script area.
88 #define SYM_FWA_SCR sym_fw2a_scr
89 #define SYM_FWB_SCR sym_fw2b_scr
90 #define SYM_FWZ_SCR sym_fw2z_scr
92 #include <dev/sym/sym_fw2.h>
96 static struct sym_fwa_ofs sym_fw2a_ofs
= {
97 SYM_GEN_FW_A(struct SYM_FWA_SCR
)
99 static struct sym_fwb_ofs sym_fw2b_ofs
= {
100 SYM_GEN_FW_B(struct SYM_FWB_SCR
)
101 #ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
102 SYM_GEN_B(struct SYM_FWB_SCR
, data_io
)
104 SYM_GEN_B(struct SYM_FWB_SCR
, start64
)
105 SYM_GEN_B(struct SYM_FWB_SCR
, pm_handle
)
107 static struct sym_fwz_ofs sym_fw2z_ofs
= {
108 SYM_GEN_FW_Z(struct SYM_FWZ_SCR
)
120 #if SYM_CONF_GENERIC_SUPPORT
122 * Patch routine for firmware #1.
125 sym_fw1_patch(struct sym_hcb
*np
)
127 struct sym_fw1a_scr
*scripta0
;
128 struct sym_fw1b_scr
*scriptb0
;
130 scripta0
= (struct sym_fw1a_scr
*) np
->scripta0
;
131 scriptb0
= (struct sym_fw1b_scr
*) np
->scriptb0
;
134 * Remove LED support if not needed.
136 if (!(np
->features
& FE_LED0
)) {
137 scripta0
->idle
[0] = cpu_to_scr(SCR_NO_OP
);
138 scripta0
->reselected
[0] = cpu_to_scr(SCR_NO_OP
);
139 scripta0
->start
[0] = cpu_to_scr(SCR_NO_OP
);
142 #ifdef SYM_CONF_IARB_SUPPORT
144 * If user does not want to use IMMEDIATE ARBITRATION
145 * when we are reselected while attempting to arbitrate,
146 * patch the SCRIPTS accordingly with a SCRIPT NO_OP.
148 if (!SYM_CONF_SET_IARB_ON_ARB_LOST
)
149 scripta0
->ungetjob
[0] = cpu_to_scr(SCR_NO_OP
);
152 * Patch some data in SCRIPTS.
153 * - start and done queue initial bus address.
154 * - target bus address table bus address.
156 scriptb0
->startpos
[0] = cpu_to_scr(np
->squeue_ba
);
157 scriptb0
->done_pos
[0] = cpu_to_scr(np
->dqueue_ba
);
158 scriptb0
->targtbl
[0] = cpu_to_scr(np
->targtbl_ba
);
160 #endif /* SYM_CONF_GENERIC_SUPPORT */
163 * Patch routine for firmware #2.
166 sym_fw2_patch(struct sym_hcb
*np
)
168 struct sym_fw2a_scr
*scripta0
;
169 struct sym_fw2b_scr
*scriptb0
;
171 scripta0
= (struct sym_fw2a_scr
*) np
->scripta0
;
172 scriptb0
= (struct sym_fw2b_scr
*) np
->scriptb0
;
175 * Remove LED support if not needed.
177 if (!(np
->features
& FE_LED0
)) {
178 scripta0
->idle
[0] = cpu_to_scr(SCR_NO_OP
);
179 scripta0
->reselected
[0] = cpu_to_scr(SCR_NO_OP
);
180 scripta0
->start
[0] = cpu_to_scr(SCR_NO_OP
);
183 #if SYM_CONF_DMA_ADDRESSING_MODE == 2
185 * Remove useless 64 bit DMA specific SCRIPTS,
186 * when this feature is not available.
189 scripta0
->is_dmap_dirty
[0] = cpu_to_scr(SCR_NO_OP
);
190 scripta0
->is_dmap_dirty
[1] = 0;
191 scripta0
->is_dmap_dirty
[2] = cpu_to_scr(SCR_NO_OP
);
192 scripta0
->is_dmap_dirty
[3] = 0;
196 #ifdef SYM_CONF_IARB_SUPPORT
198 * If user does not want to use IMMEDIATE ARBITRATION
199 * when we are reselected while attempting to arbitrate,
200 * patch the SCRIPTS accordingly with a SCRIPT NO_OP.
202 if (!SYM_CONF_SET_IARB_ON_ARB_LOST
)
203 scripta0
->ungetjob
[0] = cpu_to_scr(SCR_NO_OP
);
206 * Patch some variable in SCRIPTS.
207 * - start and done queue initial bus address.
208 * - target bus address table bus address.
210 scriptb0
->startpos
[0] = cpu_to_scr(np
->squeue_ba
);
211 scriptb0
->done_pos
[0] = cpu_to_scr(np
->dqueue_ba
);
212 scriptb0
->targtbl
[0] = cpu_to_scr(np
->targtbl_ba
);
215 * Remove the load of SCNTL4 on reselection if not a C10.
217 if (!(np
->features
& FE_C10
)) {
218 scripta0
->resel_scntl4
[0] = cpu_to_scr(SCR_NO_OP
);
219 scripta0
->resel_scntl4
[1] = cpu_to_scr(0);
223 * Remove a couple of work-arounds specific to C1010 if
224 * they are not desirable. See `sym_fw2.h' for more details.
226 if (!(np
->device_id
== PCI_DEVICE_ID_LSI_53C1010_66
&&
227 np
->revision_id
< 0x1 &&
228 np
->pciclk_khz
< 60000)) {
229 scripta0
->datao_phase
[0] = cpu_to_scr(SCR_NO_OP
);
230 scripta0
->datao_phase
[1] = cpu_to_scr(0);
232 if (!(np
->device_id
== PCI_DEVICE_ID_LSI_53C1010_33
&&
233 /* np->revision_id < 0xff */ 1)) {
234 scripta0
->sel_done
[0] = cpu_to_scr(SCR_NO_OP
);
235 scripta0
->sel_done
[1] = cpu_to_scr(0);
239 * Patch some other variables in SCRIPTS.
240 * These ones are loaded by the SCRIPTS processor.
242 scriptb0
->pm0_data_addr
[0] =
243 cpu_to_scr(np
->scripta_ba
+
244 offsetof(struct sym_fw2a_scr
, pm0_data
));
245 scriptb0
->pm1_data_addr
[0] =
246 cpu_to_scr(np
->scripta_ba
+
247 offsetof(struct sym_fw2a_scr
, pm1_data
));
251 * Fill the data area in scripts.
252 * To be done for all firmwares.
255 sym_fw_fill_data (u32
*in
, u32
*out
)
259 for (i
= 0; i
< SYM_CONF_MAX_SG
; i
++) {
260 *in
++ = SCR_CHMOV_TBL
^ SCR_DATA_IN
;
261 *in
++ = offsetof (struct sym_dsb
, data
[i
]);
262 *out
++ = SCR_CHMOV_TBL
^ SCR_DATA_OUT
;
263 *out
++ = offsetof (struct sym_dsb
, data
[i
]);
268 * Setup useful script bus addresses.
269 * To be done for all firmwares.
272 sym_fw_setup_bus_addresses(struct sym_hcb
*np
, struct sym_fw
*fw
)
279 * Build the bus address table for script A
280 * from the script A offset table.
282 po
= (u_short
*) fw
->a_ofs
;
283 pa
= (u32
*) &np
->fwa_bas
;
284 for (i
= 0 ; i
< sizeof(np
->fwa_bas
)/sizeof(u32
) ; i
++)
285 pa
[i
] = np
->scripta_ba
+ po
[i
];
290 po
= (u_short
*) fw
->b_ofs
;
291 pa
= (u32
*) &np
->fwb_bas
;
292 for (i
= 0 ; i
< sizeof(np
->fwb_bas
)/sizeof(u32
) ; i
++)
293 pa
[i
] = np
->scriptb_ba
+ po
[i
];
298 po
= (u_short
*) fw
->z_ofs
;
299 pa
= (u32
*) &np
->fwz_bas
;
300 for (i
= 0 ; i
< sizeof(np
->fwz_bas
)/sizeof(u32
) ; i
++)
301 pa
[i
] = np
->scriptz_ba
+ po
[i
];
304 #if SYM_CONF_GENERIC_SUPPORT
306 * Setup routine for firmware #1.
309 sym_fw1_setup(struct sym_hcb
*np
, struct sym_fw
*fw
)
311 struct sym_fw1a_scr
*scripta0
;
312 struct sym_fw1b_scr
*scriptb0
;
314 scripta0
= (struct sym_fw1a_scr
*) np
->scripta0
;
315 scriptb0
= (struct sym_fw1b_scr
*) np
->scriptb0
;
318 * Fill variable parts in scripts.
320 sym_fw_fill_data(scripta0
->data_in
, scripta0
->data_out
);
323 * Setup bus addresses used from the C code..
325 sym_fw_setup_bus_addresses(np
, fw
);
327 #endif /* SYM_CONF_GENERIC_SUPPORT */
330 * Setup routine for firmware #2.
333 sym_fw2_setup(struct sym_hcb
*np
, struct sym_fw
*fw
)
335 struct sym_fw2a_scr
*scripta0
;
336 struct sym_fw2b_scr
*scriptb0
;
338 scripta0
= (struct sym_fw2a_scr
*) np
->scripta0
;
339 scriptb0
= (struct sym_fw2b_scr
*) np
->scriptb0
;
342 * Fill variable parts in scripts.
344 sym_fw_fill_data(scripta0
->data_in
, scripta0
->data_out
);
347 * Setup bus addresses used from the C code..
349 sym_fw_setup_bus_addresses(np
, fw
);
353 * Allocate firmware descriptors.
355 #if SYM_CONF_GENERIC_SUPPORT
356 static struct sym_fw sym_fw1
= SYM_FW_ENTRY(sym_fw1
, "NCR-generic");
357 #endif /* SYM_CONF_GENERIC_SUPPORT */
358 static struct sym_fw sym_fw2
= SYM_FW_ENTRY(sym_fw2
, "LOAD/STORE-based");
361 * Find the most appropriate firmware for a chip.
364 sym_find_firmware(struct sym_chip
*chip
)
366 if (chip
->features
& FE_LDSTR
)
368 #if SYM_CONF_GENERIC_SUPPORT
369 else if (!(chip
->features
& (FE_PFEN
|FE_NOPM
|FE_DAC
)))
377 * Bind a script to physical addresses.
379 void sym_fw_bind_script(struct sym_hcb
*np
, u32
*start
, int len
)
381 u32 opcode
, new, old
, tmp1
, tmp2
;
393 * If we forget to change the length
394 * in scripts, a field will be
395 * padded with 0. This is an illegal
399 printf ("%s: ERROR0 IN SCRIPT at %d.\n",
400 sym_name(np
), (int) (cur
-start
));
406 * We use the bogus value 0xf00ff00f ;-)
407 * to reserve data area in SCRIPTS.
409 if (opcode
== SCR_DATA_ZERO
) {
414 if (DEBUG_FLAGS
& DEBUG_SCRIPT
)
415 printf ("%d: <%x>\n", (int) (cur
-start
),
419 * We don't have to decode ALL commands
421 switch (opcode
>> 28) {
424 * LOAD / STORE DSA relative, don't relocate.
430 * LOAD / STORE absolute.
436 * COPY has TWO arguments.
441 if ((tmp1
^ tmp2
) & 3) {
442 printf ("%s: ERROR1 IN SCRIPT at %d.\n",
443 sym_name(np
), (int) (cur
-start
));
446 * If PREFETCH feature not enabled, remove
447 * the NO FLUSH bit if present.
449 if ((opcode
& SCR_NO_FLUSH
) &&
450 !(np
->features
& FE_PFEN
)) {
451 opcode
= (opcode
& ~SCR_NO_FLUSH
);
456 * MOVE/CHMOV (absolute address)
458 if (!(np
->features
& FE_WIDE
))
459 opcode
= (opcode
| OPC_MOVE
);
464 * MOVE/CHMOV (table indirect)
466 if (!(np
->features
& FE_WIDE
))
467 opcode
= (opcode
| OPC_MOVE
);
470 #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
473 * MOVE/CHMOV in target role (absolute address)
475 opcode
&= ~0x20000000;
476 if (!(np
->features
& FE_WIDE
))
477 opcode
= (opcode
& ~OPC_TCHMOVE
);
482 * MOVE/CHMOV in target role (table indirect)
484 opcode
&= ~0x20000000;
485 if (!(np
->features
& FE_WIDE
))
486 opcode
= (opcode
& ~OPC_TCHMOVE
);
493 * don't relocate if relative :-)
495 if (opcode
& 0x00800000)
497 else if ((opcode
& 0xf8400000) == 0x80400000)/*JUMP64*/
514 * Scriptify:) the opcode.
516 *cur
++ = cpu_to_scr(opcode
);
519 * If no relocation, assume 1 argument
520 * and just scriptize:) it.
523 *cur
= cpu_to_scr(*cur
);
529 * Otherwise performs all needed relocations.
534 switch (old
& RELOC_MASK
) {
536 new = (old
& ~RELOC_MASK
) + np
->mmio_ba
;
539 new = (old
& ~RELOC_MASK
) + np
->scripta_ba
;
542 new = (old
& ~RELOC_MASK
) + np
->scriptb_ba
;
545 new = (old
& ~RELOC_MASK
) + np
->hcb_ba
;
549 * Don't relocate a 0 address.
550 * They are mostly used for patched or
551 * script self-modified areas.
560 panic("sym_fw_bind_script: "
561 "weird relocation %x\n", old
);
565 *cur
++ = cpu_to_scr(new);