Rev 16 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | #include <ll/i386/hw-instr.h> |
2 | #include <ll/i386/hw-data.h> |
||
3 | #include <ll/i386/hw-arch.h> |
||
4 | #include <ll/i386/hw-io.h> |
||
5 | #include <ll/i386/cons.h> |
||
6 | #include <ll/stdlib.h> |
||
7 | #include <drivers/llpci.h> |
||
8 | #include <drivers/pci.h> |
||
9 | #include <drivers/linuxpci.h> |
||
10 | |||
16 | pj | 11 | #include <kernel/log.h> |
12 | |||
2 | pj | 13 | static int ndev = 0; |
14 | static struct pci_des pci_devs[N_MAX_DEVS]; |
||
15 | |||
16 | /* scan the bus to find all the connected devices */ |
||
17 | int scan_bus(struct pci_des *p_des) |
||
18 | { |
||
19 | int ndev; |
||
20 | DWORD tmp; |
||
21 | BYTE hdr; |
||
22 | int j, ok; |
||
23 | BYTE bus, b; |
||
24 | WORD dev; |
||
25 | int present; |
||
26 | |||
27 | if (pcibios_present() == 0) return -1; |
||
28 | ndev = 0; |
||
29 | |||
49 | pj | 30 | for (bus = 0; bus <= 1; bus++) { |
2 | pj | 31 | for (dev = 0; dev <= 0xFF; dev++) { |
32 | present = 0; |
||
33 | if ((dev & 0x07) == 0) { |
||
34 | present = pcibios_read_config_byte(bus, dev, 0x0e, &hdr); |
||
35 | } |
||
36 | if (hdr & 0x80) { |
||
37 | present = 1; |
||
38 | } |
||
39 | if (present) { |
||
40 | ok = pcibios_read_config_dword(bus, dev, 0, &tmp); |
||
41 | if ( ok && (((tmp & 0xFFFF) != 0xFFFF) && ((tmp >> 16) != 0xFFFF))) { |
||
42 | p_des[ndev].bus = bus; |
||
43 | p_des[ndev].dev = dev; |
||
44 | for (j = 0; j <= 255; j++) { |
||
45 | pcibios_read_config_byte(bus, dev, j, &b); |
||
46 | p_des[ndev].mem[j] = b; |
||
47 | } |
||
48 | ndev++; |
||
49 | } |
||
50 | } |
||
51 | } |
||
52 | } |
||
53 | return ndev; |
||
54 | } |
||
55 | |||
56 | struct pci_regs *pci_device(WORD vendor, WORD device, WORD index, BYTE *bus, BYTE *dev) |
||
57 | { |
||
58 | int i, curr; |
||
59 | struct pci_regs *regs; |
||
60 | |||
61 | curr = 0; |
||
62 | for (i = 0; i < ndev; i++) { |
||
63 | regs = (struct pci_regs *)pci_devs[i].mem; |
||
64 | if ((regs->VendorId == vendor) && (regs->DeviceId == device)) { |
||
65 | if (curr == index) { |
||
66 | *dev = pci_devs[i].dev; |
||
67 | *bus = pci_devs[i].bus; |
||
68 | return regs; |
||
69 | } |
||
70 | ++curr; |
||
71 | } |
||
72 | } |
||
73 | return NULL; |
||
74 | } |
||
75 | |||
76 | struct pci_regs *pci_class(DWORD class_code, WORD index, BYTE *bus, BYTE *dev) |
||
77 | { |
||
78 | int i, curr; |
||
79 | struct pci_regs *regs; |
||
80 | |||
81 | curr = 0; |
||
82 | for (i = 0; i < ndev; i++) { |
||
83 | regs = (struct pci_regs *)pci_devs[i].mem; |
||
84 | if ((regs->ClassCode << 8) == class_code) { |
||
85 | if (curr == index) { |
||
86 | *dev = pci_devs[i].dev; |
||
87 | *bus = pci_devs[i].bus; |
||
88 | return regs; |
||
89 | } |
||
90 | ++curr; |
||
91 | } |
||
92 | } |
||
93 | return NULL; |
||
94 | } |
||
95 | |||
96 | int pcibios_find_device(WORD vendor, WORD device, WORD index, BYTE *bus, BYTE *dev) |
||
97 | { |
||
98 | |||
99 | if (pci_device(vendor, device, index, bus, dev) != NULL) { |
||
100 | return PCIBIOS_SUCCESSFUL; |
||
101 | } else { |
||
102 | return PCIBIOS_DEVICE_NOT_FOUND; |
||
103 | } |
||
104 | } |
||
105 | int pcibios_find_class(DWORD class_code, WORD index, BYTE *bus, BYTE *dev) |
||
106 | { |
||
107 | |||
108 | if (pci_class(class_code, index, bus, dev) != NULL) { |
||
16 | pj | 109 | #ifdef DEBUG_PCI |
110 | printk(KERN_DEBUG "PCIBIOS_FIND_CLASS:" |
||
111 | "found at bus %d, dev %d\n", *bus, *dev); |
||
112 | #endif |
||
2 | pj | 113 | return PCIBIOS_SUCCESSFUL; |
114 | } else { |
||
115 | return PCIBIOS_DEVICE_NOT_FOUND; |
||
116 | } |
||
117 | } |
||
118 | |||
119 | |||
120 | /* shows the detected devices */ |
||
121 | void pci_show(void) |
||
122 | { |
||
123 | int i; |
||
124 | struct pci_regs *r; |
||
125 | |||
16 | pj | 126 | printk(KERN_INFO "DevLib PCI support\n\n"); |
127 | printk(KERN_INFO "PCI config type %d\n", pcibios_present()); |
||
128 | printk(KERN_INFO "%d PCI devices found:\n\n", ndev); |
||
2 | pj | 129 | for(i = 0; i < ndev; i++) { |
130 | r = (struct pci_regs *) pci_devs[i].mem; |
||
16 | pj | 131 | printk(KERN_INFO "%d: bus %d dev %d\n", |
132 | i, pci_devs[i].bus, pci_devs[i].dev); |
||
133 | printk(KERN_INFO "Vendor: %s", pci_strvendor(r->VendorId)); |
||
134 | printk(KERN_INFO "Class: %s\n", pci_strclass(r->ClassCode << 8)); |
||
2 | pj | 135 | } |
136 | } |
||
137 | |||
138 | /*Linux-->unsigned long pci_init(unsigned long mem_start, unsigned long mem_end) */ |
||
139 | /* H-PCI --> void pci_init(void) */ |
||
140 | /* (mem_start/mem_end have no sense) */ |
||
141 | |||
142 | int pci_init(void) |
||
143 | { |
||
144 | if (pcibios_init() == -1) { |
||
145 | return -1; |
||
146 | } |
||
147 | ndev = scan_bus(pci_devs); |
||
148 | return 1; |
||
149 | } |