source: GPL/trunk/lib32/pci.c@ 452

Last change on this file since 452 was 452, checked in by Paul Smedley, 16 years ago

Mods to allow detection of more than one audio adapter in uniaud32

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