source: sbliveos2/trunk/lib32/pci.c@ 172

Last change on this file since 172 was 153, checked in by sandervl, 25 years ago

update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
Line 
1/* $Id: pci.c 153 2000-07-23 16:21:57Z sandervl $ */
2
3//******************************************************************************
4// OS/2 IDC services (callback to 16 bits MMPM2 driver)
5//
6// Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
7//
8// Parts based on Linux kernel code (pci_read/write_*)
9//
10// This program is free software; you can redistribute it and/or
11// modify it under the terms of the GNU General Public License as
12// published by the Free Software Foundation; either version 2 of
13// the License, or (at your option) any later version.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public
21// License along with this program; if not, write to the Free
22// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
23// USA.
24//
25//******************************************************************************
26#include "hwaccess.h"
27#include <linux/init.h>
28#include <linux/poll.h>
29#include <asm/uaccess.h>
30#include <asm/hardirq.h>
31#include <asm/io.h>
32
33#define LINUX
34#include <ossidc.h>
35#include <stacktoflat.h>
36
37#define MAX_PCI_DEVICES 16
38#define MAX_PCI_BUSSES 2
39
40static struct pci_dev pci_devices[MAX_PCI_DEVICES] = {0};
41static struct pci_bus pci_busses[MAX_PCI_BUSSES] = {0};
42
43//******************************************************************************
44//******************************************************************************
45int pcidev_prepare(struct pci_dev *dev)
46{
47 return 1; //todo: correct return value??
48}
49//******************************************************************************
50//******************************************************************************
51int pcidev_activate(struct pci_dev *dev)
52{
53 return 1; //todo: correct return value??
54}
55//******************************************************************************
56//******************************************************************************
57int pcidev_deactivate(struct pci_dev *dev)
58{
59 return 1; //todo: correct return value??
60}
61//******************************************************************************
62//TODO: Doesn't completely fill in the pci_dev structure
63//******************************************************************************
64int FindPCIDevice(unsigned int vendor, unsigned int device, struct pci_dev near *pcidev)
65{
66 IDC_RESOURCE idcres;
67 ULONG devid, pResource;
68 int i, residx = 0;
69
70 pcidev->prepare = pcidev_prepare;
71 pcidev->activate = pcidev_activate;
72 pcidev->deactivate = pcidev_deactivate;
73 pcidev->active = 1;
74 pcidev->ro = 0;
75 pcidev->sibling = NULL;
76 pcidev->next = NULL;
77 pcidev->vendor = vendor;
78 pcidev->device = device;
79
80 devid = (device << 16) | vendor;
81
82#ifdef KEE
83 pResource = __FlatToStack(&idcres);
84#else
85 pResource = __Compress48Pointer((char FAR48 *)&idcres);
86#endif
87 if(CallOSS16(IDC16_FIND_PCIDEVICE, devid, pResource) == FALSE) {
88 return FALSE;
89 }
90
91 for(i=0;i<MAX_RES_IO;i++) {
92 if(idcres.io[i] != 0xffff) {
93 pcidev->resource[residx].name = 0;
94 pcidev->resource[residx].child = 0;
95 pcidev->resource[residx].sibling = 0;
96 pcidev->resource[residx].parent = 0;
97 pcidev->resource[residx].start = idcres.io[i];
98 pcidev->resource[residx].end = idcres.io[i] + idcres.iolength[i]; //inclusive??
99 pcidev->resource[residx].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
100
101 residx++;
102 }
103 }
104 for(i=0;i<MAX_RES_MEM;i++) {
105 if(idcres.mem[i] != 0xffffffff) {
106 pcidev->resource[residx].name = 0;
107 pcidev->resource[residx].child = 0;
108 pcidev->resource[residx].sibling = 0;
109 pcidev->resource[residx].parent = 0;
110 pcidev->resource[residx].start = idcres.mem[i];
111 pcidev->resource[residx].end = idcres.mem[i] + idcres.memlength[i]; //inclusive??
112 pcidev->resource[residx].flags = IORESOURCE_MEM | IORESOURCE_MEM_WRITEABLE;
113
114 residx++;
115 }
116 }
117 for(i=0;i<MAX_RES_DMA;i++) {
118 if(idcres.dma[i] != 0xffff) {
119 pcidev->dma_resource[i].name = 0;
120 pcidev->dma_resource[i].child = 0;
121 pcidev->dma_resource[i].sibling = 0;
122 pcidev->dma_resource[i].parent = 0;
123 pcidev->dma_resource[i].start = idcres.dma[i];
124 pcidev->dma_resource[i].end = idcres.dma[i];
125 //todo: 8/16 bits
126 pcidev->dma_resource[i].flags = IORESOURCE_DMA;
127 }
128 }
129 for(i=0;i<MAX_RES_IRQ;i++) {
130 if(idcres.irq[i] != 0xffff) {
131 pcidev->irq_resource[i].name = 0;
132 pcidev->irq_resource[i].child = 0;
133 pcidev->irq_resource[i].sibling = 0;
134 pcidev->irq_resource[i].parent = 0;
135 pcidev->irq_resource[i].start = idcres.irq[i];
136 pcidev->irq_resource[i].end = idcres.irq[i];
137 //todo: irq flags
138 pcidev->irq_resource[9].flags = IORESOURCE_IRQ;
139 }
140 }
141 pcidev->irq = pcidev->irq_resource[0].start;
142 pcidev->bus = &pci_busses[0];
143 return TRUE;
144}
145//******************************************************************************
146//******************************************************************************
147struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
148{
149 int i;
150
151 if(from) {
152 //requesting 2nd device of the same type; don't support this for now
153 return 0;
154 }
155 for(i=0;i<MAX_PCI_DEVICES;i++) {
156 if(pci_devices[i].devfn == 0) {
157 if(FindPCIDevice(vendor, device, (struct pci_dev near *)&pci_devices[i]) == TRUE) {
158 return &pci_devices[i];
159 }
160 break;
161 }
162 }
163 return 0;
164}
165//******************************************************************************
166#define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
167//******************************************************************************
168int pci_read_config_byte(struct pci_dev *dev, int where, u8 *value)
169{
170 outl(CONFIG_CMD(dev,where), 0xCF8);
171 *value = inb(0xCFC + (where&3));
172 return PCIBIOS_SUCCESSFUL;
173}
174//******************************************************************************
175//******************************************************************************
176int pci_read_config_word(struct pci_dev *dev, int where, u16 *value)
177{
178 outl(CONFIG_CMD(dev,where), 0xCF8);
179 *value = inw(0xCFC + (where&2));
180 return PCIBIOS_SUCCESSFUL;
181}
182//******************************************************************************
183//******************************************************************************
184int pci_read_config_dword(struct pci_dev *dev, int where, u32 *value)
185{
186 outl(CONFIG_CMD(dev,where), 0xCF8);
187 *value = inl(0xCFC);
188 return PCIBIOS_SUCCESSFUL;
189}
190//******************************************************************************
191//******************************************************************************
192int pci_write_config_byte(struct pci_dev *dev, int where, u8 value)
193{
194 outl(CONFIG_CMD(dev,where), 0xCF8);
195 outb(value, 0xCFC + (where&3));
196 return PCIBIOS_SUCCESSFUL;
197}
198//******************************************************************************
199//******************************************************************************
200int pci_write_config_word(struct pci_dev *dev, int where, u16 value)
201{
202 outl(CONFIG_CMD(dev,where), 0xCF8);
203 outw(value, 0xCFC + (where&2));
204 return PCIBIOS_SUCCESSFUL;
205}
206//******************************************************************************
207//******************************************************************************
208int pci_write_config_dword(struct pci_dev *dev, int where, u32 value)
209{
210 outl(CONFIG_CMD(dev,where), 0xCF8);
211 outl(value, 0xCFC);
212 return PCIBIOS_SUCCESSFUL;
213}
214//******************************************************************************
215//******************************************************************************
216int pcibios_present(void)
217{
218 return 1;
219}
220//******************************************************************************
221//******************************************************************************
222struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn)
223{
224 return NULL;
225}
226//******************************************************************************
227//******************************************************************************
228int pci_dma_supported(struct pci_dev *dev, unsigned long mask)
229{
230 return 1;
231}
232//******************************************************************************
233//******************************************************************************
234int pci_enable_device(struct pci_dev *dev)
235{
236 return 0;
237}
238//******************************************************************************
239struct pci_dev *sblivepcidev = NULL;
240//******************************************************************************
241int pci_register_driver(struct pci_driver *driver)
242{
243 struct pci_dev *pcidev;
244
245 pcidev = pci_find_device(driver->id_table->vendor, driver->id_table->device, NULL);
246 if(pcidev) {
247 if(driver->probe(pcidev, driver->id_table) == 0) {
248 sblivepcidev = pcidev;
249 return 0;
250 }
251 }
252 return 1;
253}
254//******************************************************************************
255//******************************************************************************
256int pci_unregister_driver(struct pci_driver *driver)
257{
258 if(driver && sblivepcidev) {
259 driver->remove(sblivepcidev);
260 }
261 return 0;
262}
263//******************************************************************************
264//******************************************************************************
265void pci_set_master(struct pci_dev *dev)
266{
267
268}
269//******************************************************************************
270//******************************************************************************
271int __compat_get_order(unsigned long size)
272{
273 int order;
274
275 size = (size-1) >> (PAGE_SHIFT-1);
276 order = -1;
277 do {
278 size >>= 1;
279 order++;
280 } while (size);
281 return order;
282}
283//******************************************************************************
284//******************************************************************************
285void *pci_alloc_consistent(struct pci_dev *hwdev,
286 size_t size, dma_addr_t *dma_handle) {
287 void *ret;
288 int gfp = GFP_ATOMIC;
289
290 if (hwdev == NULL)
291 gfp |= GFP_DMA;
292 ret = (void *)__get_free_pages(gfp, __compat_get_order(size));
293
294 if (ret != NULL) {
295 memset(ret, 0, size);
296 *dma_handle = virt_to_bus(ret);
297 }
298 return ret;
299}
300//******************************************************************************
301//******************************************************************************
302void pci_free_consistent(struct pci_dev *hwdev, size_t size,
303 void *vaddr, dma_addr_t dma_handle)
304{
305 free_pages((unsigned long)vaddr, __compat_get_order(size));
306}
307//******************************************************************************
308//******************************************************************************
Note: See TracBrowser for help on using the repository browser.