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#include "sym_nvram.h"
42
43#ifdef SYM_CONF_DEBUG_NVRAM
44static u_char Tekram_boot_delay[7] = {3, 5, 10, 20, 30, 60, 120};
45#endif
46
47
48
49
50void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram)
51{
52
53
54
55
56 switch (nvram->type) {
57 case SYM_SYMBIOS_NVRAM:
58 if (!(nvram->data.Symbios.flags & SYMBIOS_PARITY_ENABLE))
59 np->rv_scntl0 &= ~0x0a;
60 np->myaddr = nvram->data.Symbios.host_id & 0x0f;
61 if (nvram->data.Symbios.flags & SYMBIOS_VERBOSE_MSGS)
62 np->verbose += 1;
63 if (nvram->data.Symbios.flags1 & SYMBIOS_SCAN_HI_LO)
64 shost->reverse_ordering = 1;
65 if (nvram->data.Symbios.flags2 & SYMBIOS_AVOID_BUS_RESET)
66 np->usrflags |= SYM_AVOID_BUS_RESET;
67 break;
68 case SYM_TEKRAM_NVRAM:
69 np->myaddr = nvram->data.Tekram.host_id & 0x0f;
70 break;
71#ifdef CONFIG_PARISC
72 case SYM_PARISC_PDC:
73 if (nvram->data.parisc.host_id != -1)
74 np->myaddr = nvram->data.parisc.host_id;
75 if (nvram->data.parisc.factor != -1)
76 np->minsync = nvram->data.parisc.factor;
77 if (nvram->data.parisc.width != -1)
78 np->maxwide = nvram->data.parisc.width;
79 switch (nvram->data.parisc.mode) {
80 case 0: np->scsi_mode = SMODE_SE; break;
81 case 1: np->scsi_mode = SMODE_HVD; break;
82 case 2: np->scsi_mode = SMODE_LVD; break;
83 default: break;
84 }
85#endif
86 default:
87 break;
88 }
89}
90
91
92
93
94static void
95sym_Symbios_setup_target(struct sym_tcb *tp, int target, Symbios_nvram *nvram)
96{
97 Symbios_target *tn = &nvram->target[target];
98
99 if (!(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED))
100 tp->usrtags = 0;
101 if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
102 tp->usrflags &= ~SYM_DISC_ENABLED;
103 if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
104 tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
105 if (!(tn->flags & SYMBIOS_SCAN_LUNS))
106 tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
107 tp->usr_period = (tn->sync_period + 3) / 4;
108 tp->usr_width = (tn->bus_width == 0x8) ? 0 : 1;
109}
110
111static const unsigned char Tekram_sync[16] = {
112 25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21, 6, 7, 9, 10
113};
114
115
116
117
118static void
119sym_Tekram_setup_target(struct sym_tcb *tp, int target, Tekram_nvram *nvram)
120{
121 struct Tekram_target *tn = &nvram->target[target];
122
123 if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
124 tp->usrtags = 2 << nvram->max_tags_index;
125 }
126
127 if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
128 tp->usrflags |= SYM_DISC_ENABLED;
129
130 if (tn->flags & TEKRAM_SYNC_NEGO)
131 tp->usr_period = Tekram_sync[tn->sync_index & 0xf];
132 tp->usr_width = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
133}
134
135
136
137
138void sym_nvram_setup_target(struct sym_tcb *tp, int target, struct sym_nvram *nvp)
139{
140 switch (nvp->type) {
141 case SYM_SYMBIOS_NVRAM:
142 sym_Symbios_setup_target(tp, target, &nvp->data.Symbios);
143 break;
144 case SYM_TEKRAM_NVRAM:
145 sym_Tekram_setup_target(tp, target, &nvp->data.Tekram);
146 break;
147 default:
148 break;
149 }
150}
151
152#ifdef SYM_CONF_DEBUG_NVRAM
153
154
155
156static void sym_display_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram)
157{
158 int i;
159
160
161 printf("%s: HOST ID=%d%s%s%s%s%s%s\n",
162 sym_name(np), nvram->host_id & 0x0f,
163 (nvram->flags & SYMBIOS_SCAM_ENABLE) ? " SCAM" :"",
164 (nvram->flags & SYMBIOS_PARITY_ENABLE) ? " PARITY" :"",
165 (nvram->flags & SYMBIOS_VERBOSE_MSGS) ? " VERBOSE" :"",
166 (nvram->flags & SYMBIOS_CHS_MAPPING) ? " CHS_ALT" :"",
167 (nvram->flags2 & SYMBIOS_AVOID_BUS_RESET)?" NO_RESET" :"",
168 (nvram->flags1 & SYMBIOS_SCAN_HI_LO) ? " HI_LO" :"");
169
170
171 for (i = 0 ; i < 15 ; i++) {
172 struct Symbios_target *tn = &nvram->target[i];
173 printf("%s-%d:%s%s%s%s WIDTH=%d SYNC=%d TMO=%d\n",
174 sym_name(np), i,
175 (tn->flags & SYMBIOS_DISCONNECT_ENABLE) ? " DISC" : "",
176 (tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME) ? " SCAN_BOOT" : "",
177 (tn->flags & SYMBIOS_SCAN_LUNS) ? " SCAN_LUNS" : "",
178 (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? " TCQ" : "",
179 tn->bus_width,
180 tn->sync_period / 4,
181 tn->timeout);
182 }
183}
184
185
186
187
188static void sym_display_Tekram_nvram(struct sym_device *np, Tekram_nvram *nvram)
189{
190 int i, tags, boot_delay;
191 char *rem;
192
193
194 tags = 2 << nvram->max_tags_index;
195 boot_delay = 0;
196 if (nvram->boot_delay_index < 6)
197 boot_delay = Tekram_boot_delay[nvram->boot_delay_index];
198 switch ((nvram->flags & TEKRAM_REMOVABLE_FLAGS) >> 6) {
199 default:
200 case 0: rem = ""; break;
201 case 1: rem = " REMOVABLE=boot device"; break;
202 case 2: rem = " REMOVABLE=all"; break;
203 }
204
205 printf("%s: HOST ID=%d%s%s%s%s%s%s%s%s%s BOOT DELAY=%d tags=%d\n",
206 sym_name(np), nvram->host_id & 0x0f,
207 (nvram->flags1 & SYMBIOS_SCAM_ENABLE) ? " SCAM" :"",
208 (nvram->flags & TEKRAM_MORE_THAN_2_DRIVES) ? " >2DRIVES":"",
209 (nvram->flags & TEKRAM_DRIVES_SUP_1GB) ? " >1GB" :"",
210 (nvram->flags & TEKRAM_RESET_ON_POWER_ON) ? " RESET" :"",
211 (nvram->flags & TEKRAM_ACTIVE_NEGATION) ? " ACT_NEG" :"",
212 (nvram->flags & TEKRAM_IMMEDIATE_SEEK) ? " IMM_SEEK" :"",
213 (nvram->flags & TEKRAM_SCAN_LUNS) ? " SCAN_LUNS" :"",
214 (nvram->flags1 & TEKRAM_F2_F6_ENABLED) ? " F2_F6" :"",
215 rem, boot_delay, tags);
216
217
218 for (i = 0; i <= 15; i++) {
219 int sync, j;
220 struct Tekram_target *tn = &nvram->target[i];
221 j = tn->sync_index & 0xf;
222 sync = Tekram_sync[j];
223 printf("%s-%d:%s%s%s%s%s%s PERIOD=%d\n",
224 sym_name(np), i,
225 (tn->flags & TEKRAM_PARITY_CHECK) ? " PARITY" : "",
226 (tn->flags & TEKRAM_SYNC_NEGO) ? " SYNC" : "",
227 (tn->flags & TEKRAM_DISCONNECT_ENABLE) ? " DISC" : "",
228 (tn->flags & TEKRAM_START_CMD) ? " START" : "",
229 (tn->flags & TEKRAM_TAGGED_COMMANDS) ? " TCQ" : "",
230 (tn->flags & TEKRAM_WIDE_NEGO) ? " WIDE" : "",
231 sync);
232 }
233}
234#else
235static void sym_display_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram) { (void)np; (void)nvram; }
236static void sym_display_Tekram_nvram(struct sym_device *np, Tekram_nvram *nvram) { (void)np; (void)nvram; }
237#endif
238
239
240
241
242
243
244
245
246
247
248#define SET_BIT 0
249#define CLR_BIT 1
250#define SET_CLK 2
251#define CLR_CLK 3
252
253
254
255
256static void S24C16_set_bit(struct sym_device *np, u_char write_bit, u_char *gpreg,
257 int bit_mode)
258{
259 udelay(5);
260 switch (bit_mode) {
261 case SET_BIT:
262 *gpreg |= write_bit;
263 break;
264 case CLR_BIT:
265 *gpreg &= 0xfe;
266 break;
267 case SET_CLK:
268 *gpreg |= 0x02;
269 break;
270 case CLR_CLK:
271 *gpreg &= 0xfd;
272 break;
273
274 }
275 OUTB(np, nc_gpreg, *gpreg);
276 INB(np, nc_mbox1);
277 udelay(5);
278}
279
280
281
282
283static void S24C16_start(struct sym_device *np, u_char *gpreg)
284{
285 S24C16_set_bit(np, 1, gpreg, SET_BIT);
286 S24C16_set_bit(np, 0, gpreg, SET_CLK);
287 S24C16_set_bit(np, 0, gpreg, CLR_BIT);
288 S24C16_set_bit(np, 0, gpreg, CLR_CLK);
289}
290
291
292
293
294static void S24C16_stop(struct sym_device *np, u_char *gpreg)
295{
296 S24C16_set_bit(np, 0, gpreg, SET_CLK);
297 S24C16_set_bit(np, 1, gpreg, SET_BIT);
298}
299
300
301
302
303
304static void S24C16_do_bit(struct sym_device *np, u_char *read_bit, u_char write_bit,
305 u_char *gpreg)
306{
307 S24C16_set_bit(np, write_bit, gpreg, SET_BIT);
308 S24C16_set_bit(np, 0, gpreg, SET_CLK);
309 if (read_bit)
310 *read_bit = INB(np, nc_gpreg);
311 S24C16_set_bit(np, 0, gpreg, CLR_CLK);
312 S24C16_set_bit(np, 0, gpreg, CLR_BIT);
313}
314
315
316
317
318
319static void S24C16_write_ack(struct sym_device *np, u_char write_bit, u_char *gpreg,
320 u_char *gpcntl)
321{
322 OUTB(np, nc_gpcntl, *gpcntl & 0xfe);
323 S24C16_do_bit(np, NULL, write_bit, gpreg);
324 OUTB(np, nc_gpcntl, *gpcntl);
325}
326
327
328
329
330
331static void S24C16_read_ack(struct sym_device *np, u_char *read_bit, u_char *gpreg,
332 u_char *gpcntl)
333{
334 OUTB(np, nc_gpcntl, *gpcntl | 0x01);
335 S24C16_do_bit(np, read_bit, 1, gpreg);
336 OUTB(np, nc_gpcntl, *gpcntl);
337}
338
339
340
341
342
343static void S24C16_write_byte(struct sym_device *np, u_char *ack_data, u_char write_data,
344 u_char *gpreg, u_char *gpcntl)
345{
346 int x;
347
348 for (x = 0; x < 8; x++)
349 S24C16_do_bit(np, NULL, (write_data >> (7 - x)) & 0x01, gpreg);
350
351 S24C16_read_ack(np, ack_data, gpreg, gpcntl);
352}
353
354
355
356
357
358static void S24C16_read_byte(struct sym_device *np, u_char *read_data, u_char ack_data,
359 u_char *gpreg, u_char *gpcntl)
360{
361 int x;
362 u_char read_bit;
363
364 *read_data = 0;
365 for (x = 0; x < 8; x++) {
366 S24C16_do_bit(np, &read_bit, 1, gpreg);
367 *read_data |= ((read_bit & 0x01) << (7 - x));
368 }
369
370 S24C16_write_ack(np, ack_data, gpreg, gpcntl);
371}
372
373#ifdef SYM_CONF_NVRAM_WRITE_SUPPORT
374
375
376
377static int sym_write_S24C16_nvram(struct sym_device *np, int offset,
378 u_char *data, int len)
379{
380 u_char gpcntl, gpreg;
381 u_char old_gpcntl, old_gpreg;
382 u_char ack_data;
383 int x;
384
385
386 old_gpreg = INB(np, nc_gpreg);
387 old_gpcntl = INB(np, nc_gpcntl);
388 gpcntl = old_gpcntl & 0x1c;
389
390
391 OUTB(np, nc_gpreg, old_gpreg);
392 OUTB(np, nc_gpcntl, gpcntl);
393
394
395 gpreg = old_gpreg;
396 S24C16_set_bit(np, 0, &gpreg, CLR_CLK);
397 S24C16_set_bit(np, 0, &gpreg, CLR_BIT);
398
399
400 S24C16_stop(np, &gpreg);
401
402
403 for (x = 0; x < len ; x += 16) {
404 do {
405 S24C16_start(np, &gpreg);
406 S24C16_write_byte(np, &ack_data,
407 0xa0 | (((offset+x) >> 7) & 0x0e),
408 &gpreg, &gpcntl);
409 } while (ack_data & 0x01);
410
411 S24C16_write_byte(np, &ack_data, (offset+x) & 0xff,
412 &gpreg, &gpcntl);
413
414 for (y = 0; y < 16; y++)
415 S24C16_write_byte(np, &ack_data, data[x+y],
416 &gpreg, &gpcntl);
417 S24C16_stop(np, &gpreg);
418 }
419
420
421 OUTB(np, nc_gpcntl, old_gpcntl);
422 OUTB(np, nc_gpreg, old_gpreg);
423
424 return 0;
425}
426#endif
427
428
429
430
431static int sym_read_S24C16_nvram(struct sym_device *np, int offset, u_char *data, int len)
432{
433 u_char gpcntl, gpreg;
434 u_char old_gpcntl, old_gpreg;
435 u_char ack_data;
436 int retv = 1;
437 int x;
438
439
440 old_gpreg = INB(np, nc_gpreg);
441 old_gpcntl = INB(np, nc_gpcntl);
442 gpcntl = old_gpcntl & 0x1c;
443
444
445 OUTB(np, nc_gpreg, old_gpreg);
446 OUTB(np, nc_gpcntl, gpcntl);
447
448
449 gpreg = old_gpreg;
450 S24C16_set_bit(np, 0, &gpreg, CLR_CLK);
451 S24C16_set_bit(np, 0, &gpreg, CLR_BIT);
452
453
454 S24C16_stop(np, &gpreg);
455
456
457 S24C16_start(np, &gpreg);
458
459
460 S24C16_write_byte(np, &ack_data,
461 0xa0 | ((offset >> 7) & 0x0e), &gpreg, &gpcntl);
462 if (ack_data & 0x01)
463 goto out;
464
465
466 S24C16_write_byte(np, &ack_data,
467 offset & 0xff, &gpreg, &gpcntl);
468 if (ack_data & 0x01)
469 goto out;
470
471
472 S24C16_start(np, &gpreg);
473
474
475 S24C16_write_byte(np, &ack_data,
476 0xa1 | ((offset >> 7) & 0x0e), &gpreg, &gpcntl);
477 if (ack_data & 0x01)
478 goto out;
479
480
481 gpcntl |= 0x01;
482 OUTB(np, nc_gpcntl, gpcntl);
483
484
485 for (x = 0; x < len; x++)
486 S24C16_read_byte(np, &data[x], (x == (len-1)), &gpreg, &gpcntl);
487
488
489 gpcntl &= 0xfe;
490 OUTB(np, nc_gpcntl, gpcntl);
491 S24C16_stop(np, &gpreg);
492 retv = 0;
493out:
494
495 OUTB(np, nc_gpcntl, old_gpcntl);
496 OUTB(np, nc_gpreg, old_gpreg);
497
498 return retv;
499}
500
501#undef SET_BIT
502#undef CLR_BIT
503#undef SET_CLK
504#undef CLR_CLK
505
506
507
508
509
510static int sym_read_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram)
511{
512 static u_char Symbios_trailer[6] = {0xfe, 0xfe, 0, 0, 0, 0};
513 u_char *data = (u_char *) nvram;
514 int len = sizeof(*nvram);
515 u_short csum;
516 int x;
517
518
519 if (sym_read_S24C16_nvram (np, SYMBIOS_NVRAM_ADDRESS, data, len))
520 return 1;
521
522
523 if (nvram->type != 0 ||
524 memcmp(nvram->trailer, Symbios_trailer, 6) ||
525 nvram->byte_count != len - 12)
526 return 1;
527
528
529 for (x = 6, csum = 0; x < len - 6; x++)
530 csum += data[x];
531 if (csum != nvram->checksum)
532 return 1;
533
534 return 0;
535}
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551static void T93C46_Clk(struct sym_device *np, u_char *gpreg)
552{
553 OUTB(np, nc_gpreg, *gpreg | 0x04);
554 INB(np, nc_mbox1);
555 udelay(2);
556 OUTB(np, nc_gpreg, *gpreg);
557}
558
559
560
561
562static void T93C46_Read_Bit(struct sym_device *np, u_char *read_bit, u_char *gpreg)
563{
564 udelay(2);
565 T93C46_Clk(np, gpreg);
566 *read_bit = INB(np, nc_gpreg);
567}
568
569
570
571
572static void T93C46_Write_Bit(struct sym_device *np, u_char write_bit, u_char *gpreg)
573{
574 if (write_bit & 0x01)
575 *gpreg |= 0x02;
576 else
577 *gpreg &= 0xfd;
578
579 *gpreg |= 0x10;
580
581 OUTB(np, nc_gpreg, *gpreg);
582 INB(np, nc_mbox1);
583 udelay(2);
584
585 T93C46_Clk(np, gpreg);
586}
587
588
589
590
591static void T93C46_Stop(struct sym_device *np, u_char *gpreg)
592{
593 *gpreg &= 0xef;
594 OUTB(np, nc_gpreg, *gpreg);
595 INB(np, nc_mbox1);
596 udelay(2);
597
598 T93C46_Clk(np, gpreg);
599}
600
601
602
603
604static void T93C46_Send_Command(struct sym_device *np, u_short write_data,
605 u_char *read_bit, u_char *gpreg)
606{
607 int x;
608
609
610 for (x = 0; x < 9; x++)
611 T93C46_Write_Bit(np, (u_char) (write_data >> (8 - x)), gpreg);
612
613 *read_bit = INB(np, nc_gpreg);
614}
615
616
617
618
619static void T93C46_Read_Word(struct sym_device *np,
620 unsigned short *nvram_data, unsigned char *gpreg)
621{
622 int x;
623 u_char read_bit;
624
625 *nvram_data = 0;
626 for (x = 0; x < 16; x++) {
627 T93C46_Read_Bit(np, &read_bit, gpreg);
628
629 if (read_bit & 0x01)
630 *nvram_data |= (0x01 << (15 - x));
631 else
632 *nvram_data &= ~(0x01 << (15 - x));
633 }
634}
635
636
637
638
639static int T93C46_Read_Data(struct sym_device *np, unsigned short *data,
640 int len, unsigned char *gpreg)
641{
642 int x;
643
644 for (x = 0; x < len; x++) {
645 unsigned char read_bit;
646
647 T93C46_Send_Command(np, 0x180 | x, &read_bit, gpreg);
648 if (read_bit & 0x01)
649 return 1;
650 T93C46_Read_Word(np, &data[x], gpreg);
651 T93C46_Stop(np, gpreg);
652 }
653
654 return 0;
655}
656
657
658
659
660static int sym_read_T93C46_nvram(struct sym_device *np, Tekram_nvram *nvram)
661{
662 u_char gpcntl, gpreg;
663 u_char old_gpcntl, old_gpreg;
664 int retv = 1;
665
666
667 old_gpreg = INB(np, nc_gpreg);
668 old_gpcntl = INB(np, nc_gpcntl);
669
670
671
672 gpreg = old_gpreg & 0xe9;
673 OUTB(np, nc_gpreg, gpreg);
674 gpcntl = (old_gpcntl & 0xe9) | 0x09;
675 OUTB(np, nc_gpcntl, gpcntl);
676
677
678 retv = T93C46_Read_Data(np, (u_short *) nvram,
679 sizeof(*nvram) / sizeof(short), &gpreg);
680
681
682 OUTB(np, nc_gpcntl, old_gpcntl);
683 OUTB(np, nc_gpreg, old_gpreg);
684
685 return retv;
686}
687
688
689
690
691
692static int sym_read_Tekram_nvram (struct sym_device *np, Tekram_nvram *nvram)
693{
694 u_char *data = (u_char *) nvram;
695 int len = sizeof(*nvram);
696 u_short csum;
697 int x;
698
699 switch (np->pdev->device) {
700 case PCI_DEVICE_ID_NCR_53C885:
701 case PCI_DEVICE_ID_NCR_53C895:
702 case PCI_DEVICE_ID_NCR_53C896:
703 x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,
704 data, len);
705 break;
706 case PCI_DEVICE_ID_NCR_53C875:
707 x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,
708 data, len);
709 if (!x)
710 break;
711 default:
712 x = sym_read_T93C46_nvram(np, nvram);
713 break;
714 }
715 if (x)
716 return 1;
717
718
719 for (x = 0, csum = 0; x < len - 1; x += 2)
720 csum += data[x] + (data[x+1] << 8);
721 if (csum != 0x1234)
722 return 1;
723
724 return 0;
725}
726
727#ifdef CONFIG_PARISC
728
729
730
731
732
733static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *pdc)
734{
735 struct hardware_path hwpath;
736 get_pci_node_path(np->pdev, &hwpath);
737 if (!pdc_get_initiator(&hwpath, pdc))
738 return 0;
739
740 return SYM_PARISC_PDC;
741}
742#else
743static inline int sym_read_parisc_pdc(struct sym_device *np,
744 struct pdc_initiator *x)
745{
746 return 0;
747}
748#endif
749
750
751
752
753int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
754{
755 if (!sym_read_Symbios_nvram(np, &nvp->data.Symbios)) {
756 nvp->type = SYM_SYMBIOS_NVRAM;
757 sym_display_Symbios_nvram(np, &nvp->data.Symbios);
758 } else if (!sym_read_Tekram_nvram(np, &nvp->data.Tekram)) {
759 nvp->type = SYM_TEKRAM_NVRAM;
760 sym_display_Tekram_nvram(np, &nvp->data.Tekram);
761 } else {
762 nvp->type = sym_read_parisc_pdc(np, &nvp->data.parisc);
763 }
764 return nvp->type;
765}
766
767char *sym_nvram_type(struct sym_nvram *nvp)
768{
769 switch (nvp->type) {
770 case SYM_SYMBIOS_NVRAM:
771 return "Symbios NVRAM";
772 case SYM_TEKRAM_NVRAM:
773 return "Tekram NVRAM";
774 case SYM_PARISC_PDC:
775 return "PA-RISC Firmware";
776 default:
777 return "No NVRAM";
778 }
779}
780