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

Last change on this file since 76 was 76, checked in by vladest, 19 years ago

Latest ALSA patches
HDA patches
Patch for Intel from Rudy's
Fixes locks on NM256 chipsets
Fixes PM on Maestro3 chipsets

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