FreeBSD/sys/powerpc/powermac/macio.c
/*
 * PCI attach: scan Open Firmware child nodes, and attach these as children
 * of the macio bus
 */
PCI attach: scan Open Firmware child nodes, and attach these as children
of the macio bus
PCI attach : scan Open Firmware child nodes and attach these as children of the macio bus
static int 
macio_attach(device_t dev)
{
	struct macio_softc *sc;
        struct macio_devinfo *dinfo;
        phandle_t  root;
	phandle_t  child;
	phandle_t  subchild;
        device_t cdev;
        u_int reg[3];
	char compat[32];
	int error, quirks;
	sc = device_get_softc(dev);
	root = sc->sc_node = ofw_bus_get_node(dev);
	if (OF_getprop(root, "assigned-addresses", 
		       reg, sizeof(reg)) < (ssize_t)sizeof(reg)) {
		return (ENXIO);
	}
	OF_getprop(root, "compatible", compat, sizeof(compat));
	sc->sc_base = reg[2];
	sc->sc_size = MACIO_REG_SIZE;
	sc->sc_memrid = PCIR_BAR(0);
	sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &sc->sc_memrid, RF_ACTIVE);
	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
	sc->sc_mem_rman.rm_descr = "MacIO Device Memory";
	error = rman_init(&sc->sc_mem_rman);
	if (error) {
		device_printf(dev, "rman_init() failed. error = %d\n", error);
		return (error);
	}
	error = rman_manage_region(&sc->sc_mem_rman, 0, sc->sc_size);	
	if (error) {
		device_printf(dev,
		    "rman_manage_region() failed. error = %d\n", error);
		return (error);
	}
	for (child = OF_child(root); child != 0; child = OF_peer(child)) {
		dinfo = malloc(sizeof(*dinfo), M_MACIO, M_WAITOK | M_ZERO);
		if (ofw_bus_gen_setup_devinfo(&dinfo->mdi_obdinfo, child) !=
		    0) {
			free(dinfo, M_MACIO);
			continue;
		}
		quirks = macio_get_quirks(dinfo->mdi_obdinfo.obd_name);
		if ((quirks & MACIO_QUIRK_IGNORE) != 0) {
			ofw_bus_gen_destroy_devinfo(&dinfo->mdi_obdinfo);
			free(dinfo, M_MACIO);
			continue;
		}
		resource_list_init(&dinfo->mdi_resources);
		dinfo->mdi_ninterrupts = 0;
		macio_add_intr(child, dinfo);
		if ((quirks & MACIO_QUIRK_USE_CHILD_REG) != 0)
			macio_add_reg(OF_child(child), dinfo);
		else
			macio_add_reg(child, dinfo);
		if ((quirks & MACIO_QUIRK_CHILD_HAS_INTR) != 0)
			for (subchild = OF_child(child); subchild != 0;
			    subchild = OF_peer(subchild))
				macio_add_intr(subchild, dinfo);
		cdev = device_add_child(dev, NULL, -1);
		if (cdev == NULL) {
			device_printf(dev, "<%s>: device_add_child failed\n",
			    dinfo->mdi_obdinfo.obd_name);
			resource_list_free(&dinfo->mdi_resources);
			ofw_bus_gen_destroy_devinfo(&dinfo->mdi_obdinfo);
			free(dinfo, M_MACIO);
			continue;
		}
		device_set_ivars(cdev, dinfo);
		if (sc->sc_memr == NULL)
			continue;
		if (strcmp(ofw_bus_get_name(cdev), "bmac") == 0 ||
		    strcmp(ofw_bus_get_compat(cdev), "bmac+") == 0) {
			uint32_t fcr;
			fcr = bus_read_4(sc->sc_memr, HEATHROW_FCR);
			fcr |= FCR_ENET_ENABLE & ~FCR_ENET_RESET;
			bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
			DELAY(50000);
			fcr |= FCR_ENET_RESET;
			bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
			DELAY(50000);
			fcr &= ~FCR_ENET_RESET;
			bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
			DELAY(50000);
			bus_write_4(sc->sc_memr, HEATHROW_FCR, fcr);
		}
		if ((strcmp(ofw_bus_get_name(cdev), "i2s") == 0) &&
		    (strcmp(compat, "K2-Keylargo") == 0)) {
			uint32_t fcr1;
			fcr1 = bus_read_4(sc->sc_memr, KEYLARGO_FCR1);
			fcr1 |= FCR1_I2S0_CLK_ENABLE | FCR1_I2S0_ENABLE;
			bus_write_4(sc->sc_memr, KEYLARGO_FCR1, fcr1);
		}
	}
	return (bus_generic_attach(dev));
}
static int macio_attach ( device_t dev ) { struct macio_softc * sc ; struct macio_devinfo * dinfo ; phandle_t root ; phandle_t child ; phandle_t subchild ; device_t cdev ; u_int reg [ 3 ] ; char compat [ 32 ] ; int error , quirks ; sc = device_get_softc ( dev ) ; root = sc -> sc_node = ofw_bus_get_node ( dev ) ; if ( OF_getprop ( root , " " , reg , sizeof ( reg ) ) < ( ssize_t ) sizeof ( reg ) ) { return ( ENXIO ) ; } OF_getprop ( root , " " , compat , sizeof ( compat ) ) ; sc -> sc_base = reg [ 2 ] ; sc -> sc_size = MACIO_REG_SIZE ; sc -> sc_memrid = PCIR_BAR ( 0 ) ; sc -> sc_memr = bus_alloc_resource_any ( dev , SYS_RES_MEMORY , & sc -> sc_memrid , RF_ACTIVE ) ; sc -> sc_mem_rman . rm_type = RMAN_ARRAY ; sc -> sc_mem_rman . rm_descr = " " ; error = rman_init ( & sc -> sc_mem_rman ) ; if ( error ) { device_printf ( dev , " \n " , error ) ; return ( error ) ; } error = rman_manage_region ( & sc -> sc_mem_rman , 0 , sc -> sc_size ) ; if ( error ) { device_printf ( dev , " \n " , error ) ; return ( error ) ; } for ( child = OF_child ( root ) ; child != 0 ; child = OF_peer ( child ) ) { dinfo = malloc ( sizeof ( * dinfo ) , M_MACIO , M_WAITOK | M_ZERO ) ; if ( ofw_bus_gen_setup_devinfo ( & dinfo -> mdi_obdinfo , child ) != 0 ) { free ( dinfo , M_MACIO ) ; continue ; } quirks = macio_get_quirks ( dinfo -> mdi_obdinfo . obd_name ) ; if ( ( quirks & MACIO_QUIRK_IGNORE ) != 0 ) { ofw_bus_gen_destroy_devinfo ( & dinfo -> mdi_obdinfo ) ; free ( dinfo , M_MACIO ) ; continue ; } resource_list_init ( & dinfo -> mdi_resources ) ; dinfo -> mdi_ninterrupts = 0 ; macio_add_intr ( child , dinfo ) ; if ( ( quirks & MACIO_QUIRK_USE_CHILD_REG ) != 0 ) macio_add_reg ( OF_child ( child ) , dinfo ) ; else macio_add_reg ( child , dinfo ) ; if ( ( quirks & MACIO_QUIRK_CHILD_HAS_INTR ) != 0 ) for ( subchild = OF_child ( child ) ; subchild != 0 ; subchild = OF_peer ( subchild ) ) macio_add_intr ( subchild , dinfo ) ; cdev = device_add_child ( dev , NULL , -1 ) ; if ( cdev == NULL ) { device_printf ( dev , " \n " , dinfo -> mdi_obdinfo . obd_name ) ; resource_list_free ( & dinfo -> mdi_resources ) ; ofw_bus_gen_destroy_devinfo ( & dinfo -> mdi_obdinfo ) ; free ( dinfo , M_MACIO ) ; continue ; } device_set_ivars ( cdev , dinfo ) ; if ( sc -> sc_memr == NULL ) continue ; if ( strcmp ( ofw_bus_get_name ( cdev ) , " " ) == 0 || strcmp ( ofw_bus_get_compat ( cdev ) , " " ) == 0 ) { uint32_t fcr ; fcr = bus_read_4 ( sc -> sc_memr , HEATHROW_FCR ) ; fcr |= FCR_ENET_ENABLE & ~ FCR_ENET_RESET ; bus_write_4 ( sc -> sc_memr , HEATHROW_FCR , fcr ) ; DELAY ( 50000 ) ; fcr |= FCR_ENET_RESET ; bus_write_4 ( sc -> sc_memr , HEATHROW_FCR , fcr ) ; DELAY ( 50000 ) ; fcr &= ~ FCR_ENET_RESET ; bus_write_4 ( sc -> sc_memr , HEATHROW_FCR , fcr ) ; DELAY ( 50000 ) ; bus_write_4 ( sc -> sc_memr , HEATHROW_FCR , fcr ) ; } if ( ( strcmp ( ofw_bus_get_name ( cdev ) , " " ) == 0 ) && ( strcmp ( compat , " " ) == 0 ) ) { uint32_t fcr1 ; fcr1 = bus_read_4 ( sc -> sc_memr , KEYLARGO_FCR1 ) ; fcr1 |= FCR1_I2S0_CLK_ENABLE | FCR1_I2S0_ENABLE ; bus_write_4 ( sc -> sc_memr , KEYLARGO_FCR1 , fcr1 ) ; } } return ( bus_generic_attach ( dev ) ) ; }
PCI attach: scan Open Firmware child nodes, and attach these as children
 of the macio bus
PCI attach : scan Open Firmware child nodes and attach these as children of the macio bus
/*
	 * Locate the device node and it's base address
	 */ /* Used later to see if we have to enable the I2S part. */ /*
	 * Iterate through the sub-devices
	 */ /* Set FCRs to enable some devices */ /*
		 * Make sure the I2S0 and the I2S0_CLK are enabled.
		 * On certain G5's they are not.
		 */