}
}
- /* 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 )
+ if ( ( rc = undinet_probe ( undi, &pci->dev ) ) != 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 );
undinet_remove ( undi );
undi_unload ( undi );
- list_del ( &undi->dev.siblings );
free ( undi );
pci_set_drvdata ( pci, NULL );
}
/**
* Check for devices with broken support for generating interrupts
*
- * @v undi UNDI device
+ * @v desc Device description
* @ret irq_is_broken Interrupt support is broken; no interrupts are generated
*/
-static int undinet_irq_is_broken ( struct undi_device *undi ) {
+static int undinet_irq_is_broken ( struct device_description *desc ) {
const struct undinet_irq_broken *broken;
unsigned int i;
for ( i = 0 ; i < ( sizeof ( undinet_irq_broken_list ) /
sizeof ( undinet_irq_broken_list[0] ) ) ; i++ ) {
broken = &undinet_irq_broken_list[i];
- if ( ( undi->dev.desc.bus_type == BUS_TYPE_PCI ) &&
- ( undi->dev.desc.vendor == broken->pci_vendor ) &&
- ( undi->dev.desc.device == broken->pci_device ) ) {
+ if ( ( desc->bus_type == BUS_TYPE_PCI ) &&
+ ( desc->vendor == broken->pci_vendor ) &&
+ ( desc->device == broken->pci_device ) ) {
return 1;
}
}
* Probe UNDI device
*
* @v undi UNDI device
+ * @v dev Underlying generic device
* @ret rc Return status code
*/
-int undinet_probe ( struct undi_device *undi ) {
+int undinet_probe ( struct undi_device *undi, struct device *dev ) {
struct net_device *netdev;
struct undi_nic *undinic;
struct s_PXENV_START_UNDI start_undi;
netdev_init ( netdev, &undinet_operations );
undinic = netdev->priv;
undi_set_drvdata ( undi, netdev );
- netdev->dev = &undi->dev;
+ netdev->dev = dev;
memset ( undinic, 0, sizeof ( *undinic ) );
undinet_entry = undi->entry;
DBGC ( undinic, "UNDINIC %p using UNDI %p\n", undinic, undi );
undinic );
undinic->hacks |= UNDI_HACK_EB54;
}
- if ( undinet_irq_is_broken ( undi ) ) {
+ if ( undinet_irq_is_broken ( &dev->desc ) ) {
DBGC ( undinic, "UNDINIC %p forcing polling mode due to "
"broken interrupts\n", undinic );
undinic->irq_supported = 0;
* addition to the UNDI driver, build e.g. "bin/undi.dsk".
*/
+/** UNDI root bus device */
+static struct device undibus_dev;
+
/**
* Probe UNDI root bus
*
*/
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 */
}
/* Add to device hierarchy */
- undi->dev.driver_name = "undionly";
+ dev->driver_name = "undionly";
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;
- snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
- "UNDI-PCI%02x:%02x.%x",
- PCI_BUS ( undi->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 ) {
- undi->dev.desc.bus_type = BUS_TYPE_ISAPNP;
- snprintf ( undi->dev.name, sizeof ( undi->dev.name ),
- "UNDI-ISAPNP" );
+ dev->desc.bus_type = BUS_TYPE_ISAPNP;
+ snprintf ( dev->name, sizeof ( dev->name ), "ISAPNP" );
}
- undi->dev.parent = &rootdev->dev;
- list_add ( &undi->dev.siblings, &rootdev->dev.children);
- INIT_LIST_HEAD ( &undi->dev.children );
+ dev->parent = &rootdev->dev;
+ list_add ( &dev->siblings, &rootdev->dev.children);
+ INIT_LIST_HEAD ( &dev->children );
/* Create network device */
- if ( ( rc = undinet_probe ( undi ) ) != 0 )
+ if ( ( rc = undinet_probe ( undi, dev ) ) != 0 )
goto err;
return 0;
err:
- list_del ( &undi->dev.siblings );
+ list_del ( &dev->siblings );
return rc;
}
*/
static void undibus_remove ( struct root_device *rootdev __unused ) {
struct undi_device *undi = &preloaded_undi;
+ struct device *dev = &undibus_dev;
undinet_remove ( undi );
- list_del ( &undi->dev.siblings );
+ list_del ( &dev->siblings );
}
/** UNDI bus root device driver */
*/
UINT16_t flags;
- /** Generic device */
- struct device dev;
/** Driver-private data
*
* Use undi_set_drvdata() and undi_get_drvdata() to access this
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct undi_device;
+struct device;
-extern int undinet_probe ( struct undi_device *undi );
+extern int undinet_probe ( struct undi_device *undi, struct device *dev );
extern void undinet_remove ( struct undi_device *undi );
#endif /* _UNDINET_H */