1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include "sym_glue.h"
41
42
43
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
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"
60static struct sym_fwa_ofs sym_fw1a_ofs = {
61 SYM_GEN_FW_A(struct SYM_FWA_SCR)
62};
63static struct sym_fwb_ofs sym_fw1b_ofs = {
64 SYM_GEN_FW_B(struct SYM_FWB_SCR)
65};
66static 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
73
74
75
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"
81static struct sym_fwa_ofs sym_fw2a_ofs = {
82 SYM_GEN_FW_A(struct SYM_FWA_SCR)
83};
84static 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};
89static 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
105
106static void
107sym_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
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
128
129
130
131 if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
132 scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
133#endif
134
135
136
137
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
144
145
146
147
148static void
149sym_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
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
172
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
185
186
187
188 if (!SYM_CONF_SET_IARB_ON_ARB_LOST)
189 scripta0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
190#endif
191
192
193
194
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
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
210
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)) {
220 scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
221 scripta0->sel_done[1] = cpu_to_scr(0);
222 }
223
224
225
226
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
238
239
240static void
241sym_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
255
256
257static void
258sym_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
266
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
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
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
293
294static void
295sym_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
305
306 sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
307
308
309
310
311 sym_fw_setup_bus_addresses(np, fw);
312}
313#endif
314
315
316
317
318static void
319sym_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
329
330 sym_fw_fill_data(scripta0->data_in, scripta0->data_out);
331
332
333
334
335 sym_fw_setup_bus_addresses(np, fw);
336}
337
338
339
340
341#if SYM_CONF_GENERIC_SUPPORT
342static struct sym_fw sym_fw1 = SYM_FW_ENTRY(sym_fw1, "NCR-generic");
343#endif
344static struct sym_fw sym_fw2 = SYM_FW_ENTRY(sym_fw2, "LOAD/STORE-based");
345
346
347
348
349struct sym_fw *
350sym_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
364
365void 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
380
381
382
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
393
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
406
407 switch (opcode >> 28) {
408 case 0xf:
409
410
411
412 relocs = 0;
413 break;
414 case 0xe:
415
416
417
418 relocs = 1;
419 break;
420 case 0xc:
421
422
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
433
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
443
444 if (!(np->features & FE_WIDE))
445 opcode = (opcode | OPC_MOVE);
446 relocs = 1;
447 break;
448 case 0x1:
449
450
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
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
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
479
480
481 if (opcode & 0x00800000)
482 relocs = 0;
483 else if ((opcode & 0xf8400000) == 0x80400000)
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
501
502 *cur++ = cpu_to_scr(opcode);
503
504
505
506
507
508 if (!relocs) {
509 *cur = cpu_to_scr(*cur);
510 ++cur;
511 continue;
512 }
513
514
515
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
536
537
538
539 if (old == 0) {
540 new = old;
541 break;
542 }
543
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