Esempio n. 1
0
/**
 * Probe UNDI root bus
 *
 * @v rootdev		UNDI bus root device
 *
 * Scans the UNDI bus for devices and registers all devices it can
 * find.
 */
static int undibus_probe ( struct root_device *rootdev ) {
	struct undi_device *undi = &preloaded_undi;
	int rc;

	/* Check for a valie preloaded UNDI device */
	if ( ! undi->entry.segment ) {
		DBG ( "No preloaded UNDI device found!\n" );
		return -ENODEV;
	}

	/* Add to device hierarchy */
	strncpy ( undi->dev.name, "UNDI",
		  ( sizeof ( undi->dev.name ) - 1 ) );
	if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
		undi->dev.desc.bus_type = BUS_TYPE_PCI;
		undi->dev.desc.location = undi->pci_busdevfn;
		undi->dev.desc.vendor = undi->pci_vendor;
		undi->dev.desc.device = undi->pci_device;
	} else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
		undi->dev.desc.bus_type = BUS_TYPE_ISAPNP;
	}
	undi->dev.parent = &rootdev->dev;
	list_add ( &undi->dev.siblings, &rootdev->dev.children);
	INIT_LIST_HEAD ( &undi->dev.children );

	/* Create network device */
	if ( ( rc = undinet_probe ( undi ) ) != 0 )
		goto err;

	return 0;

 err:
	list_del ( &undi->dev.siblings );
	return rc;
}
Esempio n. 2
0
/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @v id		PCI ID
 * @ret rc		Return status code
 */
static int undipci_probe ( struct pci_device *pci ) {
    struct undi_device *undi;
    struct undi_rom *undirom;
    int rc;

    /* Allocate UNDI device structure */
    undi = zalloc ( sizeof ( *undi ) );
    if ( ! undi )
        return -ENOMEM;
    pci_set_drvdata ( pci, undi );

    /* Find/create our pixie */
    if ( preloaded_undi.pci_busdevfn == pci->busdevfn ) {
        /* Claim preloaded UNDI device */
        DBGC ( undi, "UNDI %p using preloaded UNDI device\n", undi );
        memcpy ( undi, &preloaded_undi, sizeof ( *undi ) );
        memset ( &preloaded_undi, 0, sizeof ( preloaded_undi ) );
    } else {
        /* Find UNDI ROM for PCI device */
        if ( ! ( undirom = undipci_find_rom ( pci ) ) ) {
            rc = -ENODEV;
            goto err_find_rom;
        }

        /* Call UNDI ROM loader to create pixie */
        if ( ( rc = undi_load_pci ( undi, undirom,
                                    pci->busdevfn ) ) != 0 ) {
            goto err_load_pci;
        }
    }

    /* Add to device hierarchy */
    snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
               "UNDI-%s", pci->dev.name );
    memcpy ( &undi->dev.desc, &pci->dev.desc, sizeof ( undi->dev.desc ) );
    undi->dev.parent = &pci->dev;
    INIT_LIST_HEAD ( &undi->dev.children );
    list_add ( &undi->dev.siblings, &pci->dev.children );

    /* Create network device */
    if ( ( rc = undinet_probe ( undi ) ) != 0 )
        goto err_undinet_probe;

    return 0;

err_undinet_probe:
    undi_unload ( undi );
    list_del ( &undi->dev.siblings );
err_find_rom:
err_load_pci:
    free ( undi );
    pci_set_drvdata ( pci, NULL );
    return rc;
}
Esempio n. 3
0
/**
 * Probe UNDI root bus
 *
 * @v rootdev		UNDI bus root device
 *
 * Scans the UNDI bus for devices and registers all devices it can
 * find.
 */
static int undibus_probe ( struct root_device *rootdev ) {
	struct undi_device *undi = &preloaded_undi;
	struct device *dev = &undibus_dev;
	int rc;

	/* Check for a valie preloaded UNDI device */
	if ( ! undi->entry.segment ) {
		DBG ( "No preloaded UNDI device found!\n" );
		return -ENODEV;
	}

	/* Add to device hierarchy */
	dev->driver_name = "undionly";
	if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
		dev->desc.bus_type = BUS_TYPE_PCI;
		dev->desc.location = undi->pci_busdevfn;
		dev->desc.vendor = undi->pci_vendor;
		dev->desc.device = undi->pci_device;
		snprintf ( dev->name, sizeof ( dev->name ),
			   "0000:%02x:%02x.%x", PCI_BUS ( undi->pci_busdevfn ),
			   PCI_SLOT ( undi->pci_busdevfn ),
			   PCI_FUNC ( undi->pci_busdevfn ) );
	} else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
		dev->desc.bus_type = BUS_TYPE_ISAPNP;
		snprintf ( dev->name, sizeof ( dev->name ), "ISAPNP" );
	}
	dev->parent = &rootdev->dev;
	list_add ( &dev->siblings, &rootdev->dev.children);
	INIT_LIST_HEAD ( &dev->children );

	/* Create network device */
	if ( ( rc = undinet_probe ( undi, dev ) ) != 0 )
		goto err;

	return 0;

 err:
	list_del ( &dev->siblings );
	return rc;
}