Browse Source

Speed up PCI bus scanning by skipping fns 1-7 if fn 0 is not present.

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
e29be5e342
2 changed files with 23 additions and 1 deletions
  1. 22
    1
      src/drivers/bus/pci.c
  2. 1
    0
      src/include/pci.h

+ 22
- 1
src/drivers/bus/pci.c View File

23
  * Returns 1 if a device was found, 0 for no device present.
23
  * Returns 1 if a device was found, 0 for no device present.
24
  */
24
  */
25
 static int fill_pci_device ( struct pci_device *pci ) {
25
 static int fill_pci_device ( struct pci_device *pci ) {
26
+	static struct {
27
+		uint16_t devfn0;
28
+		int is_present;
29
+	} cache = { 0, 1 };
26
 	uint32_t l;
30
 	uint32_t l;
27
 	int reg;
31
 	int reg;
28
 
32
 
29
 	/* Check bus is within range */
33
 	/* Check bus is within range */
30
 	if ( PCI_BUS ( pci->busdevfn ) > pci_max_bus )
34
 	if ( PCI_BUS ( pci->busdevfn ) > pci_max_bus )
31
 		return 0;
35
 		return 0;
36
+
37
+	/* Check to see if we've cached the result that this is a
38
+	 * non-zero function on a non-existent card.  This is done to
39
+	 * increase scan speed by a factor of 8.
40
+	 */
41
+	if ( ( PCI_FUNC ( pci->busdevfn ) != 0 ) &&
42
+	     ( PCI_FN0 ( pci->busdevfn ) == cache.devfn0 ) &&
43
+	     ( ! cache.is_present ) ) {
44
+		return 0;
45
+	}
32
 	
46
 	
33
 	/* Check to see if there's anything physically present.
47
 	/* Check to see if there's anything physically present.
34
 	 */
48
 	 */
35
 	pci_read_config_dword ( pci, PCI_VENDOR_ID, &l );
49
 	pci_read_config_dword ( pci, PCI_VENDOR_ID, &l );
36
 	/* some broken boards return 0 if a slot is empty: */
50
 	/* some broken boards return 0 if a slot is empty: */
37
 	if ( ( l == 0xffffffff ) || ( l == 0x00000000 ) ) {
51
 	if ( ( l == 0xffffffff ) || ( l == 0x00000000 ) ) {
52
+		if ( PCI_FUNC ( pci->busdevfn ) == 0 ) {
53
+			/* Don't look for subsequent functions if the
54
+			 * card itself is not present.
55
+			 */
56
+			cache.devfn0 = pci->busdevfn;
57
+			cache.is_present = 0;
58
+		}
38
 		return 0;
59
 		return 0;
39
 	}
60
 	}
40
 	pci->vendor = l & 0xffff;
61
 	pci->vendor = l & 0xffff;
47
 		uint16_t save_busdevfn = pci->busdevfn;
68
 		uint16_t save_busdevfn = pci->busdevfn;
48
 		uint8_t header_type;
69
 		uint8_t header_type;
49
 
70
 
50
-		pci->busdevfn &= ~PCI_FUNC ( 0xffff );
71
+		pci->busdevfn &= PCI_FN0 ( pci->busdevfn );
51
 		pci_read_config_byte ( pci, PCI_HEADER_TYPE, &header_type );
72
 		pci_read_config_byte ( pci, PCI_HEADER_TYPE, &header_type );
52
 		pci->busdevfn = save_busdevfn;
73
 		pci->busdevfn = save_busdevfn;
53
 
74
 

+ 1
- 0
src/include/pci.h View File

252
 #define PCI_BUS(busdevfn)	( ( (busdevfn) >> 8 ) & 0xff )
252
 #define PCI_BUS(busdevfn)	( ( (busdevfn) >> 8 ) & 0xff )
253
 #define PCI_DEV(busdevfn)	( ( (busdevfn) >> 3 ) & 0x1f )
253
 #define PCI_DEV(busdevfn)	( ( (busdevfn) >> 3 ) & 0x1f )
254
 #define PCI_FUNC(busdevfn)      ( (busdevfn) & 0x07 )
254
 #define PCI_FUNC(busdevfn)      ( (busdevfn) & 0x07 )
255
+#define PCI_FN0(busdevfn)	( (busdevfn) & 0xfff8 )
255
 
256
 
256
 /*
257
 /*
257
  * An individual PCI device identified by vendor and device IDs
258
  * An individual PCI device identified by vendor and device IDs

Loading…
Cancel
Save