Пример #1
0
int
ral_cardbus_match(struct device *parent,
    struct cfdata *cfdata, void *aux)
{
        struct cardbus_attach_args *ca = aux;

        if (PCI_VENDOR(ca->ca_id) == PCI_VENDOR_RALINK) {
                switch (PCI_PRODUCT(ca->ca_id)) {
		case PCI_PRODUCT_RALINK_RT2560:
		case PCI_PRODUCT_RALINK_RT2561:
		case PCI_PRODUCT_RALINK_RT2561S:
		case PCI_PRODUCT_RALINK_RT2661:
			return 1;
		default:
			return 0;
                }
        }

        return 0;
}
Пример #2
0
/*
 * Determine which flags should be passed to the primary PCI bus's
 * autoconfiguration node.  We use this to detect broken chipsets
 * which cannot safely use memory-mapped device access.
 */
int
pci_bus_flags()
{
	int rval = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
	    PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
	int device, maxndevs;
	pcitag_t tag;
	pcireg_t id;

	maxndevs = pci_bus_maxdevs(NULL, 0);

	for (device = 0; device < maxndevs; device++) {
		tag = pci_make_tag(NULL, 0, device, 0);
		id = pci_conf_read(NULL, tag, PCI_ID_REG);

		/* Invalid vendor ID value? */
		if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
			continue;
		/* XXX Not invalid, but we've done this ~forever. */
		if (PCI_VENDOR(id) == 0)
			continue;

		switch (PCI_VENDOR(id)) {
		case PCI_VENDOR_SIS:
			switch (PCI_PRODUCT(id)) {
			case PCI_PRODUCT_SIS_85C496:
				goto disable_mem;
			}
			break;
		}
	}

	return (rval);

 disable_mem:
	printf("Warning: broken PCI-Host bridge detected; "
	    "disabling memory-mapped access\n");
	rval &= ~(PCI_FLAGS_MEM_ENABLED|PCI_FLAGS_MRL_OKAY|PCI_FLAGS_MRM_OKAY|
	    PCI_FLAGS_MWI_OKAY);
	return (rval);
}
Пример #3
0
static int
ichsmb_match(device_t parent, cfdata_t match, void *aux)
{
	struct pci_attach_args *pa = aux;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) {
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_INTEL_6300ESB_SMB:
		case PCI_PRODUCT_INTEL_63XXESB_SMB:
		case PCI_PRODUCT_INTEL_82801AA_SMB:
		case PCI_PRODUCT_INTEL_82801AB_SMB:
		case PCI_PRODUCT_INTEL_82801BA_SMB:
		case PCI_PRODUCT_INTEL_82801CA_SMB:
		case PCI_PRODUCT_INTEL_82801DB_SMB:
		case PCI_PRODUCT_INTEL_82801E_SMB:
		case PCI_PRODUCT_INTEL_82801EB_SMB:
		case PCI_PRODUCT_INTEL_82801FB_SMB:
		case PCI_PRODUCT_INTEL_82801G_SMB:
		case PCI_PRODUCT_INTEL_82801H_SMB:
		case PCI_PRODUCT_INTEL_82801I_SMB:
		case PCI_PRODUCT_INTEL_82801JD_SMB:
		case PCI_PRODUCT_INTEL_82801JI_SMB:
		case PCI_PRODUCT_INTEL_3400_SMB:
		case PCI_PRODUCT_INTEL_6SERIES_SMB:
		case PCI_PRODUCT_INTEL_7SERIES_SMB:
		case PCI_PRODUCT_INTEL_8SERIES_SMB:
		case PCI_PRODUCT_INTEL_CORE4G_M_SMB:
		case PCI_PRODUCT_INTEL_BAYTRAIL_PCU_SMB:
		case PCI_PRODUCT_INTEL_C600_SMBUS:
		case PCI_PRODUCT_INTEL_C600_SMB_0:
		case PCI_PRODUCT_INTEL_C600_SMB_1:
		case PCI_PRODUCT_INTEL_C600_SMB_2:
		case PCI_PRODUCT_INTEL_EP80579_SMB:
		case PCI_PRODUCT_INTEL_DH89XXCC_SMB:
		case PCI_PRODUCT_INTEL_DH89XXCL_SMB:
		case PCI_PRODUCT_INTEL_C2000_PCU_SMBUS:
			return 1;
		}
	}
	return 0;
}
Пример #4
0
static int
iop_pci_match(struct device *parent, struct cfdata *match,
    void *aux)
{
	struct pci_attach_args *pa;
	u_int product, vendor;
	pcireg_t reg;

	pa = aux;

	/*
	 * Look for an "intelligent I/O processor" that adheres to the I2O
	 * specification.  Ignore the device if it doesn't support interrupt
	 * driven operation.
	 */
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_I2O_STANDARD &&
	    PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_I2O_INTRDRIVEN)
		return (1);

	/*
	 * Match boards that don't conform exactly to the spec.
	 */
	vendor = PCI_VENDOR(pa->pa_id);
	product = PCI_PRODUCT(pa->pa_id);

	if (vendor == PCI_VENDOR_DPT &&
	    (product == PCI_PRODUCT_DPT_RAID_I2O ||
	    product == PCI_PRODUCT_DPT_RAID_2005S))
		return (1);

	if (vendor == PCI_VENDOR_INTEL &&
	    (product == PCI_PRODUCT_INTEL_80960RM_2 ||
	    product == PCI_PRODUCT_INTEL_80960_RP)) {
		reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
		if (PCI_VENDOR(reg) == PCI_VENDOR_PROMISE)
			return (1);
	}

	return (0);
}
Пример #5
0
int
obio_match(device_t parent, cfdata_t cf, void *aux)
{
    struct pci_attach_args *pa = aux;

    if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE)
        switch (PCI_PRODUCT(pa->pa_id)) {
        case PCI_PRODUCT_APPLE_GC:
        case PCI_PRODUCT_APPLE_OHARE:
        case PCI_PRODUCT_APPLE_HEATHROW:
        case PCI_PRODUCT_APPLE_PADDINGTON:
        case PCI_PRODUCT_APPLE_KEYLARGO:
        case PCI_PRODUCT_APPLE_PANGEA_MACIO:
        case PCI_PRODUCT_APPLE_INTREPID:
        case PCI_PRODUCT_APPLE_K2:
        case PCI_PRODUCT_APPLE_SHASTA:
            return 1;
        }

    return 0;
}
Пример #6
0
static int
pchb_match(struct device *parent, struct cfdata *match, void *aux)
{
	struct pci_attach_args *pa = aux;

	/*
	 * Match all known PCI host chipsets.
	 */
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) {
		switch (PCI_VENDOR(pa->pa_id)) {
		case PCI_VENDOR_GALILEO:
			switch (PCI_PRODUCT(pa->pa_id)) {
			case PCI_PRODUCT_GALILEO_GT64120:
				return (!pcifound);
			}
			break;
		}
	}
	return (0);
}
Пример #7
0
static int
fwohci_pci_match(device_t parent, cfdata_t match, void *aux)
{
	struct pci_attach_args *pa = (struct pci_attach_args *) aux;

	/*
	 * XXX
	 * Firewire controllers used in some G3 PowerBooks hang the system
	 * when trying to discover devices - don't attach to those for now
	 * until someone with the right hardware can investigate
	 */
	if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE) &&
	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_PBG3_FW))
		return 0;
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_FIREWIRE &&
	    PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_OHCI)
		return 1;

	return 0;
}
Пример #8
0
int
pci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, pcireg_t id)
{

	/* ignore bogus IDs */
	if (PCI_VENDOR(id) == 0)
		return 0;

	/* 2700 hardware wedges on accesses to device 6. */
	if (bus == 0 && dev == 6)
		return 0;

	/* 2800 hardware wedges on accesses to device 31. */
	if (bus == 0 && dev == 31)
		return 0;

	/* Don't configure the bridge and PCI probe. */ 
	if (PCI_VENDOR(id) == PCI_VENDOR_MARVELL &&
	    PCI_PRODUCT(id) == PCI_PRODUCT_MARVELL_GT64011)
	        return 0;

	/* Don't configure on-board VIA VT82C586 (pcib, uhci) */
	if (bus == 0 && dev == 9 && (func == 0 || func == 2))
		return 0;

	/* Enable viaide secondary port. Some firmware doesn't enable it. */
	if (bus == 0 && dev == 9 && func == 1) {
		pcitag_t tag;
		pcireg_t csr;

#define	APO_VIAIDECONF	(APO_VIA_REGBASE + 0x00)

		tag = pci_make_tag(pc, bus, dev, func);
		csr = pci_conf_read(pc, tag, APO_VIAIDECONF);
		pci_conf_write(pc, tag, APO_VIAIDECONF,
		    csr | APO_IDECONF_EN(1));
	}
	return PCI_CONF_DEFAULT & ~(PCI_COMMAND_SERR_ENABLE |
	    PCI_COMMAND_PARITY_ENABLE);
}
Пример #9
0
int
yds_match(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = (struct pci_attach_args *) aux;

	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_YAMAHA:
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_YAMAHA_YMF724:
		case PCI_PRODUCT_YAMAHA_YMF740:
		case PCI_PRODUCT_YAMAHA_YMF740C:
		case PCI_PRODUCT_YAMAHA_YMF724F:
		case PCI_PRODUCT_YAMAHA_YMF744:
		case PCI_PRODUCT_YAMAHA_YMF754:
		/* 734, 737, 738?? */
			return (1);
		}
		break;
	}

	return (0);
}
Пример #10
0
static int
yds_match(device_t parent, cfdata_t match, void *aux)
{
	struct pci_attach_args *pa;

	pa = (struct pci_attach_args *)aux;
	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_YAMAHA:
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_YAMAHA_YMF724:
		case PCI_PRODUCT_YAMAHA_YMF740:
		case PCI_PRODUCT_YAMAHA_YMF740C:
		case PCI_PRODUCT_YAMAHA_YMF724F:
		case PCI_PRODUCT_YAMAHA_YMF744B:
		case PCI_PRODUCT_YAMAHA_YMF754:
			return 1;
		}
		break;
	}

	return 0;
}
Пример #11
0
int
ppbmatch(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = aux;

	/*
	 * This device is mislabeled.  It is not a PCI bridge.
	 */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VIATECH &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT82C586_PWR)
		return (0);
	/*
	 * Check the ID register to see that it's a PCI bridge.
	 * If it is, we assume that we can deal with it; it _should_
	 * work in a standardized way...
	 */
	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI)
		return (1);

	return (0);
}
Пример #12
0
static void
scan_pci_bus(void)
{
	pcitag_t tag;
	int i, x;

	for (i=0;i<32;i++){
		tag = pci_make_tag(0, 0, i, 0);
		x = pci_conf_read(0, tag, 0);
		printf("%d tag=%08x : %08x\n", i, tag, x);
#if 0
		if (PCI_VENDOR(x) == PCI_VENDOR_INTEL
		    && PCI_PRODUCT(x) == PCI_PRODUCT_INTEL_80960_RP) {
			/* Do not configure PCI bus analyzer */
			continue;
		}
		x = pci_conf_read(0, tag, PCI_COMMAND_STATUS_REG);
		x |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
		pci_conf_write(0, tag, PCI_COMMAND_STATUS_REG, x);
#endif
	}
}
Пример #13
0
int
gdt_pci_probe(struct device *parent, void *match, void *aux)
{
        struct pci_attach_args *pa = aux;

	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VORTEX &&
	    ((PCI_PRODUCT(pa->pa_id) >= GDT_DEVICE_ID_MIN &&
	    PCI_PRODUCT(pa->pa_id) <= GDT_DEVICE_ID_MAX) ||
	    PCI_PRODUCT(pa->pa_id) == GDT_DEVICE_ID_NEWRX ||
	    PCI_PRODUCT(pa->pa_id) == GDT_DEVICE_ID_NEWRX2))
		return (1);
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_GDT_RAID1 ||
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_GDT_RAID2))
		return (1);
	return (0);
}
Пример #14
0
int
kauaiatamatch(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = aux;

	/*
	 * Match the adapter
	 * XXX match routine??
	 */
	switch(PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_APPLE:
		switch (PCI_PRODUCT(pa->pa_id)) {
		case PCI_PRODUCT_APPLE_UNINORTH_ATA:
		case PCI_PRODUCT_APPLE_INTREPID_ATA:
		case PCI_PRODUCT_APPLE_INTREPID2_ATA:
		case PCI_PRODUCT_APPLE_K2_ATA:
		case PCI_PRODUCT_APPLE_SHASTA_ATA:
			return (1);
		}
		break;
	}
	return 0;
}
Пример #15
0
static const char *
iwic_find_card(const struct pci_attach_args * pa)
{
	pcireg_t type = pa->pa_id;
	pcireg_t reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	int sv = PCI_VENDOR(reg);
	int sd = PCI_PRODUCT(reg);
	struct winids *wip = win_ids;

	while (wip->type) {
		if (wip->type == type) {
			if (((wip->sv == -1) && (wip->sd == -1)) ||
			    ((wip->sv == sv) && (wip->sd == sd)))
				break;
		}
		++wip;
	}

	if (wip->desc)
		return wip->desc;

	return 0;
}
Пример #16
0
static int
pci_matchbyid(lua_State *L)
{
  struct pci_attach_args *pa;
  const struct pci_matchid *ids;
  int nent;

  const struct pci_matchid *pm;
  int i;

  pa = lua_touserdata(L, -3);
  ids = lua_touserdata(L, -2);
  nent = lua_tointeger(L, -1);
  lua_pop(L, 3);

  for (i = 0, pm = ids; i < nent; i++, pm++)
    if (PCI_VENDOR(pa->pa_id) == pm->pm_vid &&
	PCI_PRODUCT(pa->pa_id) == pm->pm_pid) {
      lua_pushinteger(L, 1);
      return 1;
    }
  lua_pushinteger(L, 0);
  return 1;
}
Пример #17
0
static int
yds_read_codec(void *sc_, uint8_t reg, uint16_t *data)
{
	struct yds_codec_softc *sc;

	sc = sc_;
	YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg);

	if (yds_ready_codec(sc)) {
		aprint_error_dev(sc->sc->sc_dev, "yds_read_codec timeout\n");
		return EIO;
	}

	if (PCI_PRODUCT(sc->sc->sc_id) == PCI_PRODUCT_YAMAHA_YMF744B &&
	    sc->sc->sc_revision < 2) {
		int i;
		for (i=0; i<600; i++)
			(void)YREAD2(sc->sc, sc->status_data);
	}

	*data = YREAD2(sc->sc, sc->status_data);

	return 0;
}
int
pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
{

	/*
	 * We need to disable devices in the Southbridge, and as
	 * we have all the tags we need at this point, this is
	 * where we do it.
	 */
	if (PCI_VENDOR(id) == PCI_VENDOR_ALI &&
	    PCI_PRODUCT(id) == PCI_PRODUCT_ALI_M1543)
	{
		pcitag_t tag;
		int status;
		pci_chipset_tag_t pc = (pci_chipset_tag_t) v;

		tag = pci_make_tag(pc, bus, dev, func);

		/* Undocumented magic */

		/* Disable USB */
		pci_conf_write_byte(pc, tag, 0x53, 0x40);
		pci_conf_write_byte(pc, tag, 0x52, 0x00);

		status = pci_conf_read_byte(pc, tag, 0x7e);
		pci_conf_write_byte(pc, tag, 0x7e, status & ~0x80);

		/* Disable modem */
		pci_conf_write_byte(pc, tag, 0x77, 1 << 6);

		/* Disable SCI */
		pci_conf_write_byte(pc, tag, 0x78, 1 << 7);
	}

	return (PCI_CONF_DEFAULT);
}
Пример #19
0
int
yds_read_codec(void *sc_, u_int8_t reg, u_int16_t *data)
{
	struct yds_codec_softc *sc = sc_;

	YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg);

	if (yds_ready_codec(sc)) {
		printf("%s: yds_read_codec timeout\n",
		       sc->sc->sc_dev.dv_xname);
		return EIO;
	}

	if (PCI_PRODUCT(sc->sc->sc_id) == PCI_PRODUCT_YAMAHA_YMF744 &&
	    sc->sc->sc_revision < 2) {
		int i;

		for (i = 0; i < 600; i++)
			YREAD2(sc->sc, sc->status_data);
	}
	*data = YREAD2(sc->sc, sc->status_data);

	return 0;
}
Пример #20
0
/*static*/ int
ndis_probe_pci(device_t parent, cfdata_t match, void *aux)
{
	struct pci_attach_args *pa = aux;
	int vendor  = PCI_VENDOR(pa->pa_id);
	int product = PCI_PRODUCT(pa->pa_id);
	
	struct ndis_pci_type *t = ndis_devs;
	driver_object        *drv = NULL;	/* = windrv_lookup(0, "PCI Bus");**/
		
#ifdef NDIS_DBG
	printf("in ndis_probe_pci\n");
	printf("vendor = %x, product = %x\n", vendor, product);
#endif
	
	while(t->ndis_name != NULL) {
#ifdef NDIS_DBG
			printf("t->ndis_vid = %x, t->ndis_did = %x\n",
			       t->ndis_vid, t->ndis_did);
#endif
		if((vendor  == t->ndis_vid) && (product == t->ndis_did)) {
#ifdef _MODULE	
			ndisdrv_modevent(NULL, MOD_LOAD);
			//kthread_create(load_ndisdrv, NULL);
#endif /* _MODULE */
				
			drv = windrv_lookup(0, "PCI Bus");
			printf("Matching vendor: %x, product: %x, name: %s\n", vendor, product, t->ndis_name);
			windrv_create_pdo(drv, parent);
			return 1;
		}
		t++;
	}
	
	return 0;  /* dosen't match */
}
Пример #21
0
void
nfe_attach(struct device *parent, struct device *self, void *aux)
{
	struct nfe_softc *sc = (struct nfe_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr;
	struct ifnet *ifp;
	bus_size_t memsize;
	pcireg_t memtype;

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA);
	if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt,
	    &sc->sc_memh, NULL, &memsize, 0)) {
		printf(": can't map mem space\n");
		return;
	}

	if (pci_intr_map(pa, &ih) != 0) {
		printf(": can't map interrupt\n");
		return;
	}

	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc,
	    sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": could not establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf(": %s", intrstr);

	sc->sc_dmat = pa->pa_dmat;
	sc->sc_flags = 0;

	switch (PCI_PRODUCT(pa->pa_id)) {
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4:
	case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP51_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP51_LAN2:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP61_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP61_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP67_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP73_LAN4:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_CORRECT_MACADDR |
		    NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP77_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP77_LAN4:
		sc->sc_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP79_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP79_LAN4:
	case PCI_PRODUCT_NVIDIA_MCP89_LAN:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_CK804_LAN1:
	case PCI_PRODUCT_NVIDIA_CK804_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP04_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM;
		break;
	case PCI_PRODUCT_NVIDIA_MCP65_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN2:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN3:
	case PCI_PRODUCT_NVIDIA_MCP65_LAN4:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR |
		    NFE_CORRECT_MACADDR | NFE_PWR_MGMT;
		break;
	case PCI_PRODUCT_NVIDIA_MCP55_LAN1:
	case PCI_PRODUCT_NVIDIA_MCP55_LAN2:
		sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM |
		    NFE_HW_VLAN | NFE_PWR_MGMT;
		break;
	}

	if (sc->sc_flags & NFE_PWR_MGMT) {
		NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_RESET | NFE_RXTX_BIT2);
		NFE_WRITE(sc, NFE_MAC_RESET, NFE_MAC_RESET_MAGIC);
		DELAY(100);
		NFE_WRITE(sc, NFE_MAC_RESET, 0);
		DELAY(100);
		NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT2);
		NFE_WRITE(sc, NFE_PWR2_CTL,
		    NFE_READ(sc, NFE_PWR2_CTL) & ~NFE_PWR2_WAKEUP_MASK);
	}

	nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr);
	printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));

	/*
	 * Allocate Tx and Rx rings.
	 */
	if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) {
		printf("%s: could not allocate Tx ring\n",
		    sc->sc_dev.dv_xname);
		return;
	}

	if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) {
		printf("%s: could not allocate Rx ring\n",
		    sc->sc_dev.dv_xname);
		nfe_free_tx_ring(sc, &sc->txq);
		return;
	}

	ifp = &sc->sc_arpcom.ac_if;
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = nfe_ioctl;
	ifp->if_start = nfe_start;
	ifp->if_watchdog = nfe_watchdog;
	IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN);
	IFQ_SET_READY(&ifp->if_snd);
	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);

	ifp->if_capabilities = IFCAP_VLAN_MTU;

#ifndef SMALL_KERNEL
	ifp->if_capabilities |= IFCAP_WOL;
	ifp->if_wol = nfe_wol;
	nfe_wol(ifp, 0);
#endif

#if NVLAN > 0
	if (sc->sc_flags & NFE_HW_VLAN)
		ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
#endif

	if (sc->sc_flags & NFE_HW_CSUM) {
		ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
		    IFCAP_CSUM_UDPv4;
	}

	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = nfe_miibus_readreg;
	sc->sc_mii.mii_writereg = nfe_miibus_writereg;
	sc->sc_mii.mii_statchg = nfe_miibus_statchg;

	ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd,
	    nfe_ifmedia_sts);
	mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 0, 0);
	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL,
		    0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);

	if_attach(ifp);
	ether_ifattach(ifp);

	timeout_set(&sc->sc_tick_ch, nfe_tick, sc);
}
Пример #22
0
int
pci_system_openbsd_create(void)
{
	struct pci_device_private *device;
	int domain, bus, dev, func, ndevs, nfuncs;
	char path[MAXPATHLEN];
	uint32_t reg;

	if (ndomains > 0)
		return 0;

	pci_sys = calloc(1, sizeof(struct pci_system));
	if (pci_sys == NULL)
		return ENOMEM;

	pci_sys->methods = &openbsd_pci_methods;

	for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) {
		snprintf(path, sizeof(path), "/dev/pci%d", domain);
	        pcifd[domain] = open(path, O_RDWR | O_CLOEXEC);
		if (pcifd[domain] == -1) {
			pcifd[domain] = open(path, O_RDONLY | O_CLOEXEC);
			if (pcifd[domain] == -1)
				break;
		}
		ndomains++;
	}

	if (ndomains == 0)
		return ENXIO;

	ndevs = 0;
	for (domain = 0; domain < ndomains; domain++) {
		for (bus = 0; bus < 256; bus++) {
			for (dev = 0; dev < 32; dev++) {
				nfuncs = pci_nfuncs(domain, bus, dev);
				for (func = 0; func < nfuncs; func++) {
					if (pci_read(domain, bus, dev, func,
					    PCI_ID_REG, &reg) != 0)
						continue;
					if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
					    PCI_VENDOR(reg) == 0)
						continue;

					ndevs++;
				}
			}
		}
	}

	pci_sys->num_devices = ndevs;
	pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
	if (pci_sys->devices == NULL) {
		free(pci_sys);
		pci_sys = NULL;
		for (domain = 0; domain < ndomains; domain++)
			close(pcifd[domain]);
		ndomains = 0;
		return ENOMEM;
	}

	device = pci_sys->devices;
	for (domain = 0; domain < ndomains; domain++) {
		for (bus = 0; bus < 256; bus++) {
			for (dev = 0; dev < 32; dev++) {
				nfuncs = pci_nfuncs(domain, bus, dev);
				for (func = 0; func < nfuncs; func++) {
					if (pci_read(domain, bus, dev, func,
					    PCI_ID_REG, &reg) != 0)
						continue;
					if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
					    PCI_VENDOR(reg) == 0)
						continue;

					device->base.domain = domain;
					device->base.bus = bus;
					device->base.dev = dev;
					device->base.func = func;
					device->base.vendor_id = PCI_VENDOR(reg);
					device->base.device_id = PCI_PRODUCT(reg);

					if (pci_read(domain, bus, dev, func,
					    PCI_CLASS_REG, &reg) != 0)
						continue;

					device->base.device_class =
					    PCI_INTERFACE(reg) |
					    PCI_CLASS(reg) << 16 |
					    PCI_SUBCLASS(reg) << 8;
					device->base.revision = PCI_REVISION(reg);

					if (pci_read(domain, bus, dev, func,
					    PCI_SUBVEND_0, &reg) != 0)
						continue;

					device->base.subvendor_id = PCI_VENDOR(reg);
					device->base.subdevice_id = PCI_PRODUCT(reg);

					device++;
				}
			}
		}
	}

	return 0;
}
Пример #23
0
void
main(int argc, char *argv[], char *bootargs_start, char *bootargs_end)
{
	unsigned long marks[MARK_MAX];
	struct brdprop *brdprop;
	char *new_argv[MAX_ARGS];
	char *bname;
	ssize_t len;
	int err, fd, howto, i, n;

	printf("\n>> %s altboot, revision %s\n", bootprog_name, bootprog_rev);

	brdprop = brd_lookup(brdtype);
	printf(">> %s, cpu %u MHz, bus %u MHz, %dMB SDRAM\n", brdprop->verbose,
	    cpuclock / 1000000, busclock / 1000000, bi_mem.memsize >> 20);

	nata = pcilookup(PCI_CLASS_IDE, lata, 2);
	if (nata == 0)
		nata = pcilookup(PCI_CLASS_RAID, lata, 2);
	if (nata == 0)
		nata = pcilookup(PCI_CLASS_MISCSTORAGE, lata, 2);
	if (nata == 0)
		nata = pcilookup(PCI_CLASS_SCSI, lata, 2);
	nnif = pcilookup(PCI_CLASS_ETH, lnif, 2);
	nusb = pcilookup(PCI_CLASS_USB, lusb, 3);

#ifdef DEBUG
	if (nata == 0)
		printf("No IDE/SATA found\n");
	else for (n = 0; n < nata; n++) {
		int b, d, f, bdf, pvd;
		bdf = lata[n].bdf;
		pvd = lata[n].pvd;
		pcidecomposetag(bdf, &b, &d, &f);
		printf("%04x.%04x DSK %02d:%02d:%02d\n",
		    PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f);
	}
	if (nnif == 0)
		printf("no NET found\n");
	else for (n = 0; n < nnif; n++) {
		int b, d, f, bdf, pvd;
		bdf = lnif[n].bdf;
		pvd = lnif[n].pvd;
		pcidecomposetag(bdf, &b, &d, &f);
		printf("%04x.%04x NET %02d:%02d:%02d\n",
		    PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f);
	}
	if (nusb == 0)
		printf("no USB found\n");
	else for (n = 0; n < nusb; n++) {
		int b, d, f, bdf, pvd;
		bdf = lusb[0].bdf;
		pvd = lusb[0].pvd;
		pcidecomposetag(bdf, &b, &d, &f);
		printf("%04x.%04x USB %02d:%02d:%02d\n",
		    PCI_VENDOR(pvd), PCI_PRODUCT(pvd), b, d, f);
	}
#endif

	pcisetup();
	pcifixup();

	/*
	 * When argc is too big then it is probably a pointer, which could
	 * indicate that we were launched as a Linux kernel module using
	 * "bootm".
	 */
	if (argc > MAX_ARGS) {
		if (argv != NULL) {
			/*
			 * initrd image was loaded:
			 * check if it contains a valid altboot command line
			 */
			char *p = (char *)argv;

			if (strncmp(p, "altboot:", 8) == 0) {
				*p = 0;
				for (p = p + 8; *p >= ' '; p++);
				argc = parse_cmdline(new_argv, MAX_ARGS,
				    ((char *)argv) + 8, p);
				argv = new_argv;
			} else
				argc = 0;	/* boot default */
		} else {
			/* parse standard Linux bootargs */
			argc = parse_cmdline(new_argv, MAX_ARGS,
			    bootargs_start, bootargs_end);
			argv = new_argv;
		}
	}

	/* look for a PATA drive configuration string under the arguments */
	for (n = 1; n < argc; n++) {
		if (strncmp(argv[n], "ide:", 4) == 0 &&
		    argv[n][4] >= '0' && argv[n][4] <= '2') {
			drive_config = &argv[n][4];
			break;
		}
	}

	/* intialize a disk driver */
	for (i = 0, n = 0; i < nata; i++)
		n += dskdv_init(&lata[i]);
	if (n == 0)
		printf("IDE/SATA device driver was not found\n");

	/* initialize a network interface */
	for (n = 0; n < nnif; n++)
		if (netif_init(&lnif[n]) != 0)
			break;
	if (n >= nnif)
		printf("no NET device driver was found\n");

	/* wait 2s for user to enter interactive mode */
	for (n = 200; n >= 0; n--) {
		if (n % 100 == 0)
			printf("\rHit any key to enter interactive mode: %d",
			    n / 100);
		if (tstchar()) {
#ifdef DEBUG
			unsigned c;

			c = toupper(getchar());
			if (c == 'C') {
				/* controller test terminal */
				sat_test();
				n = 200;
				continue;
			}
			else if (c == 'F') {
				/* find strings in Flash ROM */
				findflash();
				n = 200;
				continue;
			}
#else
			(void)getchar();
#endif
			/* enter command line */
			argv = new_argv;
			argc = input_cmdline(argv, MAX_ARGS);
			break;
		}
		delay(10000);
	}
	putchar('\n');

	howto = RB_AUTOBOOT;		/* default is autoboot = 0 */

	/* get boot options and determine bootname */
	for (n = 1; n < argc; n++) {
		if (strncmp(argv[n], "ide:", 4) == 0)
			continue; /* ignore drive configuration argument */

		for (i = 0; i < sizeof(bootargs) / sizeof(bootargs[0]); i++) {
			if (strncasecmp(argv[n], bootargs[i].name,
			    strlen(bootargs[i].name)) == 0) {
				howto |= bootargs[i].value;
				break;
			}
		}
		if (i >= sizeof(bootargs) / sizeof(bootargs[0]))
			break;	/* break on first unknown string */
	}

	/*
	 * If no device name is given, we construct a list of drives
	 * which have valid disklabels.
	 */
	if (n >= argc) {
		static const size_t blen = sizeof("wdN:");
		n = 0;
		argc = 0;
		argv = alloc(MAX_UNITS * (sizeof(char *) + blen));
		bname = (char *)(argv + MAX_UNITS);
		for (i = 0; i < MAX_UNITS; i++) {
			if (!dlabel_valid(i))
				continue;
			snprintf(bname, blen, "wd%d:", i);
			argv[argc++] = bname;
			bname += blen;
		}
		/* use default drive if no valid disklabel is found */
		if (argc == 0) {
			argc = 1;
			argv[0] = BNAME_DEFAULT;
		}
	}

	/* try to boot off kernel from the drive list */
	while (n < argc) {
		bname = argv[n++];

		if (check_bootname(bname) == 0) {
			printf("%s not a valid bootname\n", bname);
			continue;
		}

		if ((fd = open(bname, 0)) < 0) {
			if (errno == ENOENT)
				printf("\"%s\" not found\n", bi_path.bootpath);
			continue;
		}
		printf("loading \"%s\" ", bi_path.bootpath);
		marks[MARK_START] = 0;

		if (howto == -1) {
			/* load another altboot binary and replace ourselves */
			len = read(fd, (void *)0x100000, 0x1000000 - 0x100000);
			if (len == -1)
				goto loadfail;
			close(fd);
			netif_shutdown_all();

			memcpy((void *)0xf0000, newaltboot,
			    newaltboot_end - newaltboot);
			__syncicache((void *)0xf0000,
			    newaltboot_end - newaltboot);
			printf("Restarting...\n");
			run((void *)1, argv, (void *)0x100000, (void *)len,
			    (void *)0xf0000);
		}

		err = fdloadfile(fd, marks, LOAD_KERNEL);
		close(fd);
		if (err < 0)
			continue;

		printf("entry=%p, ssym=%p, esym=%p\n",
		    (void *)marks[MARK_ENTRY],
		    (void *)marks[MARK_SYM],
		    (void *)marks[MARK_END]);

		bootinfo = (void *)0x4000;
		bi_init(bootinfo);
		bi_add(&bi_cons, BTINFO_CONSOLE, sizeof(bi_cons));
		bi_add(&bi_mem, BTINFO_MEMORY, sizeof(bi_mem));
		bi_add(&bi_clk, BTINFO_CLOCK, sizeof(bi_clk));
		bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path));
		bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev));
		bi_add(&bi_fam, BTINFO_PRODFAMILY, sizeof(bi_fam));
		if (brdtype == BRD_SYNOLOGY || brdtype == BRD_DLINKDSM) {
			/* need to pass this MAC address to kernel */
			bi_add(&bi_net, BTINFO_NET, sizeof(bi_net));
		}

		if (modules_enabled) {
			if (fsmod != NULL)
				module_add(fsmod);
			kmodloadp = marks[MARK_END];
			btinfo_modulelist = NULL;
			module_load(bname);
			if (btinfo_modulelist != NULL &&
			    btinfo_modulelist->num > 0)
				bi_add(btinfo_modulelist, BTINFO_MODULELIST,
				    btinfo_modulelist_size);
		}

		launchfixup();
		netif_shutdown_all();

		__syncicache((void *)marks[MARK_ENTRY],
		    (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]);

		run((void *)marks[MARK_SYM], (void *)marks[MARK_END],
		    (void *)howto, bootinfo, (void *)marks[MARK_ENTRY]);

		/* should never come here */
		printf("exec returned. Restarting...\n");
		_rtt();
	}
  loadfail:
	printf("load failed. Restarting...\n");
	_rtt();
}
static void
ahci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct ahci_pci_softc *psc = device_private(self);
	struct ahci_softc *sc = &psc->ah_sc;
	const char *intrstr;
	bool ahci_cap_64bit;
	bool ahci_bad_64bit;
	pci_intr_handle_t intrhandle;

	sc->sc_atac.atac_dev = self;

	if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->sc_ahcit, &sc->sc_ahcih, NULL, &sc->sc_ahcis) != 0) {
		aprint_error_dev(self, "can't map ahci registers\n");
		return;
	}
	psc->sc_pc = pa->pa_pc;
	psc->sc_pcitag = pa->pa_tag;

	pci_aprint_devinfo(pa, "AHCI disk controller");
	
	if (pci_intr_map(pa, &intrhandle) != 0) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle);
	psc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n",
	    intrstr ? intrstr : "unknown interrupt");

	sc->sc_dmat = pa->pa_dmat;

	sc->sc_ahci_quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
					    PCI_PRODUCT(pa->pa_id));

	ahci_cap_64bit = (AHCI_READ(sc, AHCI_CAP) & AHCI_CAP_64BIT) != 0;
	ahci_bad_64bit = ((sc->sc_ahci_quirks & AHCI_PCI_QUIRK_BAD64) != 0);

	if (pci_dma64_available(pa) && ahci_cap_64bit) {
		if (!ahci_bad_64bit)
			sc->sc_dmat = pa->pa_dmat64;
		aprint_verbose_dev(self, "64-bit DMA%s\n",
		    (sc->sc_dmat == pa->pa_dmat) ? " unavailable" : "");
	}

	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) {
		AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE);
		sc->sc_atac_capflags = ATAC_CAP_RAID;
	} else {
		AHCIDEBUG_PRINT(("%s: SATA mode\n", AHCINAME(sc)), DEBUG_PROBE);
	}

	ahci_attach(sc);

	if (!pmf_device_register(self, NULL, ahci_pci_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Пример #25
0
void
ti_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ti_softc *sc = (struct ti_softc *)self;
	struct pci_attach_args *pa = aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	bus_size_t size;

	/*
	 * Map control/status registers.
	 */
	if (pci_mapreg_map(pa, TI_PCI_LOMEM,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->ti_btag, &sc->ti_bhandle, NULL, &size, 0)) {
 		printf(": can't map registers\n");
		return;
 	}

	sc->sc_dmatag = pa->pa_dmat;

	if (pci_intr_map(pa, &ih)) {
		printf(": can't map interrupt\n");
		goto unmap;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->ti_intrhand = pci_intr_establish(pc, ih, IPL_NET, ti_intr, sc,
	    self->dv_xname);
	if (sc->ti_intrhand == NULL) {
		printf(": can't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto unmap;
	}
	printf(": %s", intrstr);

	/*
	 * We really need a better way to tell a 1000baseTX card
	 * from a 1000baseSX one, since in theory there could be
	 * OEMed 1000baseTX cards from lame vendors who aren't
	 * clever enough to change the PCI ID. For the moment
	 * though, the AceNIC is the only copper card available.
	 */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENICT)
		sc->ti_copper = 1;
	/* Ok, it's not the only copper card available */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T)
		sc->ti_copper = 1;

	if (ti_attach(sc) == 0)
		return;

	pci_intr_disestablish(pc, sc->ti_intrhand);

unmap:
	bus_space_unmap(sc->ti_btag, sc->ti_bhandle, size);
}
Пример #26
0
void
ciss_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct ciss_softc *sc = (struct ciss_softc *)self;
	struct pci_attach_args *pa = aux;
	bus_size_t size, cfgsz;
	pci_intr_handle_t ih;
	const char *intrstr;
	int cfg_bar, memtype;
	pcireg_t reg;

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, CISS_BAR);
	if (pci_mapreg_map(pa, CISS_BAR, memtype, 0,
	    &sc->iot, &sc->ioh, NULL, &size, 0)) {
		printf(": can't map controller mem space\n");
		return;
	}
	sc->dmat = pa->pa_dmat;

	sc->iem = CISS_READYENA;
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
	if (PCI_VENDOR(reg) == PCI_VENDOR_COMPAQ &&
	    (PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA5i ||
	     PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA532 ||
	     PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA5312))
		sc->iem = CISS_READYENAB;

	cfg_bar = bus_space_read_2(sc->iot, sc->ioh, CISS_CFG_BAR);
	sc->cfgoff = bus_space_read_4(sc->iot, sc->ioh, CISS_CFG_OFF);
	if (cfg_bar != CISS_BAR) {
		if (pci_mapreg_map(pa, cfg_bar, PCI_MAPREG_TYPE_MEM, 0,
		    NULL, &sc->cfg_ioh, NULL, &cfgsz, 0)) {
			printf(": can't map controller config space\n");  
			bus_space_unmap(sc->iot, sc->ioh, size);
			return;
		}
	} else {
		sc->cfg_ioh = sc->ioh;
		cfgsz = size;
	}

	if (sc->cfgoff + sizeof(struct ciss_config) > cfgsz) {
		printf(": unfit config space\n");
		bus_space_unmap(sc->iot, sc->ioh, size);
		if (cfg_bar != CISS_BAR)
			bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
		return;
	}

	/* disable interrupts until ready */
	bus_space_write_4(sc->iot, sc->ioh, CISS_IMR,
	    bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) | sc->iem);

	if (pci_intr_map(pa, &ih)) {
		printf(": can't map interrupt\n");
		bus_space_unmap(sc->iot, sc->ioh, size);
		if (cfg_bar != CISS_BAR)
			bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ciss_intr, sc,
	    sc->sc_dev.dv_xname);
	if (!sc->sc_ih) {
		printf(": can't establish interrupt");
		if (intrstr)
			printf(" at %s", intrstr);
		printf("\n");
		bus_space_unmap(sc->iot, sc->ioh, size);
		if (cfg_bar != CISS_BAR)
			bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
	}

	printf(": %s\n%s", intrstr, sc->sc_dev.dv_xname);

	if (ciss_attach(sc)) {
		pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
		sc->sc_ih = NULL;
		bus_space_unmap(sc->iot, sc->ioh, size);
		if (cfg_bar != CISS_BAR)
			bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
		return;
	}

	/* enable interrupts now */
	bus_space_write_4(sc->iot, sc->ioh, CISS_IMR,
	    bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) & ~sc->iem);
}
Пример #27
0
static void
virtio_attach(device_t parent, device_t self, void *aux)
{
	struct virtio_softc *sc = device_private(self);
	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	int revision;
	pcireg_t id;
	char const *intrstr;
	pci_intr_handle_t ih;

	revision = PCI_REVISION(pa->pa_class);
	if (revision != 0) {
		aprint_normal(": unknown revision 0x%02x; giving up\n",
			      revision);
		return;
	}
	aprint_normal("\n");
	aprint_naive("\n");

	/* subsystem ID shows what I am */
	id = pci_conf_read(pc, tag, PCI_SUBSYS_ID_REG);
	aprint_normal_dev(self, "%s Virtio %s Device (rev. 0x%02x)\n",
			  pci_findvendor(id),
			  (PCI_PRODUCT(id)<NDEVNAMES?
			   virtio_device_name[PCI_PRODUCT(id)]:"Unknown"),
			  revision);

	sc->sc_dev = self;
	sc->sc_pc = pc;
	sc->sc_tag = tag;
	sc->sc_iot = pa->pa_iot;
	sc->sc_dmat = pa->pa_dmat;
	sc->sc_config_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI;

	if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0,
			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) {
		aprint_error_dev(self, "can't map i/o space\n");
		return;
	}

	virtio_device_reset(sc);
	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);

	/* XXX: use softc as aux... */
	sc->sc_childdevid = PCI_PRODUCT(id);
	sc->sc_child = NULL;
	config_found(self, sc, NULL);
	if (sc->sc_child == NULL) {
		aprint_error_dev(self,
				 "no matching child driver; not configured\n");
		return;
	}
	if (sc->sc_child == (void*)1) { /* this shows error */
		aprint_error_dev(self,
				 "virtio configuration failed\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}

	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, sc->sc_ipl, virtio_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_FAILED);
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);

	return;
}
Пример #28
0
static void
bwi_pci_attach(device_t parent, device_t self, void *aux)
{
	struct bwi_pci_softc *psc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct bwi_softc *sc = &psc->psc_bwi;
	const char *intrstr = NULL;
	pci_intr_handle_t ih;
	pcireg_t memtype, reg;
	int error = 0;
	char intrbuf[PCI_INTRSTR_LEN];

	aprint_naive("\n");
	aprint_normal(": Broadcom Wireless\n");

	sc->sc_dev = self;
	sc->sc_dmat = pa->pa_dmat;
	psc->psc_pc = pa->pa_pc;
	psc->psc_pcitag = pa->pa_tag;

	/* map control / status registers */
	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BWI_PCI_BAR0);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		break;
	default:
		aprint_error_dev(self, "invalid base address register\n");
		return;
	}

	if (pci_mapreg_map(pa, BWI_PCI_BAR0,
	    memtype, 0, &sc->sc_mem_bt, &sc->sc_mem_bh,
	    NULL, &psc->psc_mapsize) != 0)
	{
		aprint_error_dev(self, "could not map mem space\n");
		return;
	}

	/* map interrupt */
	if (pci_intr_map(pa, &ih) != 0) {
		aprint_error_dev(self, "could not map interrupt\n");
		goto fail;
	}

	/* establish interrupt */
	intrstr = pci_intr_string(psc->psc_pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "could not establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		goto fail;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

	/* we need to access PCI config space from the driver */
	sc->sc_conf_write = bwi_pci_conf_write;
	sc->sc_conf_read = bwi_pci_conf_read;

	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);

	sc->sc_pci_revid = PCI_REVISION(pa->pa_class);
	sc->sc_pci_did = PCI_PRODUCT(pa->pa_id);
	sc->sc_pci_subvid = PCI_VENDOR(reg);
	sc->sc_pci_subdid = PCI_PRODUCT(reg);

	if (!pmf_device_register(self, bwi_suspend, bwi_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");

	error = bwi_attach(sc);
	if (error)
		goto fail;
	return;

fail:
	if (sc->sc_ih) {
		pci_intr_disestablish(psc->psc_pc, sc->sc_ih);
		sc->sc_ih = NULL;
	}
	if (psc->psc_mapsize) {
		bus_space_unmap(sc->sc_mem_bt, sc->sc_mem_bh, psc->psc_mapsize);
		psc->psc_mapsize = 0;
	}
	return;
}
Пример #29
0
/*
 * Attach all the sub-devices we can find
 */
void
macobio_attach(struct device *parent, struct device *self, void *aux)
{
	struct macobio_softc *sc = (struct macobio_softc *)self;
	struct pci_attach_args *pa = aux;
	struct confargs ca;
	int node, child, namelen;
	u_int32_t reg[20];
	int32_t intr[8];
	char name[32];
	int need_interrupt_controller = 0;

	sc->sc_id = pa->pa_id; /* save of type for later */

	switch (PCI_PRODUCT(pa->pa_id)) {

	/* XXX should not use name */
	case PCI_PRODUCT_APPLE_GC:
		node = OF_finddevice("/bandit/gc");
		need_interrupt_controller = 1;
		break;

	case PCI_PRODUCT_APPLE_OHARE:
		node = OF_finddevice("/bandit/ohare");
		need_interrupt_controller = 1;
		break;

	case PCI_PRODUCT_APPLE_HEATHROW:
	case PCI_PRODUCT_APPLE_PADDINGTON:
		node = OF_finddevice("mac-io");
		if (node == -1)
			node = OF_finddevice("/pci/mac-io");
		if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg))
			== (sizeof (reg[0]) * 5))
		{
			/* always ??? */
			heathrow_FCR = mapiodev(reg[2] + HEATHROW_FCR_OFFSET,
			    4);
		}
		break;
	case PCI_PRODUCT_APPLE_KEYLARGO:
	case PCI_PRODUCT_APPLE_INTREPID:
	case PCI_PRODUCT_APPLE_PANGEA_MACIO:
	case PCI_PRODUCT_APPLE_SHASTA:
	case PCI_PRODUCT_APPLE_K2_MACIO:
		node = OF_finddevice("mac-io");
		if (node == -1)
			node = OF_finddevice("/pci/mac-io");
		if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg))
		    == (sizeof (reg[0]) * 5))
			 sc->obiomem = mapiodev(reg[2], 0x100);
		break;
	default:
		printf(": unknown macobio controller\n");
		return;
	}
	sc->sc_node = node;

	if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12)
		return;

	ca.ca_baseaddr = reg[2];

	sc->sc_membus_space.bus_base = ca.ca_baseaddr;

	ca.ca_iot = &sc->sc_membus_space;
	ca.ca_dmat = pa->pa_dmat;

	printf("\n");

	/*
	 * This might be a hack, but it makes the interrupt controller
	 * attach as expected if a device node existed in the OF tree.
	 */
	if (need_interrupt_controller) {
		/* force attachment of legacy interrupt controllers */
		ca.ca_name = "legacy-interrupt-controller";
		ca.ca_node = 0;

		ca.ca_nreg  = 0;
		ca.ca_nintr = 0;

		ca.ca_reg = NULL;
		ca.ca_intr = NULL;

		config_found(self, &ca, macobio_print);
	}

	for (child = OF_child(node); child; child = OF_peer(child)) {
		namelen = OF_getprop(child, "name", name, sizeof(name));
		if (namelen < 0)
			continue;
		if (namelen >= sizeof(name))
			continue;

		name[namelen] = 0;
		ca.ca_name = name;
		ca.ca_node = child;

		ca.ca_nreg  = OF_getprop(child, "reg", reg, sizeof(reg));
		ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr,
				sizeof(intr));
		if (ca.ca_nintr == -1)
			ca.ca_nintr = OF_getprop(child, "interrupts", intr,
					sizeof(intr));

		ca.ca_reg = reg;
		ca.ca_intr = intr;

		config_found(self, &ca, macobio_print);
	}
}
Пример #30
0
void
gdt_pci_attach(struct device *parent, struct device *self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct gdt_softc *sc = (void *)self;
	bus_space_tag_t dpmemt, iomemt, iot;
	bus_space_handle_t dpmemh, iomemh, ioh;
	bus_addr_t dpmembase, iomembase, iobase;
	bus_size_t dpmemsize, iomemsize, iosize;
	u_int16_t prod;
	u_int32_t status = 0;
#define DPMEM_MAPPED		1
#define IOMEM_MAPPED		2
#define IO_MAPPED		4
#define INTR_ESTABLISHED	8
	int retries;
	u_int8_t protocol;
	pci_intr_handle_t ih;
	const char *intrstr;

	printf(": ");

	sc->sc_class = 0;
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VORTEX) {
		prod = PCI_PRODUCT(pa->pa_id);
		switch (prod) {
		case PCI_PRODUCT_VORTEX_GDT_60x0:
		case PCI_PRODUCT_VORTEX_GDT_6000B:
			sc->sc_class = GDT_PCI;
			break;

		case PCI_PRODUCT_VORTEX_GDT_6x10:
		case PCI_PRODUCT_VORTEX_GDT_6x20:
		case PCI_PRODUCT_VORTEX_GDT_6530:
		case PCI_PRODUCT_VORTEX_GDT_6550:
		case PCI_PRODUCT_VORTEX_GDT_6x17:
		case PCI_PRODUCT_VORTEX_GDT_6x27:
		case PCI_PRODUCT_VORTEX_GDT_6537:
		case PCI_PRODUCT_VORTEX_GDT_6557:
		case PCI_PRODUCT_VORTEX_GDT_6x15:
		case PCI_PRODUCT_VORTEX_GDT_6x25:
		case PCI_PRODUCT_VORTEX_GDT_6535:
		case PCI_PRODUCT_VORTEX_GDT_6555:
			sc->sc_class = GDT_PCINEW;
			break;

		case PCI_PRODUCT_VORTEX_GDT_6x17RP:
		case PCI_PRODUCT_VORTEX_GDT_6x27RP:
		case PCI_PRODUCT_VORTEX_GDT_6537RP:
		case PCI_PRODUCT_VORTEX_GDT_6557RP:
		case PCI_PRODUCT_VORTEX_GDT_6x11RP:
		case PCI_PRODUCT_VORTEX_GDT_6x21RP:
		case PCI_PRODUCT_VORTEX_GDT_6x17RD:
		case PCI_PRODUCT_VORTEX_GDT_6x27RD:
		case PCI_PRODUCT_VORTEX_GDT_6537RD:
		case PCI_PRODUCT_VORTEX_GDT_6557RD:
		case PCI_PRODUCT_VORTEX_GDT_6x11RD:
		case PCI_PRODUCT_VORTEX_GDT_6x21RD:
		case PCI_PRODUCT_VORTEX_GDT_6x18RD:
		case PCI_PRODUCT_VORTEX_GDT_6x28RD:
		case PCI_PRODUCT_VORTEX_GDT_6x38RD:
		case PCI_PRODUCT_VORTEX_GDT_6x58RD:
		case PCI_PRODUCT_VORTEX_GDT_6518RS:
		case PCI_PRODUCT_VORTEX_GDT_7x18RN:
		case PCI_PRODUCT_VORTEX_GDT_7x28RN:
		case PCI_PRODUCT_VORTEX_GDT_7x38RN:
		case PCI_PRODUCT_VORTEX_GDT_7x58RN:
		case PCI_PRODUCT_VORTEX_GDT_6x19RD:
		case PCI_PRODUCT_VORTEX_GDT_6x29RD:
		case PCI_PRODUCT_VORTEX_GDT_7x19RN:
		case PCI_PRODUCT_VORTEX_GDT_7x29RN:
		case PCI_PRODUCT_VORTEX_GDT_7x43RN:
			sc->sc_class = GDT_MPR;
		}

		/* If we don't recognize it, determine class heuristically.  */
		if (sc->sc_class == 0)
			sc->sc_class = prod < 0x100 ? GDT_PCINEW : GDT_MPR;

		if (prod >= GDT_PCI_PRODUCT_FC)
			sc->sc_class |= GDT_FC;

	} else if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) {
		sc->sc_class = GDT_MPR;
	}

	if (pci_mapreg_map(pa,
	    GDT_CLASS(sc) == GDT_PCINEW ? GDT_PCINEW_DPMEM : GDT_PCI_DPMEM,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &dpmemt,
	    &dpmemh, &dpmembase, &dpmemsize, 0)) {
		if (pci_mapreg_map(pa,
		    GDT_CLASS(sc) == GDT_PCINEW ? GDT_PCINEW_DPMEM :
		    GDT_PCI_DPMEM,
		    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT_1M, 0,
		    &dpmemt,&dpmemh, &dpmembase, &dpmemsize, 0)) {
			printf("cannot map DPMEM\n");
			goto bail_out;
		}
	}
	status |= DPMEM_MAPPED;
	sc->sc_dpmemt = dpmemt;
	sc->sc_dpmemh = dpmemh;
	sc->sc_dpmembase = dpmembase;
	sc->sc_dmat = pa->pa_dmat;

	/*
	 * The GDT_PCINEW series also has two other regions to map.
	 */
	if (GDT_CLASS(sc) == GDT_PCINEW) {
		if (pci_mapreg_map(pa, GDT_PCINEW_IOMEM, PCI_MAPREG_TYPE_MEM,
		    0, &iomemt, &iomemh, &iomembase, &iomemsize, 0)) {
			printf("can't map memory mapped i/o ports\n");
			goto bail_out;
		}
		status |= IOMEM_MAPPED;

		if (pci_mapreg_map(pa, GDT_PCINEW_IO, PCI_MAPREG_TYPE_IO, 0,
		    &iot, &ioh, &iobase, &iosize, 0)) {
			printf("can't map i/o space\n");
			goto bail_out;
		}
		status |= IO_MAPPED;
		sc->sc_iot = iot;
		sc->sc_ioh = ioh;
		sc->sc_iobase = iobase;
	}

	switch (GDT_CLASS(sc)) {
	case GDT_PCI:
		bus_space_set_region_4(dpmemt, dpmemh, 0, 0,
		    GDT_DPR_IF_SZ >> 2);
		if (bus_space_read_1(dpmemt, dpmemh, 0) != 0) {
			printf("can't write to DPMEM\n");
			goto bail_out;
		}

#if 0
		/* disable board interrupts, deinit services */
		gdth_writeb(0xff, &dp6_ptr->io.irqdel);
		gdth_writeb(0x00, &dp6_ptr->io.irqen);
		gdth_writeb(0x00, &dp6_ptr->u.ic.S_Status);
		gdth_writeb(0x00, &dp6_ptr->u.ic.Cmd_Index);

		gdth_writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]);
		gdth_writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx);
		gdth_writeb(0, &dp6_ptr->io.event);
		retries = INIT_RETRIES;
		gdth_delay(20);
		while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xff) {
		  if (--retries == 0) {
		    printk("initialization error (DEINIT failed)\n");
		    gdth_munmap(ha->brd);
		    return 0;
		  }
		  gdth_delay(1);
		}
		prot_ver = (unchar)gdth_readl(&dp6_ptr->u.ic.S_Info[0]);
		gdth_writeb(0, &dp6_ptr->u.ic.S_Status);
		gdth_writeb(0xff, &dp6_ptr->io.irqdel);
		if (prot_ver != PROTOCOL_VERSION) {
		  printk("illegal protocol version\n");
		  gdth_munmap(ha->brd);
		  return 0;
		}

		ha->type = GDT_PCI;
		ha->ic_all_size = sizeof(dp6_ptr->u);

		/* special command to controller BIOS */
		gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[0]);
		gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[1]);
		gdth_writel(0x01, &dp6_ptr->u.ic.S_Info[2]);
		gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[3]);
		gdth_writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx);
		gdth_writeb(0, &dp6_ptr->io.event);
		retries = INIT_RETRIES;
		gdth_delay(20);
		while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xfe) {
		  if (--retries == 0) {
		    printk("initialization error\n");
		    gdth_munmap(ha->brd);
		    return 0;
		  }
		  gdth_delay(1);
		}
		gdth_writeb(0, &dp6_ptr->u.ic.S_Status);
		gdth_writeb(0xff, &dp6_ptr->io.irqdel);
#endif

		sc->sc_ic_all_size = GDT_DPRAM_SZ;

		sc->sc_copy_cmd = gdt_pci_copy_cmd;
		sc->sc_get_status = gdt_pci_get_status;
		sc->sc_intr = gdt_pci_intr;
		sc->sc_release_event = gdt_pci_release_event;
		sc->sc_set_sema0 = gdt_pci_set_sema0;
		sc->sc_test_busy = gdt_pci_test_busy;

		break;

	case GDT_PCINEW:
		bus_space_set_region_4(dpmemt, dpmemh, 0, 0,
		    GDT_DPR_IF_SZ >> 2);
		if (bus_space_read_1(dpmemt, dpmemh, 0) != 0) {
			printf("cannot write to DPMEM\n");
			goto bail_out;
		}

#if 0
		/* disable board interrupts, deinit services */
		outb(0x00,PTR2USHORT(&ha->plx->control1));
		outb(0xff,PTR2USHORT(&ha->plx->edoor_reg));

		gdth_writeb(0x00, &dp6c_ptr->u.ic.S_Status);
		gdth_writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index);

		gdth_writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]);
		gdth_writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx);

		outb(1,PTR2USHORT(&ha->plx->ldoor_reg));

		retries = INIT_RETRIES;
		gdth_delay(20);
		while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xff) {
		  if (--retries == 0) {
		    printk("initialization error (DEINIT failed)\n");
		    gdth_munmap(ha->brd);
		    return 0;
		  }
		  gdth_delay(1);
		}
		prot_ver = (unchar)gdth_readl(&dp6c_ptr->u.ic.S_Info[0]);
		gdth_writeb(0, &dp6c_ptr->u.ic.Status);
		if (prot_ver != PROTOCOL_VERSION) {
		  printk("illegal protocol version\n");
		  gdth_munmap(ha->brd);
		  return 0;
		}

		ha->type = GDT_PCINEW;
		ha->ic_all_size = sizeof(dp6c_ptr->u);

		/* special command to controller BIOS */
		gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[0]);
		gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[1]);
		gdth_writel(0x01, &dp6c_ptr->u.ic.S_Info[2]);
		gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[3]);
		gdth_writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx);

		outb(1,PTR2USHORT(&ha->plx->ldoor_reg));

		retries = INIT_RETRIES;
		gdth_delay(20);
		while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) {
		  if (--retries == 0) {
		    printk("initialization error\n");
		    gdth_munmap(ha->brd);
		    return 0;
		  }
		  gdth_delay(1);
		}
		gdth_writeb(0, &dp6c_ptr->u.ic.S_Status);
#endif

		sc->sc_ic_all_size = GDT_PCINEW_SZ;

		sc->sc_copy_cmd = gdt_pcinew_copy_cmd;
		sc->sc_get_status = gdt_pcinew_get_status;
		sc->sc_intr = gdt_pcinew_intr;
		sc->sc_release_event = gdt_pcinew_release_event;
		sc->sc_set_sema0 = gdt_pcinew_set_sema0;
		sc->sc_test_busy = gdt_pcinew_test_busy;

		break;

	case GDT_MPR:
		bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC, GDT_MPR_MAGIC);
		if (bus_space_read_4(dpmemt, dpmemh, GDT_MPR_IC) !=
		    GDT_MPR_MAGIC) {
			printf("cannot access DPMEM at 0x%lx (shadowed?)\n",
			    dpmembase);
			goto bail_out;
		}

		/*
		 * XXX Here the Linux driver has a weird remapping logic I
		 * don't understand.  My controller does not need it, and I
		 * cannot see what purpose it serves, therefore I did not
		 * do anything similar.
		 */

		bus_space_set_region_4(dpmemt, dpmemh, GDT_I960_SZ, 0,
		    GDT_DPR_IF_SZ >> 2);

		/* Disable everything */
		bus_space_write_1(dpmemt, dpmemh, GDT_EDOOR_EN,
		    bus_space_read_1(dpmemt, dpmemh, GDT_EDOOR_EN) | 4);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_EDOOR, 0xff);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS,
		    0);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_CMD_INDEX,
		    0);

		bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO,
		    dpmembase);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
		    0xff);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_LDOOR, 1);

		DELAY(20);
		retries = GDT_RETRIES;
		while (bus_space_read_1(dpmemt, dpmemh,
		    GDT_MPR_IC + GDT_S_STATUS) != 0xff) {
			if (--retries == 0) {
				printf("DEINIT failed (status 0x%x)\n",
				    bus_space_read_1(dpmemt, dpmemh,
				    GDT_MPR_IC + GDT_S_STATUS));
				goto bail_out;
			}
			DELAY(1);
		}

		protocol = (u_int8_t)bus_space_read_4(dpmemt, dpmemh,
		    GDT_MPR_IC + GDT_S_INFO);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS,
		    0);
		if (protocol != GDT_PROTOCOL_VERSION) {
		 	printf("unsupported protocol %d\n", protocol);
			goto bail_out;
		}

		/* special commnd to controller BIOS */
		bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO, 0);
		bus_space_write_4(dpmemt, dpmemh,
		    GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), 0);
		bus_space_write_4(dpmemt, dpmemh,
		    GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), 1);
		bus_space_write_4(dpmemt, dpmemh,
		    GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), 0);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
		    0xfe);
		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_LDOOR, 1);

		DELAY(20);
		retries = GDT_RETRIES;
		while (bus_space_read_1(dpmemt, dpmemh,
		    GDT_MPR_IC + GDT_S_STATUS) != 0xfe) {
			if (--retries == 0) {
				printf("initialization error\n");
				goto bail_out;
			}
			DELAY(1);
		}

		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS,
		    0);

		sc->sc_ic_all_size = GDT_MPR_SZ;

		sc->sc_copy_cmd = gdt_mpr_copy_cmd;
		sc->sc_get_status = gdt_mpr_get_status;
		sc->sc_intr = gdt_mpr_intr;
		sc->sc_release_event = gdt_mpr_release_event;
		sc->sc_set_sema0 = gdt_mpr_set_sema0;
		sc->sc_test_busy = gdt_mpr_test_busy;
	}

	if (pci_intr_map(pa, &ih)) {
		printf("couldn't map interrupt\n");
		goto bail_out;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, gdt_intr, sc,
	    sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf("couldn't establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		goto bail_out;
	}
	status |= INTR_ESTABLISHED;
	if (intrstr != NULL)
		printf("%s ", intrstr);

	if (gdt_attach(sc))
		goto bail_out;

	gdt_pci_enable_intr(sc);

	return;

 bail_out:
	if (status & DPMEM_MAPPED)
		bus_space_unmap(dpmemt, dpmemh, dpmemsize);
	if (status & IOMEM_MAPPED)
		bus_space_unmap(iomemt, iomemh, iomembase);
	if (status & IO_MAPPED)
		bus_space_unmap(iot, ioh, iosize);
	if (status & INTR_ESTABLISHED)
		pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
	return;
}