This source file includes following definitions.
- ahd_compose_id
- ahd_find_pci_device
- ahd_pci_probe
- ahd_pci_attach
- ahd_pci_test_register_access
- ahd_check_extport
- ahd_configure_termination
- ahd_pci_intr
- ahd_pci_split_intr
- ahd_aic7901_setup
- ahd_aic7901A_setup
- ahd_aic7902_setup
- ahd_aic790X_setup
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 #include <sys/cdefs.h>
73
74
75
76
77 #include <dev/ic/aic79xx_openbsd.h>
78 #include <dev/ic/aic79xx_inline.h>
79 #include <dev/ic/aic79xx.h>
80
81 #include <dev/pci/pcivar.h>
82
83 __inline uint64_t ahd_compose_id(u_int, u_int, u_int, u_int);
84 __inline uint64_t
85 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
86 {
87 uint64_t id;
88
89 id = subvendor
90 | (subdevice << 16)
91 | ((uint64_t)vendor << 32)
92 | ((uint64_t)device << 48);
93
94 return (id);
95 }
96
97 #define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull
98 #define ID_ALL_IROC_MASK 0xFF7FFFFFFFFFFFFFull
99 #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull
100 #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull
101 #define ID_9005_GENERIC_IROC_MASK 0xFF70FFFF00000000ull
102
103 #define ID_AIC7901 0x800F9005FFFF9005ull
104 #define ID_AHA_29320A 0x8000900500609005ull
105 #define ID_AHA_29320ALP 0x8017900500449005ull
106
107 #define ID_AIC7901A 0x801E9005FFFF9005ull
108 #define ID_AHA_29320LP 0x8014900500449005ull
109
110 #define ID_AIC7902 0x801F9005FFFF9005ull
111 #define ID_AIC7902_B 0x801D9005FFFF9005ull
112 #define ID_AHA_39320 0x8010900500409005ull
113 #define ID_AHA_29320 0x8012900500429005ull
114 #define ID_AHA_29320B 0x8013900500439005ull
115 #define ID_AHA_39320_B 0x8015900500409005ull
116 #define ID_AHA_39320_B_DELL 0x8015900501681028ull
117 #define ID_AHA_39320A 0x8016900500409005ull
118 #define ID_AHA_39320D 0x8011900500419005ull
119 #define ID_AHA_39320D_B 0x801C900500419005ull
120 #define ID_AHA_39320D_HP 0x8011900500AC0E11ull
121 #define ID_AHA_39320D_B_HP 0x801C900500AC0E11ull
122 #define ID_AIC7902_PCI_REV_A4 0x3
123 #define ID_AIC7902_PCI_REV_B0 0x10
124 #define SUBID_HP 0x0E11
125
126 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
127
128 #define DEVID_9005_TYPE(id) ((id) & 0xF)
129 #define DEVID_9005_TYPE_HBA 0x0
130 #define DEVID_9005_TYPE_HBA_2EXT 0x1
131 #define DEVID_9005_TYPE_MB 0xF
132
133 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
134
135 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
136
137 #define SUBID_9005_TYPE(id) ((id) & 0xF)
138 #define SUBID_9005_TYPE_HBA 0x0
139 #define SUBID_9005_TYPE_MB 0xF
140
141 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
142
143 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
144
145 #define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
146 #define SUBID_9005_SEEPTYPE_NONE 0x0
147 #define SUBID_9005_SEEPTYPE_4K 0x1
148
149 ahd_device_setup_t ahd_aic7901_setup;
150 ahd_device_setup_t ahd_aic7901A_setup;
151 ahd_device_setup_t ahd_aic7902_setup;
152 ahd_device_setup_t ahd_aic790X_setup;
153
154 struct ahd_pci_identity ahd_pci_ident_table [] =
155 {
156
157 {
158 ID_AHA_29320A,
159 ID_ALL_MASK,
160 ahd_aic7901_setup
161 },
162 {
163 ID_AHA_29320ALP,
164 ID_ALL_MASK,
165 ahd_aic7901_setup
166 },
167
168 {
169 ID_AHA_29320LP,
170 ID_ALL_MASK,
171 ahd_aic7901A_setup
172 },
173
174 {
175 ID_AHA_29320,
176 ID_ALL_MASK,
177 ahd_aic7902_setup
178 },
179 {
180 ID_AHA_29320B,
181 ID_ALL_MASK,
182 ahd_aic7902_setup
183 },
184 {
185 ID_AHA_39320,
186 ID_ALL_MASK,
187 ahd_aic7902_setup
188 },
189 {
190 ID_AHA_39320_B,
191 ID_ALL_MASK,
192 ahd_aic7902_setup
193 },
194 {
195 ID_AHA_39320_B_DELL,
196 ID_ALL_MASK,
197 ahd_aic7902_setup
198 },
199 {
200 ID_AHA_39320A,
201 ID_ALL_MASK,
202 ahd_aic7902_setup
203 },
204 {
205 ID_AHA_39320D,
206 ID_ALL_MASK,
207 ahd_aic7902_setup
208 },
209 {
210 ID_AHA_39320D_HP,
211 ID_ALL_MASK,
212 ahd_aic7902_setup
213 },
214 {
215 ID_AHA_39320D_B,
216 ID_ALL_MASK,
217 ahd_aic7902_setup
218 },
219 {
220 ID_AHA_39320D_B_HP,
221 ID_ALL_MASK,
222 ahd_aic7902_setup
223 },
224
225 {
226 ID_AIC7901 & ID_9005_GENERIC_MASK,
227 ID_9005_GENERIC_MASK,
228 ahd_aic7901_setup
229 },
230 {
231 ID_AIC7901A & ID_DEV_VENDOR_MASK,
232 ID_DEV_VENDOR_MASK,
233 ahd_aic7901A_setup
234 },
235 {
236 ID_AIC7902 & ID_9005_GENERIC_MASK,
237 ID_9005_GENERIC_MASK,
238 ahd_aic7902_setup
239 }
240 };
241
242 const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
243
244 #define DEVCONFIG 0x40
245 #define PCIXINITPAT 0x0000E000ul
246 #define PCIXINIT_PCI33_66 0x0000E000ul
247 #define PCIXINIT_PCIX50_66 0x0000C000ul
248 #define PCIXINIT_PCIX66_100 0x0000A000ul
249 #define PCIXINIT_PCIX100_133 0x00008000ul
250 #define PCI_BUS_MODES_INDEX(devconfig) \
251 (((devconfig) & PCIXINITPAT) >> 13)
252
253 static const char *pci_bus_modes[] =
254 {
255 "PCI bus mode unknown",
256 "PCI bus mode unknown",
257 "PCI bus mode unknown",
258 "PCI bus mode unknown",
259 "PCI-X 101-133MHz",
260 "PCI-X 67-100MHz",
261 "PCI-X 50-66MHz",
262 "PCI 33 or 66MHz"
263 };
264
265 #define TESTMODE 0x00000800ul
266 #define IRDY_RST 0x00000200ul
267 #define FRAME_RST 0x00000100ul
268 #define PCI64BIT 0x00000080ul
269 #define MRDCEN 0x00000040ul
270 #define ENDIANSEL 0x00000020ul
271 #define MIXQWENDIANEN 0x00000008ul
272 #define DACEN 0x00000004ul
273 #define STPWLEVEL 0x00000002ul
274 #define QWENDIANSEL 0x00000001ul
275
276 #define DEVCONFIG1 0x44
277 #define PREQDIS 0x01
278
279 #define CSIZE_LATTIME 0x0c
280 #define CACHESIZE 0x000000fful
281 #define LATTIME 0x0000ff00ul
282
283 int ahd_pci_probe(struct device *, void *, void *);
284 void ahd_pci_attach(struct device *, struct device *, void *);
285
286 struct cfattach ahd_pci_ca = {
287 sizeof(struct ahd_softc), ahd_pci_probe, ahd_pci_attach
288 };
289
290 int ahd_check_extport(struct ahd_softc *ahd);
291 void ahd_configure_termination(struct ahd_softc *ahd,
292 u_int adapter_control);
293 void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
294
295 const struct ahd_pci_identity *
296 ahd_find_pci_device(pcireg_t id, pcireg_t subid)
297 {
298 const struct ahd_pci_identity *entry;
299 u_int64_t full_id;
300 u_int i;
301
302 full_id = ahd_compose_id(PCI_PRODUCT(id), PCI_VENDOR(id),
303 PCI_PRODUCT(subid), PCI_VENDOR(subid));
304
305
306
307
308
309
310 if (ahd_attach_to_HostRAID_controllers)
311 full_id &= ID_ALL_IROC_MASK;
312
313 for (i = 0; i < ahd_num_pci_devs; i++) {
314 entry = &ahd_pci_ident_table[i];
315 if (entry->full_id == (full_id & entry->id_mask)) {
316 return (entry);
317 }
318 }
319 return (NULL);
320 }
321
322 int
323 ahd_pci_probe(struct device *parent, void *match, void *aux)
324 {
325 const struct ahd_pci_identity *entry;
326 struct pci_attach_args *pa = aux;
327 pcireg_t subid;
328
329 subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
330 entry = ahd_find_pci_device(pa->pa_id, subid);
331 return entry != NULL ? 1 : 0;
332 }
333
334 void
335 ahd_pci_attach(struct device *parent, struct device *self, void *aux)
336 {
337 const struct ahd_pci_identity *entry;
338 struct pci_attach_args *pa = aux;
339 struct ahd_softc *ahd = (void *)self;
340 pci_intr_handle_t ih;
341 const char *intrstr;
342 pcireg_t devconfig, memtype, reg, subid;
343 uint16_t device, subvendor;
344 int error, ioh_valid, ioh2_valid, l, memh_valid, offset;
345
346 ahd->dev_softc = pa;
347 ahd->parent_dmat = pa->pa_dmat;
348
349 if (ahd_alloc(ahd, ahd->sc_dev.dv_xname) == NULL)
350 return;
351
352 subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
353 entry = ahd_find_pci_device(pa->pa_id, subid);
354 if (entry == NULL)
355 return;
356
357
358
359
360 device = PCI_PRODUCT(pa->pa_id);
361 if (DEVID_9005_HOSTRAID(device))
362 ahd->flags |= AHD_HOSTRAID_BOARD;
363
364
365
366
367 subvendor = PCI_VENDOR(subid);
368 if (subvendor == SUBID_HP)
369 ahd->flags |= AHD_HP_BOARD;
370
371 error = entry->setup(ahd, pa);
372 if (error != 0)
373 return;
374
375
376 devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
377
378 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
379 ahd->chip |= AHD_PCI;
380
381 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
382 } else {
383 ahd->chip |= AHD_PCIX;
384 }
385 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
386
387 memh_valid = ioh_valid = ioh2_valid = 0;
388
389 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX,
390 &ahd->pcix_off, NULL)) {
391 if (ahd->chip & AHD_PCIX)
392 printf("%s: warning: can't find PCI-X capability\n",
393 ahd_name(ahd));
394 ahd->chip &= ~AHD_PCIX;
395 ahd->chip |= AHD_PCI;
396 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
397 }
398
399
400
401
402 if ((ahd->bugs & AHD_PCIX_MMAPIO_BUG) == 0) {
403 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
404 AHD_PCI_MEMADDR);
405 switch (memtype) {
406 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
407 case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
408 memh_valid = (pci_mapreg_map(pa, AHD_PCI_MEMADDR,
409 memtype, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
410 NULL, 0) == 0);
411 if (memh_valid) {
412 ahd->tags[1] = ahd->tags[0];
413 bus_space_subregion(ahd->tags[0], ahd->bshs[0],
414 0x100, 0x100,
415 &ahd->bshs[1]);
416 if (ahd_pci_test_register_access(ahd) != 0)
417 memh_valid = 0;
418 }
419 break;
420 default:
421 memh_valid = 0;
422 printf("%s: unknown memory type: 0x%x\n",
423 ahd_name(ahd), memtype);
424 break;
425 }
426
427 #ifdef AHD_DEBUG
428 printf("%s: doing memory mapping tag0 0x%x, tag1 0x%x, shs0 "
429 "0x%lx, shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0],
430 ahd->tags[1], ahd->bshs[0], ahd->bshs[1]);
431 #endif
432 }
433
434 if (!memh_valid) {
435
436 ioh_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR,
437 PCI_MAPREG_TYPE_IO, 0, &ahd->tags[0], &ahd->bshs[0], NULL,
438 NULL, 0) == 0);
439
440
441 ioh2_valid = (pci_mapreg_map(pa, AHD_PCI_IOADDR1,
442 PCI_MAPREG_TYPE_IO, 0, &ahd->tags[1], &ahd->bshs[1], NULL,
443 NULL, 0) == 0);
444
445 #ifdef AHD_DEBUG
446 printf("%s: doing io mapping tag0 0x%x, tag1 0x%x, shs0 0x%lx, "
447 "shs1 0x%lx\n", ahd_name(ahd), ahd->tags[0], ahd->tags[1],
448 ahd->bshs[0], ahd->bshs[1]);
449 #endif
450 }
451
452 if (memh_valid == 0 && (ioh_valid == 0 || ioh2_valid == 0)) {
453 printf("%s: unable to map registers\n", ahd_name(ahd));
454 return;
455 }
456
457
458
459
460 if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT, &offset,
461 NULL)) {
462
463 offset += 4;
464 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, offset);
465 if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
466 pci_conf_write(pa->pa_pc, pa->pa_tag, offset,
467 (reg & ~PCI_PMCSR_STATE_MASK) | PCI_PMCSR_STATE_D0);
468 }
469 }
470
471
472
473
474
475 if (sizeof(bus_addr_t) > 4)
476 ahd->flags |= AHD_39BIT_ADDRESSING;
477
478
479
480
481
482
483
484 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
485 pcireg_t devconfig;
486
487 if (bootverbose)
488 printf("%s: Enabling 39Bit Addressing\n",
489 ahd_name(ahd));
490 devconfig = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
491 devconfig |= DACEN;
492 pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG, devconfig);
493 }
494
495 ahd_softc_init(ahd);
496
497
498
499
500 ahd->bus_intr = ahd_pci_intr;
501
502 error = ahd_reset(ahd, FALSE);
503 if (error != 0) {
504 ahd_free(ahd);
505 return;
506 }
507
508 if (pci_intr_map(pa, &ih)) {
509 printf("%s: couldn't map interrupt\n", ahd_name(ahd));
510 ahd_free(ahd);
511 return;
512 }
513 intrstr = pci_intr_string(pa->pa_pc, ih);
514 ahd->ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
515 ahd_platform_intr, ahd, ahd->sc_dev.dv_xname);
516 if (ahd->ih == NULL) {
517 printf("%s: couldn't establish interrupt", ahd_name(ahd));
518 if (intrstr != NULL)
519 printf(" at %s", intrstr);
520 printf("\n");
521 ahd_free(ahd);
522 return;
523 }
524 if (intrstr != NULL)
525 printf(": %s\n", intrstr);
526
527
528 ahd->pci_cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
529 ahd->pci_cachesize *= 4;
530
531 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
532
533 error = ahd_check_extport(ahd);
534 if (error != 0)
535 return;
536
537
538 error = ahd_init(ahd);
539 if (error != 0)
540 return;
541
542 ahd_list_lock(&l);
543
544
545
546 ahd_softc_insert(ahd);
547 ahd_list_unlock(&l);
548
549
550 ahd_attach(ahd);
551 }
552
553
554
555
556
557 int
558 ahd_pci_test_register_access(struct ahd_softc *ahd)
559 {
560 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
561 const pcitag_t tag = ahd->dev_softc->pa_tag;
562 pcireg_t cmd;
563 u_int targpcistat;
564 pcireg_t pci_status1;
565 int error;
566 uint8_t hcntrl;
567
568 error = EIO;
569
570
571
572
573
574 cmd = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
575 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
576 cmd & ~PCI_COMMAND_SERR_ENABLE);
577
578
579
580
581
582
583
584
585
586 hcntrl = ahd_inb(ahd, HCNTRL);
587 if (hcntrl == 0xFF)
588 goto fail;
589
590
591
592
593
594
595
596
597
598 hcntrl &= ~CHIPRST;
599 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
600 while (ahd_is_paused(ahd) == 0)
601 ;
602
603
604 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
605 targpcistat = ahd_inb(ahd, TARGPCISTAT);
606 ahd_outb(ahd, TARGPCISTAT, targpcistat);
607 pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
608 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
609 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
610 ahd_outb(ahd, CLRINT, CLRPCIINT);
611
612 ahd_outb(ahd, SEQCTL0, PERRORDIS);
613 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
614 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
615 goto fail;
616
617 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
618 u_int targpcistat;
619
620 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
621 targpcistat = ahd_inb(ahd, TARGPCISTAT);
622 if ((targpcistat & STA) != 0)
623 goto fail;
624 }
625
626 error = 0;
627
628 fail:
629 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
630
631 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
632 targpcistat = ahd_inb(ahd, TARGPCISTAT);
633
634
635 ahd_outb(ahd, TARGPCISTAT, targpcistat);
636 pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
637 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, pci_status1);
638 ahd_outb(ahd, CLRINT, CLRPCIINT);
639 }
640 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
641 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmd);
642 return (error);
643 }
644
645
646
647
648
649 int
650 ahd_check_extport(struct ahd_softc *ahd)
651 {
652 struct vpd_config vpd;
653 struct seeprom_config *sc;
654 u_int adapter_control;
655 int have_seeprom;
656 int error;
657
658 sc = ahd->seep_config;
659 have_seeprom = ahd_acquire_seeprom(ahd);
660 if (have_seeprom) {
661 u_int start_addr;
662
663
664
665
666 if (bootverbose)
667 printf("%s: Reading VPD from SEEPROM...",
668 ahd_name(ahd));
669
670
671 start_addr = ((2 * sizeof(*sc))
672 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
673
674 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
675 start_addr, sizeof(vpd)/2,
676 TRUE);
677 if (error == 0)
678 error = ahd_parse_vpddata(ahd, &vpd);
679 if (bootverbose)
680 printf("%s: VPD parsing %s\n",
681 ahd_name(ahd),
682 error == 0 ? "successful" : "failed");
683
684 if (bootverbose)
685 printf("%s: Reading SEEPROM...", ahd_name(ahd));
686
687
688 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
689
690 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
691 start_addr, sizeof(*sc)/2,
692 FALSE);
693
694 if (error != 0) {
695 printf("Unable to read SEEPROM\n");
696 have_seeprom = 0;
697 } else {
698 have_seeprom = ahd_verify_cksum(sc);
699
700 if (bootverbose) {
701 if (have_seeprom == 0)
702 printf ("checksum error\n");
703 else
704 printf ("done.\n");
705 }
706 }
707 ahd_release_seeprom(ahd);
708 }
709
710 if (!have_seeprom) {
711 u_int nvram_scb;
712
713
714
715
716
717
718
719
720 ahd_set_scbptr(ahd, 0xFF);
721 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
722 if (nvram_scb != 0xFF
723 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
724 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
725 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
726 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
727 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
728 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
729 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
730 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
731 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
732 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
733 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
734 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
735 uint16_t *sc_data;
736 int i;
737
738 ahd_set_scbptr(ahd, nvram_scb);
739 sc_data = (uint16_t *)sc;
740 for (i = 0; i < 64; i += 2)
741 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
742 have_seeprom = ahd_verify_cksum(sc);
743 if (have_seeprom)
744 ahd->flags |= AHD_SCB_CONFIG_USED;
745 }
746 }
747
748 #ifdef AHD_DEBUG
749 if (have_seeprom != 0
750 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
751 uint16_t *sc_data;
752 int i;
753
754 printf("%s: Seeprom Contents:", ahd_name(ahd));
755 sc_data = (uint16_t *)sc;
756 for (i = 0; i < (sizeof(*sc)); i += 2)
757 printf("\n\t0x%.4x", sc_data[i]);
758 printf("\n");
759 }
760 #endif
761
762 if (!have_seeprom) {
763 if (bootverbose)
764 printf("%s: No SEEPROM available.\n", ahd_name(ahd));
765 ahd->flags |= AHD_USEDEFAULTS;
766 error = ahd_default_config(ahd);
767 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
768 free(ahd->seep_config, M_DEVBUF);
769 ahd->seep_config = NULL;
770 } else {
771 error = ahd_parse_cfgdata(ahd, sc);
772 adapter_control = sc->adapter_control;
773 }
774 if (error != 0)
775 return (error);
776
777 ahd_configure_termination(ahd, adapter_control);
778
779 return (0);
780 }
781
782 void
783 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
784 {
785 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
786 const pcitag_t tag = ahd->dev_softc->pa_tag;
787 int error;
788 u_int sxfrctl1;
789 uint8_t termctl;
790 pcireg_t devconfig;
791
792 devconfig = pci_conf_read(pc, tag, DEVCONFIG);
793 devconfig &= ~STPWLEVEL;
794 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
795 devconfig |= STPWLEVEL;
796 if (bootverbose)
797 printf("%s: STPWLEVEL is %s\n",
798 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
799 pci_conf_write(pc, tag, DEVCONFIG, devconfig);
800
801
802 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
803 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
804 }
805
806
807
808
809 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
810 if ((adapter_control & CFAUTOTERM) == 0) {
811 if (bootverbose)
812 printf("%s: Manual Primary Termination\n",
813 ahd_name(ahd));
814 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
815 if ((adapter_control & CFSTERM) != 0)
816 termctl |= FLX_TERMCTL_ENPRILOW;
817 if ((adapter_control & CFWSTERM) != 0)
818 termctl |= FLX_TERMCTL_ENPRIHIGH;
819 } else if (error != 0) {
820 printf("%s: Primary Auto-Term Sensing failed! "
821 "Using Defaults.\n", ahd_name(ahd));
822 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
823 }
824
825 if ((adapter_control & CFSEAUTOTERM) == 0) {
826 if (bootverbose)
827 printf("%s: Manual Secondary Termination\n",
828 ahd_name(ahd));
829 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
830 if ((adapter_control & CFSELOWTERM) != 0)
831 termctl |= FLX_TERMCTL_ENSECLOW;
832 if ((adapter_control & CFSEHIGHTERM) != 0)
833 termctl |= FLX_TERMCTL_ENSECHIGH;
834 } else if (error != 0) {
835 printf("%s: Secondary Auto-Term Sensing failed! "
836 "Using Defaults.\n", ahd_name(ahd));
837 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
838 }
839
840
841
842
843 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
844 ahd->flags &= ~AHD_TERM_ENB_A;
845 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
846 ahd->flags |= AHD_TERM_ENB_A;
847 sxfrctl1 |= STPWEN;
848 }
849
850 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
851 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
852
853 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
854 if (error != 0) {
855 printf("%s: Unable to set termination settings!\n",
856 ahd_name(ahd));
857 } else if (bootverbose) {
858 printf("%s: Primary High byte termination %sabled\n",
859 ahd_name(ahd),
860 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
861
862 printf("%s: Primary Low byte termination %sabled\n",
863 ahd_name(ahd),
864 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
865
866 printf("%s: Secondary High byte termination %sabled\n",
867 ahd_name(ahd),
868 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
869
870 printf("%s: Secondary Low byte termination %sabled\n",
871 ahd_name(ahd),
872 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
873 }
874 return;
875 }
876
877 #define DPE 0x80
878 #define SSE 0x40
879 #define RMA 0x20
880 #define RTA 0x10
881 #define STA 0x08
882 #define DPR 0x01
883
884 static const char *split_status_source[] =
885 {
886 "DFF0",
887 "DFF1",
888 "OVLY",
889 "CMC",
890 };
891
892 static const char *pci_status_source[] =
893 {
894 "DFF0",
895 "DFF1",
896 "SG",
897 "CMC",
898 "OVLY",
899 "NONE",
900 "MSI",
901 "TARG"
902 };
903
904 static const char *split_status_strings[] =
905 {
906 "%s: Received split response in %s.\n",
907 "%s: Received split completion error message in %s\n",
908 "%s: Receive overrun in %s\n",
909 "%s: Count not complete in %s\n",
910 "%s: Split completion data bucket in %s\n",
911 "%s: Split completion address error in %s\n",
912 "%s: Split completion byte count error in %s\n",
913 "%s: Signaled Target-abort to early terminate a split in %s\n"
914 };
915
916 static const char *pci_status_strings[] =
917 {
918 "%s: Data Parity Error has been reported via PERR# in %s\n",
919 "%s: Target initial wait state error in %s\n",
920 "%s: Split completion read data parity error in %s\n",
921 "%s: Split completion address attribute parity error in %s\n",
922 "%s: Received a Target Abort in %s\n",
923 "%s: Received a Master Abort in %s\n",
924 "%s: Signal System Error Detected in %s\n",
925 "%s: Address or Write Phase Parity Error Detected in %s.\n"
926 };
927
928 void
929 ahd_pci_intr(struct ahd_softc *ahd)
930 {
931 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
932 const pcitag_t tag = ahd->dev_softc->pa_tag;
933 uint8_t pci_status[8];
934 ahd_mode_state saved_modes;
935 pcireg_t pci_status1;
936 u_int intstat;
937 u_int i;
938 u_int reg;
939
940 intstat = ahd_inb(ahd, INTSTAT);
941
942 if ((intstat & SPLTINT) != 0)
943 ahd_pci_split_intr(ahd, intstat);
944
945 if ((intstat & PCIINT) == 0)
946 return;
947
948 printf("%s: PCI error Interrupt\n", ahd_name(ahd));
949 saved_modes = ahd_save_modes(ahd);
950 ahd_dump_card_state(ahd);
951 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
952 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
953
954 if (i == 5)
955 continue;
956 pci_status[i] = ahd_inb(ahd, reg);
957
958 ahd_outb(ahd, reg, pci_status[i]);
959 }
960
961 for (i = 0; i < 8; i++) {
962 u_int bit;
963
964 if (i == 5)
965 continue;
966
967 for (bit = 0; bit < 8; bit++) {
968
969 if ((pci_status[i] & (0x1 << bit)) != 0) {
970 static const char *s;
971
972 s = pci_status_strings[bit];
973 if (i == 7 && bit == 3)
974 s = "%s: Signaled Target Abort\n";
975 printf(s, ahd_name(ahd), pci_status_source[i]);
976 }
977 }
978 }
979 pci_status1 = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
980 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG , pci_status1);
981
982 ahd_restore_modes(ahd, saved_modes);
983 ahd_outb(ahd, CLRINT, CLRPCIINT);
984 ahd_unpause(ahd);
985
986 return;
987 }
988
989 void
990 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
991 {
992 const pci_chipset_tag_t pc = ahd->dev_softc->pa_pc;
993 const pcitag_t tag = ahd->dev_softc->pa_tag;
994 uint8_t split_status[4];
995 uint8_t split_status1[4];
996 uint8_t sg_split_status[2];
997 uint8_t sg_split_status1[2];
998 ahd_mode_state saved_modes;
999 u_int i;
1000 pcireg_t pcix_status;
1001
1002
1003
1004
1005
1006 pcix_status = pci_conf_read(pc, tag, ahd->pcix_off + 0x04);
1007 printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
1008 ahd_name(ahd), pcix_status);
1009
1010 saved_modes = ahd_save_modes(ahd);
1011 for (i = 0; i < 4; i++) {
1012 ahd_set_modes(ahd, i, i);
1013
1014 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
1015 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
1016
1017 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
1018 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
1019 if (i > 1)
1020 continue;
1021 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
1022 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
1023
1024 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
1025 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
1026 }
1027
1028 for (i = 0; i < 4; i++) {
1029 u_int bit;
1030
1031 for (bit = 0; bit < 8; bit++) {
1032
1033 if ((split_status[i] & (0x1 << bit)) != 0) {
1034 static const char *s;
1035
1036 s = split_status_strings[bit];
1037 printf(s, ahd_name(ahd),
1038 split_status_source[i]);
1039 }
1040
1041 if (i > 1)
1042 continue;
1043
1044 if ((sg_split_status[i] & (0x1 << bit)) != 0) {
1045 static const char *s;
1046
1047 s = split_status_strings[bit];
1048 printf(s, ahd_name(ahd), "SG");
1049 }
1050 }
1051 }
1052
1053
1054
1055 pci_conf_write(pc, tag, ahd->pcix_off + 0x04, pcix_status);
1056 ahd_outb(ahd, CLRINT, CLRSPLTINT);
1057 ahd_restore_modes(ahd, saved_modes);
1058 }
1059
1060 int
1061 ahd_aic7901_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1062 {
1063
1064 ahd->chip = AHD_AIC7901;
1065 ahd->features = AHD_AIC7901_FE;
1066 return (ahd_aic790X_setup(ahd, pa));
1067 }
1068
1069 int
1070 ahd_aic7901A_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1071 {
1072
1073 ahd->chip = AHD_AIC7901A;
1074 ahd->features = AHD_AIC7901A_FE;
1075 return (ahd_aic790X_setup(ahd, pa));
1076 }
1077
1078 int
1079 ahd_aic7902_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1080 {
1081 ahd->chip = AHD_AIC7902;
1082 ahd->features = AHD_AIC7902_FE;
1083 return (ahd_aic790X_setup(ahd, pa));
1084 }
1085
1086 int
1087 ahd_aic790X_setup(struct ahd_softc *ahd, struct pci_attach_args *pa)
1088 {
1089 u_int rev;
1090
1091 rev = PCI_REVISION(pa->pa_class);
1092 #ifdef AHD_DEBUG
1093 printf("\n%s: aic7902 chip revision 0x%x\n", ahd_name(ahd), rev);
1094 #endif
1095 if (rev < ID_AIC7902_PCI_REV_A4) {
1096 printf("%s: Unable to attach to unsupported chip revision %d\n",
1097 ahd_name(ahd), rev);
1098 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 0);
1099 return (ENXIO);
1100 }
1101
1102 ahd->channel = (pa->pa_function == 1) ? 'B' : 'A';
1103 if (rev < ID_AIC7902_PCI_REV_B0) {
1104
1105
1106
1107 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
1108 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
1109 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
1110 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
1111 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
1112 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
1113 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
1114 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
1115 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
1116 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
1117 | AHD_FAINT_LED_BUG;
1118
1119
1120
1121
1122 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
1123
1124 if ((ahd->flags & AHD_HP_BOARD) == 0)
1125 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
1126 } else {
1127 pcireg_t devconfig1;
1128
1129 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
1130 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
1131 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG
1132 | AHD_BUSFREEREV_BUG;
1133
1134
1135
1136
1137 if ((ahd->features & AHD_MULTI_FUNC) != 0)
1138 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
1139
1140
1141
1142
1143 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
1144 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
1145 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
1146
1147
1148
1149
1150
1151
1152
1153 devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
1154 pci_conf_write(pa->pa_pc, pa->pa_tag, DEVCONFIG1, devconfig1|PREQDIS);
1155 devconfig1 = pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG1);
1156 }
1157
1158 return (0);
1159 }