source: GPL/branches/uniaud32-2.1.x/lib32/pci.c@ 519

Last change on this file since 519 was 519, checked in by David Azarewicz, 15 years ago

Changes to PCI bus scan, malloc, cleanup all warnings, misc other changes

File size: 30.9 KB
Line 
1/* $Id: pci.c,v 1.1.1.1 2003/07/02 13:57:02 eleph Exp $ */
2/*
3 * OS/2 implementation of Linux PCI functions (using direct port I/O)
4 *
5 * (C) 2000-2002 InnoTek Systemberatung GmbH
6 * (C) 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * Parts based on Linux kernel sources
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
27#include "linux.h"
28#include <linux/init.h>
29#include <linux/poll.h>
30#include <asm/uaccess.h>
31#include <asm/hardirq.h>
32#include <asm/io.h>
33#include <sound/config.h>
34#include <sound/core.h>
35#include <sound/asound.h>
36
37#define LINUX
38#include <ossidc.h>
39#include <stacktoflat.h>
40#include <dbgos2.h>
41#include <osspci.h>
42
43#define MAX_PCI_BUSSES 16
44#define MAX_PCI_DEVICES 16
45
46struct pci_dev pci_devices[MAX_PCI_DEVICES] = {0};
47struct pci_bus pci_busses[MAX_PCI_BUSSES] = {0};
48
49BOOL fSuspended = FALSE;
50extern int nrCardsDetected;
51
52
53#define PCI_CONFIG_ENABLE 0x80000000
54#define PCI_CONFIG_ADDRESS 0xCF8
55#define PCI_CONFIG_DATA 0xCFC
56
57#ifdef ACPI
58APIRET APIENTRY ACPIFindPCIDevice(ULONG Bus, ULONG Dev, ULONG Fun, ULONG *PicIRQ, ULONG *ApicIRQ, ULONG *Hdl, char *Component);
59#endif
60
61//******************************************************************************
62#define CONFIG_CMD(dev, where) \
63 (PCI_CONFIG_ENABLE | (dev->bus->number<<16) | (dev->devfn<<8) | (where & ~3))
64//******************************************************************************
65int pci_read_config_byte(struct pci_dev *dev, int where, u8 *value)
66{
67 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS);
68 *value = inb(PCI_CONFIG_DATA + (where&3));
69 return PCIBIOS_SUCCESSFUL;
70}
71//******************************************************************************
72//******************************************************************************
73int pci_read_config_word(struct pci_dev *dev, int where, u16 *value)
74{
75 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS);
76 *value = inw(PCI_CONFIG_DATA + (where&2));
77 return PCIBIOS_SUCCESSFUL;
78}
79//******************************************************************************
80//******************************************************************************
81int pci_read_config_dword(struct pci_dev *dev, int where, u32 *value)
82{
83 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS);
84 *value = inl(PCI_CONFIG_DATA);
85 return PCIBIOS_SUCCESSFUL;
86}
87//******************************************************************************
88//******************************************************************************
89int pci_write_config_byte(struct pci_dev *dev, int where, u8 value)
90{
91 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS);
92 outb(value, PCI_CONFIG_DATA + (where&3));
93 return PCIBIOS_SUCCESSFUL;
94}
95//******************************************************************************
96//******************************************************************************
97int pci_write_config_word(struct pci_dev *dev, int where, u16 value)
98{
99 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS);
100 outw(value, PCI_CONFIG_DATA + (where&2));
101 return PCIBIOS_SUCCESSFUL;
102}
103//******************************************************************************
104//******************************************************************************
105int pci_write_config_dword(struct pci_dev *dev, int where, u32 value)
106{
107 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS);
108 outl(value, PCI_CONFIG_DATA);
109 return PCIBIOS_SUCCESSFUL;
110}
111//******************************************************************************
112//******************************************************************************
113int pcidev_prepare(struct pci_dev *dev)
114{
115 dprintf(("pcidev_prepare %x not implemented", dev));
116 return 1; //todo: correct return value??
117}
118//******************************************************************************
119//******************************************************************************
120int pcidev_activate(struct pci_dev *dev)
121{
122 dprintf(("pcidev_activate %x not implemented", dev));
123 return 1; //todo: correct return value??
124}
125//******************************************************************************
126//******************************************************************************
127int pcidev_deactivate(struct pci_dev *dev)
128{
129 dprintf(("pcidev_deactivate %x not implemented", dev));
130 return 1; //todo: correct return value??
131}
132
133
134
135//******************************************************************************
136//******************************************************************************
137#ifdef ACPI
138struct SaveIRQForSlot
139{
140 ULONG ulSlotNo;
141 BYTE LowIRQ;
142 BYTE HighIRQ;
143 BYTE Pin;
144};
145extern struct SaveIRQForSlot sISRHigh[];
146extern int SaveIRQCounter;
147#endif
148
149//Find the next matching PCI device starting with the device specified by pcidev
150static ULONG pci_query_device(const struct pci_device_id *id_table, struct pci_dev near *pcidev, ULONG ulLast)
151{
152 int resNo, addr;
153 u32 devNr, busNr, funcNr, detectedId, cfgaddrreg, temp, temp2;
154#ifdef ACPI
155 APIRET rc;
156 ULONG temp1,temp3; //PS++
157#endif
158 u8 headerType;
159
160 busNr = (ulLast >> 8) & 0x1f;
161 devNr = PCI_SLOT(ulLast);
162 funcNr = PCI_FUNC(ulLast);
163 if (ulLast) funcNr++;
164
165 cfgaddrreg = inl(PCI_CONFIG_ADDRESS);
166 for(;busNr<MAX_PCI_BUSSES;busNr++) { //BusNumber<255
167 for(;devNr<32;devNr++) {
168 for(;funcNr<8;funcNr++) {
169 headerType = 0;
170 temp = PCI_CONFIG_ENABLE | (busNr<<16) | (devNr<<11) | (funcNr<<8);
171 outl(temp, PCI_CONFIG_ADDRESS);
172 detectedId = inl(PCI_CONFIG_DATA);
173
174 if ( detectedId == 0xffffffff ) {
175 if ( funcNr == 0 ) break; /* if func 0 isn't there, the others aren't either */
176 continue;
177 }
178
179 outl(temp + PCI_CLASS_REVISION, PCI_CONFIG_ADDRESS);
180 temp2 = inl(PCI_CONFIG_DATA) >> 8; /* get class */
181
182 //dprintf(("det=%x(%x) %x need=%x%x %x", detectedId, headerType, temp2, id_table->device&0xffff, id_table->vendor, id_table->class));
183
184 if ( id_table->class ) {
185 if ( (temp2 & id_table->class_mask) != id_table->class ) continue;
186 } else {
187 if ( (id_table->device == PCI_ANY_ID) && ((temp2 >> 8) != PCI_CLASS_MULTIMEDIA_AUDIO) ) continue;
188 }
189
190 if (id_table->vendor != (detectedId & 0xffff)) continue;
191 if ( (id_table->device != PCI_ANY_ID) && (id_table->device != (detectedId >> 16)) ) continue;
192
193 outl(temp | (PCI_HEADER_TYPE & ~3), PCI_CONFIG_ADDRESS);
194 headerType = inb(PCI_CONFIG_DATA + (PCI_HEADER_TYPE & 3));
195
196 if ( (headerType & 0x7f) != PCI_HEADER_TYPE_NORMAL ) continue;
197
198 memset((void near *)pcidev, 0, sizeof(struct pci_dev));
199
200 pcidev->vendor = detectedId & 0xffff;
201 pcidev->device = detectedId >> 16;
202 pcidev->bus = &pci_busses[busNr];
203 pcidev->bus->number = busNr;
204 pcidev->devfn = PCI_DEVFN(devNr, funcNr);
205 pcidev->hdr_type = headerType & 0x7f;
206
207 pcidev->prepare = pcidev_prepare;
208 pcidev->activate = pcidev_activate;
209 pcidev->deactivate = pcidev_deactivate;
210 pcidev->active = 1;
211 pcidev->ro = 0;
212 pcidev->sibling = NULL;
213 pcidev->next = NULL;
214 pcidev->dma_mask = 0xFFFFFFFF;
215
216 // Subsystem ID
217 pci_read_config_word(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &pcidev->subsystem_vendor);
218 pci_read_config_word(pcidev, PCI_SUBSYSTEM_ID, &pcidev->subsystem_device);
219
220 // I/O and MEM
221 resNo = 0;
222 for( addr = PCI_BASE_ADDRESS_0; addr <= PCI_BASE_ADDRESS_5; addr += 4 ) {
223 pci_read_config_dword(pcidev, addr, &temp);
224 if( temp != 0 && temp != 0xffffffff ) {
225 pci_write_config_dword(pcidev, addr, 0xffffffff);
226 pci_read_config_dword(pcidev, addr, &temp2);
227 pci_write_config_dword(pcidev, addr, temp);
228
229 if( temp & PCI_BASE_ADDRESS_SPACE_IO ) {
230 pcidev->resource[resNo].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
231 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_IO_MASK;
232 pcidev->resource[resNo].end = pcidev->resource[resNo].start +
233 ~(temp2 & PCI_BASE_ADDRESS_IO_MASK) + 1;
234 }
235 else
236 {
237 pcidev->resource[resNo].flags = IORESOURCE_MEM | IORESOURCE_MEM_WRITEABLE;
238 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_MEM_MASK;
239 pcidev->resource[resNo].end = pcidev->resource[resNo].start +
240 ~(temp2 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
241 }
242
243 resNo++;
244
245 }
246 }
247
248 // IRQ and PIN
249 pci_read_config_dword(pcidev, PCI_INTERRUPT_LINE, &temp);
250#ifdef ACPI
251 sISRHigh[SaveIRQCounter].Pin = (temp >> 8) & 0xf;
252 temp2 = temp3 = 0;
253 rc = ACPIFindPCIDevice( (ULONG)busNr, // Bus
254 (ULONG)devNr, // Dev
255 (ULONG)(pcidev->devfn >> 8) & 7, // Function
256 &temp1, // PIC IRQ
257 &temp3, // APIC IRQ
258 NULL, // ACPI handle to finding device
259 "Uniaud32"); // Name for acpi log
260 if (!rc) {
261 // Check APIC IRQ, if we have /SMP /APIC, must be set
262 if (temp1) temp = (temp & (~0xff)) | (temp1 & 0xff);
263 // Check PIC IRQ
264 else if (temp3) temp = (temp & (~0xff)) | (temp3 & 0xff);
265 dprintf(("pci_query_device: IRQs ACPI PIC%d APIC%d", temp1, temp3));
266 sISRHigh[SaveIRQCounter].LowIRQ = temp1;
267 sISRHigh[SaveIRQCounter].HighIRQ = temp3;
268 }
269#endif /* ACPI */
270 if( (u8)temp && (u8)temp != 0xff ) {
271 pcidev->irq_resource[0].flags = IORESOURCE_IRQ;
272 pcidev->irq_resource[0].start = pcidev->irq_resource[0].end = temp & 0xffff;
273 pcidev->irq = (u8)temp;
274 }
275
276 return (0x8000 | (busNr << 8) | PCI_DEVFN(devNr, funcNr));
277 } /* for funcNr */
278 funcNr = 0;
279 } /* for devNr */
280 devNr = 0;
281 }
282 outl(cfgaddrreg, PCI_CONFIG_ADDRESS);
283 return 0;
284}
285
286//******************************************************************************
287//******************************************************************************
288// Called from:
289//if from==NULL search pci bus
290//if from!=NULL only search already found devices starting with from
291struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
292{
293 int i;
294 struct pci_device_id id_table;
295
296 for(i=0;i<MAX_PCI_DEVICES;i++) {
297 if ( pci_devices[i].devfn && (pci_devices[i].vendor == vendor) && (pci_devices[i].device == device) ) return &pci_devices[i];
298 }
299
300 for(i=0;i<MAX_PCI_DEVICES;i++) {
301 if(pci_devices[i].devfn == 0) {
302 memset(&id_table, 0, sizeof(id_table));
303 id_table.vendor = vendor;
304 id_table.device = device;
305 if( pci_query_device(&id_table, (struct pci_dev near *)&pci_devices[i], 0) ) return &pci_devices[i];
306 else break;
307 }
308 }
309
310 return NULL;
311}
312//******************************************************************************
313//******************************************************************************
314struct resource * __request_region(struct resource *a, unsigned long start,
315 unsigned long n, const char *name)
316{
317 struct resource *resource;
318
319 if(a->flags & IORESOURCE_MEM) {
320 if(RMRequestMem(/*hResMgr,*/ start, n) == FALSE) {
321 printk("RMRequestIO failed for io %x, length %x\n", start, n);
322 return NULL;
323 }
324 }
325 else if(a->flags & IORESOURCE_IO) {
326 if(RMRequestIO(/*hResMgr,*/ start, n) == FALSE) {
327 printk("RMRequestIO failed for io %x, length %x\n", start, n);
328 return NULL;
329 }
330 }
331
332 resource = kmalloc(sizeof(struct resource), GFP_KERNEL);
333 if (resource == NULL)
334 return NULL;
335 resource->name = name;
336 resource->start = start;
337 resource->end = start + n; // - 1;
338 resource->flags = a->flags;
339 resource->parent =
340 resource->child = NULL;
341
342 // insert in list
343 resource->sibling = a->sibling;
344 a->sibling = resource;
345
346 return resource;
347}
348//******************************************************************************
349//******************************************************************************
350void __release_region(struct resource *a,
351 unsigned long start, unsigned long n)
352{
353 struct resource *resource;
354 struct resource **ppres = &a->sibling;
355 unsigned long end = start + n; // - 1;
356
357 while( *ppres )
358 {
359 resource = *ppres;
360
361 if( resource->start == start && resource->end == end )
362 {
363 // remove from list
364 *ppres = resource->sibling;
365 kfree(resource);
366 return;
367 }
368
369 ppres = &resource->sibling;
370 }
371}
372//******************************************************************************
373//******************************************************************************
374int pci_get_flags (struct pci_dev *dev, int n_base)
375{
376 if(n_base >= DEVICE_COUNT_RESOURCE || !dev->resource[n_base].flags) {
377 DebugInt3();
378 return 0;
379 }
380 return dev->resource[n_base].flags;
381}
382//******************************************************************************
383//******************************************************************************
384int pcibios_present(void)
385{
386 printk("pcibios_present -> pretend BIOS present\n");
387 return 1;
388}
389//******************************************************************************
390//******************************************************************************
391struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn)
392{
393 printk("pci_find_slot %d %x not implemented!!\n", bus, devfn);
394 DebugInt3();
395 return NULL;
396}
397//******************************************************************************
398//******************************************************************************
399int pci_dma_supported(struct pci_dev *dev, unsigned long mask)
400{
401 printk("pci_dma_supported: return TRUE\n");
402 return 1;
403}
404//******************************************************************************
405//******************************************************************************
406int pci_find_capability(struct pci_dev *dev, int cap)
407{
408 u16 status;
409 u8 pos, id;
410 int ttl = 48;
411
412 pci_read_config_word(dev, PCI_STATUS, &status);
413 if (!(status & PCI_STATUS_CAP_LIST))
414 return 0;
415 pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos);
416 while (ttl-- && pos >= 0x40) {
417 pos &= ~3;
418 pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
419 if (id == 0xff)
420 break;
421 if (id == cap)
422 return pos;
423 pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
424 }
425 return 0;
426}
427//******************************************************************************
428/*
429 * Set power management state of a device. For transitions from state D3
430 * it isn't as straightforward as one could assume since many devices forget
431 * their configuration space during wakeup. Returns old power state.
432 */
433//******************************************************************************
434int pci_set_power_state(struct pci_dev *dev, int new_state)
435{
436 u32 base[5], romaddr;
437 u16 pci_command, pwr_command;
438 u8 pci_latency, pci_cacheline;
439 int i, old_state;
440 int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
441
442 if (!pm)
443 return 0;
444 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pwr_command);
445 old_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
446 if (old_state == new_state)
447 return old_state;
448 if (old_state == 3) {
449 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
450 pci_write_config_word(dev, PCI_COMMAND, pci_command & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
451 for (i = 0; i < 5; i++)
452 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, &base[i]);
453 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &romaddr);
454 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
455 pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_cacheline);
456 pci_write_config_word(dev, pm + PCI_PM_CTRL, new_state);
457 for (i = 0; i < 5; i++)
458 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, base[i]);
459 pci_write_config_dword(dev, PCI_ROM_ADDRESS, romaddr);
460 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
461 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cacheline);
462 pci_write_config_byte(dev, PCI_LATENCY_TIMER, pci_latency);
463 pci_write_config_word(dev, PCI_COMMAND, pci_command);
464 } else
465 pci_write_config_word(dev, pm + PCI_PM_CTRL, (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | new_state);
466 return old_state;
467}
468//******************************************************************************
469/*
470 * Initialize device before it's used by a driver. Ask low-level code
471 * to enable I/O and memory. Wake up the device if it was suspended.
472 * Beware, this function can fail.
473 */
474//******************************************************************************
475int pci_enable_device(struct pci_dev *dev)
476{
477 u16 pci_command;
478
479 dprintf(("pci_enable_device %x\n", dev));
480
481 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
482 pci_write_config_word(dev, PCI_COMMAND, pci_command | (PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
483 pci_set_power_state(dev, 0);
484 return 0;
485}
486//******************************************************************************
487//******************************************************************************
488int pci_register_driver(struct pci_driver *driver)
489{
490 int iTableIx, iNumCards, iTmp;
491 ULONG ulLast;
492 struct pci_dev *pcidev;
493
494 if (!driver->probe) return 0;
495
496 iNumCards = 0;
497
498 /* find an empty slot */
499 for (iTmp=0; iTmp<MAX_PCI_DEVICES; iTmp++) {
500 if (pci_devices[iTmp].devfn == 0) break;
501 }
502 if (iTmp >= MAX_PCI_DEVICES) return 0;
503 pcidev = &pci_devices[iTmp];
504
505 for( iTableIx = 0; driver->id_table[iTableIx].vendor; iTableIx++) {
506 ulLast = 0;
507 while( (ulLast = pci_query_device(&driver->id_table[iTableIx], pcidev, ulLast)) ) {
508
509
510 RMInit();
511 dprintf(("pci_register_driver: found=%x:%x searching for %x:%x\n",
512 pcidev->vendor, pcidev->device, driver->id_table[iTableIx].vendor, driver->id_table[iTableIx].device));
513
514 if(driver->probe(pcidev, &driver->id_table[iTableIx]) == 0) {
515 pcidev->pcidriver = (void *)driver;
516 pcidev->current_state = 4;
517
518 // create adapter
519 RMDone((pcidev->device << 16) | pcidev->vendor);
520 iNumCards++;
521
522 /* find another empty slot */
523 for (iTmp=0; iTmp<MAX_PCI_DEVICES; iTmp++) {
524 if (pci_devices[iTmp].devfn == 0) break;
525 }
526 if (iTmp >= MAX_PCI_DEVICES) break;
527 pcidev = &pci_devices[iTmp];
528 } else pcidev->devfn = 0;
529
530 RMDone(0);
531 }
532 }
533
534 return iNumCards;
535}
536//******************************************************************************
537//******************************************************************************
538int pci_module_init(struct pci_driver *drv)
539{
540 int res = pci_register_driver(drv);
541 if (res == 0) return -ENODEV;
542 return res;
543}
544//******************************************************************************
545//******************************************************************************
546int pci_unregister_driver(struct pci_driver *driver)
547{
548 struct pci_dev *pcidev;
549 int i = 0, j;
550
551 while(driver->id_table[i].vendor)
552 {
553 for(j=0;j<MAX_PCI_DEVICES;j++)
554 {
555 if(pci_devices[j].vendor == driver->id_table[i].vendor &&
556 pci_devices[j].device == driver->id_table[i].device)
557 {
558 if(driver->remove) {
559 driver->remove(&pci_devices[j]);
560 }
561 }
562 }
563 i++;
564 }
565 return 0;
566}
567//******************************************************************************
568//******************************************************************************
569void pci_set_master(struct pci_dev *dev)
570{
571 u16 cmd;
572
573 pci_read_config_word(dev, PCI_COMMAND, &cmd);
574 if (! (cmd & PCI_COMMAND_MASTER)) {
575 dprintf(("pci_set_master %x", dev));
576 cmd |= PCI_COMMAND_MASTER;
577 pci_write_config_word(dev, PCI_COMMAND, cmd);
578 }
579 return;
580}
581//******************************************************************************
582// * Register a device with power management
583//******************************************************************************
584struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback callback)
585{
586 dprintf(("pm_register STUB"));
587 DebugInt3();
588 return NULL;
589}
590//******************************************************************************
591// * Unregister a device with power management
592//******************************************************************************
593void pm_unregister(struct pm_dev *dev)
594{
595 dprintf(("pm_unregister STUB"));
596}
597//******************************************************************************
598//******************************************************************************
599int __compat_get_order(unsigned long size)
600{
601 int order;
602
603 size = (size-1) >> (PAGE_SHIFT-1);
604 order = -1;
605 do {
606 size >>= 1;
607 order++;
608 } while (size);
609 return order;
610}
611//******************************************************************************
612//******************************************************************************
613void *pci_alloc_consistent(struct pci_dev *hwdev,
614 long size, dma_addr_t *dma_handle)
615{
616 void *ret = NULL;
617 int gfp = GFP_ATOMIC;
618 int order;
619 dprintf(("pci_alloc_consistent %d mask %x", size, (hwdev) ? hwdev->dma_mask : 0));
620 if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) {
621 //try not to exhaust low memory (< 16mb) so allocate from the high region first
622 //if that doesn't satisfy the dma mask requirement, then get it from the low
623 //regino anyway
624 if(hwdev->dma_mask > 0x00ffffff) {
625 order = __compat_get_order(size);
626 ret = (void *)__get_free_pages(gfp|GFP_DMAHIGHMEM, order);
627 *dma_handle = virt_to_bus(ret);
628 if(*dma_handle > hwdev->dma_mask) {
629 free_pages((unsigned long)ret, __compat_get_order(size));
630 //be sure and allocate below 16 mb
631 gfp |= GFP_DMA;
632 ret = NULL;
633 }
634 }
635 else { //must always allocate below 16 mb
636 gfp |= GFP_DMA;
637 }
638 }
639 if(ret == NULL) {
640 ret = (void *)__get_free_pages(gfp, __compat_get_order(size));
641 }
642
643 if (ret != NULL) {
644 memset(ret, 0, size);
645 *dma_handle = virt_to_bus(ret);
646 }
647 return ret;
648}
649//******************************************************************************
650//******************************************************************************
651void pci_free_consistent(struct pci_dev *hwdev, long size,
652 void *vaddr, dma_addr_t dma_handle)
653{
654 free_pages((unsigned long)vaddr, __compat_get_order(size));
655}
656//******************************************************************************
657//******************************************************************************
658void pci_set_driver_data (struct pci_dev *dev, void *driver_data)
659{
660 if (dev)
661 dev->driver_data = driver_data;
662}
663//******************************************************************************
664//******************************************************************************
665void *pci_get_driver_data (struct pci_dev *dev)
666{
667 if (dev)
668 return dev->driver_data;
669 return 0;
670}
671//******************************************************************************
672//******************************************************************************
673unsigned long pci_get_dma_mask (struct pci_dev *dev)
674{
675 if (dev)
676 return dev->dma_mask;
677 return 0;
678}
679//******************************************************************************
680//******************************************************************************
681int release_resource(struct resource *newres)
682{
683 return 0;
684}
685
686//******************************************************************************
687//******************************************************************************
688int pci_set_latency_time(struct pci_dev *dev, int latency)
689{
690 pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
691 return 0;
692}
693
694//******************************************************************************
695//******************************************************************************
696/**
697 * pci_save_state - save the PCI configuration space of a device before suspending
698 * @dev: - PCI device that we're dealing with
699 * @buffer: - buffer to hold config space context
700 *
701 * @buffer must be large enough to hold the entire PCI 2.2 config space
702 * (>= 64 bytes).
703 */
704int pci_orig_save_state(struct pci_dev *dev, u32 *buffer)
705{
706 int i;
707 if (buffer) {
708 /* XXX: 100% dword access ok here? */
709 for (i = 0; i < 16; i++)
710 pci_read_config_dword(dev, i * 4,&buffer[i]);
711 }
712 return 0;
713}
714
715/**
716 * pci_restore_state - Restore the saved state of a PCI device
717 * @dev: - PCI device that we're dealing with
718 * @buffer: - saved PCI config space
719 *
720 */
721int
722pci_orig_restore_state(struct pci_dev *dev, u32 *buffer)
723{
724 int i;
725
726 if (buffer) {
727 for (i = 0; i < 16; i++)
728 pci_write_config_dword(dev,i * 4, buffer[i]);
729 }
730 /*
731 * otherwise, write the context information we know from bootup.
732 * This works around a problem where warm-booting from Windows
733 * combined with a D3(hot)->D0 transition causes PCI config
734 * header data to be forgotten.
735 */
736 else {
737 for (i = 0; i < 6; i ++)
738 pci_write_config_dword(dev,
739 PCI_BASE_ADDRESS_0 + (i * 4),
740 dev->resource[i].start);
741 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
742 }
743 return 0;
744}
745
746struct saved_config_tbl {
747 struct pci_dev *pci;
748 u32 config[16];
749};
750static struct saved_config_tbl saved_tbl[16];
751
752int pci_save_state(struct pci_dev *pci)
753{
754 int i;
755 /* FIXME: mutex needed for race? */
756 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) {
757 if (! saved_tbl[i].pci) {
758 saved_tbl[i].pci = pci;
759 pci_orig_save_state(pci, saved_tbl[i].config);
760 return 1;
761 }
762 }
763 printk(KERN_DEBUG "snd: no pci config space found!\n");
764 return 0;
765}
766
767int pci_restore_state(struct pci_dev *pci)
768{
769 int i;
770 /* FIXME: mutex needed for race? */
771 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) {
772 if (saved_tbl[i].pci == pci) {
773 saved_tbl[i].pci = NULL;
774 pci_orig_restore_state(pci, saved_tbl[i].config);
775 return 0;
776 }
777 }
778 printk(KERN_DEBUG "snd: no saved pci config!\n");
779 return 1;
780}
781
782void pci_disable_device(struct pci_dev *dev)
783{
784 u16 pci_command;
785
786 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
787 if (pci_command & PCI_COMMAND_MASTER) {
788 pci_command &= ~PCI_COMMAND_MASTER;
789 pci_write_config_word(dev, PCI_COMMAND, pci_command);
790 }
791}
792
793int pci_request_region(struct pci_dev *pdev, int bar, char *res_name)
794{
795 int flags;
796
797 if (pci_resource_len(pdev, bar) == 0)
798 return 0;
799 flags = pci_get_flags(pdev, bar);
800 if (flags & IORESOURCE_IO) {
801 if (check_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar)))
802 goto err_out;
803 request_region(pci_resource_start(pdev, bar),
804 pci_resource_len(pdev, bar), res_name);
805 }
806 else if (flags & IORESOURCE_MEM) {
807 if (check_mem_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar)))
808 goto err_out;
809 request_mem_region(pci_resource_start(pdev, bar),
810 pci_resource_len(pdev, bar), res_name);
811 }
812
813 return 0;
814
815err_out:
816 printk(KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n",
817 flags & IORESOURCE_IO ? "I/O" : "mem",
818 bar + 1, /* PCI BAR # */
819 pci_resource_len(pdev, bar), pci_resource_start(pdev, bar),
820 res_name);
821 return -EBUSY;
822}
823
824void pci_release_region(struct pci_dev *pdev, int bar)
825{
826 int flags;
827
828 if (pci_resource_len(pdev, bar) == 0)
829 return;
830 flags = pci_get_flags(pdev, bar);
831 if (flags & IORESOURCE_IO) {
832 release_region(pci_resource_start(pdev, bar),
833 pci_resource_len(pdev, bar));
834 }
835 else if (flags & IORESOURCE_MEM) {
836 release_mem_region(pci_resource_start(pdev, bar),
837 pci_resource_len(pdev, bar));
838 }
839}
840
841int pci_request_regions(struct pci_dev *pdev, char *res_name)
842{
843 int i;
844
845 for (i = 0; i < 6; i++)
846 if (pci_request_region(pdev, i, res_name))
847 goto err;
848 return 0;
849 err:
850 while (--i >= 0)
851 pci_release_region(pdev, i);
852 return -EBUSY;
853}
854
855void pci_release_regions(struct pci_dev *pdev)
856{
857 int i;
858 for (i = 0; i < 6; i++)
859 pci_release_region(pdev, i);
860}
861
862const struct pci_device_id * pci_match_device(const struct pci_device_id *ids, struct pci_dev *dev)
863{
864 u16 subsystem_vendor, subsystem_device;
865
866 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
867 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &subsystem_device);
868
869 while (ids->vendor || ids->subvendor || ids->class_mask) {
870 if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
871 (ids->device == PCI_ANY_ID || ids->device == dev->device) &&
872 (ids->subvendor == PCI_ANY_ID || ids->subvendor == subsystem_vendor) &&
873 (ids->subdevice == PCI_ANY_ID || ids->subdevice == subsystem_device) &&
874 !((ids->class ^ dev->_class) & ids->class_mask))
875 return ids;
876 ids++;
877 }
878 return NULL;
879}
880
881int snd_pci_dev_present(const struct pci_device_id *ids)
882{
883 while (ids->vendor || ids->subvendor) {
884 if (pci_find_device(ids->vendor, ids->subvendor, NULL))
885 return 1;
886 ids++;
887 }
888 return 0;
889}
890
891struct pci_driver_mapping {
892 struct pci_dev *dev;
893 struct pci_driver *drv;
894 unsigned long dma_mask;
895 void *driver_data;
896 u32 saved_config[16];
897};
898
899#define PCI_MAX_MAPPINGS 64
900static struct pci_driver_mapping drvmap [PCI_MAX_MAPPINGS] = { { NULL, } , };
901
902
903static struct pci_driver_mapping *get_pci_driver_mapping(struct pci_dev *dev)
904{
905 int i;
906
907 for (i = 0; i < PCI_MAX_MAPPINGS; i++)
908 if (drvmap[i].dev == dev)
909 return &drvmap[i];
910 return NULL;
911}
912
913struct pci_driver *snd_pci_compat_get_pci_driver(struct pci_dev *dev)
914{
915 struct pci_driver_mapping *map = get_pci_driver_mapping(dev);
916 if (map)
917 return map->drv;
918 return NULL;
919}
920#if 0
921void * pci_get_drvdata (struct pci_dev *dev)
922{
923 struct pci_driver_mapping *map = get_pci_driver_mapping(dev);
924 if (map)
925 return map->driver_data;
926 return NULL;
927}
928
929
930void pci_set_drvdata (struct pci_dev *dev, void *driver_data)
931{
932 struct pci_driver_mapping *map = get_pci_driver_mapping(dev);
933 if (map)
934 map->driver_data = driver_data;
935}
936#endif
937
938
939//******************************************************************************
940//******************************************************************************
941OSSRET OSS32_APMResume()
942{
943 int i;
944 struct pci_driver *driver;
945
946 dprintf(("OSS32_APMResume"));
947
948 fSuspended = FALSE;
949
950 for(i=0;i<MAX_PCI_DEVICES;i++)
951 {
952 if(pci_devices[i].devfn)
953 {
954 driver = pci_devices[i].pcidriver;
955 if(driver && driver->resume) {
956 driver->resume(&pci_devices[i]);
957 }
958 }
959 }
960
961 return OSSERR_SUCCESS;
962}
963//******************************************************************************
964//******************************************************************************
965OSSRET OSS32_APMSuspend()
966{
967 int i;
968 struct pci_driver *driver;
969
970 dprintf(("OSS32_APMSuspend 1"));
971
972 fSuspended = TRUE;
973
974 for(i=0;i<MAX_PCI_DEVICES;i++)
975 {
976 if(pci_devices[i].devfn)
977 {
978 driver = pci_devices[i].pcidriver;
979 if(driver && driver->suspend) {
980 driver->suspend(&pci_devices[i], SNDRV_CTL_POWER_D3cold);
981 }
982 }
983 }
984
985 dprintf(("OSS32_APMSuspend 2"));
986 return OSSERR_SUCCESS;
987}
988
Note: See TracBrowser for help on using the repository browser.