xref: /illumos-gate/usr/src/uts/i86pc/os/pci_mech1.c (revision 5661bb7641e85c46713da7a3002b29ecd2c3daf0)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * PCI Mechanism 1 low-level routines
31  */
32 
33 #include <sys/types.h>
34 #include <sys/pci.h>
35 #include <sys/pci_impl.h>
36 #include <sys/sunddi.h>
37 #include <sys/pci_cfgspace_impl.h>
38 
39 /*
40  * Per PCI 2.1 section 3.7.4.1 and PCI-PCI Bridge Architecture 1.0 section
41  * 5.3.1.2:  dev=31 func=7 reg=0 means a special cycle.  We don't want to
42  * trigger that by accident, so we pretend that dev 31, func 7 doesn't
43  * exist.  If we ever want special cycle support, we'll add explicit
44  * special cycle support.
45  */
46 
47 uint8_t
48 pci_mech1_getb(int bus, int device, int function, int reg)
49 {
50 	uint8_t val;
51 	if (device == PCI_MECH1_SPEC_CYCLE_DEV &&
52 	    function == PCI_MECH1_SPEC_CYCLE_FUNC) {
53 		return (0xff);
54 	}
55 
56 	mutex_enter(&pcicfg_mutex);
57 	outl(PCI_CONFADD, PCI_CADDR1(bus, device, function, reg));
58 	val = inb(PCI_CONFDATA | (reg & 0x3));
59 	mutex_exit(&pcicfg_mutex);
60 	return (val);
61 }
62 
63 uint16_t
64 pci_mech1_getw(int bus, int device, int function, int reg)
65 {
66 	uint16_t val;
67 
68 	if (device == PCI_MECH1_SPEC_CYCLE_DEV &&
69 	    function == PCI_MECH1_SPEC_CYCLE_FUNC) {
70 		return (0xffff);
71 	}
72 
73 	mutex_enter(&pcicfg_mutex);
74 	outl(PCI_CONFADD, PCI_CADDR1(bus, device, function, reg));
75 	val =  inw(PCI_CONFDATA | (reg & 0x2));
76 	mutex_exit(&pcicfg_mutex);
77 	return (val);
78 }
79 
80 uint32_t
81 pci_mech1_getl(int bus, int device, int function, int reg)
82 {
83 	uint32_t val;
84 
85 	if (device == PCI_MECH1_SPEC_CYCLE_DEV &&
86 	    function == PCI_MECH1_SPEC_CYCLE_FUNC) {
87 		return (0xffffffffu);
88 	}
89 
90 	mutex_enter(&pcicfg_mutex);
91 	outl(PCI_CONFADD, PCI_CADDR1(bus, device, function, reg));
92 	val = inl(PCI_CONFDATA);
93 	mutex_exit(&pcicfg_mutex);
94 	return (val);
95 }
96 
97 void
98 pci_mech1_putb(int bus, int device, int function, int reg, uint8_t val)
99 {
100 	if (device == PCI_MECH1_SPEC_CYCLE_DEV &&
101 	    function == PCI_MECH1_SPEC_CYCLE_FUNC) {
102 		return;
103 	}
104 
105 	mutex_enter(&pcicfg_mutex);
106 	outl(PCI_CONFADD, PCI_CADDR1(bus, device, function, reg));
107 	outb(PCI_CONFDATA | (reg & 0x3), val);
108 	mutex_exit(&pcicfg_mutex);
109 }
110 
111 void
112 pci_mech1_putw(int bus, int device, int function, int reg, uint16_t val)
113 {
114 	if (device == PCI_MECH1_SPEC_CYCLE_DEV &&
115 	    function == PCI_MECH1_SPEC_CYCLE_FUNC) {
116 		return;
117 	}
118 
119 	mutex_enter(&pcicfg_mutex);
120 	outl(PCI_CONFADD, PCI_CADDR1(bus, device, function, reg));
121 	outw(PCI_CONFDATA | (reg & 0x2), val);
122 	mutex_exit(&pcicfg_mutex);
123 }
124 
125 void
126 pci_mech1_putl(int bus, int device, int function, int reg, uint32_t val)
127 {
128 	if (device == PCI_MECH1_SPEC_CYCLE_DEV &&
129 	    function == PCI_MECH1_SPEC_CYCLE_FUNC) {
130 		return;
131 	}
132 
133 	mutex_enter(&pcicfg_mutex);
134 	outl(PCI_CONFADD, PCI_CADDR1(bus, device, function, reg));
135 	outl(PCI_CONFDATA, val);
136 	mutex_exit(&pcicfg_mutex);
137 }
138