dpt_eisa.c revision 119418
1/*- 2 * Copyright (c) 1997, 2000 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 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD: head/sys/dev/dpt/dpt_eisa.c 119418 2003-08-24 17:55:58Z obrien $"); 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/module.h> 35#include <sys/lock.h> 36#include <sys/mutex.h> 37#include <sys/bus.h> 38 39#include <machine/bus_pio.h> 40#include <machine/bus.h> 41#include <machine/resource.h> 42#include <sys/rman.h> 43 44#include <dev/eisa/eisaconf.h> 45 46#include <cam/scsi/scsi_all.h> 47 48#include <dev/dpt/dpt.h> 49 50#define DPT_EISA_IOSIZE 0x9 51#define DPT_EISA_SLOT_OFFSET 0x0c00 52#define DPT_EISA_EATA_REG_OFFSET 0x0088 53 54#define DPT_EISA_DPT2402 0x12142402 /* DPT PM2012A/9X */ 55#define DPT_EISA_DPTA401 0x1214A401 /* DPT PM2012B/9X */ 56#define DPT_EISA_DPTA402 0x1214A402 /* DPT PM2012B2/9X */ 57#define DPT_EISA_DPTA410 0x1214A410 /* DPT PM2x22A/9X */ 58#define DPT_EISA_DPTA411 0x1214A411 /* DPT Spectre */ 59#define DPT_EISA_DPTA412 0x1214A412 /* DPT PM2021A/9X */ 60#define DPT_EISA_DPTA420 0x1214A420 /* DPT Smart Cache IV (PM2042) */ 61#define DPT_EISA_DPTA501 0x1214A501 /* DPT PM2012B1/9X" */ 62#define DPT_EISA_DPTA502 0x1214A502 /* DPT PM2012Bx/9X */ 63#define DPT_EISA_DPTA701 0x1214A701 /* DPT PM2011B1/9X */ 64#define DPT_EISA_DPTBC01 0x1214BC01 /* DPT PM3011/7X ESDI */ 65#define DPT_EISA_DPT8200 0x12148200 /* NEC EATA SCSI */ 66#define DPT_EISA_DPT2408 0x12142408 /* ATT EATA SCSI */ 67 68/* Function Prototypes */ 69 70static const char * dpt_eisa_match (eisa_id_t); 71static int dpt_eisa_probe (device_t); 72static int dpt_eisa_attach (device_t); 73 74static int 75dpt_eisa_probe (device_t dev) 76{ 77 const char * desc; 78 u_int32_t io_base; 79 dpt_conf_t * conf; 80 81 desc = dpt_eisa_match(eisa_get_id(dev)); 82 if (!desc) 83 return (ENXIO); 84 device_set_desc(dev, desc); 85 86 io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + 87 DPT_EISA_SLOT_OFFSET + 88 DPT_EISA_EATA_REG_OFFSET; 89 90 conf = dpt_pio_get_conf(io_base); 91 if (!conf) { 92 printf("dpt: dpt_pio_get_conf() failed.\n"); 93 return (ENXIO); 94 } 95 96 eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE); 97 eisa_add_intr(dev, conf->IRQ, 98 (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE)); 99 100 return 0; 101} 102 103static int 104dpt_eisa_attach (device_t dev) 105{ 106 dpt_softc_t * dpt; 107 int s; 108 int error = 0; 109 110 dpt = device_get_softc(dev); 111 112 dpt->io_rid = 0; 113 dpt->io_type = SYS_RES_IOPORT; 114 dpt->irq_rid = 0; 115 116 error = dpt_alloc_resources(dev); 117 if (error) { 118 goto bad; 119 } 120 121 dpt_alloc(dev); 122 123 /* Allocate a dmatag representing the capabilities of this attachment */ 124 /* XXX Should be a child of the EISA bus dma tag */ 125 if (bus_dma_tag_create( /* parent */ NULL, 126 /* alignemnt */ 1, 127 /* boundary */ 0, 128 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 129 /* highaddr */ BUS_SPACE_MAXADDR, 130 /* filter */ NULL, 131 /* filterarg */ NULL, 132 /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, 133 /* nsegments */ ~0, 134 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 135 /* flags */ 0, 136 /* lockfunc */ busdma_lock_mutex, 137 /* lockarg */ &Giant, 138 &dpt->parent_dmat) != 0) { 139 error = ENXIO; 140 goto bad; 141 } 142 143 s = splcam(); 144 145 if (dpt_init(dpt) != 0) { 146 splx(s); 147 error = ENXIO; 148 goto bad; 149 } 150 151 /* Register with the XPT */ 152 dpt_attach(dpt); 153 154 splx(s); 155 156 if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, 157 dpt_intr, dpt, &dpt->ih)) { 158 device_printf(dev, "Unable to register interrupt handler\n"); 159 error = ENXIO; 160 goto bad; 161 } 162 163 return (error); 164 165 bad: 166 dpt_release_resources(dev); 167 168 if (dpt) 169 dpt_free(dpt); 170 171 return (error); 172} 173 174static const char * 175dpt_eisa_match(type) 176 eisa_id_t type; 177{ 178 switch (type) { 179 case DPT_EISA_DPT2402: 180 case DPT_EISA_DPTA401: 181 case DPT_EISA_DPTA402: 182 case DPT_EISA_DPTA410: 183 case DPT_EISA_DPTA411: 184 case DPT_EISA_DPTA412: 185 case DPT_EISA_DPTA420: 186 case DPT_EISA_DPTA501: 187 case DPT_EISA_DPTA502: 188 case DPT_EISA_DPTA701: 189 case DPT_EISA_DPTBC01: 190 case DPT_EISA_DPT8200: 191 case DPT_EISA_DPT2408: 192 return ("DPT SCSI Host Bus Adapter"); 193 break; 194 default: 195 break; 196 } 197 198 return (NULL); 199} 200 201static device_method_t dpt_eisa_methods[] = { 202 /* Device interface */ 203 DEVMETHOD(device_probe, dpt_eisa_probe), 204 DEVMETHOD(device_attach, dpt_eisa_attach), 205 DEVMETHOD(device_detach, dpt_detach), 206 207 { 0, 0 } 208}; 209 210static driver_t dpt_eisa_driver = { 211 "dpt", 212 dpt_eisa_methods, 213 sizeof(dpt_softc_t), 214}; 215 216DRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0); 217