dpt_eisa.c revision 165102
1342084Smw/*- 2342084Smw * Copyright (c) 1997, 2000 Matthew N. Dodd <winter@jurai.net> 3342084Smw * All rights reserved. 4342084Smw * 5342084Smw * Redistribution and use in source and binary forms, with or without 6342084Smw * modification, are permitted provided that the following conditions 7342084Smw * are met: 8342084Smw * 1. Redistributions of source code must retain the above copyright 9342084Smw * notice, this list of conditions and the following disclaimer. 10342084Smw * 2. Redistributions in binary form must reproduce the above copyright 11342084Smw * notice, this list of conditions and the following disclaimer in the 12342084Smw * documentation and/or other materials provided with the distribution. 13342084Smw * 14342084Smw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15342084Smw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16342084Smw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17342084Smw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18342084Smw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19342084Smw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20342084Smw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21342084Smw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22342084Smw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23342084Smw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24342084Smw * SUCH DAMAGE. 25342084Smw * 26342084Smw */ 27342084Smw 28342084Smw#include <sys/cdefs.h> 29342084Smw__FBSDID("$FreeBSD: head/sys/dev/dpt/dpt_eisa.c 165102 2006-12-11 18:28:31Z mjacob $"); 30342084Smw 31342084Smw#include <sys/param.h> 32342084Smw#include <sys/systm.h> 33342084Smw#include <sys/kernel.h> 34342084Smw#include <sys/module.h> 35342084Smw#include <sys/lock.h> 36342084Smw#include <sys/mutex.h> 37342084Smw#include <sys/bus.h> 38342084Smw 39342084Smw#include <machine/bus.h> 40342084Smw#include <machine/resource.h> 41342084Smw#include <sys/rman.h> 42342084Smw 43342084Smw#include <dev/eisa/eisaconf.h> 44342084Smw 45342084Smw#include <cam/scsi/scsi_all.h> 46342084Smw 47342084Smw#include <dev/dpt/dpt.h> 48342084Smw 49342084Smw#define DPT_EISA_IOSIZE 0x9 50342084Smw#define DPT_EISA_SLOT_OFFSET 0x0c00 51342084Smw#define DPT_EISA_EATA_REG_OFFSET 0x0088 52342084Smw 53342084Smw#define DPT_EISA_DPT2402 0x12142402 /* DPT PM2012A/9X */ 54342084Smw#define DPT_EISA_DPTA401 0x1214A401 /* DPT PM2012B/9X */ 55342084Smw#define DPT_EISA_DPTA402 0x1214A402 /* DPT PM2012B2/9X */ 56342084Smw#define DPT_EISA_DPTA410 0x1214A410 /* DPT PM2x22A/9X */ 57342084Smw#define DPT_EISA_DPTA411 0x1214A411 /* DPT Spectre */ 58342084Smw#define DPT_EISA_DPTA412 0x1214A412 /* DPT PM2021A/9X */ 59342084Smw#define DPT_EISA_DPTA420 0x1214A420 /* DPT Smart Cache IV (PM2042) */ 60342084Smw#define DPT_EISA_DPTA501 0x1214A501 /* DPT PM2012B1/9X" */ 61342084Smw#define DPT_EISA_DPTA502 0x1214A502 /* DPT PM2012Bx/9X */ 62342084Smw#define DPT_EISA_DPTA701 0x1214A701 /* DPT PM2011B1/9X */ 63342084Smw#define DPT_EISA_DPTBC01 0x1214BC01 /* DPT PM3011/7X ESDI */ 64342084Smw#define DPT_EISA_DPT8200 0x12148200 /* NEC EATA SCSI */ 65342084Smw#define DPT_EISA_DPT2408 0x12142408 /* ATT EATA SCSI */ 66342084Smw 67342084Smw/* Function Prototypes */ 68342084Smw 69342084Smwstatic const char * dpt_eisa_match (eisa_id_t); 70342084Smwstatic int dpt_eisa_probe (device_t); 71342084Smwstatic int dpt_eisa_attach (device_t); 72342084Smw 73342084Smwstatic int 74342084Smwdpt_eisa_probe (device_t dev) 75342084Smw{ 76342084Smw const char * desc; 77342084Smw u_int32_t io_base; 78342084Smw dpt_conf_t * conf; 79342084Smw 80342084Smw desc = dpt_eisa_match(eisa_get_id(dev)); 81342084Smw if (!desc) 82342084Smw return (ENXIO); 83342084Smw device_set_desc(dev, desc); 84342084Smw 85342084Smw io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + 86342084Smw DPT_EISA_SLOT_OFFSET + 87342084Smw DPT_EISA_EATA_REG_OFFSET; 88342084Smw 89342084Smw conf = dpt_pio_get_conf(io_base); 90342084Smw if (!conf) { 91342084Smw printf("dpt: dpt_pio_get_conf() failed.\n"); 92342084Smw return (ENXIO); 93342084Smw } 94342084Smw 95342084Smw eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE); 96342084Smw eisa_add_intr(dev, conf->IRQ, 97342084Smw (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE)); 98342084Smw 99342084Smw return 0; 100342084Smw} 101342084Smw 102342084Smwstatic int 103346722Smwdpt_eisa_attach (device_t dev) 104346722Smw{ 105346722Smw dpt_softc_t * dpt; 106342084Smw int s; 107342084Smw int error = 0; 108342084Smw 109342084Smw dpt = device_get_softc(dev); 110346722Smw 111346722Smw dpt->io_rid = 0; 112346722Smw dpt->io_type = SYS_RES_IOPORT; 113346722Smw dpt->irq_rid = 0; 114346722Smw 115342084Smw error = dpt_alloc_resources(dev); 116342084Smw if (error) { 117346722Smw goto bad; 118342084Smw } 119342084Smw 120342084Smw dpt_alloc(dev); 121342084Smw 122342084Smw /* Allocate a dmatag representing the capabilities of this attachment */ 123342084Smw /* XXX Should be a child of the EISA bus dma tag */ 124342084Smw if (bus_dma_tag_create( /* parent */ NULL, 125342084Smw /* alignemnt */ 1, 126342084Smw /* boundary */ 0, 127342084Smw /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 128342084Smw /* highaddr */ BUS_SPACE_MAXADDR, 129342084Smw /* filter */ NULL, 130342084Smw /* filterarg */ NULL, 131342084Smw /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, 132342084Smw /* nsegments */ ~0, 133342084Smw /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 134342084Smw /* flags */ 0, 135342084Smw /* lockfunc */ busdma_lock_mutex, 136342084Smw /* lockarg */ &Giant, 137342084Smw &dpt->parent_dmat) != 0) { 138342084Smw error = ENXIO; 139342084Smw goto bad; 140342084Smw } 141342084Smw 142342084Smw s = splcam(); 143342084Smw 144342084Smw if (dpt_init(dpt) != 0) { 145342084Smw splx(s); 146342084Smw error = ENXIO; 147342084Smw goto bad; 148342084Smw } 149342084Smw 150342084Smw /* Register with the XPT */ 151342084Smw dpt_attach(dpt); 152342084Smw 153342084Smw splx(s); 154342084Smw 155342084Smw if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, 156342084Smw dpt_intr, dpt, &dpt->ih)) { 157342084Smw device_printf(dev, "Unable to register interrupt handler\n"); 158342084Smw error = ENXIO; 159342084Smw goto bad; 160342084Smw } 161342084Smw 162342084Smw return (error); 163342084Smw 164342084Smw bad: 165342084Smw dpt_release_resources(dev); 166342084Smw 167342084Smw dpt_free(dpt); 168342084Smw 169342084Smw return (error); 170342084Smw} 171342084Smw 172342084Smwstatic const char * 173342084Smwdpt_eisa_match(type) 174342084Smw eisa_id_t type; 175342084Smw{ 176342084Smw switch (type) { 177342084Smw case DPT_EISA_DPT2402: 178342084Smw case DPT_EISA_DPTA401: 179342084Smw case DPT_EISA_DPTA402: 180342084Smw case DPT_EISA_DPTA410: 181342084Smw case DPT_EISA_DPTA411: 182342084Smw case DPT_EISA_DPTA412: 183342084Smw case DPT_EISA_DPTA420: 184342084Smw case DPT_EISA_DPTA501: 185342084Smw case DPT_EISA_DPTA502: 186342084Smw case DPT_EISA_DPTA701: 187342084Smw case DPT_EISA_DPTBC01: 188342084Smw case DPT_EISA_DPT8200: 189342084Smw case DPT_EISA_DPT2408: 190342084Smw return ("DPT SCSI Host Bus Adapter"); 191342084Smw break; 192342084Smw default: 193342084Smw break; 194342084Smw } 195342084Smw 196342084Smw return (NULL); 197342084Smw} 198342084Smw 199342084Smwstatic device_method_t dpt_eisa_methods[] = { 200342084Smw /* Device interface */ 201342084Smw DEVMETHOD(device_probe, dpt_eisa_probe), 202342084Smw DEVMETHOD(device_attach, dpt_eisa_attach), 203342084Smw DEVMETHOD(device_detach, dpt_detach), 204342084Smw 205342084Smw { 0, 0 } 206342084Smw}; 207342084Smw 208342084Smwstatic driver_t dpt_eisa_driver = { 209342084Smw "dpt", 210342084Smw dpt_eisa_methods, 211342084Smw sizeof(dpt_softc_t), 212342084Smw}; 213342084Smw 214342084SmwDRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0); 215342084SmwMODULE_DEPEND(dpt, eisa, 1, 1, 1); 216342084SmwMODULE_DEPEND(dpt, cam, 1, 1, 1); 217342084Smw