1 /*
2  * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
3  * of PCI-SCSI IO processors.
4  *
5  * Copyright (C) 1999-2001  Gerard Roudier <groudier@free.fr>
6  *
7  * This driver is derived from the Linux sym53c8xx driver.
8  * Copyright (C) 1998-2000  Gerard Roudier
9  *
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.
12  *
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
17  *
18  * Other major contributions:
19  *
20  * NVRAM detection and reading.
21  * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
22  *
23  *-----------------------------------------------------------------------------
24  *
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.
29  *
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.
34  *
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
38  */
39 
40 #include "sym_glue.h"
41 
42 /*
43  *  Macros used for all firmwares.
44  */
45 #define	SYM_GEN_A(s, label)	((short) offsetof(s, label)),
46 #define	SYM_GEN_B(s, label)	((short) offsetof(s, label)),
47 #define	SYM_GEN_Z(s, label)	((short) offsetof(s, label)),
48 #define	PADDR_A(label)		SYM_GEN_PADDR_A(struct SYM_FWA_SCR, label)
49 #define	PADDR_B(label)		SYM_GEN_PADDR_B(struct SYM_FWB_SCR, label)
50 
51 
52 #if	SYM_CONF_GENERIC_SUPPORT
53 /*
54  *  Allocate firmware #1 script area.
55  */
56 #define	SYM_FWA_SCR		sym_fw1a_scr
57 #define	SYM_FWB_SCR		sym_fw1b_scr
58 #define	SYM_FWZ_SCR		sym_fw1z_scr
59 #include "sym_fw1.h"
60 static struct sym_fwa_ofs sym_fw1a_ofs = {
61 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
62 };
63 static struct sym_fwb_ofs sym_fw1b_ofs = {
64 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
65 };
66 static struct sym_fwz_ofs sym_fw1z_ofs = {
67 	SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
68 };
69 #undef	SYM_FWA_SCR
70 #undef	SYM_FWB_SCR
71 #undef	SYM_FWZ_SCR
72 #endif	/* SYM_CONF_GENERIC_SUPPORT */
73 
74 /*
75  *  Allocate firmware #2 script area.
76  */
77 #define	SYM_FWA_SCR		sym_fw2a_scr
78 #define	SYM_FWB_SCR		sym_fw2b_scr
79 #define	SYM_FWZ_SCR		sym_fw2z_scr
80 #include "sym_fw2.h"
81 static struct sym_fwa_ofs sym_fw2a_ofs = {
82 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
83 };
84 static struct sym_fwb_ofs sym_fw2b_ofs = {
85 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
86 	SYM_GEN_B(struct SYM_FWB_SCR, start64)
87 	SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
88 };
89 static struct sym_fwz_ofs sym_fw2z_ofs = {
90 	SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
91 };
92 #undef	SYM_FWA_SCR
93 #undef	SYM_FWB_SCR
94 #undef	SYM_FWZ_SCR
95 
96 #undef	SYM_GEN_A
97 #undef	SYM_GEN_B
98 #undef	SYM_GEN_Z
99 #undef	PADDR_A
100 #undef	PADDR_B
101 
102 #if	SYM_CONF_GENERIC_SUPPORT
103 /*
104  *  Patch routine for firmware #1.
105  */
106 static void
107 sym_fw1_patch(struct Scsi_Host *shost)
108 {
109 	struct sym_hcb *np = sym_get_hcb(shost);
110 	struct sym_fw1a_scr *scripta0;
111 	struct sym_fw1b_scr *scriptb0;
112 
113 	scripta0 = (struct sym_fw1a_scr *) np->scripta0;
114 	scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
115 
116 	/*
117 	 *  Remove LED support if not needed.
118 	 */
119 	if (!(np->features & FE_LED0)) {
120 		scripta0->idle[0]	= cpu_to_scr(SCR_NO_OP);
121 		scripta0->reselected[0]	= cpu_to_scr(SCR_NO_OP);
122 		scripta0->start[0]	= cpu_to_scr(SCR_NO_OP);
123 	}
124 
125 #ifdef SYM_CONF_IARB_SUPPORT
126 	/*
127 	 *    If user does not want to use IMMEDIATE ARBITRATION
128 	 *    when we are reselected while attempting to arbitrate,
129 	 *    patch the SCRIPTS accordingly with a SCRIPT NO_OP.
130 	 */
131 	if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
132 		scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
133 #endif
134 	/*
135 	 *  Patch some data in SCRIPTS.
136 	 *  - start and done queue initial bus address.
137 	 *  - target bus address table bus address.
138 	 */
139 	scriptb0->startpos[0]	= cpu_to_scr(np->squeue_ba);
140 	scriptb0->done_pos[0]	= cpu_to_scr(np->dqueue_ba);
141 	scriptb0->targtbl[0]	= cpu_to_scr(np->targtbl_ba);
142 }
143 #endif	/* SYM_CONF_GENERIC_SUPPORT */
144 
145 /*
146  *  Patch routine for firmware #2.
147  */
148 static void
149 sym_fw2_patch(struct Scsi_Host *shost)
150 {
151 	struct sym_data *sym_data = shost_priv(shost);
152 	struct pci_dev *pdev = sym_data->pdev;
153 	struct sym_hcb *np = sym_data->ncb;
154 	struct sym_fw2a_scr *scripta0;
155 	struct sym_fw2b_scr *scriptb0;
156 
157 	scripta0 = (struct sym_fw2a_scr *) np->scripta0;
158 	scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
159 
160 	/*
161 	 *  Remove LED support if not needed.
162 	 */
163 	if (!(np->features & FE_LED0)) {
164 		scripta0->idle[0]	= cpu_to_scr(SCR_NO_OP);
165 		scripta0->reselected[0]	= cpu_to_scr(SCR_NO_OP);
166 		scripta0->start[0]	= cpu_to_scr(SCR_NO_OP);
167 	}
168 
169 #if   SYM_CONF_DMA_ADDRESSING_MODE == 2
170 	/*
171 	 *  Remove useless 64 bit DMA specific SCRIPTS,
172 	 *  when this feature is not available.
173 	 */
174 	if (!use_dac(np)) {
175 		scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP);
176 		scripta0->is_dmap_dirty[1] = 0;
177 		scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP);
178 		scripta0->is_dmap_dirty[3] = 0;
179 	}
180 #endif
181 
182 #ifdef SYM_CONF_IARB_SUPPORT
183 	/*
184 	 *    If user does not want to use IMMEDIATE ARBITRATION
185 	 *    when we are reselected while attempting to arbitrate,
186 	 *    patch the SCRIPTS accordingly with a SCRIPT NO_OP.
187 	 */
188 	if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
189 		scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
190 #endif
191 	/*
192 	 *  Patch some variable in SCRIPTS.
193 	 *  - start and done queue initial bus address.
194 	 *  - target bus address table bus address.
195 	 */
196 	scriptb0->startpos[0]	= cpu_to_scr(np->squeue_ba);
197 	scriptb0->done_pos[0]	= cpu_to_scr(np->dqueue_ba);
198 	scriptb0->targtbl[0]	= cpu_to_scr(np->targtbl_ba);
199 
200 	/*
201 	 *  Remove the load of SCNTL4 on reselection if not a C10.
202 	 */
203 	if (!(np->features & FE_C10)) {
204 		scripta0->resel_scntl4[0] = cpu_to_scr(SCR_NO_OP);
205 		scripta0->resel_scntl4[1] = cpu_to_scr(0);
206 	}
207 
208 	/*
209 	 *  Remove a couple of work-arounds specific to C1010 if
210 	 *  they are not desirable. See `sym_fw2.h' for more details.
211 	 */
212 	if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_66 &&
213 	      pdev->revision < 0x1 &&
214 	      np->pciclk_khz < 60000)) {
215 		scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
216 		scripta0->datao_phase[1] = cpu_to_scr(0);
217 	}
218 	if (!(pdev->device == PCI_DEVICE_ID_LSI_53C1010_33 /* &&
219 	      pdev->revision < 0xff */)) {
220 		scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
221 		scripta0->sel_done[1] = cpu_to_scr(0);
222 	}
223 
224 	/*
225 	 *  Patch some other variables in SCRIPTS.
226 	 *  These ones are loaded by the SCRIPTS processor.
227 	 */
228 	scriptb0->pm0_data_addr[0] =
229 		cpu_to_scr(np->scripta_ba +
230 			   offsetof(struct sym_fw2a_scr, pm0_data));
231 	scriptb0->pm1_data_addr[0] =
232 		cpu_to_scr(np->scripta_ba +
233 			   offsetof(struct sym_fw2a_scr, pm1_data));
234 }
235 
236 /*
237  *  Fill the data area in scripts.
238  *  To be done for all firmwares.
239  */
240 static void
241 sym_fw_fill_data (u32 *in, u32 *out)
242 {
243 	int	i;
244 
245 	for (i = 0; i < SYM_CONF_MAX_SG; i++) {
246 		*in++  = SCR_CHMOV_TBL ^ SCR_DATA_IN;
247 		*in++  = offsetof (struct sym_dsb, data[i]);
248 		*out++ = SCR_CHMOV_TBL ^ SCR_DATA_OUT;
249 		*out++ = offsetof (struct sym_dsb, data[i]);
250 	}
251 }
252 
253 /*
254  *  Setup useful script bus addresses.
255  *  To be done for all firmwares.
256  */
257 static void
258 sym_fw_setup_bus_addresses(struct sym_hcb *np, struct sym_fw *fw)
259 {
260 	u32 *pa;
261 	u_short *po;
262 	int i;
263 
264 	/*
265 	 *  Build the bus address table for script A
266 	 *  from the script A offset table.
267 	 */
268 	po = (u_short *) fw->a_ofs;
269 	pa = (u32 *) &np->fwa_bas;
270 	for (i = 0 ; i < sizeof(np->fwa_bas)/sizeof(u32) ; i++)
271 		pa[i] = np->scripta_ba + po[i];
272 
273 	/*
274 	 *  Same for script B.
275 	 */
276 	po = (u_short *) fw->b_ofs;
277 	pa = (u32 *) &np->fwb_bas;
278 	for (i = 0 ; i < sizeof(np->fwb_bas)/sizeof(u32) ; i++)
279 		pa[i] = np->scriptb_ba + po[i];
280 
281 	/*
282 	 *  Same for script Z.
283 	 */
284 	po = (u_short *) fw->z_ofs;
285 	pa = (u32 *) &np->fwz_bas;
286 	for (i = 0 ; i < sizeof(np->fwz_bas)/sizeof(u32) ; i++)
287 		pa[i] = np->scriptz_ba + po[i];
288 }
289 
290 #if	SYM_CONF_GENERIC_SUPPORT
291 /*
292  *  Setup routine for firmware #1.
293  */
294 static void
295 sym_fw1_setup(struct sym_hcb *np, struct sym_fw *fw)
296 {
297 	struct sym_fw1a_scr *scripta0;
298 	struct sym_fw1b_scr *scriptb0;
299 
300 	scripta0 = (struct sym_fw1a_scr *) np->scripta0;
301 	scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
302 
303 	/*
304 	 *  Fill variable parts in scripts.
305 	 */
306 	sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
307 
308 	/*
309 	 *  Setup bus addresses used from the C code..
310 	 */
311 	sym_fw_setup_bus_addresses(np, fw);
312 }
313 #endif	/* SYM_CONF_GENERIC_SUPPORT */
314 
315 /*
316  *  Setup routine for firmware #2.
317  */
318 static void
319 sym_fw2_setup(struct sym_hcb *np, struct sym_fw *fw)
320 {
321 	struct sym_fw2a_scr *scripta0;
322 	struct sym_fw2b_scr *scriptb0;
323 
324 	scripta0 = (struct sym_fw2a_scr *) np->scripta0;
325 	scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
326 
327 	/*
328 	 *  Fill variable parts in scripts.
329 	 */
330 	sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
331 
332 	/*
333 	 *  Setup bus addresses used from the C code..
334 	 */
335 	sym_fw_setup_bus_addresses(np, fw);
336 }
337 
338 /*
339  *  Allocate firmware descriptors.
340  */
341 #if	SYM_CONF_GENERIC_SUPPORT
342 static struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic");
343 #endif	/* SYM_CONF_GENERIC_SUPPORT */
344 static struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
345 
346 /*
347  *  Find the most appropriate firmware for a chip.
348  */
349 struct sym_fw *
350 sym_find_firmware(struct sym_chip *chip)
351 {
352 	if (chip->features & FE_LDSTR)
353 		return &sym_fw2;
354 #if	SYM_CONF_GENERIC_SUPPORT
355 	else if (!(chip->features & (FE_PFEN|FE_NOPM|FE_DAC)))
356 		return &sym_fw1;
357 #endif
358 	else
359 		return NULL;
360 }
361 
362 /*
363  *  Bind a script to physical addresses.
364  */
365 void sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len)
366 {
367 	u32 opcode, new, old, tmp1, tmp2;
368 	u32 *end, *cur;
369 	int relocs;
370 
371 	cur = start;
372 	end = start + len/4;
373 
374 	while (cur < end) {
375 
376 		opcode = *cur;
377 
378 		/*
379 		 *  If we forget to change the length
380 		 *  in scripts, a field will be
381 		 *  padded with 0. This is an illegal
382 		 *  command.
383 		 */
384 		if (opcode == 0) {
385 			printf ("%s: ERROR0 IN SCRIPT at %d.\n",
386 				sym_name(np), (int) (cur-start));
387 			++cur;
388 			continue;
389 		};
390 
391 		/*
392 		 *  We use the bogus value 0xf00ff00f ;-)
393 		 *  to reserve data area in SCRIPTS.
394 		 */
395 		if (opcode == SCR_DATA_ZERO) {
396 			*cur++ = 0;
397 			continue;
398 		}
399 
400 		if (DEBUG_FLAGS & DEBUG_SCRIPT)
401 			printf ("%d:  <%x>\n", (int) (cur-start),
402 				(unsigned)opcode);
403 
404 		/*
405 		 *  We don't have to decode ALL commands
406 		 */
407 		switch (opcode >> 28) {
408 		case 0xf:
409 			/*
410 			 *  LOAD / STORE DSA relative, don't relocate.
411 			 */
412 			relocs = 0;
413 			break;
414 		case 0xe:
415 			/*
416 			 *  LOAD / STORE absolute.
417 			 */
418 			relocs = 1;
419 			break;
420 		case 0xc:
421 			/*
422 			 *  COPY has TWO arguments.
423 			 */
424 			relocs = 2;
425 			tmp1 = cur[1];
426 			tmp2 = cur[2];
427 			if ((tmp1 ^ tmp2) & 3) {
428 				printf ("%s: ERROR1 IN SCRIPT at %d.\n",
429 					sym_name(np), (int) (cur-start));
430 			}
431 			/*
432 			 *  If PREFETCH feature not enabled, remove
433 			 *  the NO FLUSH bit if present.
434 			 */
435 			if ((opcode & SCR_NO_FLUSH) &&
436 			    !(np->features & FE_PFEN)) {
437 				opcode = (opcode & ~SCR_NO_FLUSH);
438 			}
439 			break;
440 		case 0x0:
441 			/*
442 			 *  MOVE/CHMOV (absolute address)
443 			 */
444 			if (!(np->features & FE_WIDE))
445 				opcode = (opcode | OPC_MOVE);
446 			relocs = 1;
447 			break;
448 		case 0x1:
449 			/*
450 			 *  MOVE/CHMOV (table indirect)
451 			 */
452 			if (!(np->features & FE_WIDE))
453 				opcode = (opcode | OPC_MOVE);
454 			relocs = 0;
455 			break;
456 #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
457 		case 0x2:
458 			/*
459 			 *  MOVE/CHMOV in target role (absolute address)
460 			 */
461 			opcode &= ~0x20000000;
462 			if (!(np->features & FE_WIDE))
463 				opcode = (opcode & ~OPC_TCHMOVE);
464 			relocs = 1;
465 			break;
466 		case 0x3:
467 			/*
468 			 *  MOVE/CHMOV in target role (table indirect)
469 			 */
470 			opcode &= ~0x20000000;
471 			if (!(np->features & FE_WIDE))
472 				opcode = (opcode & ~OPC_TCHMOVE);
473 			relocs = 0;
474 			break;
475 #endif
476 		case 0x8:
477 			/*
478 			 *  JUMP / CALL
479 			 *  don't relocate if relative :-)
480 			 */
481 			if (opcode & 0x00800000)
482 				relocs = 0;
483 			else if ((opcode & 0xf8400000) == 0x80400000)/*JUMP64*/
484 				relocs = 2;
485 			else
486 				relocs = 1;
487 			break;
488 		case 0x4:
489 		case 0x5:
490 		case 0x6:
491 		case 0x7:
492 			relocs = 1;
493 			break;
494 		default:
495 			relocs = 0;
496 			break;
497 		};
498 
499 		/*
500 		 *  Scriptify:) the opcode.
501 		 */
502 		*cur++ = cpu_to_scr(opcode);
503 
504 		/*
505 		 *  If no relocation, assume 1 argument
506 		 *  and just scriptize:) it.
507 		 */
508 		if (!relocs) {
509 			*cur = cpu_to_scr(*cur);
510 			++cur;
511 			continue;
512 		}
513 
514 		/*
515 		 *  Otherwise performs all needed relocations.
516 		 */
517 		while (relocs--) {
518 			old = *cur;
519 
520 			switch (old & RELOC_MASK) {
521 			case RELOC_REGISTER:
522 				new = (old & ~RELOC_MASK) + np->mmio_ba;
523 				break;
524 			case RELOC_LABEL_A:
525 				new = (old & ~RELOC_MASK) + np->scripta_ba;
526 				break;
527 			case RELOC_LABEL_B:
528 				new = (old & ~RELOC_MASK) + np->scriptb_ba;
529 				break;
530 			case RELOC_SOFTC:
531 				new = (old & ~RELOC_MASK) + np->hcb_ba;
532 				break;
533 			case 0:
534 				/*
535 				 *  Don't relocate a 0 address.
536 				 *  They are mostly used for patched or
537 				 *  script self-modified areas.
538 				 */
539 				if (old == 0) {
540 					new = old;
541 					break;
542 				}
543 				/* fall through */
544 			default:
545 				new = 0;
546 				panic("sym_fw_bind_script: "
547 				      "weird relocation %x\n", old);
548 				break;
549 			}
550 
551 			*cur++ = cpu_to_scr(new);
552 		}
553 	};
554 }
555