Beispiel #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);
}
Beispiel #2
0
int
ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
{
	u_int	 command;
	u_int	 our_id;
	u_int	 sxfrctl1;
	u_int	 scsiseq;
	u_int	 dscommand0;
	uint32_t devconfig;
	int	 error;
	uint8_t	 sblkctl;

	our_id = 0;
	error = entry->setup(ahc);
	if (error != 0)
		return (error);
	ahc->chip |= AHC_PCI;
	ahc->description = entry->name;

	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);

	error = ahc_pci_map_registers(ahc);
	if (error != 0)
		return (error);

	
	ahc_intr_enable(ahc, FALSE);

	devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, 4);

	
	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {

		if (bootverbose)
			printf("%s: Enabling 39Bit Addressing\n",
			       ahc_name(ahc));
		devconfig |= DACEN;
	}
	
	
	devconfig |= PCIERRGENDIS;

	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, 4);

	
	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 2);
	command |= PCIM_CMD_BUSMASTEREN;

	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 2);

	
	ahc->flags |= AHC_PAGESCBS;

	error = ahc_softc_init(ahc);
	if (error != 0)
		return (error);

	
	if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
		ahc->seqctl |= FAILDIS;

	ahc->bus_intr = ahc_pci_intr;
	ahc->bus_chip_init = ahc_pci_chip_init;

	
	if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
		ahc_pause(ahc);
		if ((ahc->features & AHC_ULTRA2) != 0)
			our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
		else
			our_id = ahc_inb(ahc, SCSIID) & OID;
		sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN;
		scsiseq = ahc_inb(ahc, SCSISEQ);
	} else {
		sxfrctl1 = STPWEN;
		our_id = 7;
		scsiseq = 0;
	}

	error = ahc_reset(ahc, FALSE);
	if (error != 0)
		return (ENXIO);

	if ((ahc->features & AHC_DT) != 0) {
		u_int sfunct;

		
		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
		ahc_outb(ahc, OPTIONMODE,
			 OPTIONMODE_DEFAULTS|AUTOACKEN|BUSFREEREV|EXPPHASEDIS);
		ahc_outb(ahc, SFUNCT, sfunct);

		
		ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN
					  |TARGCRCENDEN);
	}

	dscommand0 = ahc_inb(ahc, DSCOMMAND0);
	dscommand0 |= MPARCKEN|CACHETHEN;
	if ((ahc->features & AHC_ULTRA2) != 0) {

		
		dscommand0 &= ~DPARCKEN;
	}

	
	if ((ahc->bugs & AHC_CACHETHEN_DIS_BUG) != 0)
		dscommand0 |= CACHETHEN;

	if ((ahc->bugs & AHC_CACHETHEN_BUG) != 0)
		dscommand0 &= ~CACHETHEN;

	ahc_outb(ahc, DSCOMMAND0, dscommand0);

	ahc->pci_cachesize =
	    ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME,
				1) & CACHESIZE;
	ahc->pci_cachesize *= 4;

	if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0
	 && ahc->pci_cachesize == 4) {

		ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
				     0, 1);
		ahc->pci_cachesize = 0;
	}

	
	if ((ahc->features & AHC_ULTRA) != 0) {
		uint32_t devconfig;

		devconfig = ahc_pci_read_config(ahc->dev_softc,
						DEVCONFIG, 4);
		if ((devconfig & REXTVALID) == 0)
			ahc->features &= ~AHC_ULTRA;
	}

	
	check_extport(ahc, &sxfrctl1);

	
	sblkctl = ahc_inb(ahc, SBLKCTL);
	ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));

	if ((ahc->features & AHC_ULTRA2) != 0) {
		ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_MAX|WR_DFTHRSH_MAX);
	} else {
		ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100);
	}

	if (ahc->flags & AHC_USEDEFAULTS) {
		
		
		if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
		 && scsiseq != 0) {
			printf("%s: Using left over BIOS settings\n",
				ahc_name(ahc));
			ahc->flags &= ~AHC_USEDEFAULTS;
			ahc->flags |= AHC_BIOS_ENABLED;
		} else {
			
 			our_id = 0x07;
			sxfrctl1 = STPWEN;
		}
		ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);

		ahc->our_id = our_id;
	}

	
	ahc_probe_ext_scbram(ahc);

	
	if ((sxfrctl1 & STPWEN) != 0)
		ahc->flags |= AHC_TERM_ENB_A;

	
	ahc->bus_softc.pci_softc.devconfig =
	    ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, 4);
	ahc->bus_softc.pci_softc.command =
	    ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 1);
	ahc->bus_softc.pci_softc.csize_lattime =
	    ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, 1);
	ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
	ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
	if ((ahc->features & AHC_DT) != 0) {
		u_int sfunct;

		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
		ahc->bus_softc.pci_softc.optionmode = ahc_inb(ahc, OPTIONMODE);
		ahc->bus_softc.pci_softc.targcrccnt = ahc_inw(ahc, TARGCRCCNT);
		ahc_outb(ahc, SFUNCT, sfunct);
		ahc->bus_softc.pci_softc.crccontrol1 =
		    ahc_inb(ahc, CRCCONTROL1);
	}
	if ((ahc->features & AHC_MULTI_FUNC) != 0)
		ahc->bus_softc.pci_softc.scbbaddr = ahc_inb(ahc, SCBBADDR);

	if ((ahc->features & AHC_ULTRA2) != 0)
		ahc->bus_softc.pci_softc.dff_thrsh = ahc_inb(ahc, DFF_THRSH);

	
	error = ahc_init(ahc);
	if (error != 0)
		return (error);
	ahc->init_level++;

	
	return ahc_pci_map_int(ahc);
}