dpt_eisa.c revision 39234
1/* 2 * Copyright (c) 1997 by Matthew N. Dodd <winter@jurai.net> 3 * All Rights Reserved 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * Credits: Based on and part of the DPT driver for FreeBSD written and 32 * maintained by Simon Shapiro <shimon@simon-shapiro.org> 33 */ 34 35/* 36 * $Id: dpt_eisa.c,v 1.3 1998/08/09 02:22:34 jkh Exp $ 37 */ 38 39#include "eisa.h" 40#if NEISA > 0 41#include "opt_dpt.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/malloc.h> 46#include <sys/buf.h> 47#include <sys/proc.h> 48#include <sys/kernel.h> 49 50#include <machine/bus_pio.h> 51#include <machine/bus.h> 52 53#include <cam/scsi/scsi_all.h> 54 55#include <dev/dpt/dpt.h> 56 57#include <i386/eisa/eisaconf.h> 58#include <i386/eisa/dpt_eisa.h> 59 60#include <machine/clock.h> 61 62#include <vm/vm.h> 63#include <vm/vm_param.h> 64#include <vm/pmap.h> 65 66/* Function Prototypes */ 67 68static int dpt_eisa_probe(void); 69static int dpt_eisa_attach(struct eisa_device*); 70 71static const char *dpt_eisa_match(eisa_id_t); 72 73static struct eisa_driver dpt_eisa_driver = 74{ 75 "dpt", 76 dpt_eisa_probe, 77 dpt_eisa_attach, 78 NULL, 79 &dpt_unit 80}; 81 82DATA_SET (eisadriver_set, dpt_eisa_driver); 83 84static int 85dpt_eisa_probe(void) 86{ 87 struct eisa_device *e_dev = NULL; 88 int count; 89 u_int32_t io_base; 90 u_int intdef; 91 u_int irq; 92 93 e_dev = NULL; 94 count = 0; 95 while ((e_dev = eisa_match_dev(e_dev, dpt_eisa_match))) { 96 io_base = (e_dev->ioconf.slot * EISA_SLOT_SIZE) 97 + DPT_EISA_SLOT_OFFSET; 98 99 eisa_add_iospace(e_dev, io_base, 100 DPT_EISA_IOSIZE, RESVADDR_NONE); 101 102 intdef = inb(DPT_EISA_INTDEF + io_base); 103 104 irq = intdef & DPT_EISA_INT_NUM_MASK; 105 switch (irq) { 106 case DPT_EISA_INT_NUM_11: 107 irq = 11; 108 break; 109 case DPT_EISA_INT_NUM_15: 110 irq = 15; 111 break; 112 case DPT_EISA_INT_NUM_14: 113 irq = 14; 114 break; 115 default: 116 printf("dpt at slot %d: illegal irq setting %d\n", 117 e_dev->ioconf.slot, irq); 118 irq = 0; 119 break; 120 } 121 if (irq == 0) 122 continue; 123 124 eisa_add_intr(e_dev, irq); 125 eisa_registerdev(e_dev, &dpt_eisa_driver); 126 count++; 127 } 128 return count; 129} 130 131int 132dpt_eisa_attach(e_dev) 133 struct eisa_device *e_dev; 134{ 135 dpt_softc_t *dpt; 136 resvaddr_t *io_space; 137 int unit = e_dev->unit; 138 int irq; 139 int shared; 140 int s; 141 142 if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL) { 143 printf("dpt%d: Can't retrieve irq from EISA config struct.\n", 144 unit); 145 return -1; 146 } 147 148 irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no; 149 io_space = e_dev->ioconf.ioaddrs.lh_first; 150 151 if (!io_space) { 152 printf("dpt%d: No I/O space?!\n", unit); 153 return -1; 154 } 155 156 shared = inb(DPT_EISA_INTDEF + io_space->addr) & DPT_EISA_INT_LEVEL; 157 158 dpt = dpt_alloc(unit, I386_BUS_SPACE_IO, 159 io_space->addr + DPT_EISA_EATA_REG_OFFSET); 160 if (dpt == NULL) 161 return -1; 162 163 /* Allocate a dmatag representing the capabilities of this attachment */ 164 /* XXX Should be a child of the EISA bus dma tag */ 165 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0, 166 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 167 /*highaddr*/BUS_SPACE_MAXADDR, 168 /*filter*/NULL, /*filterarg*/NULL, 169 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 170 /*nsegments*/BUS_SPACE_UNRESTRICTED, 171 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 172 /*flags*/0, &dpt->parent_dmat) != 0) { 173 dpt_free(dpt); 174 return -1; 175 } 176 177 if (eisa_reg_intr(e_dev, irq, dpt_intr, (void *)dpt, &cam_imask, 178 shared)) { 179 printf("dpt%d: eisa_reg_intr() failed.\n", unit); 180 dpt_free(dpt); 181 return -1; 182 } 183 eisa_reg_end(e_dev); 184 185 /* Enable our interrupt handler. */ 186 if (eisa_enable_intr(e_dev, irq)) { 187#ifdef DPT_DEBUG_ERROR 188 printf("dpt%d: eisa_enable_intr() failed.\n", unit); 189#endif 190 free(dpt, M_DEVBUF); 191 eisa_release_intr(e_dev, irq, dpt_intr); 192 return -1; 193 } 194 /* 195 * Enable our interrupt handler. 196 */ 197 if (eisa_enable_intr(e_dev, irq)) { 198 dpt_free(dpt); 199 eisa_release_intr(e_dev, irq, dpt_intr); 200 return -1; 201 } 202 203 s = splcam(); 204 if (dpt_init(dpt) != 0) { 205 dpt_free(dpt); 206 return -1; 207 } 208 209 /* Register with the XPT */ 210 dpt_attach(dpt); 211 splx(s); 212 213 return 0; 214} 215 216static const char * 217dpt_eisa_match(type) 218 eisa_id_t type; 219{ 220 switch (type) { 221 case DPT_EISA_DPT2402 : 222 return ("DPT PM2012A/9X"); 223 break; 224 case DPT_EISA_DPTA401 : 225 return ("DPT PM2012B/9X"); 226 break; 227 case DPT_EISA_DPTA402 : 228 return ("DPT PM2012B2/9X"); 229 break; 230 case DPT_EISA_DPTA410 : 231 return ("DPT PM2x22A/9X"); 232 break; 233 case DPT_EISA_DPTA411 : 234 return ("DPT Spectre"); 235 break; 236 case DPT_EISA_DPTA412 : 237 return ("DPT PM2021A/9X"); 238 break; 239 case DPT_EISA_DPTA420 : 240 return ("DPT Smart Cache IV (PM2042)"); 241 break; 242 case DPT_EISA_DPTA501 : 243 return ("DPT PM2012B1/9X"); 244 break; 245 case DPT_EISA_DPTA502 : 246 return ("DPT PM2012Bx/9X"); 247 break; 248 case DPT_EISA_DPTA701 : 249 return ("DPT PM2011B1/9X"); 250 break; 251 case DPT_EISA_DPTBC01 : 252 return ("DPT PM3011/7X ESDI"); 253 break; 254 case DPT_EISA_NEC8200 : 255 return ("NEC EATA SCSI"); 256 break; 257 case DPT_EISA_ATT2408 : 258 return ("ATT EATA SCSI"); 259 break; 260 default: 261 break; 262 } 263 264 return (NULL); 265} 266 267#endif /* NEISA > 0 */ 268