[init] Show startup and shutdown function names in debug messages
[ipxe.git] / src / arch / x86 / drivers / net / undionly.c
1 /*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <ipxe/device.h>
31 #include <ipxe/init.h>
32 #include <ipxe/pci.h>
33 #include <undi.h>
34 #include <undinet.h>
35 #include <undipreload.h>
36
37 /** @file
38 *
39 * "Pure" UNDI driver
40 *
41 * This is the UNDI driver without explicit support for PCI or any
42 * other bus type. It is capable only of using the preloaded UNDI
43 * device. It must not be combined in an image with any other
44 * drivers.
45 *
46 * If you want a PXE-loadable image that contains only the UNDI
47 * driver, build "bin/undionly.kpxe".
48 *
49 * If you want any other image format, or any other drivers in
50 * addition to the UNDI driver, build e.g. "bin/undi.dsk".
51 */
52
53 /** UNDI root bus device */
54 static struct device undibus_dev;
55
56 /**
57 * Probe UNDI root bus
58 *
59 * @v rootdev UNDI bus root device
60 *
61 * Scans the UNDI bus for devices and registers all devices it can
62 * find.
63 */
64 static int undibus_probe ( struct root_device *rootdev ) {
65 struct undi_device *undi = &preloaded_undi;
66 struct device *dev = &undibus_dev;
67 int rc;
68
69 /* Check for a valie preloaded UNDI device */
70 if ( ! undi->entry.segment ) {
71 DBG ( "No preloaded UNDI device found!\n" );
72 return -ENODEV;
73 }
74
75 /* Add to device hierarchy */
76 dev->driver_name = "undionly";
77 if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) {
78 dev->desc.bus_type = BUS_TYPE_PCI;
79 dev->desc.location = undi->pci_busdevfn;
80 dev->desc.vendor = undi->pci_vendor;
81 dev->desc.device = undi->pci_device;
82 snprintf ( dev->name, sizeof ( dev->name ),
83 "0000:%02x:%02x.%x", PCI_BUS ( undi->pci_busdevfn ),
84 PCI_SLOT ( undi->pci_busdevfn ),
85 PCI_FUNC ( undi->pci_busdevfn ) );
86 } else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) {
87 dev->desc.bus_type = BUS_TYPE_ISAPNP;
88 snprintf ( dev->name, sizeof ( dev->name ), "ISAPNP" );
89 }
90 dev->parent = &rootdev->dev;
91 list_add ( &dev->siblings, &rootdev->dev.children);
92 INIT_LIST_HEAD ( &dev->children );
93
94 /* Create network device */
95 if ( ( rc = undinet_probe ( undi, dev ) ) != 0 )
96 goto err;
97
98 return 0;
99
100 err:
101 list_del ( &dev->siblings );
102 return rc;
103 }
104
105 /**
106 * Remove UNDI root bus
107 *
108 * @v rootdev UNDI bus root device
109 */
110 static void undibus_remove ( struct root_device *rootdev __unused ) {
111 struct undi_device *undi = &preloaded_undi;
112 struct device *dev = &undibus_dev;
113
114 undinet_remove ( undi );
115 list_del ( &dev->siblings );
116 }
117
118 /** UNDI bus root device driver */
119 static struct root_driver undi_root_driver = {
120 .probe = undibus_probe,
121 .remove = undibus_remove,
122 };
123
124 /** UNDI bus root device */
125 struct root_device undi_root_device __root_device = {
126 .dev = { .name = "UNDI" },
127 .driver = &undi_root_driver,
128 };
129
130 /**
131 * Prepare for exit
132 *
133 * @v booting System is shutting down for OS boot
134 */
135 static void undionly_shutdown ( int booting ) {
136 /* If we are shutting down to boot an OS, clear the "keep PXE
137 * stack" flag.
138 */
139 if ( booting )
140 preloaded_undi.flags &= ~UNDI_FL_KEEP_ALL;
141 }
142
143 struct startup_fn startup_undionly __startup_fn ( STARTUP_LATE ) = {
144 .name = "undionly",
145 .shutdown = undionly_shutdown,
146 };