static int ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length) { struct seeprom_descriptor sd; int have_seeprom; u_long s; int paused; int written; /* Default to failure. */ written = -EINVAL; ahc_lock(ahc, &s); paused = ahc_is_paused(ahc); if (!paused) ahc_pause(ahc); if (length != sizeof(struct seeprom_config)) { printf("ahc_proc_write_seeprom: incorrect buffer size\n"); goto done; } have_seeprom = ahc_verify_cksum((struct seeprom_config*)buffer); if (have_seeprom == 0) { printf("ahc_proc_write_seeprom: cksum verification failed\n"); goto done; } sd.sd_ahc = ahc; #if AHC_PCI_CONFIG > 0 if ((ahc->chip & AHC_PCI) != 0) { sd.sd_control_offset = SEECTL; sd.sd_status_offset = SEECTL; sd.sd_dataout_offset = SEECTL; if (ahc->flags & AHC_LARGE_SEEPROM) sd.sd_chip = C56_66; else sd.sd_chip = C46; sd.sd_MS = SEEMS; sd.sd_RDY = SEERDY; sd.sd_CS = SEECS; sd.sd_CK = SEECK; sd.sd_DO = SEEDO; sd.sd_DI = SEEDI; have_seeprom = ahc_acquire_seeprom(ahc, &sd); } else #endif if ((ahc->chip & AHC_VL) != 0) { sd.sd_control_offset = SEECTL_2840; sd.sd_status_offset = STATUS_2840; sd.sd_dataout_offset = STATUS_2840; sd.sd_chip = C46; sd.sd_MS = 0; sd.sd_RDY = EEPROM_TF; sd.sd_CS = CS_2840; sd.sd_CK = CK_2840; sd.sd_DO = DO_2840; sd.sd_DI = DI_2840; have_seeprom = TRUE; } else { printf("ahc_proc_write_seeprom: unsupported adapter type\n"); goto done; } if (!have_seeprom) { printf("ahc_proc_write_seeprom: No Serial EEPROM\n"); goto done; } else { u_int start_addr; if (ahc->seep_config == NULL) { ahc->seep_config = malloc(sizeof(*ahc->seep_config), M_DEVBUF, M_NOWAIT); if (ahc->seep_config == NULL) { printf("aic7xxx: Unable to allocate serial " "eeprom buffer. Write failing\n"); goto done; } } printf("aic7xxx: Writing Serial EEPROM\n"); start_addr = 32 * (ahc->channel - 'A'); ahc_write_seeprom(&sd, (u_int16_t *)buffer, start_addr, sizeof(struct seeprom_config)/2); ahc_read_seeprom(&sd, (uint16_t *)ahc->seep_config, start_addr, sizeof(struct seeprom_config)/2); #if AHC_PCI_CONFIG > 0 if ((ahc->chip & AHC_VL) == 0) ahc_release_seeprom(&sd); #endif written = length; } done: if (!paused) ahc_unpause(ahc); ahc_unlock(ahc, &s); return (written); }
int ahc_pci_test_register_access(struct ahc_softc *ahc) { int error; u_int status1; uint32_t cmd; uint8_t hcntrl; error = EIO; cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 2); ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd & ~PCIM_CMD_SERRESPEN, 2); hcntrl = ahc_inb(ahc, HCNTRL); if (hcntrl == 0xFF) goto fail; if ((hcntrl & CHIPRST) != 0) { ahc->flags |= AHC_NO_BIOS_INIT; } hcntrl &= ~CHIPRST; ahc_outb(ahc, HCNTRL, hcntrl|PAUSE); while (ahc_is_paused(ahc) == 0) ; status1 = ahc_pci_read_config(ahc->dev_softc, PCIR_STATUS + 1, 1); ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, status1, 1); ahc_outb(ahc, CLRINT, CLRPARERR); ahc_outb(ahc, SEQCTL, PERRORDIS); ahc_outb(ahc, SCBPTR, 0); ahc_outl(ahc, SCB_BASE, 0x5aa555aa); if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa) goto fail; status1 = ahc_pci_read_config(ahc->dev_softc, PCIR_STATUS + 1, 1); if ((status1 & STA) != 0) goto fail; error = 0; fail: status1 = ahc_pci_read_config(ahc->dev_softc, PCIR_STATUS + 1, 1); ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1, status1, 1); ahc_outb(ahc, CLRINT, CLRPARERR); ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS); ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, 2); return (error); }