source: cmedia/trunk/Lib32/pci.c@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 11.2 KB
Line 
1/* $Id: pci.c,v 1.3 2000/07/23 16:21:56 sandervl Exp $ */
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.