xref: /onnv-gate/usr/src/grub/grub-0.97/netboot/config.c (revision 8044:b3af80bbf173)
1*8044SWilliam.Kucharski@Sun.COM /*
2*8044SWilliam.Kucharski@Sun.COM  * This program is free software; you can redistribute it and/or
3*8044SWilliam.Kucharski@Sun.COM  * modify it under the terms of the GNU General Public License as
4*8044SWilliam.Kucharski@Sun.COM  * published by the Free Software Foundation; either version 2, or (at
5*8044SWilliam.Kucharski@Sun.COM  * your option) any later version.
6*8044SWilliam.Kucharski@Sun.COM  */
7*8044SWilliam.Kucharski@Sun.COM 
8*8044SWilliam.Kucharski@Sun.COM #include	"grub.h"
9*8044SWilliam.Kucharski@Sun.COM #include	"pci.h"
10*8044SWilliam.Kucharski@Sun.COM #include	"isa.h"
11*8044SWilliam.Kucharski@Sun.COM #include	"nic.h"
12*8044SWilliam.Kucharski@Sun.COM 
13*8044SWilliam.Kucharski@Sun.COM #ifdef CONFIG_PCI
pci_probe(struct dev * dev,const char * type_name)14*8044SWilliam.Kucharski@Sun.COM static int pci_probe(struct dev *dev, const char *type_name)
15*8044SWilliam.Kucharski@Sun.COM {
16*8044SWilliam.Kucharski@Sun.COM /*
17*8044SWilliam.Kucharski@Sun.COM  *	NIC probing is in pci device order, followed by the
18*8044SWilliam.Kucharski@Sun.COM  *      link order of the drivers.  A driver that matches
19*8044SWilliam.Kucharski@Sun.COM  *      on vendor and device id will supersede a driver
20*8044SWilliam.Kucharski@Sun.COM  *      that matches on pci class.
21*8044SWilliam.Kucharski@Sun.COM  *
22*8044SWilliam.Kucharski@Sun.COM  *	If you want to probe for another device behind the same pci
23*8044SWilliam.Kucharski@Sun.COM  *      device just increment index.  And the previous probe call
24*8044SWilliam.Kucharski@Sun.COM  *      will be repeated.
25*8044SWilliam.Kucharski@Sun.COM  */
26*8044SWilliam.Kucharski@Sun.COM 	struct pci_probe_state *state = &dev->state.pci;
27*8044SWilliam.Kucharski@Sun.COM 	printf("Probing pci %s...\n", type_name);
28*8044SWilliam.Kucharski@Sun.COM 	if (dev->how_probe == PROBE_FIRST) {
29*8044SWilliam.Kucharski@Sun.COM 		state->advance    = 1;
30*8044SWilliam.Kucharski@Sun.COM 		state->dev.driver = 0;
31*8044SWilliam.Kucharski@Sun.COM 		state->dev.bus    = 0;
32*8044SWilliam.Kucharski@Sun.COM 		state->dev.devfn  = 0;
33*8044SWilliam.Kucharski@Sun.COM 		dev->index        = -1;
34*8044SWilliam.Kucharski@Sun.COM 	}
35*8044SWilliam.Kucharski@Sun.COM 	for(;;) {
36*8044SWilliam.Kucharski@Sun.COM 		if ((dev->how_probe != PROBE_AWAKE) && state->advance) {
37*8044SWilliam.Kucharski@Sun.COM 			find_pci(dev->type, &state->dev);
38*8044SWilliam.Kucharski@Sun.COM 			dev->index = -1;
39*8044SWilliam.Kucharski@Sun.COM 		}
40*8044SWilliam.Kucharski@Sun.COM 		state->advance = 1;
41*8044SWilliam.Kucharski@Sun.COM 
42*8044SWilliam.Kucharski@Sun.COM 		if (state->dev.driver == 0)
43*8044SWilliam.Kucharski@Sun.COM 			break;
44*8044SWilliam.Kucharski@Sun.COM 
45*8044SWilliam.Kucharski@Sun.COM #if 0
46*8044SWilliam.Kucharski@Sun.COM 		/* FIXME the romaddr code needs a total rethought to be useful */
47*8044SWilliam.Kucharski@Sun.COM 		if (state->dev.romaddr != ((unsigned long) rom.rom_segment << 4)) {
48*8044SWilliam.Kucharski@Sun.COM 			continue;
49*8044SWilliam.Kucharski@Sun.COM 		}
50*8044SWilliam.Kucharski@Sun.COM #endif
51*8044SWilliam.Kucharski@Sun.COM 		if (dev->how_probe != PROBE_AWAKE) {
52*8044SWilliam.Kucharski@Sun.COM 			dev->type_index++;
53*8044SWilliam.Kucharski@Sun.COM 		}
54*8044SWilliam.Kucharski@Sun.COM 		dev->devid.bus_type = PCI_BUS_TYPE;
55*8044SWilliam.Kucharski@Sun.COM 		dev->devid.vendor_id = htons(state->dev.vendor);
56*8044SWilliam.Kucharski@Sun.COM 		dev->devid.device_id = htons(state->dev.dev_id);
57*8044SWilliam.Kucharski@Sun.COM 		/* FIXME how do I handle dev->index + PROBE_AGAIN?? */
58*8044SWilliam.Kucharski@Sun.COM 
59*8044SWilliam.Kucharski@Sun.COM 		printf("[%s]", state->dev.name);
60*8044SWilliam.Kucharski@Sun.COM 		if (state->dev.driver->probe(dev, &state->dev)) {
61*8044SWilliam.Kucharski@Sun.COM 			state->advance = (dev->index == -1);
62*8044SWilliam.Kucharski@Sun.COM 			return PROBE_WORKED;
63*8044SWilliam.Kucharski@Sun.COM 		}
64*8044SWilliam.Kucharski@Sun.COM 		putchar('\n');
65*8044SWilliam.Kucharski@Sun.COM 	}
66*8044SWilliam.Kucharski@Sun.COM 	return PROBE_FAILED;
67*8044SWilliam.Kucharski@Sun.COM }
68*8044SWilliam.Kucharski@Sun.COM #endif
69*8044SWilliam.Kucharski@Sun.COM 
70*8044SWilliam.Kucharski@Sun.COM #ifdef CONFIG_ISA
isa_probe(struct dev * dev,const char * type_name)71*8044SWilliam.Kucharski@Sun.COM static int isa_probe(struct dev *dev, const char *type_name)
72*8044SWilliam.Kucharski@Sun.COM {
73*8044SWilliam.Kucharski@Sun.COM /*
74*8044SWilliam.Kucharski@Sun.COM  *	NIC probing is in the order the drivers were linked togeter.
75*8044SWilliam.Kucharski@Sun.COM  *	If for some reason you want to change the order,
76*8044SWilliam.Kucharski@Sun.COM  *	just change the order you list the drivers in.
77*8044SWilliam.Kucharski@Sun.COM  */
78*8044SWilliam.Kucharski@Sun.COM 	struct isa_probe_state *state = &dev->state.isa;
79*8044SWilliam.Kucharski@Sun.COM 	printf("Probing isa %s...\n", type_name);
80*8044SWilliam.Kucharski@Sun.COM 	if (dev->how_probe == PROBE_FIRST) {
81*8044SWilliam.Kucharski@Sun.COM 		state->advance = 0;
82*8044SWilliam.Kucharski@Sun.COM 		state->driver  = isa_drivers;
83*8044SWilliam.Kucharski@Sun.COM 		dev->index     = -1;
84*8044SWilliam.Kucharski@Sun.COM 	}
85*8044SWilliam.Kucharski@Sun.COM 	for(;;)
86*8044SWilliam.Kucharski@Sun.COM 	{
87*8044SWilliam.Kucharski@Sun.COM 		if ((dev->how_probe != PROBE_AWAKE) && state->advance) {
88*8044SWilliam.Kucharski@Sun.COM 			state->driver++;
89*8044SWilliam.Kucharski@Sun.COM 			dev->index = -1;
90*8044SWilliam.Kucharski@Sun.COM 		}
91*8044SWilliam.Kucharski@Sun.COM 		state->advance = 1;
92*8044SWilliam.Kucharski@Sun.COM 
93*8044SWilliam.Kucharski@Sun.COM 		if (state->driver >= isa_drivers_end)
94*8044SWilliam.Kucharski@Sun.COM 			break;
95*8044SWilliam.Kucharski@Sun.COM 
96*8044SWilliam.Kucharski@Sun.COM 		if (state->driver->type != dev->type)
97*8044SWilliam.Kucharski@Sun.COM 			continue;
98*8044SWilliam.Kucharski@Sun.COM 
99*8044SWilliam.Kucharski@Sun.COM 		if (dev->how_probe != PROBE_AWAKE) {
100*8044SWilliam.Kucharski@Sun.COM 			dev->type_index++;
101*8044SWilliam.Kucharski@Sun.COM 		}
102*8044SWilliam.Kucharski@Sun.COM 		printf("[%s]", state->driver->name);
103*8044SWilliam.Kucharski@Sun.COM 		dev->devid.bus_type = ISA_BUS_TYPE;
104*8044SWilliam.Kucharski@Sun.COM 		/* FIXME how do I handle dev->index + PROBE_AGAIN?? */
105*8044SWilliam.Kucharski@Sun.COM 		/* driver will fill in vendor and device IDs */
106*8044SWilliam.Kucharski@Sun.COM 		if (state->driver->probe(dev, state->driver->ioaddrs)) {
107*8044SWilliam.Kucharski@Sun.COM 			state->advance = (dev->index == -1);
108*8044SWilliam.Kucharski@Sun.COM 			return PROBE_WORKED;
109*8044SWilliam.Kucharski@Sun.COM 		}
110*8044SWilliam.Kucharski@Sun.COM 		putchar('\n');
111*8044SWilliam.Kucharski@Sun.COM 	}
112*8044SWilliam.Kucharski@Sun.COM 	return PROBE_FAILED;
113*8044SWilliam.Kucharski@Sun.COM }
114*8044SWilliam.Kucharski@Sun.COM #else
115*8044SWilliam.Kucharski@Sun.COM #define isa_probe(d,tn) (PROBE_FAILED)
116*8044SWilliam.Kucharski@Sun.COM #endif
117*8044SWilliam.Kucharski@Sun.COM static const char *driver_name[] = {
118*8044SWilliam.Kucharski@Sun.COM 	"nic",
119*8044SWilliam.Kucharski@Sun.COM 	"disk",
120*8044SWilliam.Kucharski@Sun.COM 	"floppy",
121*8044SWilliam.Kucharski@Sun.COM };
probe(struct dev * dev)122*8044SWilliam.Kucharski@Sun.COM int probe(struct dev *dev)
123*8044SWilliam.Kucharski@Sun.COM {
124*8044SWilliam.Kucharski@Sun.COM 	const char *type_name;
125*8044SWilliam.Kucharski@Sun.COM 
126*8044SWilliam.Kucharski@Sun.COM 	EnterFunction("probe");
127*8044SWilliam.Kucharski@Sun.COM 
128*8044SWilliam.Kucharski@Sun.COM 	type_name = "";
129*8044SWilliam.Kucharski@Sun.COM 	if ((dev->type >= 0) &&
130*8044SWilliam.Kucharski@Sun.COM 		(dev->type < sizeof(driver_name)/sizeof(driver_name[0]))) {
131*8044SWilliam.Kucharski@Sun.COM 		type_name = driver_name[dev->type];
132*8044SWilliam.Kucharski@Sun.COM 	}
133*8044SWilliam.Kucharski@Sun.COM 	if (dev->how_probe == PROBE_FIRST) {
134*8044SWilliam.Kucharski@Sun.COM 		dev->to_probe = PROBE_PCI;
135*8044SWilliam.Kucharski@Sun.COM 		memset(&dev->state, 0, sizeof(dev->state));
136*8044SWilliam.Kucharski@Sun.COM 	}
137*8044SWilliam.Kucharski@Sun.COM 	if (dev->to_probe == PROBE_PCI) {
138*8044SWilliam.Kucharski@Sun.COM 		dev->how_probe = pci_probe(dev, type_name);
139*8044SWilliam.Kucharski@Sun.COM 		if (dev->how_probe == PROBE_FAILED) {
140*8044SWilliam.Kucharski@Sun.COM 			dev->to_probe = PROBE_ISA;
141*8044SWilliam.Kucharski@Sun.COM 		}
142*8044SWilliam.Kucharski@Sun.COM 	}
143*8044SWilliam.Kucharski@Sun.COM 	if (dev->to_probe == PROBE_ISA) {
144*8044SWilliam.Kucharski@Sun.COM 		dev->how_probe = isa_probe(dev, type_name);
145*8044SWilliam.Kucharski@Sun.COM 		if (dev->how_probe == PROBE_FAILED) {
146*8044SWilliam.Kucharski@Sun.COM 			dev->to_probe = PROBE_NONE;
147*8044SWilliam.Kucharski@Sun.COM 		}
148*8044SWilliam.Kucharski@Sun.COM 	}
149*8044SWilliam.Kucharski@Sun.COM 	if ((dev->to_probe != PROBE_PCI) &&
150*8044SWilliam.Kucharski@Sun.COM 		(dev->to_probe != PROBE_ISA)) {
151*8044SWilliam.Kucharski@Sun.COM 		dev->how_probe = PROBE_FAILED;
152*8044SWilliam.Kucharski@Sun.COM 
153*8044SWilliam.Kucharski@Sun.COM 	}
154*8044SWilliam.Kucharski@Sun.COM 
155*8044SWilliam.Kucharski@Sun.COM 	LeaveFunction("probe");
156*8044SWilliam.Kucharski@Sun.COM 	return dev->how_probe;
157*8044SWilliam.Kucharski@Sun.COM }
158*8044SWilliam.Kucharski@Sun.COM 
disable(struct dev * dev)159*8044SWilliam.Kucharski@Sun.COM void disable(struct dev *dev)
160*8044SWilliam.Kucharski@Sun.COM {
161*8044SWilliam.Kucharski@Sun.COM 	if (dev->disable) {
162*8044SWilliam.Kucharski@Sun.COM 		dev->disable(dev);
163*8044SWilliam.Kucharski@Sun.COM 		dev->disable = 0;
164*8044SWilliam.Kucharski@Sun.COM 	}
165*8044SWilliam.Kucharski@Sun.COM }
166