0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 #include "aic79xx_osm.h"
0045 #include "aic79xx_inline.h"
0046 #include "aic79xx_pci.h"
0047
0048 static inline uint64_t
0049 ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
0050 {
0051 uint64_t id;
0052
0053 id = subvendor
0054 | (subdevice << 16)
0055 | ((uint64_t)vendor << 32)
0056 | ((uint64_t)device << 48);
0057
0058 return (id);
0059 }
0060
0061 #define ID_AIC7902_PCI_REV_A4 0x3
0062 #define ID_AIC7902_PCI_REV_B0 0x10
0063 #define SUBID_HP 0x0E11
0064
0065 #define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
0066
0067 #define DEVID_9005_TYPE(id) ((id) & 0xF)
0068 #define DEVID_9005_TYPE_HBA 0x0
0069 #define DEVID_9005_TYPE_HBA_2EXT 0x1
0070 #define DEVID_9005_TYPE_IROC 0x8
0071 #define DEVID_9005_TYPE_MB 0xF
0072
0073 #define DEVID_9005_MFUNC(id) ((id) & 0x10)
0074
0075 #define DEVID_9005_PACKETIZED(id) ((id) & 0x8000)
0076
0077 #define SUBID_9005_TYPE(id) ((id) & 0xF)
0078 #define SUBID_9005_TYPE_HBA 0x0
0079 #define SUBID_9005_TYPE_MB 0xF
0080
0081 #define SUBID_9005_AUTOTERM(id) (((id) & 0x10) == 0)
0082
0083 #define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
0084
0085 #define SUBID_9005_SEEPTYPE(id) (((id) & 0x0C0) >> 6)
0086 #define SUBID_9005_SEEPTYPE_NONE 0x0
0087 #define SUBID_9005_SEEPTYPE_4K 0x1
0088
0089 static ahd_device_setup_t ahd_aic7901_setup;
0090 static ahd_device_setup_t ahd_aic7901A_setup;
0091 static ahd_device_setup_t ahd_aic7902_setup;
0092 static ahd_device_setup_t ahd_aic790X_setup;
0093
0094 static const struct ahd_pci_identity ahd_pci_ident_table[] =
0095 {
0096
0097 {
0098 ID_AHA_29320A,
0099 ID_ALL_MASK,
0100 "Adaptec 29320A Ultra320 SCSI adapter",
0101 ahd_aic7901_setup
0102 },
0103 {
0104 ID_AHA_29320ALP,
0105 ID_ALL_MASK,
0106 "Adaptec 29320ALP PCIx Ultra320 SCSI adapter",
0107 ahd_aic7901_setup
0108 },
0109 {
0110 ID_AHA_29320LPE,
0111 ID_ALL_MASK,
0112 "Adaptec 29320LPE PCIe Ultra320 SCSI adapter",
0113 ahd_aic7901_setup
0114 },
0115
0116 {
0117 ID_AHA_29320LP,
0118 ID_ALL_MASK,
0119 "Adaptec 29320LP Ultra320 SCSI adapter",
0120 ahd_aic7901A_setup
0121 },
0122
0123 {
0124 ID_AHA_29320,
0125 ID_ALL_MASK,
0126 "Adaptec 29320 Ultra320 SCSI adapter",
0127 ahd_aic7902_setup
0128 },
0129 {
0130 ID_AHA_29320B,
0131 ID_ALL_MASK,
0132 "Adaptec 29320B Ultra320 SCSI adapter",
0133 ahd_aic7902_setup
0134 },
0135 {
0136 ID_AHA_39320,
0137 ID_ALL_MASK,
0138 "Adaptec 39320 Ultra320 SCSI adapter",
0139 ahd_aic7902_setup
0140 },
0141 {
0142 ID_AHA_39320_B,
0143 ID_ALL_MASK,
0144 "Adaptec 39320 Ultra320 SCSI adapter",
0145 ahd_aic7902_setup
0146 },
0147 {
0148 ID_AHA_39320_B_DELL,
0149 ID_ALL_MASK,
0150 "Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",
0151 ahd_aic7902_setup
0152 },
0153 {
0154 ID_AHA_39320A,
0155 ID_ALL_MASK,
0156 "Adaptec 39320A Ultra320 SCSI adapter",
0157 ahd_aic7902_setup
0158 },
0159 {
0160 ID_AHA_39320D,
0161 ID_ALL_MASK,
0162 "Adaptec 39320D Ultra320 SCSI adapter",
0163 ahd_aic7902_setup
0164 },
0165 {
0166 ID_AHA_39320D_HP,
0167 ID_ALL_MASK,
0168 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
0169 ahd_aic7902_setup
0170 },
0171 {
0172 ID_AHA_39320D_B,
0173 ID_ALL_MASK,
0174 "Adaptec 39320D Ultra320 SCSI adapter",
0175 ahd_aic7902_setup
0176 },
0177 {
0178 ID_AHA_39320D_B_HP,
0179 ID_ALL_MASK,
0180 "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
0181 ahd_aic7902_setup
0182 },
0183
0184 {
0185 ID_AIC7901 & ID_9005_GENERIC_MASK,
0186 ID_9005_GENERIC_MASK,
0187 "Adaptec AIC7901 Ultra320 SCSI adapter",
0188 ahd_aic7901_setup
0189 },
0190 {
0191 ID_AIC7901A & ID_DEV_VENDOR_MASK,
0192 ID_DEV_VENDOR_MASK,
0193 "Adaptec AIC7901A Ultra320 SCSI adapter",
0194 ahd_aic7901A_setup
0195 },
0196 {
0197 ID_AIC7902 & ID_9005_GENERIC_MASK,
0198 ID_9005_GENERIC_MASK,
0199 "Adaptec AIC7902 Ultra320 SCSI adapter",
0200 ahd_aic7902_setup
0201 }
0202 };
0203
0204 static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
0205
0206 #define DEVCONFIG 0x40
0207 #define PCIXINITPAT 0x0000E000ul
0208 #define PCIXINIT_PCI33_66 0x0000E000ul
0209 #define PCIXINIT_PCIX50_66 0x0000C000ul
0210 #define PCIXINIT_PCIX66_100 0x0000A000ul
0211 #define PCIXINIT_PCIX100_133 0x00008000ul
0212 #define PCI_BUS_MODES_INDEX(devconfig) \
0213 (((devconfig) & PCIXINITPAT) >> 13)
0214 static const char *pci_bus_modes[] =
0215 {
0216 "PCI bus mode unknown",
0217 "PCI bus mode unknown",
0218 "PCI bus mode unknown",
0219 "PCI bus mode unknown",
0220 "PCI-X 101-133MHz",
0221 "PCI-X 67-100MHz",
0222 "PCI-X 50-66MHz",
0223 "PCI 33 or 66MHz"
0224 };
0225
0226 #define TESTMODE 0x00000800ul
0227 #define IRDY_RST 0x00000200ul
0228 #define FRAME_RST 0x00000100ul
0229 #define PCI64BIT 0x00000080ul
0230 #define MRDCEN 0x00000040ul
0231 #define ENDIANSEL 0x00000020ul
0232 #define MIXQWENDIANEN 0x00000008ul
0233 #define DACEN 0x00000004ul
0234 #define STPWLEVEL 0x00000002ul
0235 #define QWENDIANSEL 0x00000001ul
0236
0237 #define DEVCONFIG1 0x44
0238 #define PREQDIS 0x01
0239
0240 #define CSIZE_LATTIME 0x0c
0241 #define CACHESIZE 0x000000fful
0242 #define LATTIME 0x0000ff00ul
0243
0244 static int ahd_check_extport(struct ahd_softc *ahd);
0245 static void ahd_configure_termination(struct ahd_softc *ahd,
0246 u_int adapter_control);
0247 static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
0248 static void ahd_pci_intr(struct ahd_softc *ahd);
0249
0250 const struct ahd_pci_identity *
0251 ahd_find_pci_device(ahd_dev_softc_t pci)
0252 {
0253 uint64_t full_id;
0254 uint16_t device;
0255 uint16_t vendor;
0256 uint16_t subdevice;
0257 uint16_t subvendor;
0258 const struct ahd_pci_identity *entry;
0259 u_int i;
0260
0261 vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, 2);
0262 device = ahd_pci_read_config(pci, PCIR_DEVICE, 2);
0263 subvendor = ahd_pci_read_config(pci, PCI_SUBSYSTEM_VENDOR_ID, 2);
0264 subdevice = ahd_pci_read_config(pci, PCI_SUBSYSTEM_ID, 2);
0265 full_id = ahd_compose_id(device,
0266 vendor,
0267 subdevice,
0268 subvendor);
0269
0270
0271
0272
0273
0274 full_id &= ID_ALL_IROC_MASK;
0275
0276 for (i = 0; i < ahd_num_pci_devs; i++) {
0277 entry = &ahd_pci_ident_table[i];
0278 if (entry->full_id == (full_id & entry->id_mask)) {
0279
0280 if (entry->name == NULL)
0281 return (NULL);
0282 return (entry);
0283 }
0284 }
0285 return (NULL);
0286 }
0287
0288 int
0289 ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
0290 {
0291 u_int command;
0292 uint32_t devconfig;
0293 uint16_t subvendor;
0294 int error;
0295
0296 ahd->description = entry->name;
0297
0298
0299
0300 subvendor = ahd_pci_read_config(ahd->dev_softc,
0301 PCI_SUBSYSTEM_VENDOR_ID, 2);
0302 if (subvendor == SUBID_HP)
0303 ahd->flags |= AHD_HP_BOARD;
0304
0305 error = entry->setup(ahd);
0306 if (error != 0)
0307 return (error);
0308
0309 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, 4);
0310 if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
0311 ahd->chip |= AHD_PCI;
0312
0313 ahd->bugs &= ~AHD_PCIX_BUG_MASK;
0314 } else {
0315 ahd->chip |= AHD_PCIX;
0316 }
0317 ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
0318
0319 ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
0320
0321 error = ahd_pci_map_registers(ahd);
0322 if (error != 0)
0323 return (error);
0324
0325
0326
0327
0328
0329
0330
0331 if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
0332 if (bootverbose)
0333 printk("%s: Enabling 39Bit Addressing\n",
0334 ahd_name(ahd));
0335 devconfig = ahd_pci_read_config(ahd->dev_softc,
0336 DEVCONFIG, 4);
0337 devconfig |= DACEN;
0338 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
0339 devconfig, 4);
0340 }
0341
0342
0343 command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 2);
0344 command |= PCIM_CMD_BUSMASTEREN;
0345 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 2);
0346
0347 error = ahd_softc_init(ahd);
0348 if (error != 0)
0349 return (error);
0350
0351 ahd->bus_intr = ahd_pci_intr;
0352
0353 error = ahd_reset(ahd, FALSE);
0354 if (error != 0)
0355 return (ENXIO);
0356
0357 ahd->pci_cachesize =
0358 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
0359 1) & CACHESIZE;
0360 ahd->pci_cachesize *= 4;
0361
0362 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
0363
0364 error = ahd_check_extport(ahd);
0365 if (error != 0)
0366 return (error);
0367
0368
0369 error = ahd_init(ahd);
0370 if (error != 0)
0371 return (error);
0372 ahd->init_level++;
0373
0374
0375
0376
0377 return ahd_pci_map_int(ahd);
0378 }
0379
0380 void __maybe_unused
0381 ahd_pci_suspend(struct ahd_softc *ahd)
0382 {
0383
0384
0385
0386
0387 ahd->suspend_state.pci_state.devconfig =
0388 ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, 4);
0389 ahd->suspend_state.pci_state.command =
0390 ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 1);
0391 ahd->suspend_state.pci_state.csize_lattime =
0392 ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME, 1);
0393
0394 }
0395
0396 void __maybe_unused
0397 ahd_pci_resume(struct ahd_softc *ahd)
0398 {
0399 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
0400 ahd->suspend_state.pci_state.devconfig, 4);
0401 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
0402 ahd->suspend_state.pci_state.command, 1);
0403 ahd_pci_write_config(ahd->dev_softc, CSIZE_LATTIME,
0404 ahd->suspend_state.pci_state.csize_lattime, 1);
0405 }
0406
0407
0408
0409
0410
0411 int
0412 ahd_pci_test_register_access(struct ahd_softc *ahd)
0413 {
0414 uint32_t cmd;
0415 u_int targpcistat;
0416 u_int pci_status1;
0417 int error;
0418 uint8_t hcntrl;
0419
0420 error = EIO;
0421
0422
0423
0424
0425
0426 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 2);
0427 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
0428 cmd & ~PCIM_CMD_SERRESPEN, 2);
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 hcntrl = ahd_inb(ahd, HCNTRL);
0439 if (hcntrl == 0xFF)
0440 goto fail;
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450 hcntrl &= ~CHIPRST;
0451 ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
0452 while (ahd_is_paused(ahd) == 0)
0453 ;
0454
0455
0456 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0457 targpcistat = ahd_inb(ahd, TARGPCISTAT);
0458 ahd_outb(ahd, TARGPCISTAT, targpcistat);
0459 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
0460 PCIR_STATUS + 1, 1);
0461 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
0462 pci_status1, 1);
0463 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
0464 ahd_outb(ahd, CLRINT, CLRPCIINT);
0465
0466 ahd_outb(ahd, SEQCTL0, PERRORDIS);
0467 ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
0468 if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
0469 goto fail;
0470
0471 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
0472 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0473 targpcistat = ahd_inb(ahd, TARGPCISTAT);
0474 if ((targpcistat & STA) != 0)
0475 goto fail;
0476 }
0477
0478 error = 0;
0479
0480 fail:
0481 if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
0482
0483 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0484 targpcistat = ahd_inb(ahd, TARGPCISTAT);
0485
0486
0487 ahd_outb(ahd, TARGPCISTAT, targpcistat);
0488 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
0489 PCIR_STATUS + 1, 1);
0490 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
0491 pci_status1, 1);
0492 ahd_outb(ahd, CLRINT, CLRPCIINT);
0493 }
0494 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
0495 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, 2);
0496 return (error);
0497 }
0498
0499
0500
0501
0502
0503 static int
0504 ahd_check_extport(struct ahd_softc *ahd)
0505 {
0506 struct vpd_config vpd;
0507 struct seeprom_config *sc;
0508 u_int adapter_control;
0509 int have_seeprom;
0510 int error;
0511
0512 sc = ahd->seep_config;
0513 have_seeprom = ahd_acquire_seeprom(ahd);
0514 if (have_seeprom) {
0515 u_int start_addr;
0516
0517
0518
0519
0520 if (bootverbose)
0521 printk("%s: Reading VPD from SEEPROM...",
0522 ahd_name(ahd));
0523
0524
0525 start_addr = ((2 * sizeof(*sc))
0526 + (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
0527
0528 error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
0529 start_addr, sizeof(vpd)/2,
0530 TRUE);
0531 if (error == 0)
0532 error = ahd_parse_vpddata(ahd, &vpd);
0533 if (bootverbose)
0534 printk("%s: VPD parsing %s\n",
0535 ahd_name(ahd),
0536 error == 0 ? "successful" : "failed");
0537
0538 if (bootverbose)
0539 printk("%s: Reading SEEPROM...", ahd_name(ahd));
0540
0541
0542 start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
0543
0544 error = ahd_read_seeprom(ahd, (uint16_t *)sc,
0545 start_addr, sizeof(*sc)/2,
0546 FALSE);
0547
0548 if (error != 0) {
0549 printk("Unable to read SEEPROM\n");
0550 have_seeprom = 0;
0551 } else {
0552 have_seeprom = ahd_verify_cksum(sc);
0553
0554 if (bootverbose) {
0555 if (have_seeprom == 0)
0556 printk ("checksum error\n");
0557 else
0558 printk ("done.\n");
0559 }
0560 }
0561 ahd_release_seeprom(ahd);
0562 }
0563
0564 if (!have_seeprom) {
0565 u_int nvram_scb;
0566
0567
0568
0569
0570
0571
0572
0573
0574 ahd_set_scbptr(ahd, 0xFF);
0575 nvram_scb = ahd_inb_scbram(ahd, SCB_BASE + NVRAM_SCB_OFFSET);
0576 if (nvram_scb != 0xFF
0577 && ((ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
0578 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'D'
0579 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
0580 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'T')
0581 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'B'
0582 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'I'
0583 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'O'
0584 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'S')
0585 || (ahd_inb_scbram(ahd, SCB_BASE + 0) == 'A'
0586 && ahd_inb_scbram(ahd, SCB_BASE + 1) == 'S'
0587 && ahd_inb_scbram(ahd, SCB_BASE + 2) == 'P'
0588 && ahd_inb_scbram(ahd, SCB_BASE + 3) == 'I'))) {
0589 uint16_t *sc_data;
0590 int i;
0591
0592 ahd_set_scbptr(ahd, nvram_scb);
0593 sc_data = (uint16_t *)sc;
0594 for (i = 0; i < 64; i += 2)
0595 *sc_data++ = ahd_inw_scbram(ahd, SCB_BASE+i);
0596 have_seeprom = ahd_verify_cksum(sc);
0597 if (have_seeprom)
0598 ahd->flags |= AHD_SCB_CONFIG_USED;
0599 }
0600 }
0601
0602 #ifdef AHD_DEBUG
0603 if (have_seeprom != 0
0604 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
0605 uint16_t *sc_data;
0606 int i;
0607
0608 printk("%s: Seeprom Contents:", ahd_name(ahd));
0609 sc_data = (uint16_t *)sc;
0610 for (i = 0; i < (sizeof(*sc)); i += 2)
0611 printk("\n\t0x%.4x", sc_data[i]);
0612 printk("\n");
0613 }
0614 #endif
0615
0616 if (!have_seeprom) {
0617 if (bootverbose)
0618 printk("%s: No SEEPROM available.\n", ahd_name(ahd));
0619 ahd->flags |= AHD_USEDEFAULTS;
0620 error = ahd_default_config(ahd);
0621 adapter_control = CFAUTOTERM|CFSEAUTOTERM;
0622 kfree(ahd->seep_config);
0623 ahd->seep_config = NULL;
0624 } else {
0625 error = ahd_parse_cfgdata(ahd, sc);
0626 adapter_control = sc->adapter_control;
0627 }
0628 if (error != 0)
0629 return (error);
0630
0631 ahd_configure_termination(ahd, adapter_control);
0632
0633 return (0);
0634 }
0635
0636 static void
0637 ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
0638 {
0639 int error;
0640 u_int sxfrctl1;
0641 uint8_t termctl;
0642 uint32_t devconfig;
0643
0644 devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, 4);
0645 devconfig &= ~STPWLEVEL;
0646 if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
0647 devconfig |= STPWLEVEL;
0648 if (bootverbose)
0649 printk("%s: STPWLEVEL is %s\n",
0650 ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
0651 ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, 4);
0652
0653
0654 if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
0655 (void)ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
0656 }
0657
0658
0659
0660
0661 error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
0662 if ((adapter_control & CFAUTOTERM) == 0) {
0663 if (bootverbose)
0664 printk("%s: Manual Primary Termination\n",
0665 ahd_name(ahd));
0666 termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
0667 if ((adapter_control & CFSTERM) != 0)
0668 termctl |= FLX_TERMCTL_ENPRILOW;
0669 if ((adapter_control & CFWSTERM) != 0)
0670 termctl |= FLX_TERMCTL_ENPRIHIGH;
0671 } else if (error != 0) {
0672 printk("%s: Primary Auto-Term Sensing failed! "
0673 "Using Defaults.\n", ahd_name(ahd));
0674 termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
0675 }
0676
0677 if ((adapter_control & CFSEAUTOTERM) == 0) {
0678 if (bootverbose)
0679 printk("%s: Manual Secondary Termination\n",
0680 ahd_name(ahd));
0681 termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
0682 if ((adapter_control & CFSELOWTERM) != 0)
0683 termctl |= FLX_TERMCTL_ENSECLOW;
0684 if ((adapter_control & CFSEHIGHTERM) != 0)
0685 termctl |= FLX_TERMCTL_ENSECHIGH;
0686 } else if (error != 0) {
0687 printk("%s: Secondary Auto-Term Sensing failed! "
0688 "Using Defaults.\n", ahd_name(ahd));
0689 termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
0690 }
0691
0692
0693
0694
0695 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
0696 ahd->flags &= ~AHD_TERM_ENB_A;
0697 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
0698 ahd->flags |= AHD_TERM_ENB_A;
0699 sxfrctl1 |= STPWEN;
0700 }
0701
0702 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
0703 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
0704
0705 error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
0706 if (error != 0) {
0707 printk("%s: Unable to set termination settings!\n",
0708 ahd_name(ahd));
0709 } else if (bootverbose) {
0710 printk("%s: Primary High byte termination %sabled\n",
0711 ahd_name(ahd),
0712 (termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
0713
0714 printk("%s: Primary Low byte termination %sabled\n",
0715 ahd_name(ahd),
0716 (termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
0717
0718 printk("%s: Secondary High byte termination %sabled\n",
0719 ahd_name(ahd),
0720 (termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
0721
0722 printk("%s: Secondary Low byte termination %sabled\n",
0723 ahd_name(ahd),
0724 (termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
0725 }
0726 return;
0727 }
0728
0729 #define DPE 0x80
0730 #define SSE 0x40
0731 #define RMA 0x20
0732 #define RTA 0x10
0733 #define STA 0x08
0734 #define DPR 0x01
0735
0736 static const char *split_status_source[] =
0737 {
0738 "DFF0",
0739 "DFF1",
0740 "OVLY",
0741 "CMC",
0742 };
0743
0744 static const char *pci_status_source[] =
0745 {
0746 "DFF0",
0747 "DFF1",
0748 "SG",
0749 "CMC",
0750 "OVLY",
0751 "NONE",
0752 "MSI",
0753 "TARG"
0754 };
0755
0756 static const char *split_status_strings[] =
0757 {
0758 "%s: Received split response in %s.\n",
0759 "%s: Received split completion error message in %s\n",
0760 "%s: Receive overrun in %s\n",
0761 "%s: Count not complete in %s\n",
0762 "%s: Split completion data bucket in %s\n",
0763 "%s: Split completion address error in %s\n",
0764 "%s: Split completion byte count error in %s\n",
0765 "%s: Signaled Target-abort to early terminate a split in %s\n"
0766 };
0767
0768 static const char *pci_status_strings[] =
0769 {
0770 "%s: Data Parity Error has been reported via PERR# in %s\n",
0771 "%s: Target initial wait state error in %s\n",
0772 "%s: Split completion read data parity error in %s\n",
0773 "%s: Split completion address attribute parity error in %s\n",
0774 "%s: Received a Target Abort in %s\n",
0775 "%s: Received a Master Abort in %s\n",
0776 "%s: Signal System Error Detected in %s\n",
0777 "%s: Address or Write Phase Parity Error Detected in %s.\n"
0778 };
0779
0780 static void
0781 ahd_pci_intr(struct ahd_softc *ahd)
0782 {
0783 uint8_t pci_status[8];
0784 ahd_mode_state saved_modes;
0785 u_int pci_status1;
0786 u_int intstat;
0787 u_int i;
0788 u_int reg;
0789
0790 intstat = ahd_inb(ahd, INTSTAT);
0791
0792 if ((intstat & SPLTINT) != 0)
0793 ahd_pci_split_intr(ahd, intstat);
0794
0795 if ((intstat & PCIINT) == 0)
0796 return;
0797
0798 printk("%s: PCI error Interrupt\n", ahd_name(ahd));
0799 saved_modes = ahd_save_modes(ahd);
0800 ahd_dump_card_state(ahd);
0801 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
0802 for (i = 0, reg = DF0PCISTAT; i < 8; i++, reg++) {
0803
0804 if (i == 5)
0805 continue;
0806 pci_status[i] = ahd_inb(ahd, reg);
0807
0808 ahd_outb(ahd, reg, pci_status[i]);
0809 }
0810
0811 for (i = 0; i < 8; i++) {
0812 u_int bit;
0813
0814 if (i == 5)
0815 continue;
0816
0817 for (bit = 0; bit < 8; bit++) {
0818
0819 if ((pci_status[i] & (0x1 << bit)) != 0) {
0820 const char *s;
0821
0822 s = pci_status_strings[bit];
0823 if (i == 7 && bit == 3)
0824 s = "%s: Signaled Target Abort\n";
0825 printk(s, ahd_name(ahd), pci_status_source[i]);
0826 }
0827 }
0828 }
0829 pci_status1 = ahd_pci_read_config(ahd->dev_softc,
0830 PCIR_STATUS + 1, 1);
0831 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
0832 pci_status1, 1);
0833 ahd_restore_modes(ahd, saved_modes);
0834 ahd_outb(ahd, CLRINT, CLRPCIINT);
0835 ahd_unpause(ahd);
0836 }
0837
0838 static void
0839 ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
0840 {
0841 uint8_t split_status[4];
0842 uint8_t split_status1[4];
0843 uint8_t sg_split_status[2];
0844 uint8_t sg_split_status1[2];
0845 ahd_mode_state saved_modes;
0846 u_int i;
0847 uint16_t pcix_status;
0848
0849
0850
0851
0852
0853 pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
0854 2);
0855 printk("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
0856 ahd_name(ahd), pcix_status);
0857 saved_modes = ahd_save_modes(ahd);
0858 for (i = 0; i < 4; i++) {
0859 ahd_set_modes(ahd, i, i);
0860
0861 split_status[i] = ahd_inb(ahd, DCHSPLTSTAT0);
0862 split_status1[i] = ahd_inb(ahd, DCHSPLTSTAT1);
0863
0864 ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
0865 ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
0866 if (i > 1)
0867 continue;
0868 sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
0869 sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
0870
0871 ahd_outb(ahd, SGSPLTSTAT0, sg_split_status[i]);
0872 ahd_outb(ahd, SGSPLTSTAT1, sg_split_status1[i]);
0873 }
0874
0875 for (i = 0; i < 4; i++) {
0876 u_int bit;
0877
0878 for (bit = 0; bit < 8; bit++) {
0879
0880 if ((split_status[i] & (0x1 << bit)) != 0)
0881 printk(split_status_strings[bit], ahd_name(ahd),
0882 split_status_source[i]);
0883
0884 if (i > 1)
0885 continue;
0886
0887 if ((sg_split_status[i] & (0x1 << bit)) != 0)
0888 printk(split_status_strings[bit], ahd_name(ahd), "SG");
0889 }
0890 }
0891
0892
0893
0894 ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
0895 pcix_status, 2);
0896 ahd_outb(ahd, CLRINT, CLRSPLTINT);
0897 ahd_restore_modes(ahd, saved_modes);
0898 }
0899
0900 static int
0901 ahd_aic7901_setup(struct ahd_softc *ahd)
0902 {
0903
0904 ahd->chip = AHD_AIC7901;
0905 ahd->features = AHD_AIC7901_FE;
0906 return (ahd_aic790X_setup(ahd));
0907 }
0908
0909 static int
0910 ahd_aic7901A_setup(struct ahd_softc *ahd)
0911 {
0912
0913 ahd->chip = AHD_AIC7901A;
0914 ahd->features = AHD_AIC7901A_FE;
0915 return (ahd_aic790X_setup(ahd));
0916 }
0917
0918 static int
0919 ahd_aic7902_setup(struct ahd_softc *ahd)
0920 {
0921 ahd->chip = AHD_AIC7902;
0922 ahd->features = AHD_AIC7902_FE;
0923 return (ahd_aic790X_setup(ahd));
0924 }
0925
0926 static int
0927 ahd_aic790X_setup(struct ahd_softc *ahd)
0928 {
0929 ahd_dev_softc_t pci;
0930 u_int rev;
0931
0932 pci = ahd->dev_softc;
0933 rev = ahd_pci_read_config(pci, PCIR_REVID, 1);
0934 if (rev < ID_AIC7902_PCI_REV_A4) {
0935 printk("%s: Unable to attach to unsupported chip revision %d\n",
0936 ahd_name(ahd), rev);
0937 ahd_pci_write_config(pci, PCIR_COMMAND, 0, 2);
0938 return (ENXIO);
0939 }
0940 ahd->channel = ahd_get_pci_function(pci) + 'A';
0941 if (rev < ID_AIC7902_PCI_REV_B0) {
0942
0943
0944
0945 ahd->bugs |= AHD_SENT_SCB_UPDATE_BUG|AHD_ABORT_LQI_BUG
0946 | AHD_PKT_BITBUCKET_BUG|AHD_LONG_SETIMO_BUG
0947 | AHD_NLQICRC_DELAYED_BUG|AHD_SCSIRST_BUG
0948 | AHD_LQO_ATNO_BUG|AHD_AUTOFLUSH_BUG
0949 | AHD_CLRLQO_AUTOCLR_BUG|AHD_PCIX_MMAPIO_BUG
0950 | AHD_PCIX_CHIPRST_BUG|AHD_PCIX_SCBRAM_RD_BUG
0951 | AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
0952 | AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
0953 | AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
0954 | AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
0955 | AHD_FAINT_LED_BUG;
0956
0957
0958
0959
0960 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
0961
0962 if ((ahd->flags & AHD_HP_BOARD) == 0)
0963 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVA);
0964 } else {
0965
0966 extern uint32_t aic79xx_slowcrc;
0967 u_int devconfig1;
0968
0969 ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
0970 | AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY
0971 | AHD_BUSFREEREV_BUG;
0972 ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
0973
0974
0975 if (aic79xx_slowcrc)
0976 ahd->features |= AHD_AIC79XXB_SLOWCRC;
0977
0978
0979
0980
0981 if ((ahd->features & AHD_MULTI_FUNC) != 0)
0982 ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
0983
0984
0985
0986
0987 AHD_SET_PRECOMP(ahd, AHD_PRECOMP_CUTBACK_29);
0988 AHD_SET_SLEWRATE(ahd, AHD_SLEWRATE_DEF_REVB);
0989 AHD_SET_AMPLITUDE(ahd, AHD_AMPLITUDE_DEF);
0990
0991
0992
0993
0994
0995
0996
0997 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, 1);
0998 ahd_pci_write_config(pci, DEVCONFIG1,
0999 devconfig1|PREQDIS, 1);
1000 devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, 1);
1001 }
1002
1003 return (0);
1004 }