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);
}
Exemple #2
0
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);
}