1 /*****************************************************************************/
4 * comemlite.c -- PCI access code for embedded CO-MEM Lite PCI controller.
6 * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
7 * (C) Copyright 2000, Lineo (www.lineo.com)
10 /*****************************************************************************/
12 #include <linux/config.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/pci.h>
16 #include <linux/ptrace.h>
17 #include <linux/spinlock.h>
18 #include <linux/interrupt.h>
19 #include <linux/sched.h>
20 #include <asm/coldfire.h>
21 #include <asm/mcfsim.h>
23 #include <asm/anchor.h>
29 /*****************************************************************************/
32 * Debug configuration defines. DEBUGRES sets debugging output for
33 * the resource allocation phase. DEBUGPCI traces on pcibios_ function
34 * calls, and DEBUGIO traces all accesses to devices on the PCI bus.
36 /*#define DEBUGRES 1*/
37 /*#define DEBUGPCI 1*/
40 /*****************************************************************************/
43 * PCI markers for bus present and active slots.
45 int pci_bus_is_present
= 0;
46 unsigned long pci_slotmask
= 0;
49 * We may or may not need to swap the bytes of PCI bus tranfers.
50 * The endianess is re-roder automatically by the CO-MEM, but it
51 * will get the wrong byte order for a pure data stream.
53 #define pci_byteswap 0
57 * Resource tracking. The CO-MEM part creates a virtual address
58 * space that all the PCI devices live in - it is not in any way
59 * directly mapped into the ColdFire address space. So we can
60 * really assign any resources we like to devices, as long as
61 * they do not clash with other PCI devices.
63 unsigned int pci_iobase
= PCIBIOS_MIN_IO
; /* Arbitrary start address */
64 unsigned int pci_membase
= PCIBIOS_MIN_MEM
; /* Arbitrary start address */
66 #define PCI_MINIO 0x100 /* 256 byte minimum I/O */
67 #define PCI_MINMEM 0x00010000 /* 64k minimum chunk */
70 * The CO-MEM's shared memory segment is visible inside the PCI
71 * memory address space. We need to keep track of the address that
72 * this is mapped at, to setup the bus masters pointers.
74 unsigned int pci_shmemaddr
;
76 /*****************************************************************************/
78 void pci_interrupt(int irq
, void *id
, struct pt_regs
*fp
);
80 /*****************************************************************************/
83 * Some platforms have custom ways of reseting the PCI bus.
86 void pci_resetbus(void)
92 printk(KERN_DEBUG
"pci_resetbus()\n");
95 *((volatile unsigned short *) (MCF_MBAR
+MCFSIM_PADDR
)) |= eLIA_PCIRESET
;
96 for (i
= 0; (i
< 1000); i
++) {
97 *((volatile unsigned short *) (MCF_MBAR
+ MCFSIM_PADAT
)) =
98 (ppdata
| eLIA_PCIRESET
);
102 *((volatile unsigned short *) (MCF_MBAR
+ MCFSIM_PADAT
)) = ppdata
;
106 /*****************************************************************************/
108 int pcibios_assign_resource_slot(int slot
)
110 volatile unsigned long *rp
;
111 volatile unsigned char *ip
;
112 unsigned int idsel
, addr
, val
, align
, i
;
116 printk(KERN_INFO
"pcibios_assign_resource_slot(slot=%x)\n", slot
);
119 rp
= (volatile unsigned long *) COMEM_BASE
;
120 idsel
= COMEM_DA_ADDR(0x1 << (slot
+ 16));
122 /* Try to assign resource to each BAR */
123 for (bar
= 0; (bar
< 6); bar
++) {
124 addr
= COMEM_PCIBUS
+ PCI_BASE_ADDRESS_0
+ (bar
* 4);
125 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGRD
| idsel
;
126 val
= rp
[LREG(addr
)];
128 printk(KERN_DEBUG
"-----------------------------------"
129 "-------------------------------------\n");
130 printk(KERN_DEBUG
"BAR[%d]: read=%08x ", bar
, val
);
133 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGWR
| idsel
;
134 rp
[LREG(addr
)] = 0xffffffff;
136 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGRD
| idsel
;
137 val
= rp
[LREG(addr
)];
139 printk(KERN_DEBUG
"write=%08x ", val
);
143 printk(KERN_DEBUG
"\n");
148 /* Determine space required by BAR */
149 /* FIXME: this should go backwords from 0x80000000... */
150 for (i
= 0; (i
< 32); i
++) {
151 if ((0x1 << i
) & (val
& 0xfffffffc))
156 printk(KERN_DEBUG
"size=%08x(%d)\n", (0x1 << i
), i
);
160 /* Assign a resource */
161 if (val
& PCI_BASE_ADDRESS_SPACE_IO
) {
165 printk(KERN_DEBUG
"BAR[%d]: IO size=%08x iobase=%08x\n",
170 val
= 0 | PCI_BASE_ADDRESS_SPACE_IO
;
172 printk(KERN_DEBUG
"BAR[%d]: too big for IO??\n", bar
);
175 /* Check for un-alignment */
176 if ((align
= pci_iobase
% i
))
177 pci_iobase
+= (i
- align
);
178 val
= pci_iobase
| PCI_BASE_ADDRESS_SPACE_IO
;
185 printk(KERN_DEBUG
"BAR[%d]: MEMORY size=%08x membase=%08x\n",
186 bar
, i
, pci_membase
);
188 /* Check for un-alignment */
189 if ((align
= pci_membase
% i
))
190 pci_membase
+= (i
- align
);
191 val
= pci_membase
| PCI_BASE_ADDRESS_SPACE_MEMORY
;
195 /* Write resource back into BAR register */
196 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGWR
| idsel
;
197 rp
[LREG(addr
)] = val
;
199 printk(KERN_DEBUG
"BAR[%d]: assigned bar=%08x\n", bar
, val
);
204 printk(KERN_DEBUG
"-----------------------------------"
205 "-------------------------------------\n");
208 /* Assign IRQ if one is wanted... */
209 ip
= (volatile unsigned char *) (COMEM_BASE
+ COMEM_PCIBUS
);
210 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGRD
| idsel
;
212 addr
= (PCI_INTERRUPT_PIN
& 0xfc) + (~PCI_INTERRUPT_PIN
& 0x03);
214 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGWR
| idsel
;
215 addr
= (PCI_INTERRUPT_LINE
& 0xfc)+(~PCI_INTERRUPT_LINE
& 0x03);
218 printk(KERN_DEBUG
"IRQ LINE=25\n");
225 /*****************************************************************************/
227 int pcibios_enable_slot(int slot
)
229 volatile unsigned long *rp
;
230 volatile unsigned short *wp
;
231 unsigned int idsel
, addr
;
235 printk(KERN_DEBUG
"pcibios_enbale_slot(slot=%x)\n", slot
);
238 rp
= (volatile unsigned long *) COMEM_BASE
;
239 wp
= (volatile unsigned short *) COMEM_BASE
;
240 idsel
= COMEM_DA_ADDR(0x1 << (slot
+ 16));
242 /* Get current command settings */
243 addr
= COMEM_PCIBUS
+ PCI_COMMAND
;
244 addr
= (addr
& ~0x3) + (~addr
& 0x02);
245 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGRD
| idsel
;
246 cmd
= wp
[WREG(addr
)];
247 /*val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);*/
249 /* Enable I/O and memory accesses to this device */
250 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_CFGWR
| idsel
;
251 cmd
|= PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER
;
252 wp
[WREG(addr
)] = cmd
;
257 /*****************************************************************************/
259 void pcibios_assign_resources(void)
261 volatile unsigned long *rp
;
262 unsigned long sel
, id
;
265 rp
= (volatile unsigned long *) COMEM_BASE
;
268 * Do a quick scan of the PCI bus and see what is here.
270 for (slot
= COMEM_MINDEV
; (slot
<= COMEM_MAXDEV
); slot
++) {
271 sel
= COMEM_DA_CFGRD
| COMEM_DA_ADDR(0x1 << (slot
+ 16));
272 rp
[LREG(COMEM_DAHBASE
)] = sel
;
273 rp
[LREG(COMEM_PCIBUS
)] = 0; /* Clear bus */
274 id
= rp
[LREG(COMEM_PCIBUS
)];
275 if ((id
!= 0) && ((id
& 0xffff0000) != (sel
& 0xffff0000))) {
276 printk(KERN_INFO
"PCI: slot=%d id=%08x\n", slot
, (int) id
);
277 pci_slotmask
|= 0x1 << slot
;
278 pcibios_assign_resource_slot(slot
);
279 pcibios_enable_slot(slot
);
284 /*****************************************************************************/
286 int pcibios_init(void)
288 volatile unsigned long *rp
;
289 unsigned long sel
, id
;
293 printk(KERN_DEBUG
"pcibios_init()\n");
299 * Do some sort of basic check to see if the CO-MEM part
300 * is present... This works ok, but I think we really need
301 * something better...
303 rp
= (volatile unsigned long *) COMEM_BASE
;
304 if ((rp
[LREG(COMEM_LBUSCFG
)] & 0xff) != 0x50) {
305 printk(KERN_INFO
"PCI: no PCI bus present\n");
309 #ifdef COMEM_BRIDGEDEV
311 * Setup the PCI bridge device first. It needs resources too,
312 * so that bus masters can get to its shared memory.
314 slot
= COMEM_BRIDGEDEV
;
315 sel
= COMEM_DA_CFGRD
| COMEM_DA_ADDR(0x1 << (slot
+ 16));
316 rp
[LREG(COMEM_DAHBASE
)] = sel
;
317 rp
[LREG(COMEM_PCIBUS
)] = 0; /* Clear bus */
318 id
= rp
[LREG(COMEM_PCIBUS
)];
319 if ((id
== 0) || ((id
& 0xffff0000) == (sel
& 0xffff0000))) {
320 printk(KERN_INFO
"PCI: no PCI bus bridge present\n");
324 printk(KERN_INFO
"PCI: bridge device at slot=%d id=%08x\n", slot
, (int) id
);
325 pci_slotmask
|= 0x1 << slot
;
326 pci_shmemaddr
= pci_membase
;
327 pcibios_assign_resource_slot(slot
);
328 pcibios_enable_slot(slot
);
331 pci_bus_is_present
= 1;
333 /* Get PCI irq for local vectoring */
334 if (request_irq(COMEM_IRQ
, pci_interrupt
, 0, "PCI bridge", NULL
)) {
335 printk(KERN_WARNING
"PCI: failed to acquire interrupt %d\n", COMEM_IRQ
);
337 mcf_autovector(COMEM_IRQ
);
340 pcibios_assign_resources();
345 /*****************************************************************************/
347 char *pcibios_setup(char *option
)
349 /* Nothing for us to handle. */
352 /*****************************************************************************/
354 void pcibios_fixup_bus(struct pci_bus
*b
)
358 /*****************************************************************************/
360 void pcibios_align_resource(void *data
, struct resource
*res
, unsigned long size
, unsigned long align
)
364 /*****************************************************************************/
366 int pcibios_enable_device(struct pci_dev
*dev
, int mask
)
370 slot
= PCI_SLOT(dev
->devfn
);
371 if ((dev
->bus
== 0) && (pci_slotmask
& (1 << slot
)))
372 pcibios_enable_slot(slot
);
376 /*****************************************************************************/
378 void pcibios_update_resource(struct pci_dev
*dev
, struct resource
*root
, struct resource
*r
, int resource
)
380 printk(KERN_WARNING
"%s(%d): no support for changing PCI resources...\n",
385 /*****************************************************************************/
388 * Local routines to interrcept the standard I/O and vector handling
389 * code. Don't include this 'till now - initialization code above needs
390 * access to the real code too.
392 #include <asm/mcfpci.h>
394 /*****************************************************************************/
396 void pci_outb(unsigned char val
, unsigned int addr
)
398 volatile unsigned long *rp
;
399 volatile unsigned char *bp
;
402 printk(KERN_DEBUG
"pci_outb(val=%02x,addr=%x)\n", val
, addr
);
405 rp
= (volatile unsigned long *) COMEM_BASE
;
406 bp
= (volatile unsigned char *) COMEM_BASE
;
407 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IOWR
| COMEM_DA_ADDR(addr
);
408 addr
= (addr
& ~0x3) + (~addr
& 0x03);
409 bp
[(COMEM_PCIBUS
+ COMEM_DA_OFFSET(addr
))] = val
;
412 /*****************************************************************************/
414 void pci_outw(unsigned short val
, unsigned int addr
)
416 volatile unsigned long *rp
;
417 volatile unsigned short *sp
;
420 printk(KERN_DEBUG
"pci_outw(val=%04x,addr=%x)\n", val
, addr
);
423 rp
= (volatile unsigned long *) COMEM_BASE
;
424 sp
= (volatile unsigned short *) COMEM_BASE
;
425 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IOWR
| COMEM_DA_ADDR(addr
);
426 addr
= (addr
& ~0x3) + (~addr
& 0x02);
428 val
= ((val
& 0xff) << 8) | ((val
>> 8) & 0xff);
429 sp
[WREG(COMEM_PCIBUS
+ COMEM_DA_OFFSET(addr
))] = val
;
432 /*****************************************************************************/
434 void pci_outl(unsigned int val
, unsigned int addr
)
436 volatile unsigned long *rp
;
437 volatile unsigned int *lp
;
440 printk(KERN_DEBUG
"pci_outl(val=%08x,addr=%x)\n", val
, addr
);
443 rp
= (volatile unsigned long *) COMEM_BASE
;
444 lp
= (volatile unsigned int *) COMEM_BASE
;
445 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IOWR
| COMEM_DA_ADDR(addr
);
448 val
= (val
<< 24) | ((val
& 0x0000ff00) << 8) |
449 ((val
& 0x00ff0000) >> 8) | (val
>> 24);
451 lp
[LREG(COMEM_PCIBUS
+ COMEM_DA_OFFSET(addr
))] = val
;
454 /*****************************************************************************/
456 unsigned long pci_blmask
[] = {
463 unsigned char pci_inb(unsigned int addr
)
465 volatile unsigned long *rp
;
466 volatile unsigned char *bp
;
471 printk(KERN_DEBUG
"pci_inb(addr=%x)\n", addr
);
474 rp
= (volatile unsigned long *) COMEM_BASE
;
475 bp
= (volatile unsigned char *) COMEM_BASE
;
477 r
= COMEM_DA_IORD
| COMEM_DA_ADDR(addr
) | pci_blmask
[(addr
& 0x3)];
478 rp
[LREG(COMEM_DAHBASE
)] = r
;
480 addr
= (addr
& ~0x3) + (~addr
& 0x3);
481 val
= bp
[(COMEM_PCIBUS
+ COMEM_DA_OFFSET(addr
))];
485 /*****************************************************************************/
487 unsigned long pci_bwmask
[] = {
494 unsigned short pci_inw(unsigned int addr
)
496 volatile unsigned long *rp
;
497 volatile unsigned short *sp
;
502 printk(KERN_DEBUG
"pci_inw(addr=%x)", addr
);
505 rp
= (volatile unsigned long *) COMEM_BASE
;
506 r
= COMEM_DA_IORD
| COMEM_DA_ADDR(addr
) | pci_bwmask
[(addr
& 0x3)];
507 rp
[LREG(COMEM_DAHBASE
)] = r
;
509 sp
= (volatile unsigned short *) COMEM_BASE
;
510 addr
= (addr
& ~0x3) + (~addr
& 0x02);
511 val
= sp
[WREG(COMEM_PCIBUS
+ COMEM_DA_OFFSET(addr
))];
513 val
= ((val
& 0xff) << 8) | ((val
>> 8) & 0xff);
515 printk(KERN_DEBUG
"=%04x\n", val
);
520 /*****************************************************************************/
522 unsigned int pci_inl(unsigned int addr
)
524 volatile unsigned long *rp
;
525 volatile unsigned int *lp
;
529 printk(KERN_DEBUG
"pci_inl(addr=%x)", addr
);
532 rp
= (volatile unsigned long *) COMEM_BASE
;
533 lp
= (volatile unsigned int *) COMEM_BASE
;
534 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IORD
| COMEM_DA_ADDR(addr
);
535 val
= lp
[LREG(COMEM_PCIBUS
+ COMEM_DA_OFFSET(addr
))];
538 val
= (val
<< 24) | ((val
& 0x0000ff00) << 8) |
539 ((val
& 0x00ff0000) >> 8) | (val
>> 24);
542 printk(KERN_DEBUG
"=%08x\n", val
);
547 /*****************************************************************************/
549 void pci_outsb(void *addr
, void *buf
, int len
)
551 volatile unsigned long *rp
;
552 volatile unsigned char *bp
;
553 unsigned char *dp
= (unsigned char *) buf
;
554 unsigned int a
= (unsigned int) addr
;
557 printk(KERN_DEBUG
"pci_outsb(addr=%x,buf=%x,len=%d)\n", (int)addr
, (int)buf
, len
);
560 rp
= (volatile unsigned long *) COMEM_BASE
;
561 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IOWR
| COMEM_DA_ADDR(a
);
563 a
= (a
& ~0x3) + (~a
& 0x03);
564 bp
= (volatile unsigned char *)
565 (COMEM_BASE
+ COMEM_PCIBUS
+ COMEM_DA_OFFSET(a
));
571 /*****************************************************************************/
573 void pci_outsw(void *addr
, void *buf
, int len
)
575 volatile unsigned long *rp
;
576 volatile unsigned short *wp
;
577 unsigned short w
, *dp
= (unsigned short *) buf
;
578 unsigned int a
= (unsigned int) addr
;
581 printk(KERN_DEBUG
"pci_outsw(addr=%x,buf=%x,len=%d)\n", (int)addr
, (int)buf
, len
);
584 rp
= (volatile unsigned long *) COMEM_BASE
;
585 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IOWR
| COMEM_DA_ADDR(a
);
587 a
= (a
& ~0x3) + (~a
& 0x2);
588 wp
= (volatile unsigned short *)
589 (COMEM_BASE
+ COMEM_PCIBUS
+ COMEM_DA_OFFSET(a
));
594 w
= ((w
& 0xff) << 8) | ((w
>> 8) & 0xff);
599 /*****************************************************************************/
601 void pci_outsl(void *addr
, void *buf
, int len
)
603 volatile unsigned long *rp
;
604 volatile unsigned long *lp
;
605 unsigned long l
, *dp
= (unsigned long *) buf
;
606 unsigned int a
= (unsigned int) addr
;
609 printk(KERN_DEBUG
"pci_outsl(addr=%x,buf=%x,len=%d)\n", (int)addr
, (int)buf
, len
);
612 rp
= (volatile unsigned long *) COMEM_BASE
;
613 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IOWR
| COMEM_DA_ADDR(a
);
615 lp
= (volatile unsigned long *)
616 (COMEM_BASE
+ COMEM_PCIBUS
+ COMEM_DA_OFFSET(a
));
621 l
= (l
<< 24) | ((l
& 0x0000ff00) << 8) |
622 ((l
& 0x00ff0000) >> 8) | (l
>> 24);
627 /*****************************************************************************/
629 void pci_insb(void *addr
, void *buf
, int len
)
631 volatile unsigned long *rp
;
632 volatile unsigned char *bp
;
633 unsigned char *dp
= (unsigned char *) buf
;
634 unsigned int a
= (unsigned int) addr
;
637 printk(KERN_DEBUG
"pci_insb(addr=%x,buf=%x,len=%d)\n", (int)addr
, (int)buf
, len
);
640 rp
= (volatile unsigned long *) COMEM_BASE
;
641 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IORD
| COMEM_DA_ADDR(a
);
643 a
= (a
& ~0x3) + (~a
& 0x03);
644 bp
= (volatile unsigned char *)
645 (COMEM_BASE
+ COMEM_PCIBUS
+ COMEM_DA_OFFSET(a
));
651 /*****************************************************************************/
653 void pci_insw(void *addr
, void *buf
, int len
)
655 volatile unsigned long *rp
;
656 volatile unsigned short *wp
;
657 unsigned short w
, *dp
= (unsigned short *) buf
;
658 unsigned int a
= (unsigned int) addr
;
661 printk(KERN_DEBUG
"pci_insw(addr=%x,buf=%x,len=%d)\n", (int)addr
, (int)buf
, len
);
664 rp
= (volatile unsigned long *) COMEM_BASE
;
665 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IORD
| COMEM_DA_ADDR(a
);
667 a
= (a
& ~0x3) + (~a
& 0x2);
668 wp
= (volatile unsigned short *)
669 (COMEM_BASE
+ COMEM_PCIBUS
+ COMEM_DA_OFFSET(a
));
674 w
= ((w
& 0xff) << 8) | ((w
>> 8) & 0xff);
679 /*****************************************************************************/
681 void pci_insl(void *addr
, void *buf
, int len
)
683 volatile unsigned long *rp
;
684 volatile unsigned long *lp
;
685 unsigned long l
, *dp
= (unsigned long *) buf
;
686 unsigned int a
= (unsigned int) addr
;
689 printk(KERN_DEBUG
"pci_insl(addr=%x,buf=%x,len=%d)\n", (int)addr
, (int)buf
, len
);
692 rp
= (volatile unsigned long *) COMEM_BASE
;
693 rp
[LREG(COMEM_DAHBASE
)] = COMEM_DA_IORD
| COMEM_DA_ADDR(a
);
695 lp
= (volatile unsigned long *)
696 (COMEM_BASE
+ COMEM_PCIBUS
+ COMEM_DA_OFFSET(a
));
701 l
= (l
<< 24) | ((l
& 0x0000ff00) << 8) |
702 ((l
& 0x00ff0000) >> 8) | (l
>> 24);
707 /*****************************************************************************/
709 struct pci_localirqlist
{
710 void (*handler
)(int, void *, struct pt_regs
*);
715 struct pci_localirqlist pci_irqlist
[COMEM_MAXPCI
];
717 /*****************************************************************************/
719 int pci_request_irq(unsigned int irq
,
720 void (*handler
)(int, void *, struct pt_regs
*),
721 unsigned long flags
, const char *device
, void *dev_id
)
726 printk(KERN_DEBUG
"pci_request_irq(irq=%d,handler=%x,flags=%x,device=%s,"
727 "dev_id=%x)\n", irq
, (int) handler
, (int) flags
, device
,
731 /* Check if this interrupt handler is already lodged */
732 for (i
= 0; (i
< COMEM_MAXPCI
); i
++) {
733 if (pci_irqlist
[i
].handler
== handler
)
737 /* Find a free spot to put this handler */
738 for (i
= 0; (i
< COMEM_MAXPCI
); i
++) {
739 if (pci_irqlist
[i
].handler
== 0) {
740 pci_irqlist
[i
].handler
= handler
;
741 pci_irqlist
[i
].device
= device
;
742 pci_irqlist
[i
].dev_id
= dev_id
;
751 /*****************************************************************************/
753 void pci_free_irq(unsigned int irq
, void *dev_id
)
758 printk(KERN_DEBUG
"pci_free_irq(irq=%d,dev_id=%x)\n", irq
, (int) dev_id
);
761 if (dev_id
== (void *) NULL
)
764 /* Check if this interrupt handler is lodged */
765 for (i
= 0; (i
< COMEM_MAXPCI
); i
++) {
766 if (pci_irqlist
[i
].dev_id
== dev_id
) {
767 pci_irqlist
[i
].handler
= NULL
;
768 pci_irqlist
[i
].device
= NULL
;
769 pci_irqlist
[i
].dev_id
= NULL
;
775 /*****************************************************************************/
777 void pci_interrupt(int irq
, void *id
, struct pt_regs
*fp
)
782 printk(KERN_DEBUG
"pci_interrupt(irq=%d,id=%x,fp=%x)\n", irq
, (int) id
, (int) fp
);
785 for (i
= 0; (i
< COMEM_MAXPCI
); i
++) {
786 if (pci_irqlist
[i
].handler
)
787 (*pci_irqlist
[i
].handler
)(irq
,pci_irqlist
[i
].dev_id
,fp
);
791 /*****************************************************************************/
794 * The shared memory region is broken up into contiguous 512 byte
795 * regions for easy allocation... This is not an optimal solution
796 * but it makes allocation and freeing regions really easy.
799 #define PCI_MEMSLOTSIZE 512
800 #define PCI_MEMSLOTS (COMEM_SHMEMSIZE / PCI_MEMSLOTSIZE)
802 char pci_shmemmap
[PCI_MEMSLOTS
];
805 void *pci_bmalloc(int size
)
810 printk(KERN_DEBUG
"pci_bmalloc(size=%d)\n", size
);
814 return((void *) NULL
);
816 nrslots
= (size
- 1) / PCI_MEMSLOTSIZE
;
818 for (i
= 0; (i
< (PCI_MEMSLOTS
-nrslots
)); i
++) {
819 if (pci_shmemmap
[i
] == 0) {
820 for (j
= i
+1; (j
< (i
+nrslots
)); j
++) {
825 for (j
= i
; (j
<= i
+nrslots
); j
++)
832 return((void *) (COMEM_BASE
+ COMEM_SHMEM
+ (i
* PCI_MEMSLOTSIZE
)));
835 /*****************************************************************************/
837 void pci_bmfree(void *mp
, int size
)
842 printk(KERN_DEBUG
"pci_bmfree(mp=%x,size=%d)\n", (int) mp
, size
);
845 nrslots
= size
/ PCI_MEMSLOTSIZE
;
846 i
= (((unsigned long) mp
) - (COMEM_BASE
+ COMEM_SHMEM
)) /
849 for (j
= i
; (j
< (i
+nrslots
)); j
++)
853 /*****************************************************************************/
855 unsigned long pci_virt_to_bus(volatile void *address
)
860 printk(KERN_DEBUG
"pci_virt_to_bus(address=%x)", (int) address
);
863 l
= ((unsigned long) address
) - COMEM_BASE
;
865 printk(KERN_DEBUG
"=%x\n", (int) (l
+pci_shmemaddr
));
867 return(l
+ pci_shmemaddr
);
870 /*****************************************************************************/
872 void *pci_bus_to_virt(unsigned long address
)
877 printk(KERN_DEBUG
"pci_bus_to_virt(address=%x)", (int) address
);
880 l
= address
- pci_shmemaddr
;
882 printk(KERN_DEBUG
"=%x\n", (int) (address
+ COMEM_BASE
));
884 return((void *) (address
+ COMEM_BASE
));
887 /*****************************************************************************/
889 void pci_bmcpyto(void *dst
, void *src
, int len
)
891 unsigned long *dp
, *sp
, val
;
892 unsigned char *dcp
, *scp
;
896 printk(KERN_DEBUG
"pci_bmcpyto(dst=%x,src=%x,len=%d)\n", (int)dst
, (int)src
, len
);
899 dp
= (unsigned long *) dst
;
900 sp
= (unsigned long *) src
;
904 printk(KERN_INFO
"DATA:");
905 scp
= (unsigned char *) sp
;
906 for (i
= 0; (i
< len
); i
++) {
907 if ((i
% 16) == 0) printk(KERN_INFO
"\n%04x: ", i
);
908 printk(KERN_INFO
"%02x ", *scp
++);
910 printk(KERN_INFO
"\n");
913 for (j
= 0; (i
>= 0); i
--, j
++) {
915 val
= (val
<< 24) | ((val
& 0x0000ff00) << 8) |
916 ((val
& 0x00ff0000) >> 8) | (val
>> 24);
921 dcp
= (unsigned char *) dp
;
922 scp
= ((unsigned char *) sp
) + 3;
923 for (i
= 0; (i
< (len
& 0x3)); i
++)
928 /*****************************************************************************/
930 void pci_bmcpyfrom(void *dst
, void *src
, int len
)
932 unsigned long *dp
, *sp
, val
;
933 unsigned char *dcp
, *scp
;
937 printk(KERN_DEBUG
"pci_bmcpyfrom(dst=%x,src=%x,len=%d)\n",(int)dst
,(int)src
,len
);
940 dp
= (unsigned long *) dst
;
941 sp
= (unsigned long *) src
;
944 for (; (i
>= 0); i
--) {
946 val
= (val
<< 24) | ((val
& 0x0000ff00) << 8) |
947 ((val
& 0x00ff0000) >> 8) | (val
>> 24);
952 dcp
= ((unsigned char *) dp
) + 3;
953 scp
= (unsigned char *) sp
;
954 for (i
= 0; (i
< (len
& 0x3)); i
++)
959 printk(KERN_INFO
"DATA:");
960 dcp
= (unsigned char *) dst
;
961 for (i
= 0; (i
< len
); i
++) {
962 if ((i
% 16) == 0) printk(KERN_INFO
"\n%04x: ", i
);
963 printk(KERN_INFO
"%02x ", *dcp
++);
965 printk(KERN_INFO
"\n");
969 /*****************************************************************************/
971 void *pci_alloc_consistent(struct pci_dev
*dev
, size_t size
, dma_addr_t
*dma_addr
)
974 if ((mp
= pci_bmalloc(size
)) != NULL
) {
975 dma_addr
= mp
- (COMEM_BASE
+ COMEM_SHMEM
);
978 *dma_addr
= (dma_addr_t
) NULL
;
982 /*****************************************************************************/
984 void pci_free_consistent(struct pci_dev
*dev
, size_t size
, void *cpu_addr
, dma_addr_t dma_addr
)
986 pci_bmfree(cpu_addr
, size
);
989 /*****************************************************************************/