iPXE
undionly.c
Go to the documentation of this file.
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
24FILE_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 */
54static 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 */
64static 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 ) {
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 ) {
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 */
110static 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 */
120 .probe = undibus_probe,
121 .remove = undibus_remove,
122};
123
124/** UNDI bus root device */
125struct 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 */
135static 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 )
141}
142
143struct startup_fn startup_undionly __startup_fn ( STARTUP_LATE ) = {
144 .name = "undionly",
145 .shutdown = undionly_shutdown,
146};
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
Device model.
#define BUS_TYPE_PCI
PCI bus type.
Definition device.h:44
#define BUS_TYPE_ISAPNP
ISAPnP bus type.
Definition device.h:47
#define __root_device
Declare a root device.
Definition device.h:136
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENODEV
No such device.
Definition errno.h:510
#define STARTUP_LATE
Late startup.
Definition init.h:66
String functions.
#define __startup_fn(startup_order)
Declare a startup/shutdown function.
Definition init.h:53
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
PCI bus.
#define PCI_FUNC(busdevfn)
Definition pci.h:286
#define PCI_BUS(busdevfn)
Definition pci.h:284
#define PCI_SLOT(busdevfn)
Definition pci.h:285
unsigned int bus_type
Bus type.
Definition device.h:25
unsigned int device
Device ID.
Definition device.h:34
unsigned int vendor
Vendor ID.
Definition device.h:32
unsigned int location
Location.
Definition device.h:30
A hardware device.
Definition device.h:77
struct device_description desc
Device description.
Definition device.h:83
struct device * parent
Bus device.
Definition device.h:89
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
const char * driver_name
Driver name.
Definition device.h:81
char name[40]
Name.
Definition device.h:79
A root device.
Definition device.h:98
struct device dev
Device chain.
Definition device.h:103
A root device driver.
Definition device.h:111
A startup/shutdown function.
Definition init.h:43
An UNDI device.
Definition undi.h:22
UINT16_t pci_busdevfn
PCI bus:dev.fn, or UNDI_NO_PCI_BUSDEVFN.
Definition undi.h:34
UINT16_t isapnp_csn
ISAPnP card select number, or UNDI_NO_ISAPNP_CSN.
Definition undi.h:36
UINT16_t pci_vendor
PCI vendor ID.
Definition undi.h:43
UINT16_t pci_device
PCI device ID.
Definition undi.h:48
SEGOFF16_t entry
Entry point.
Definition undi.h:28
UNDI driver.
#define UNDI_FL_KEEP_ALL
UNDI flag: keep stack resident.
Definition undi.h:102
#define UNDI_NO_PCI_BUSDEVFN
PCI bus:dev.fn field is invalid.
Definition undi.h:87
#define UNDI_NO_ISAPNP_CSN
ISAPnP card select number field is invalid.
Definition undi.h:90
int undinet_probe(struct undi_device *undi, struct device *dev)
Probe UNDI device.
Definition undinet.c:931
void undinet_remove(struct undi_device *undi)
Remove UNDI device.
Definition undinet.c:1089
UNDI network device driver.
static struct root_driver undi_root_driver
UNDI bus root device driver.
Definition undionly.c:119
static struct device undibus_dev
UNDI root bus device.
Definition undionly.c:54
static void undibus_remove(struct root_device *rootdev __unused)
Remove UNDI root bus.
Definition undionly.c:110
static int undibus_probe(struct root_device *rootdev)
Probe UNDI root bus.
Definition undionly.c:64
static void undionly_shutdown(int booting)
Prepare for exit.
Definition undionly.c:135
Preloaded UNDI stack.
#define preloaded_undi
Definition undipreload.h:16
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383