source: GPL/branches/1.1.x/lib32/pci.c@ 548

Last change on this file since 548 was 328, checked in by Brendan Oakley, 17 years ago

Added option for ACPI support provided by Pavel, requires AcpiDrv.lib

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