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

Last change on this file since 35 was 35, checked in by vladest, 20 years ago

Fixed UNIAUD API
Added PM support for Yamaha chipsets
Added PM support for Intel chipsets

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