1 /* $NetBSD: pci_axppci_33.c,v 1.28 2002/05/15 16:57:42 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 5 * All rights reserved. 6 * 7 * Authors: Jeffrey Hsu and Chris G. Demetriou 8 * 9 * Permission to use, copy, modify and distribute this software and 10 * its documentation is hereby granted, provided that both the copyright 11 * notice and this permission notice appear in all copies of the 12 * software, derivative works or modified versions, and any portions 13 * thereof, and that both notices appear in supporting documentation. 14 * 15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 * 19 * Carnegie Mellon requests users of this software to return to 20 * 21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22 * School of Computer Science 23 * Carnegie Mellon University 24 * Pittsburgh PA 15213-3890 25 * 26 * any improvements or extensions that they make and grant Carnegie the 27 * rights to redistribute these changes. 28 */ 29 30 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 31 32 __KERNEL_RCSID(0, "$NetBSD: pci_axppci_33.c,v 1.28 2002/05/15 16:57:42 thorpej Exp $"); 33 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/time.h> 37 #include <sys/systm.h> 38 #include <sys/errno.h> 39 #include <sys/device.h> 40 41 #include <uvm/uvm_extern.h> 42 43 #include <machine/autoconf.h> 44 #include <machine/bus.h> 45 #include <machine/intr.h> 46 47 #include <dev/isa/isavar.h> 48 #include <dev/pci/pcireg.h> 49 #include <dev/pci/pcivar.h> 50 51 #include <alpha/pci/lcavar.h> 52 53 #include <alpha/pci/pci_axppci_33.h> 54 #include <alpha/pci/siovar.h> 55 #include <alpha/pci/sioreg.h> 56 57 #include "sio.h" 58 59 int dec_axppci_33_intr_map __P((struct pci_attach_args *, pci_intr_handle_t *)); 60 const char *dec_axppci_33_intr_string __P((void *, pci_intr_handle_t)); 61 const struct evcnt *dec_axppci_33_intr_evcnt __P((void *, pci_intr_handle_t)); 62 void *dec_axppci_33_intr_establish __P((void *, pci_intr_handle_t, 63 int, int (*func)(void *), void *)); 64 void dec_axppci_33_intr_disestablish __P((void *, void *)); 65 66 #define LCA_SIO_DEVICE 7 /* XXX */ 67 68 void 69 pci_axppci_33_pickintr(lcp) 70 struct lca_config *lcp; 71 { 72 bus_space_tag_t iot = &lcp->lc_iot; 73 pci_chipset_tag_t pc = &lcp->lc_pc; 74 pcireg_t sioclass; 75 int sioII; 76 77 /* XXX MAGIC NUMBER */ 78 sioclass = pci_conf_read(pc, pci_make_tag(pc, 0, LCA_SIO_DEVICE, 0), 79 PCI_CLASS_REG); 80 sioII = (sioclass & 0xff) >= 3; 81 82 if (!sioII) 83 printf("WARNING: SIO NOT SIO II... NO BETS...\n"); 84 85 pc->pc_intr_v = lcp; 86 pc->pc_intr_map = dec_axppci_33_intr_map; 87 pc->pc_intr_string = dec_axppci_33_intr_string; 88 pc->pc_intr_evcnt = dec_axppci_33_intr_evcnt; 89 pc->pc_intr_establish = dec_axppci_33_intr_establish; 90 pc->pc_intr_disestablish = dec_axppci_33_intr_disestablish; 91 92 /* Not supported on AXPpci33. */ 93 pc->pc_pciide_compat_intr_establish = NULL; 94 95 #if NSIO 96 sio_intr_setup(pc, iot); 97 #else 98 panic("pci_axppci_33_pickintr: no I/O interrupt handler (no sio)"); 99 #endif 100 } 101 102 int 103 dec_axppci_33_intr_map(pa, ihp) 104 struct pci_attach_args *pa; 105 pci_intr_handle_t *ihp; 106 { 107 pcitag_t bustag = pa->pa_intrtag; 108 int buspin = pa->pa_intrpin; 109 pci_chipset_tag_t pc = pa->pa_pc; 110 int device, pirq; 111 pcireg_t pirqreg; 112 u_int8_t pirqline; 113 114 #ifndef DIAGNOSTIC 115 pirq = 0; /* XXX gcc -Wuninitialized */ 116 #endif 117 118 if (buspin == 0) { 119 /* No IRQ used. */ 120 return 1; 121 } 122 if (buspin > 4) { 123 printf("dec_axppci_33_intr_map: bad interrupt pin %d\n", 124 buspin); 125 return 1; 126 } 127 128 pci_decompose_tag(pc, bustag, NULL, &device, NULL); 129 130 switch (device) { 131 case 6: /* NCR SCSI */ 132 pirq = 3; 133 break; 134 135 case 11: /* slot 1 */ 136 switch (buspin) { 137 case PCI_INTERRUPT_PIN_A: 138 case PCI_INTERRUPT_PIN_D: 139 pirq = 0; 140 break; 141 case PCI_INTERRUPT_PIN_B: 142 pirq = 2; 143 break; 144 case PCI_INTERRUPT_PIN_C: 145 pirq = 1; 146 break; 147 #ifdef DIAGNOSTIC 148 default: /* XXX gcc -Wuninitialized */ 149 panic("dec_axppci_33_intr_map: bogus PCI pin %d\n", 150 buspin); 151 #endif 152 }; 153 break; 154 155 case 12: /* slot 2 */ 156 switch (buspin) { 157 case PCI_INTERRUPT_PIN_A: 158 case PCI_INTERRUPT_PIN_D: 159 pirq = 1; 160 break; 161 case PCI_INTERRUPT_PIN_B: 162 pirq = 0; 163 break; 164 case PCI_INTERRUPT_PIN_C: 165 pirq = 2; 166 break; 167 #ifdef DIAGNOSTIC 168 default: /* XXX gcc -Wuninitialized */ 169 panic("dec_axppci_33_intr_map: bogus PCI pin %d\n", 170 buspin); 171 #endif 172 }; 173 break; 174 175 case 8: /* slot 3 */ 176 switch (buspin) { 177 case PCI_INTERRUPT_PIN_A: 178 case PCI_INTERRUPT_PIN_D: 179 pirq = 2; 180 break; 181 case PCI_INTERRUPT_PIN_B: 182 pirq = 1; 183 break; 184 case PCI_INTERRUPT_PIN_C: 185 pirq = 0; 186 break; 187 #ifdef DIAGNOSTIC 188 default: /* XXX gcc -Wuninitialized */ 189 panic("dec_axppci_33_intr_map bogus: PCI pin %d\n", 190 buspin); 191 #endif 192 }; 193 break; 194 195 default: 196 printf("dec_axppci_33_intr_map: weird device number %d\n", 197 device); 198 return 1; 199 } 200 201 pirqreg = pci_conf_read(pc, pci_make_tag(pc, 0, LCA_SIO_DEVICE, 0), 202 SIO_PCIREG_PIRQ_RTCTRL); 203 #if 0 204 printf("dec_axppci_33_intr_map: device %d pin %c: pirq %d, reg = %x\n", 205 device, '@' + buspin, pirq, pirqreg); 206 #endif 207 pirqline = (pirqreg >> (pirq * 8)) & 0xff; 208 if ((pirqline & 0x80) != 0) 209 return 1; /* not routed? */ 210 pirqline &= 0xf; 211 212 #if 0 213 printf("dec_axppci_33_intr_map: device %d pin %c: mapped to line %d\n", 214 device, '@' + buspin, pirqline); 215 #endif 216 217 *ihp = pirqline; 218 return (0); 219 } 220 221 const char * 222 dec_axppci_33_intr_string(lcv, ih) 223 void *lcv; 224 pci_intr_handle_t ih; 225 { 226 #if 0 227 struct lca_config *lcp = lcv; 228 #endif 229 230 return sio_intr_string(NULL /*XXX*/, ih); 231 } 232 233 const struct evcnt * 234 dec_axppci_33_intr_evcnt(lcv, ih) 235 void *lcv; 236 pci_intr_handle_t ih; 237 { 238 #if 0 239 struct lca_config *lcp = lcv; 240 #endif 241 242 return sio_intr_evcnt(NULL /*XXX*/, ih); 243 } 244 245 void * 246 dec_axppci_33_intr_establish(lcv, ih, level, func, arg) 247 void *lcv, *arg; 248 pci_intr_handle_t ih; 249 int level; 250 int (*func) __P((void *)); 251 { 252 #if 0 253 struct lca_config *lcp = lcv; 254 #endif 255 256 return sio_intr_establish(NULL /*XXX*/, ih, IST_LEVEL, level, func, 257 arg); 258 } 259 260 void 261 dec_axppci_33_intr_disestablish(lcv, cookie) 262 void *lcv, *cookie; 263 { 264 #if 0 265 struct lca_config *lcp = lcv; 266 #endif 267 268 sio_intr_disestablish(NULL /*XXX*/, cookie); 269 } 270