159078Smdodd/*- 259078Smdodd * Copyright (c) 1997, 2000 Matthew N. Dodd <winter@jurai.net> 359078Smdodd * All rights reserved. 434480Sjulian * 534480Sjulian * Redistribution and use in source and binary forms, with or without 634480Sjulian * modification, are permitted provided that the following conditions 734480Sjulian * are met: 834480Sjulian * 1. Redistributions of source code must retain the above copyright 959078Smdodd * notice, this list of conditions and the following disclaimer. 1034480Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1134480Sjulian * notice, this list of conditions and the following disclaimer in the 1234480Sjulian * documentation and/or other materials provided with the distribution. 1334480Sjulian * 1434480Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1534480Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1634480Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1759078Smdodd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1859078Smdodd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1934480Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2034480Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2134480Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2234480Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2334480Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2434480Sjulian * SUCH DAMAGE. 2559078Smdodd * 2634480Sjulian */ 2734480Sjulian 28119418Sobrien#include <sys/cdefs.h> 29119418Sobrien__FBSDID("$FreeBSD$"); 30119418Sobrien 31166091Smarius#include "opt_eisa.h" 32166091Smarius 3334480Sjulian#include <sys/param.h> 3434480Sjulian#include <sys/systm.h> 3534480Sjulian#include <sys/kernel.h> 3645791Speter#include <sys/module.h> 37117126Sscottl#include <sys/lock.h> 38117126Sscottl#include <sys/mutex.h> 3945791Speter#include <sys/bus.h> 4034480Sjulian 4139234Sgibbs#include <machine/bus.h> 4245791Speter#include <machine/resource.h> 4345791Speter#include <sys/rman.h> 4434480Sjulian 4559078Smdodd#include <dev/eisa/eisaconf.h> 4659078Smdodd 4739234Sgibbs#include <cam/scsi/scsi_all.h> 4839234Sgibbs 4939234Sgibbs#include <dev/dpt/dpt.h> 5039234Sgibbs 51112780Smdodd#define DPT_EISA_IOSIZE 0x9 5252042Smdodd#define DPT_EISA_SLOT_OFFSET 0x0c00 5352042Smdodd#define DPT_EISA_EATA_REG_OFFSET 0x0088 5452042Smdodd 5559078Smdodd#define DPT_EISA_DPT2402 0x12142402 /* DPT PM2012A/9X */ 5659078Smdodd#define DPT_EISA_DPTA401 0x1214A401 /* DPT PM2012B/9X */ 5759078Smdodd#define DPT_EISA_DPTA402 0x1214A402 /* DPT PM2012B2/9X */ 5859078Smdodd#define DPT_EISA_DPTA410 0x1214A410 /* DPT PM2x22A/9X */ 5959078Smdodd#define DPT_EISA_DPTA411 0x1214A411 /* DPT Spectre */ 6059078Smdodd#define DPT_EISA_DPTA412 0x1214A412 /* DPT PM2021A/9X */ 6159078Smdodd#define DPT_EISA_DPTA420 0x1214A420 /* DPT Smart Cache IV (PM2042) */ 6259078Smdodd#define DPT_EISA_DPTA501 0x1214A501 /* DPT PM2012B1/9X" */ 6359078Smdodd#define DPT_EISA_DPTA502 0x1214A502 /* DPT PM2012Bx/9X */ 6459078Smdodd#define DPT_EISA_DPTA701 0x1214A701 /* DPT PM2011B1/9X */ 6559078Smdodd#define DPT_EISA_DPTBC01 0x1214BC01 /* DPT PM3011/7X ESDI */ 6659078Smdodd#define DPT_EISA_DPT8200 0x12148200 /* NEC EATA SCSI */ 6759078Smdodd#define DPT_EISA_DPT2408 0x12142408 /* ATT EATA SCSI */ 6852042Smdodd 6934480Sjulian/* Function Prototypes */ 7034480Sjulian 7159078Smdoddstatic const char * dpt_eisa_match (eisa_id_t); 7259078Smdoddstatic int dpt_eisa_probe (device_t); 7359078Smdoddstatic int dpt_eisa_attach (device_t); 7434480Sjulian 7539234Sgibbsstatic int 7659078Smdodddpt_eisa_probe (device_t dev) 7734480Sjulian{ 7852042Smdodd const char * desc; 7952042Smdodd u_int32_t io_base; 8052042Smdodd dpt_conf_t * conf; 8134480Sjulian 8245791Speter desc = dpt_eisa_match(eisa_get_id(dev)); 8345791Speter if (!desc) 8445791Speter return (ENXIO); 8545791Speter device_set_desc(dev, desc); 8634480Sjulian 87112780Smdodd io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + 88112780Smdodd DPT_EISA_SLOT_OFFSET + 89112780Smdodd DPT_EISA_EATA_REG_OFFSET; 9045791Speter 91112780Smdodd conf = dpt_pio_get_conf(io_base); 9252042Smdodd if (!conf) { 9352042Smdodd printf("dpt: dpt_pio_get_conf() failed.\n"); 9452042Smdodd return (ENXIO); 9545791Speter } 9634480Sjulian 9752042Smdodd eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE); 9852042Smdodd eisa_add_intr(dev, conf->IRQ, 9952042Smdodd (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE)); 10045791Speter 10145791Speter return 0; 10234480Sjulian} 10334480Sjulian 10445791Speterstatic int 10559078Smdodddpt_eisa_attach (device_t dev) 10634480Sjulian{ 107112780Smdodd dpt_softc_t * dpt; 10859078Smdodd int error = 0; 10934480Sjulian 110112780Smdodd dpt = device_get_softc(dev); 111170872Sscottl dpt->dev = dev; 112241593Sjhb dpt_alloc(dev); 11334480Sjulian 114112780Smdodd dpt->io_rid = 0; 115112780Smdodd dpt->io_type = SYS_RES_IOPORT; 116112780Smdodd dpt->irq_rid = 0; 11759078Smdodd 118112780Smdodd error = dpt_alloc_resources(dev); 119112780Smdodd if (error) { 12045791Speter goto bad; 12159078Smdodd } 12234480Sjulian 12339234Sgibbs /* Allocate a dmatag representing the capabilities of this attachment */ 124241593Sjhb if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), 12559078Smdodd /* alignemnt */ 1, 12659078Smdodd /* boundary */ 0, 12759078Smdodd /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 12859078Smdodd /* highaddr */ BUS_SPACE_MAXADDR, 12959078Smdodd /* filter */ NULL, 13059078Smdodd /* filterarg */ NULL, 13159078Smdodd /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, 132104710Speter /* nsegments */ ~0, 13359078Smdodd /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 134117126Sscottl /* flags */ 0, 135241593Sjhb /* lockfunc */ NULL, 136241593Sjhb /* lockarg */ NULL, 13759078Smdodd &dpt->parent_dmat) != 0) { 13859078Smdodd error = ENXIO; 13945791Speter goto bad; 14034480Sjulian } 14134480Sjulian 14239234Sgibbs if (dpt_init(dpt) != 0) { 14359078Smdodd error = ENXIO; 14445791Speter goto bad; 14534480Sjulian } 14634480Sjulian 14739234Sgibbs /* Register with the XPT */ 14839234Sgibbs dpt_attach(dpt); 14945791Speter 150241593Sjhb if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | 151241593Sjhb INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) { 15259078Smdodd device_printf(dev, "Unable to register interrupt handler\n"); 15359078Smdodd error = ENXIO; 15459078Smdodd goto bad; 15559078Smdodd } 15645791Speter 15759078Smdodd return (error); 15859078Smdodd 15945791Speter bad: 160112780Smdodd dpt_release_resources(dev); 16159078Smdodd 162142357Ssam dpt_free(dpt); 163112780Smdodd 16459078Smdodd return (error); 16534480Sjulian} 16634480Sjulian 16734480Sjulianstatic const char * 16834480Sjuliandpt_eisa_match(type) 16934480Sjulian eisa_id_t type; 17034480Sjulian{ 17134480Sjulian switch (type) { 17259078Smdodd case DPT_EISA_DPT2402: 17359078Smdodd case DPT_EISA_DPTA401: 17459078Smdodd case DPT_EISA_DPTA402: 17559078Smdodd case DPT_EISA_DPTA410: 17659078Smdodd case DPT_EISA_DPTA411: 17759078Smdodd case DPT_EISA_DPTA412: 17859078Smdodd case DPT_EISA_DPTA420: 17959078Smdodd case DPT_EISA_DPTA501: 18059078Smdodd case DPT_EISA_DPTA502: 18159078Smdodd case DPT_EISA_DPTA701: 18259078Smdodd case DPT_EISA_DPTBC01: 18359078Smdodd case DPT_EISA_DPT8200: 18459078Smdodd case DPT_EISA_DPT2408: 18559078Smdodd return ("DPT SCSI Host Bus Adapter"); 18634480Sjulian break; 18734480Sjulian default: 18834480Sjulian break; 18934480Sjulian } 19034480Sjulian 19134480Sjulian return (NULL); 19234480Sjulian} 19334480Sjulian 19445791Speterstatic device_method_t dpt_eisa_methods[] = { 19545791Speter /* Device interface */ 19645791Speter DEVMETHOD(device_probe, dpt_eisa_probe), 19745791Speter DEVMETHOD(device_attach, dpt_eisa_attach), 198112780Smdodd DEVMETHOD(device_detach, dpt_detach), 19945791Speter 20045791Speter { 0, 0 } 20145791Speter}; 20245791Speter 20345791Speterstatic driver_t dpt_eisa_driver = { 20445791Speter "dpt", 20545791Speter dpt_eisa_methods, 20659078Smdodd sizeof(dpt_softc_t), 20745791Speter}; 20845791Speter 20945791SpeterDRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0); 210165102SmjacobMODULE_DEPEND(dpt, eisa, 1, 1, 1); 211165102SmjacobMODULE_DEPEND(dpt, cam, 1, 1, 1); 212