예제 #1
0
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);
}
예제 #2
0
static void
ahc_pci_intr(struct ahc_softc *ahc)
{
	u_int error;
	u_int status1;

	error = ahc_inb(ahc, ERROR);
	if ((error & PCIERRSTAT) == 0)
		return;

	status1 = ahc_pci_read_config(ahc->dev_softc,
				      PCIR_STATUS + 1, 1);

	printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
	      ahc_name(ahc),
	      ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));

	if (status1 & DPE) {
		ahc->pci_target_perr_count++;
		printf("%s: Data Parity Error Detected during address "
		       "or write data phase\n", ahc_name(ahc));
	}
	if (status1 & SSE) {
		printf("%s: Signal System Error Detected\n", ahc_name(ahc));
	}
	if (status1 & RMA) {
		printf("%s: Received a Master Abort\n", ahc_name(ahc));
	}
	if (status1 & RTA) {
		printf("%s: Received a Target Abort\n", ahc_name(ahc));
	}
	if (status1 & STA) {
		printf("%s: Signaled a Target Abort\n", ahc_name(ahc));
	}
	if (status1 & DPR) {
		printf("%s: Data Parity Error has been reported via PERR#\n",
		       ahc_name(ahc));
	}

	
	ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
			     status1, 1);

	if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
		printf("%s: Latched PCIERR interrupt with "
		       "no status bits set\n", ahc_name(ahc)); 
	} else {
		ahc_outb(ahc, CLRINT, CLRPARERR);
	}

	if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {
		printf(
"%s: WARNING WARNING WARNING WARNING\n"
"%s: Too many PCI parity errors observed as a target.\n"
"%s: Some device on this bus is generating bad parity.\n"
"%s: This is an error *observed by*, not *generated by*, this controller.\n"
"%s: PCI parity error checking has been disabled.\n"
"%s: WARNING WARNING WARNING WARNING\n",
		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
		ahc->seqctl |= FAILDIS;
		ahc_outb(ahc, SEQCTL, ahc->seqctl);
	}
	ahc_unpause(ahc);
}