source: GPL/branches/uniaud32-2.0/lib32/pci.c@ 421

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

Updates from Pasha to improve IRQ handling and resolve long delays at startup in APIC mode when using ACPI

File size: 34.6 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 sISRHigh[SaveIRQCounter].Pin = (temp >> 8) & 0xf;
245#ifdef ACPI
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 return 1;
514 }
515 else pcidev->devfn = 0;
516 }
517
518 RMDone(0);
519
520 dev_num++;
521
522 }
523 }
524 return 0;
525}
526//******************************************************************************
527//******************************************************************************
528int pci_module_init(struct pci_driver *drv)
529{
530 int res = pci_register_driver(drv);
531 if (res < 0)
532 return res;
533 if (res == 0)
534 return -ENODEV;
535 return 0;
536}
537//******************************************************************************
538//******************************************************************************
539int pci_unregister_driver(struct pci_driver *driver)
540{
541 struct pci_dev *pcidev;
542 int i = 0, j;
543
544 while(driver->id_table[i].vendor)
545 {
546 for(j=0;j<MAX_PCI_DEVICES;j++)
547 {
548 if(pci_devices[j].vendor == driver->id_table[i].vendor &&
549 pci_devices[j].device == driver->id_table[i].device)
550 {
551 if(driver->remove) {
552 driver->remove(&pci_devices[j]);
553 }
554 }
555 }
556 i++;
557 }
558 return 0;
559}
560//******************************************************************************
561//******************************************************************************
562void pci_set_master(struct pci_dev *dev)
563{
564 u16 cmd;
565
566 pci_read_config_word(dev, PCI_COMMAND, &cmd);
567 if (! (cmd & PCI_COMMAND_MASTER)) {
568 dprintf(("pci_set_master %x", dev));
569 cmd |= PCI_COMMAND_MASTER;
570 pci_write_config_word(dev, PCI_COMMAND, cmd);
571 }
572 return;
573}
574//******************************************************************************
575// * Register a device with power management
576//******************************************************************************
577struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback callback)
578{
579 dprintf(("pm_register STUB"));
580 DebugInt3();
581 return NULL;
582}
583//******************************************************************************
584// * Unregister a device with power management
585//******************************************************************************
586void pm_unregister(struct pm_dev *dev)
587{
588 dprintf(("pm_unregister STUB"));
589}
590//******************************************************************************
591//******************************************************************************
592int __compat_get_order(unsigned long size)
593{
594 int order;
595
596 size = (size-1) >> (PAGE_SHIFT-1);
597 order = -1;
598 do {
599 size >>= 1;
600 order++;
601 } while (size);
602 return order;
603}
604//******************************************************************************
605//******************************************************************************
606void *pci_alloc_consistent(struct pci_dev *hwdev,
607 long size, dma_addr_t *dma_handle)
608{
609 void *ret = NULL;
610 int gfp = GFP_ATOMIC;
611 int order;
612#ifdef DEBUG
613 dprintf(("pci_alloc_consistent %d mask %x", size, (hwdev) ? hwdev->dma_mask : 0));
614#endif
615 if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) {
616 //try not to exhaust low memory (< 16mb) so allocate from the high region first
617 //if that doesn't satisfy the dma mask requirement, then get it from the low
618 //regino anyway
619 if(hwdev->dma_mask > 0x00ffffff) {
620 order = __compat_get_order(size);
621 ret = (void *)__get_free_pages(gfp|GFP_DMAHIGHMEM, order);
622 *dma_handle = virt_to_bus(ret);
623 if(*dma_handle > hwdev->dma_mask) {
624 free_pages((unsigned long)ret, __compat_get_order(size));
625 //be sure and allocate below 16 mb
626 gfp |= GFP_DMA;
627 ret = NULL;
628 }
629 }
630 else { //must always allocate below 16 mb
631 gfp |= GFP_DMA;
632 }
633 }
634 if(ret == NULL) {
635 ret = (void *)__get_free_pages(gfp, __compat_get_order(size));
636 }
637
638 if (ret != NULL) {
639 memset(ret, 0, size);
640 *dma_handle = virt_to_bus(ret);
641 }
642 return ret;
643}
644//******************************************************************************
645//******************************************************************************
646void pci_free_consistent(struct pci_dev *hwdev, long size,
647 void *vaddr, dma_addr_t dma_handle)
648{
649 free_pages((unsigned long)vaddr, __compat_get_order(size));
650}
651//******************************************************************************
652//******************************************************************************
653void pci_set_driver_data (struct pci_dev *dev, void *driver_data)
654{
655 if (dev)
656 dev->driver_data = driver_data;
657}
658//******************************************************************************
659//******************************************************************************
660void *pci_get_driver_data (struct pci_dev *dev)
661{
662 if (dev)
663 return dev->driver_data;
664 return 0;
665}
666//******************************************************************************
667//******************************************************************************
668unsigned long pci_get_dma_mask (struct pci_dev *dev)
669{
670 if (dev)
671 return dev->dma_mask;
672 return 0;
673}
674//******************************************************************************
675//******************************************************************************
676int pci_set_dma_mask (struct pci_dev *dev, unsigned long mask)
677{
678 if (dev)
679 {
680 dev->dma_mask = mask;
681 return 0;
682 }
683 return -1;
684}
685//******************************************************************************
686//******************************************************************************
687int release_resource(struct resource *newres)
688{
689 return 0;
690}
691
692//******************************************************************************
693//******************************************************************************
694int pci_set_latency_time(struct pci_dev *dev, int latency)
695{
696 pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
697 return 0;
698}
699
700//******************************************************************************
701//******************************************************************************
702/**
703 * pci_save_state - save the PCI configuration space of a device before suspending
704 * @dev: - PCI device that we're dealing with
705 * @buffer: - buffer to hold config space context
706 *
707 * @buffer must be large enough to hold the entire PCI 2.2 config space
708 * (>= 64 bytes).
709 */
710int pci_orig_save_state(struct pci_dev *dev, u32 *buffer)
711{
712 int i;
713 if (buffer) {
714 /* XXX: 100% dword access ok here? */
715 for (i = 0; i < 16; i++)
716 pci_read_config_dword(dev, i * 4,&buffer[i]);
717 }
718 return 0;
719}
720
721/**
722 * pci_restore_state - Restore the saved state of a PCI device
723 * @dev: - PCI device that we're dealing with
724 * @buffer: - saved PCI config space
725 *
726 */
727int
728pci_orig_restore_state(struct pci_dev *dev, u32 *buffer)
729{
730 int i;
731
732 if (buffer) {
733 for (i = 0; i < 16; i++)
734 pci_write_config_dword(dev,i * 4, buffer[i]);
735 }
736 /*
737 * otherwise, write the context information we know from bootup.
738 * This works around a problem where warm-booting from Windows
739 * combined with a D3(hot)->D0 transition causes PCI config
740 * header data to be forgotten.
741 */
742 else {
743 for (i = 0; i < 6; i ++)
744 pci_write_config_dword(dev,
745 PCI_BASE_ADDRESS_0 + (i * 4),
746 dev->resource[i].start);
747 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
748 }
749 return 0;
750}
751
752struct saved_config_tbl {
753 struct pci_dev *pci;
754 u32 config[16];
755};
756static struct saved_config_tbl saved_tbl[16];
757
758void pci_save_state(struct pci_dev *pci)
759{
760 int i;
761 /* FIXME: mutex needed for race? */
762 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) {
763 if (! saved_tbl[i].pci) {
764 saved_tbl[i].pci = pci;
765 pci_orig_save_state(pci, saved_tbl[i].config);
766 return;
767 }
768 }
769 printk(KERN_DEBUG "snd: no pci config space found!\n");
770}
771
772int pci_restore_state(struct pci_dev *pci)
773{
774 int i;
775 /* FIXME: mutex needed for race? */
776 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) {
777 if (saved_tbl[i].pci == pci) {
778 saved_tbl[i].pci = NULL;
779 pci_orig_restore_state(pci, saved_tbl[i].config);
780 return 0;
781 }
782 }
783 printk(KERN_DEBUG "snd: no saved pci config!\n");
784 return 1;
785}
786
787void pci_disable_device(struct pci_dev *dev)
788{
789 u16 pci_command;
790
791 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
792 if (pci_command & PCI_COMMAND_MASTER) {
793 pci_command &= ~PCI_COMMAND_MASTER;
794 pci_write_config_word(dev, PCI_COMMAND, pci_command);
795 }
796}
797
798int pci_request_region(struct pci_dev *pdev, int bar, char *res_name)
799{
800 int flags;
801
802 if (pci_resource_len(pdev, bar) == 0)
803 return 0;
804 flags = pci_get_flags(pdev, bar);
805 if (flags & IORESOURCE_IO) {
806 if (check_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar)))
807 goto err_out;
808 request_region(pci_resource_start(pdev, bar),
809 pci_resource_len(pdev, bar), res_name);
810 }
811 else if (flags & IORESOURCE_MEM) {
812 if (check_mem_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar)))
813 goto err_out;
814 request_mem_region(pci_resource_start(pdev, bar),
815 pci_resource_len(pdev, bar), res_name);
816 }
817
818 return 0;
819
820err_out:
821 printk(KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n",
822 flags & IORESOURCE_IO ? "I/O" : "mem",
823 bar + 1, /* PCI BAR # */
824 pci_resource_len(pdev, bar), pci_resource_start(pdev, bar),
825 res_name);
826 return -EBUSY;
827}
828
829void pci_release_region(struct pci_dev *pdev, int bar)
830{
831 int flags;
832
833 if (pci_resource_len(pdev, bar) == 0)
834 return;
835 flags = pci_get_flags(pdev, bar);
836 if (flags & IORESOURCE_IO) {
837 release_region(pci_resource_start(pdev, bar),
838 pci_resource_len(pdev, bar));
839 }
840 else if (flags & IORESOURCE_MEM) {
841 release_mem_region(pci_resource_start(pdev, bar),
842 pci_resource_len(pdev, bar));
843 }
844}
845
846int pci_request_regions(struct pci_dev *pdev, char *res_name)
847{
848 int i;
849
850 for (i = 0; i < 6; i++)
851 if (pci_request_region(pdev, i, res_name))
852 goto err;
853 return 0;
854 err:
855 while (--i >= 0)
856 pci_release_region(pdev, i);
857 return -EBUSY;
858}
859
860void pci_release_regions(struct pci_dev *pdev)
861{
862 int i;
863 for (i = 0; i < 6; i++)
864 pci_release_region(pdev, i);
865}
866
867const struct pci_device_id * pci_match_device(const struct pci_device_id *ids, struct pci_dev *dev)
868{
869 u16 subsystem_vendor, subsystem_device;
870
871 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
872 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &subsystem_device);
873
874 while (ids->vendor || ids->subvendor || ids->class_mask) {
875 if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
876 (ids->device == PCI_ANY_ID || ids->device == dev->device) &&
877 (ids->subvendor == PCI_ANY_ID || ids->subvendor == subsystem_vendor) &&
878 (ids->subdevice == PCI_ANY_ID || ids->subdevice == subsystem_device) &&
879 !((ids->class ^ dev->_class) & ids->class_mask))
880 return ids;
881 ids++;
882 }
883 return NULL;
884}
885
886int snd_pci_dev_present(const struct pci_device_id *ids)
887{
888 while (ids->vendor || ids->subvendor) {
889 if (pci_find_device(ids->vendor, ids->subvendor, NULL))
890 return 1;
891 ids++;
892 }
893 return 0;
894}
895
896struct pci_driver_mapping {
897 struct pci_dev *dev;
898 struct pci_driver *drv;
899 unsigned long dma_mask;
900 void *driver_data;
901 u32 saved_config[16];
902};
903
904#define PCI_MAX_MAPPINGS 64
905static struct pci_driver_mapping drvmap [PCI_MAX_MAPPINGS] = { { NULL, } , };
906
907
908static struct pci_driver_mapping *get_pci_driver_mapping(struct pci_dev *dev)
909{
910 int i;
911
912 for (i = 0; i < PCI_MAX_MAPPINGS; i++)
913 if (drvmap[i].dev == dev)
914 return &drvmap[i];
915 return NULL;
916}
917
918struct pci_driver *snd_pci_compat_get_pci_driver(struct pci_dev *dev)
919{
920 struct pci_driver_mapping *map = get_pci_driver_mapping(dev);
921 if (map)
922 return map->drv;
923 return NULL;
924}
925#if 0
926void * pci_get_drvdata (struct pci_dev *dev)
927{
928 struct pci_driver_mapping *map = get_pci_driver_mapping(dev);
929 if (map)
930 return map->driver_data;
931 return NULL;
932}
933
934
935void pci_set_drvdata (struct pci_dev *dev, void *driver_data)
936{
937 struct pci_driver_mapping *map = get_pci_driver_mapping(dev);
938 if (map)
939 map->driver_data = driver_data;
940}
941#endif
942
943
944//******************************************************************************
945//******************************************************************************
946OSSRET OSS32_APMResume()
947{
948 int i;
949 struct pci_driver *driver;
950
951 dprintf(("OSS32_APMResume"));
952
953 fSuspended = FALSE;
954
955 for(i=0;i<MAX_PCI_DEVICES;i++)
956 {
957 if(pci_devices[i].devfn)
958 {
959 driver = pci_devices[i].pcidriver;
960 if(driver && driver->resume) {
961 driver->resume(&pci_devices[i]);
962 }
963 }
964 }
965
966 return OSSERR_SUCCESS;
967}
968//******************************************************************************
969//******************************************************************************
970OSSRET OSS32_APMSuspend()
971{
972 int i;
973 struct pci_driver *driver;
974
975 dprintf(("OSS32_APMSuspend"));
976
977 fSuspended = TRUE;
978
979 for(i=0;i<MAX_PCI_DEVICES;i++)
980 {
981 if(pci_devices[i].devfn)
982 {
983 driver = pci_devices[i].pcidriver;
984 if(driver && driver->suspend) {
985 driver->suspend(&pci_devices[i], SNDRV_CTL_POWER_D3cold);
986 }
987 }
988 }
989
990 return OSSERR_SUCCESS;
991}
992
Note: See TracBrowser for help on using the repository browser.