1 /* $NetBSD: pci_axppci_33.c,v 1.39 2020/09/22 15:24:02 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.39 2020/09/22 15:24:02 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 <machine/autoconf.h> 42 #include <sys/bus.h> 43 #include <machine/intr.h> 44 45 #include <dev/isa/isavar.h> 46 #include <dev/pci/pcireg.h> 47 #include <dev/pci/pcivar.h> 48 49 #include <alpha/pci/lcavar.h> 50 51 #include <alpha/pci/pci_axppci_33.h> 52 #include <alpha/pci/siovar.h> 53 #include <alpha/pci/sioreg.h> 54 55 #include "sio.h" 56 57 static int dec_axppci_33_intr_map(const struct pci_attach_args *, 58 pci_intr_handle_t *); 59 60 #define LCA_SIO_DEVICE 7 /* XXX */ 61 62 void 63 pci_axppci_33_pickintr(struct lca_config *lcp) 64 { 65 bus_space_tag_t iot = &lcp->lc_iot; 66 pci_chipset_tag_t pc = &lcp->lc_pc; 67 pcireg_t sioclass; 68 int sioII; 69 70 /* XXX MAGIC NUMBER */ 71 sioclass = pci_conf_read(pc, pci_make_tag(pc, 0, LCA_SIO_DEVICE, 0), 72 PCI_CLASS_REG); 73 sioII = (sioclass & 0xff) >= 3; 74 75 if (!sioII) 76 printf("WARNING: SIO NOT SIO II... NO BETS...\n"); 77 78 pc->pc_intr_v = lcp; 79 pc->pc_intr_map = dec_axppci_33_intr_map; 80 pc->pc_intr_string = sio_pci_intr_string; 81 pc->pc_intr_evcnt = sio_pci_intr_evcnt; 82 pc->pc_intr_establish = sio_pci_intr_establish; 83 pc->pc_intr_disestablish = sio_pci_intr_disestablish; 84 85 /* Not supported on AXPpci33. */ 86 pc->pc_pciide_compat_intr_establish = NULL; 87 88 #if NSIO 89 sio_intr_setup(pc, iot); 90 #else 91 panic("pci_axppci_33_pickintr: no I/O interrupt handler (no sio)"); 92 #endif 93 } 94 95 int 96 dec_axppci_33_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp) 97 { 98 pcitag_t bustag = pa->pa_intrtag; 99 int buspin = pa->pa_intrpin; 100 pci_chipset_tag_t pc = pa->pa_pc; 101 int device, pirq; 102 pcireg_t pirqreg; 103 uint8_t pirqline; 104 105 #ifndef DIAGNOSTIC 106 pirq = 0; /* XXX gcc -Wuninitialized */ 107 #endif 108 109 if (buspin == 0) { 110 /* No IRQ used. */ 111 return 1; 112 } 113 if (buspin < 0 || buspin > 4) { 114 printf("dec_axppci_33_intr_map: bad interrupt pin %d\n", 115 buspin); 116 return 1; 117 } 118 119 pci_decompose_tag(pc, bustag, NULL, &device, NULL); 120 121 switch (device) { 122 case 6: /* NCR SCSI */ 123 pirq = 3; 124 break; 125 126 case 11: /* slot 1 */ 127 switch (buspin) { 128 case PCI_INTERRUPT_PIN_A: 129 case PCI_INTERRUPT_PIN_D: 130 pirq = 0; 131 break; 132 case PCI_INTERRUPT_PIN_B: 133 pirq = 2; 134 break; 135 case PCI_INTERRUPT_PIN_C: 136 pirq = 1; 137 break; 138 #ifdef DIAGNOSTIC 139 default: /* XXX gcc -Wuninitialized */ 140 panic("dec_axppci_33_intr_map: bogus PCI pin %d", 141 buspin); 142 #endif 143 }; 144 break; 145 146 case 12: /* slot 2 */ 147 switch (buspin) { 148 case PCI_INTERRUPT_PIN_A: 149 case PCI_INTERRUPT_PIN_D: 150 pirq = 1; 151 break; 152 case PCI_INTERRUPT_PIN_B: 153 pirq = 0; 154 break; 155 case PCI_INTERRUPT_PIN_C: 156 pirq = 2; 157 break; 158 #ifdef DIAGNOSTIC 159 default: /* XXX gcc -Wuninitialized */ 160 panic("dec_axppci_33_intr_map: bogus PCI pin %d", 161 buspin); 162 #endif 163 }; 164 break; 165 166 case 8: /* slot 3 */ 167 switch (buspin) { 168 case PCI_INTERRUPT_PIN_A: 169 case PCI_INTERRUPT_PIN_D: 170 pirq = 2; 171 break; 172 case PCI_INTERRUPT_PIN_B: 173 pirq = 1; 174 break; 175 case PCI_INTERRUPT_PIN_C: 176 pirq = 0; 177 break; 178 #ifdef DIAGNOSTIC 179 default: /* XXX gcc -Wuninitialized */ 180 panic("dec_axppci_33_intr_map bogus: PCI pin %d", 181 buspin); 182 #endif 183 }; 184 break; 185 186 default: 187 printf("dec_axppci_33_intr_map: weird device number %d\n", 188 device); 189 return 1; 190 } 191 192 pirqreg = pci_conf_read(pc, pci_make_tag(pc, 0, LCA_SIO_DEVICE, 0), 193 SIO_PCIREG_PIRQ_RTCTRL); 194 #if 0 195 printf("dec_axppci_33_intr_map: device %d pin %c: pirq %d, reg = %x\n", 196 device, '@' + buspin, pirq, pirqreg); 197 #endif 198 pirqline = (pirqreg >> (pirq * 8)) & 0xff; 199 if ((pirqline & 0x80) != 0) 200 return 1; /* not routed? */ 201 pirqline &= 0xf; 202 203 #if 0 204 printf("dec_axppci_33_intr_map: device %d pin %c: mapped to line %d\n", 205 device, '@' + buspin, pirqline); 206 #endif 207 208 alpha_pci_intr_handle_init(ihp, pirqline, 0); 209 return (0); 210 } 211