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  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  * 1. Redistributions of source code must retain the above copyright
29  *    notice, this list of conditions and the following disclaimer.
30  * 2. The name of the author may not be used to endorse or promote products
31  *    derived from this software without specific prior written permission.
32  *
33  * Where this Software is combined with software released under the terms of
34  * the GNU Public License ("GPL") and the terms of the GPL would require the
35  * combined work to also be released under the terms of the GPL, the terms
36  * and conditions of this License will apply in addition to those of the
37  * GPL with the exception of any terms or conditions of this License that
38  * conflict with, or are expressly prohibited by, the GPL.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
44  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  */
52 
53 #ifdef __FreeBSD__
54 #include <dev/sym/sym_glue.h>
55 #else
56 #include "sym_glue.h"
57 #endif
58 
59 /*
60  *  Macros used for all firmwares.
61  */
62 #define	SYM_GEN_A(s, label)	((short) offsetof(s, label)),
63 #define	SYM_GEN_B(s, label)	((short) offsetof(s, label)),
64 #define	SYM_GEN_Z(s, label)	((short) offsetof(s, label)),
65 #define	PADDR_A(label)		SYM_GEN_PADDR_A(struct SYM_FWA_SCR, label)
66 #define	PADDR_B(label)		SYM_GEN_PADDR_B(struct SYM_FWB_SCR, label)
67 
68 
69 #if	SYM_CONF_GENERIC_SUPPORT
70 /*
71  *  Allocate firmware #1 script area.
72  */
73 #define	SYM_FWA_SCR		sym_fw1a_scr
74 #define	SYM_FWB_SCR		sym_fw1b_scr
75 #define	SYM_FWZ_SCR		sym_fw1z_scr
76 #ifdef __FreeBSD__
77 #include <dev/sym/sym_fw1.h>
78 #else
79 #include "sym_fw1.h"
80 #endif
81 static struct sym_fwa_ofs sym_fw1a_ofs = {
82 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
83 };
84 static struct sym_fwb_ofs sym_fw1b_ofs = {
85 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
86 #ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
87 	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
88 #endif
89 };
90 static struct sym_fwz_ofs sym_fw1z_ofs = {
91 	SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
92 #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
93 	SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram)
94 #endif
95 };
96 #undef	SYM_FWA_SCR
97 #undef	SYM_FWB_SCR
98 #undef	SYM_FWZ_SCR
99 #endif	/* SYM_CONF_GENERIC_SUPPORT */
100 
101 /*
102  *  Allocate firmware #2 script area.
103  */
104 #define	SYM_FWA_SCR		sym_fw2a_scr
105 #define	SYM_FWB_SCR		sym_fw2b_scr
106 #define	SYM_FWZ_SCR		sym_fw2z_scr
107 #ifdef __FreeBSD__
108 #include <dev/sym/sym_fw2.h>
109 #else
110 #include "sym_fw2.h"
111 #endif
112 static struct sym_fwa_ofs sym_fw2a_ofs = {
113 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
114 };
115 static struct sym_fwb_ofs sym_fw2b_ofs = {
116 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
117 #ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
118 	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
119 #endif
120 	SYM_GEN_B(struct SYM_FWB_SCR, start64)
121 	SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
122 };
123 static struct sym_fwz_ofs sym_fw2z_ofs = {
124 	SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
125 #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
126 	SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram)
127 	SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram64)
128 #endif
129 };
130 #undef	SYM_FWA_SCR
131 #undef	SYM_FWB_SCR
132 #undef	SYM_FWZ_SCR
133 
134 #undef	SYM_GEN_A
135 #undef	SYM_GEN_B
136 #undef	SYM_GEN_Z
137 #undef	PADDR_A
138 #undef	PADDR_B
139 
140 #if	SYM_CONF_GENERIC_SUPPORT
141 /*
142  *  Patch routine for firmware #1.
143  */
144 static void
sym_fw1_patch(hcb_p np)145 sym_fw1_patch(hcb_p np)
146 {
147 	struct sym_fw1a_scr *scripta0;
148 	struct sym_fw1b_scr *scriptb0;
149 #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
150 	struct sym_fw1z_scr *scriptz0 =
151 		(struct sym_fw1z_scr *) np->scriptz0;
152 #endif
153 
154 	scripta0 = (struct sym_fw1a_scr *) np->scripta0;
155 	scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
156 
157 #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
158 	/*
159 	 *  Set up BUS physical address of SCRIPTS that is to
160 	 *  be copied to on-chip RAM by the SCRIPTS processor.
161 	 */
162 	scriptz0->scripta0_ba[0]	= cpu_to_scr(vtobus(scripta0));
163 #endif
164 
165 	/*
166 	 *  Remove LED support if not needed.
167 	 */
168 	if (!(np->features & FE_LED0)) {
169 		scripta0->idle[0]	= cpu_to_scr(SCR_NO_OP);
170 		scripta0->reselected[0]	= cpu_to_scr(SCR_NO_OP);
171 		scripta0->start[0]	= cpu_to_scr(SCR_NO_OP);
172 	}
173 
174 #ifdef SYM_CONF_IARB_SUPPORT
175 	/*
176 	 *    If user does not want to use IMMEDIATE ARBITRATION
177 	 *    when we are reselected while attempting to arbitrate,
178 	 *    patch the SCRIPTS accordingly with a SCRIPT NO_OP.
179 	 */
180 	if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
181 		scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
182 #endif
183 	/*
184 	 *  Patch some data in SCRIPTS.
185 	 *  - start and done queue initial bus address.
186 	 *  - target bus address table bus address.
187 	 */
188 	scriptb0->startpos[0]	= cpu_to_scr(np->squeue_ba);
189 	scriptb0->done_pos[0]	= cpu_to_scr(np->dqueue_ba);
190 	scriptb0->targtbl[0]	= cpu_to_scr(np->targtbl_ba);
191 }
192 #endif	/* SYM_CONF_GENERIC_SUPPORT */
193 
194 /*
195  *  Patch routine for firmware #2.
196  */
197 static void
sym_fw2_patch(hcb_p np)198 sym_fw2_patch(hcb_p np)
199 {
200 	struct sym_fw2a_scr *scripta0;
201 	struct sym_fw2b_scr *scriptb0;
202 #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
203 	struct sym_fw2z_scr *scriptz0 =
204 		(struct sym_fw2z_scr *) np->scriptz0;
205 #endif
206 
207 	scripta0 = (struct sym_fw2a_scr *) np->scripta0;
208 	scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
209 
210 #ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
211 	/*
212 	 *  Set up BUS physical address of SCRIPTS that is to
213 	 *  be copied to on-chip RAM by the SCRIPTS processor.
214 	 */
215 	scriptz0->scripta0_ba64[0]	= /* Nothing is missing here */
216 	scriptz0->scripta0_ba[0]	= cpu_to_scr(vtobus(scripta0));
217 	scriptz0->scriptb0_ba64[0]	= cpu_to_scr(vtobus(scriptb0));
218 	scriptz0->ram_seg64[0]		= np->scr_ram_seg;
219 #endif
220 
221 	/*
222 	 *  Remove LED support if not needed.
223 	 */
224 	if (!(np->features & FE_LED0)) {
225 		scripta0->idle[0]	= cpu_to_scr(SCR_NO_OP);
226 		scripta0->reselected[0]	= cpu_to_scr(SCR_NO_OP);
227 		scripta0->start[0]	= cpu_to_scr(SCR_NO_OP);
228 	}
229 
230 #if   SYM_CONF_DMA_ADDRESSING_MODE == 2
231 	/*
232 	 *  Remove useless 64 bit DMA specific SCRIPTS,
233 	 *  when this feature is not available.
234 	 */
235 	if (!np->use_dac) {
236 		scripta0->is_dmap_dirty[0] = cpu_to_scr(SCR_NO_OP);
237 		scripta0->is_dmap_dirty[1] = 0;
238 		scripta0->is_dmap_dirty[2] = cpu_to_scr(SCR_NO_OP);
239 		scripta0->is_dmap_dirty[3] = 0;
240 	}
241 #endif
242 
243 #ifdef SYM_CONF_IARB_SUPPORT
244 	/*
245 	 *    If user does not want to use IMMEDIATE ARBITRATION
246 	 *    when we are reselected while attempting to arbitrate,
247 	 *    patch the SCRIPTS accordingly with a SCRIPT NO_OP.
248 	 */
249 	if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
250 		scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
251 #endif
252 	/*
253 	 *  Patch some variable in SCRIPTS.
254 	 *  - start and done queue initial bus address.
255 	 *  - target bus address table bus address.
256 	 */
257 	scriptb0->startpos[0]	= cpu_to_scr(np->squeue_ba);
258 	scriptb0->done_pos[0]	= cpu_to_scr(np->dqueue_ba);
259 	scriptb0->targtbl[0]	= cpu_to_scr(np->targtbl_ba);
260 
261 	/*
262 	 *  Remove the load of SCNTL4 on reselection if not a C10.
263 	 */
264 	if (!(np->features & FE_C10)) {
265 		scripta0->resel_scntl4[0] = cpu_to_scr(SCR_NO_OP);
266 		scripta0->resel_scntl4[1] = cpu_to_scr(0);
267 	}
268 
269 	/*
270 	 *  Remove a couple of work-arounds specific to C1010 if
271 	 *  they are not desirable. See `sym_fw2.h' for more details.
272 	 */
273 	if (!(np->device_id == PCI_ID_LSI53C1010_2 &&
274 	      np->revision_id < 0x1 &&
275 	      np->pciclk_khz < 60000)) {
276 		scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
277 		scripta0->datao_phase[1] = cpu_to_scr(0);
278 	}
279 	if (!(np->device_id == PCI_ID_LSI53C1010 &&
280 	      /* np->revision_id < 0xff */ 1)) {
281 		scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
282 		scripta0->sel_done[1] = cpu_to_scr(0);
283 	}
284 
285 	/*
286 	 *  Patch some other variables in SCRIPTS.
287 	 *  These ones are loaded by the SCRIPTS processor.
288 	 */
289 	scriptb0->pm0_data_addr[0] =
290 		cpu_to_scr(np->scripta_ba +
291 			   offsetof(struct sym_fw2a_scr, pm0_data));
292 	scriptb0->pm1_data_addr[0] =
293 		cpu_to_scr(np->scripta_ba +
294 			   offsetof(struct sym_fw2a_scr, pm1_data));
295 }
296 
297 /*
298  *  Fill the data area in scripts.
299  *  To be done for all firmwares.
300  */
301 static void
sym_fw_fill_data(u32 * in,u32 * out)302 sym_fw_fill_data (u32 *in, u32 *out)
303 {
304 	int	i;
305 
306 	for (i = 0; i < SYM_CONF_MAX_SG; i++) {
307 		*in++  = SCR_CHMOV_TBL ^ SCR_DATA_IN;
308 		*in++  = offsetof (struct sym_dsb, data[i]);
309 		*out++ = SCR_CHMOV_TBL ^ SCR_DATA_OUT;
310 		*out++ = offsetof (struct sym_dsb, data[i]);
311 	}
312 }
313 
314 /*
315  *  Setup useful script bus addresses.
316  *  To be done for all firmwares.
317  */
318 static void
sym_fw_setup_bus_addresses(hcb_p np,struct sym_fw * fw)319 sym_fw_setup_bus_addresses(hcb_p np, struct sym_fw *fw)
320 {
321 	u32 *pa;
322 	u_short *po;
323 	int i;
324 
325 	/*
326 	 *  Build the bus address table for script A
327 	 *  from the script A offset table.
328 	 */
329 	po = (u_short *) fw->a_ofs;
330 	pa = (u32 *) &np->fwa_bas;
331 	for (i = 0 ; i < sizeof(np->fwa_bas)/sizeof(u32) ; i++)
332 		pa[i] = np->scripta_ba + po[i];
333 
334 	/*
335 	 *  Same for script B.
336 	 */
337 	po = (u_short *) fw->b_ofs;
338 	pa = (u32 *) &np->fwb_bas;
339 	for (i = 0 ; i < sizeof(np->fwb_bas)/sizeof(u32) ; i++)
340 		pa[i] = np->scriptb_ba + po[i];
341 
342 	/*
343 	 *  Same for script Z.
344 	 */
345 	po = (u_short *) fw->z_ofs;
346 	pa = (u32 *) &np->fwz_bas;
347 	for (i = 0 ; i < sizeof(np->fwz_bas)/sizeof(u32) ; i++)
348 		pa[i] = np->scriptz_ba + po[i];
349 }
350 
351 #if	SYM_CONF_GENERIC_SUPPORT
352 /*
353  *  Setup routine for firmware #1.
354  */
355 static void
sym_fw1_setup(hcb_p np,struct sym_fw * fw)356 sym_fw1_setup(hcb_p np, struct sym_fw *fw)
357 {
358 	struct sym_fw1a_scr *scripta0;
359 	struct sym_fw1b_scr *scriptb0;
360 
361 	scripta0 = (struct sym_fw1a_scr *) np->scripta0;
362 	scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
363 
364 	/*
365 	 *  Fill variable parts in scripts.
366 	 */
367 	sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
368 
369 	/*
370 	 *  Setup bus addresses used from the C code..
371 	 */
372 	sym_fw_setup_bus_addresses(np, fw);
373 }
374 #endif	/* SYM_CONF_GENERIC_SUPPORT */
375 
376 /*
377  *  Setup routine for firmware #2.
378  */
379 static void
sym_fw2_setup(hcb_p np,struct sym_fw * fw)380 sym_fw2_setup(hcb_p np, struct sym_fw *fw)
381 {
382 	struct sym_fw2a_scr *scripta0;
383 	struct sym_fw2b_scr *scriptb0;
384 
385 	scripta0 = (struct sym_fw2a_scr *) np->scripta0;
386 	scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
387 
388 	/*
389 	 *  Fill variable parts in scripts.
390 	 */
391 	sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
392 
393 	/*
394 	 *  Setup bus addresses used from the C code..
395 	 */
396 	sym_fw_setup_bus_addresses(np, fw);
397 }
398 
399 /*
400  *  Allocate firmware descriptors.
401  */
402 #if	SYM_CONF_GENERIC_SUPPORT
403 static struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic");
404 #endif	/* SYM_CONF_GENERIC_SUPPORT */
405 static struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
406 
407 /*
408  *  Find the most appropriate firmware for a chip.
409  */
410 struct sym_fw *
sym_find_firmware(struct sym_pci_chip * chip)411 sym_find_firmware(struct sym_pci_chip *chip)
412 {
413 	if (chip->features & FE_LDSTR)
414 		return &sym_fw2;
415 #if	SYM_CONF_GENERIC_SUPPORT
416 	else if (!(chip->features & (FE_PFEN|FE_NOPM|FE_DAC)))
417 		return &sym_fw1;
418 #endif
419 	else
420 		return 0;
421 }
422 
423 /*
424  *  Bind a script to physical addresses.
425  */
sym_fw_bind_script(hcb_p np,u32 * start,int len)426 void sym_fw_bind_script (hcb_p np, u32 *start, int len)
427 {
428 	u32 opcode, new, old, tmp1, tmp2;
429 	u32 *end, *cur;
430 	int relocs;
431 
432 	cur = start;
433 	end = start + len/4;
434 
435 	while (cur < end) {
436 
437 		opcode = *cur;
438 
439 		/*
440 		 *  If we forget to change the length
441 		 *  in scripts, a field will be
442 		 *  padded with 0. This is an illegal
443 		 *  command.
444 		 */
445 		if (opcode == 0) {
446 			printf ("%s: ERROR0 IN SCRIPT at %d.\n",
447 				sym_name(np), (int) (cur-start));
448 			MDELAY (10000);
449 			++cur;
450 			continue;
451 		};
452 
453 		/*
454 		 *  We use the bogus value 0xf00ff00f ;-)
455 		 *  to reserve data area in SCRIPTS.
456 		 */
457 		if (opcode == SCR_DATA_ZERO) {
458 			*cur++ = 0;
459 			continue;
460 		}
461 
462 		if (DEBUG_FLAGS & DEBUG_SCRIPT)
463 			printf ("%d:  <%x>\n", (int) (cur-start),
464 				(unsigned)opcode);
465 
466 		/*
467 		 *  We don't have to decode ALL commands
468 		 */
469 		switch (opcode >> 28) {
470 		case 0xf:
471 			/*
472 			 *  LOAD / STORE DSA relative, don't relocate.
473 			 */
474 			relocs = 0;
475 			break;
476 		case 0xe:
477 			/*
478 			 *  LOAD / STORE absolute.
479 			 */
480 			relocs = 1;
481 			break;
482 		case 0xc:
483 			/*
484 			 *  COPY has TWO arguments.
485 			 */
486 			relocs = 2;
487 			tmp1 = cur[1];
488 			tmp2 = cur[2];
489 			if ((tmp1 ^ tmp2) & 3) {
490 				printf ("%s: ERROR1 IN SCRIPT at %d.\n",
491 					sym_name(np), (int) (cur-start));
492 				MDELAY (10000);
493 			}
494 			/*
495 			 *  If PREFETCH feature not enabled, remove
496 			 *  the NO FLUSH bit if present.
497 			 */
498 			if ((opcode & SCR_NO_FLUSH) &&
499 			    !(np->features & FE_PFEN)) {
500 				opcode = (opcode & ~SCR_NO_FLUSH);
501 			}
502 			break;
503 		case 0x0:
504 			/*
505 			 *  MOVE/CHMOV (absolute address)
506 			 */
507 			if (!(np->features & FE_WIDE))
508 				opcode = (opcode | OPC_MOVE);
509 			relocs = 1;
510 			break;
511 		case 0x1:
512 			/*
513 			 *  MOVE/CHMOV (table indirect)
514 			 */
515 			if (!(np->features & FE_WIDE))
516 				opcode = (opcode | OPC_MOVE);
517 			relocs = 0;
518 			break;
519 #ifdef SYM_CONF_TARGET_ROLE_SUPPORT
520 		case 0x2:
521 			/*
522 			 *  MOVE/CHMOV in target role (absolute address)
523 			 */
524 			opcode &= ~0x20000000;
525 			if (!(np->features & FE_WIDE))
526 				opcode = (opcode & ~OPC_TCHMOVE);
527 			relocs = 1;
528 			break;
529 		case 0x3:
530 			/*
531 			 *  MOVE/CHMOV in target role (table indirect)
532 			 */
533 			opcode &= ~0x20000000;
534 			if (!(np->features & FE_WIDE))
535 				opcode = (opcode & ~OPC_TCHMOVE);
536 			relocs = 0;
537 			break;
538 #endif
539 		case 0x8:
540 			/*
541 			 *  JUMP / CALL
542 			 *  dont't relocate if relative :-)
543 			 */
544 			if (opcode & 0x00800000)
545 				relocs = 0;
546 			else if ((opcode & 0xf8400000) == 0x80400000)/*JUMP64*/
547 				relocs = 2;
548 			else
549 				relocs = 1;
550 			break;
551 		case 0x4:
552 		case 0x5:
553 		case 0x6:
554 		case 0x7:
555 			relocs = 1;
556 			break;
557 		default:
558 			relocs = 0;
559 			break;
560 		};
561 
562 		/*
563 		 *  Scriptify:) the opcode.
564 		 */
565 		*cur++ = cpu_to_scr(opcode);
566 
567 		/*
568 		 *  If no relocation, assume 1 argument
569 		 *  and just scriptize:) it.
570 		 */
571 		if (!relocs) {
572 			*cur = cpu_to_scr(*cur);
573 			++cur;
574 			continue;
575 		}
576 
577 		/*
578 		 *  Otherwise performs all needed relocations.
579 		 */
580 		while (relocs--) {
581 			old = *cur;
582 
583 			switch (old & RELOC_MASK) {
584 			case RELOC_REGISTER:
585 				new = (old & ~RELOC_MASK) + np->mmio_ba;
586 				break;
587 			case RELOC_LABEL_A:
588 				new = (old & ~RELOC_MASK) + np->scripta_ba;
589 				break;
590 			case RELOC_LABEL_B:
591 				new = (old & ~RELOC_MASK) + np->scriptb_ba;
592 				break;
593 			case RELOC_SOFTC:
594 				new = (old & ~RELOC_MASK) + np->hcb_ba;
595 				break;
596 			case 0:
597 				/*
598 				 *  Don't relocate a 0 address.
599 				 *  They are mostly used for patched or
600 				 *  script self-modified areas.
601 				 */
602 				if (old == 0) {
603 					new = old;
604 					break;
605 				}
606 				/* fall through */
607 			default:
608 				new = 0;
609 				panic("sym_fw_bind_script: "
610 				      "weird relocation %x\n", old);
611 				break;
612 			}
613 
614 			*cur++ = cpu_to_scr(new);
615 		}
616 	};
617 }
618