Browse Source

If preloaded device matches, use that rather than going via the UNDI

loader.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
f2f492a536
1 changed files with 46 additions and 21 deletions
  1. 46
    21
      src/arch/i386/drivers/net/undi.c

+ 46
- 21
src/arch/i386/drivers/net/undi.c View File

24
 #include <undirom.h>
24
 #include <undirom.h>
25
 #include <undiload.h>
25
 #include <undiload.h>
26
 #include <undinet.h>
26
 #include <undinet.h>
27
+#include <undipreload.h>
27
 
28
 
28
 /** @file
29
 /** @file
29
  *
30
  *
31
  *
32
  *
32
  */
33
  */
33
 
34
 
35
+/**
36
+ * Find UNDI ROM for PCI device
37
+ *
38
+ * @v pci		PCI device
39
+ * @ret undirom		UNDI ROM, or NULL
40
+ *
41
+ * Try to find a driver for this device.  Try an exact match on the
42
+ * ROM address first, then fall back to a vendor/device ID match only
43
+ */
44
+static struct undi_rom * undipci_find_rom ( struct pci_device *pci ) {
45
+	struct undi_rom *undirom;
46
+	unsigned long rombase;
47
+	
48
+	rombase = pci_bar_start ( pci, PCI_ROM_ADDRESS );
49
+	undirom = undirom_find_pci ( pci->vendor, pci->device, rombase );
50
+	if ( ! undirom )
51
+		undirom = undirom_find_pci ( pci->vendor, pci->device, 0 );
52
+	return undirom;
53
+}
54
+
34
 /**
55
 /**
35
  * Probe PCI device
56
  * Probe PCI device
36
  *
57
  *
37
- * @v pci	PCI device
38
- * @v id	PCI ID
39
- * @ret rc	Return status code
58
+ * @v pci		PCI device
59
+ * @v id		PCI ID
60
+ * @ret rc		Return status code
40
  */
61
  */
41
 static int undipci_probe ( struct pci_device *pci,
62
 static int undipci_probe ( struct pci_device *pci,
42
 			   const struct pci_device_id *id __unused ) {
63
 			   const struct pci_device_id *id __unused ) {
43
 	struct undi_device *undi;
64
 	struct undi_device *undi;
44
 	struct undi_rom *undirom;
65
 	struct undi_rom *undirom;
45
-	unsigned long rombase;
66
+	unsigned int busdevfn = ( ( pci->bus << 8 ) | pci->devfn );
46
 	int rc;
67
 	int rc;
47
 
68
 
48
 	/* Ignore non-network devices */
69
 	/* Ignore non-network devices */
49
 	if ( PCI_BASE_CLASS ( pci->class ) != PCI_BASE_CLASS_NETWORK )
70
 	if ( PCI_BASE_CLASS ( pci->class ) != PCI_BASE_CLASS_NETWORK )
50
 		return -ENOTTY;
71
 		return -ENOTTY;
51
 
72
 
52
-	/* Try to find a driver for this device.  Try an exact match
53
-	 * on the ROM address first, then fall back to a vendor/device
54
-	 * ID match only
55
-	 */
56
-	rombase = pci_bar_start ( pci, PCI_ROM_ADDRESS );
57
-	undirom = undirom_find_pci ( pci->vendor, pci->device, rombase );
58
-	if ( ! undirom )
59
-		undirom = undirom_find_pci ( pci->vendor, pci->device, 0 );
60
-	if ( ! undirom )
61
-		return -ENODEV;
62
-
63
 	/* Allocate UNDI device structure */
73
 	/* Allocate UNDI device structure */
64
 	undi = malloc ( sizeof ( *undi ) );
74
 	undi = malloc ( sizeof ( *undi ) );
65
 	if ( ! undi )
75
 	if ( ! undi )
67
 	memset ( undi, 0, sizeof ( *undi ) );
77
 	memset ( undi, 0, sizeof ( *undi ) );
68
 	pci_set_drvdata ( pci, undi );
78
 	pci_set_drvdata ( pci, undi );
69
 
79
 
80
+	/* Find/create our pixie */
81
+	if ( preloaded_undi.pci_busdevfn == busdevfn ) {
82
+		/* Claim preloaded UNDI device */
83
+		DBGC ( undi, "UNDI %p using preloaded UNDI device\n", undi );
84
+		memcpy ( undi, &preloaded_undi, sizeof ( *undi ) );
85
+		memset ( &preloaded_undi, 0, sizeof ( preloaded_undi ) );
86
+	} else {
87
+		/* Find UNDI ROM for PCI device */
88
+		if ( ! ( undirom = undipci_find_rom ( pci ) ) ) {
89
+			rc = -ENODEV;
90
+			goto err_find_rom;
91
+		}
92
+
93
+		/* Call UNDI ROM loader to create pixie */
94
+		if ( ( rc = undi_load_pci ( undi, undirom, pci->bus,
95
+					    pci->devfn ) ) != 0 )
96
+			goto err_load_pci;
97
+	}
98
+
70
 	/* Add to device hierarchy */
99
 	/* Add to device hierarchy */
71
 	undi->dev.parent = &pci->dev;
100
 	undi->dev.parent = &pci->dev;
72
 	INIT_LIST_HEAD ( &undi->dev.children );
101
 	INIT_LIST_HEAD ( &undi->dev.children );
73
 	list_add ( &undi->dev.siblings, &pci->dev.children );
102
 	list_add ( &undi->dev.siblings, &pci->dev.children );
74
 
103
 
75
-	/* Call UNDI ROM loader to create pixie */
76
-	if ( ( rc = undi_load_pci ( undi, undirom, pci->bus,
77
-				    pci->devfn ) ) != 0 )
78
-		goto err_load_pci;
79
-
80
 	/* Create network device */
104
 	/* Create network device */
81
 	if ( ( rc = undinet_probe ( undi ) ) != 0 )
105
 	if ( ( rc = undinet_probe ( undi ) ) != 0 )
82
 		goto err_undinet_probe;
106
 		goto err_undinet_probe;
85
 
109
 
86
  err_undinet_probe:
110
  err_undinet_probe:
87
 	undi_unload ( undi );
111
 	undi_unload ( undi );
88
- err_load_pci:
89
 	list_del ( &undi->dev.siblings );
112
 	list_del ( &undi->dev.siblings );
113
+ err_find_rom:
114
+ err_load_pci:
90
 	free ( undi );
115
 	free ( undi );
91
 	pci_set_drvdata ( pci, NULL );
116
 	pci_set_drvdata ( pci, NULL );
92
 	return rc;
117
 	return rc;

Loading…
Cancel
Save