dpt_eisa.c revision 59078
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 * 2659078Smdodd * $FreeBSD: head/sys/dev/dpt/dpt_eisa.c 59078 2000-04-07 02:50:24Z mdodd $ 2734480Sjulian */ 2834480Sjulian 2934480Sjulian#include <sys/param.h> 3034480Sjulian#include <sys/systm.h> 3134480Sjulian#include <sys/kernel.h> 3245791Speter#include <sys/module.h> 3345791Speter#include <sys/bus.h> 3434480Sjulian 3539234Sgibbs#include <machine/bus_pio.h> 3639234Sgibbs#include <machine/bus.h> 3745791Speter#include <machine/resource.h> 3845791Speter#include <sys/rman.h> 3934480Sjulian 4059078Smdodd#include <dev/eisa/eisaconf.h> 4159078Smdodd 4239234Sgibbs#include <cam/scsi/scsi_all.h> 4339234Sgibbs 4439234Sgibbs#include <dev/dpt/dpt.h> 4539234Sgibbs 4652042Smdodd#define DPT_EISA_IOSIZE 0x100 4752042Smdodd#define DPT_EISA_SLOT_OFFSET 0x0c00 4852042Smdodd#define DPT_EISA_EATA_REG_OFFSET 0x0088 4952042Smdodd 5059078Smdodd#define DPT_EISA_DPT2402 0x12142402 /* DPT PM2012A/9X */ 5159078Smdodd#define DPT_EISA_DPTA401 0x1214A401 /* DPT PM2012B/9X */ 5259078Smdodd#define DPT_EISA_DPTA402 0x1214A402 /* DPT PM2012B2/9X */ 5359078Smdodd#define DPT_EISA_DPTA410 0x1214A410 /* DPT PM2x22A/9X */ 5459078Smdodd#define DPT_EISA_DPTA411 0x1214A411 /* DPT Spectre */ 5559078Smdodd#define DPT_EISA_DPTA412 0x1214A412 /* DPT PM2021A/9X */ 5659078Smdodd#define DPT_EISA_DPTA420 0x1214A420 /* DPT Smart Cache IV (PM2042) */ 5759078Smdodd#define DPT_EISA_DPTA501 0x1214A501 /* DPT PM2012B1/9X" */ 5859078Smdodd#define DPT_EISA_DPTA502 0x1214A502 /* DPT PM2012Bx/9X */ 5959078Smdodd#define DPT_EISA_DPTA701 0x1214A701 /* DPT PM2011B1/9X */ 6059078Smdodd#define DPT_EISA_DPTBC01 0x1214BC01 /* DPT PM3011/7X ESDI */ 6159078Smdodd#define DPT_EISA_DPT8200 0x12148200 /* NEC EATA SCSI */ 6259078Smdodd#define DPT_EISA_DPT2408 0x12142408 /* ATT EATA SCSI */ 6352042Smdodd 6434480Sjulian/* Function Prototypes */ 6534480Sjulian 6659078Smdoddstatic const char * dpt_eisa_match (eisa_id_t); 6759078Smdoddstatic int dpt_eisa_probe (device_t); 6859078Smdoddstatic int dpt_eisa_attach (device_t); 6934480Sjulian 7059078Smdodd 7139234Sgibbsstatic int 7259078Smdodddpt_eisa_probe (device_t dev) 7334480Sjulian{ 7452042Smdodd const char * desc; 7552042Smdodd u_int32_t io_base; 7652042Smdodd dpt_conf_t * conf; 7734480Sjulian 7845791Speter desc = dpt_eisa_match(eisa_get_id(dev)); 7945791Speter if (!desc) 8045791Speter return (ENXIO); 8145791Speter device_set_desc(dev, desc); 8234480Sjulian 8352042Smdodd io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + DPT_EISA_SLOT_OFFSET; 8445791Speter 8552042Smdodd conf = dpt_pio_get_conf(io_base + DPT_EISA_EATA_REG_OFFSET); 8652042Smdodd if (!conf) { 8752042Smdodd printf("dpt: dpt_pio_get_conf() failed.\n"); 8852042Smdodd return (ENXIO); 8945791Speter } 9034480Sjulian 9152042Smdodd eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE); 9252042Smdodd eisa_add_intr(dev, conf->IRQ, 9352042Smdodd (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE)); 9445791Speter 9545791Speter return 0; 9634480Sjulian} 9734480Sjulian 9845791Speterstatic int 9959078Smdodddpt_eisa_attach (device_t dev) 10034480Sjulian{ 10159078Smdodd dpt_softc_t * dpt; 10245791Speter struct resource *io = 0; 10345791Speter struct resource *irq = 0; 10439234Sgibbs int s; 10545791Speter int rid; 10659078Smdodd void * ih; 10759078Smdodd int error = 0; 10834480Sjulian 10945791Speter rid = 0; 11059078Smdodd io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); 11145791Speter if (!io) { 11245791Speter device_printf(dev, "No I/O space?!\n"); 11359078Smdodd error = ENOMEM; 11459078Smdodd goto bad; 11534480Sjulian } 11634480Sjulian 11759078Smdodd rid = 0; 11859078Smdodd irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE); 11959078Smdodd if (!irq) { 12059078Smdodd device_printf(dev, "No irq?!\n"); 12159078Smdodd error = ENOMEM; 12259078Smdodd goto bad; 12359078Smdodd } 12459078Smdodd 12559078Smdodd dpt = dpt_alloc(dev, rman_get_bustag(io), 12645791Speter rman_get_bushandle(io) + DPT_EISA_EATA_REG_OFFSET); 12759078Smdodd if (dpt == NULL) { 12859078Smdodd error = ENOMEM; 12945791Speter goto bad; 13059078Smdodd } 13134480Sjulian 13239234Sgibbs /* Allocate a dmatag representing the capabilities of this attachment */ 13339234Sgibbs /* XXX Should be a child of the EISA bus dma tag */ 13459078Smdodd if (bus_dma_tag_create( /* parent */ NULL, 13559078Smdodd /* alignemnt */ 1, 13659078Smdodd /* boundary */ 0, 13759078Smdodd /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 13859078Smdodd /* highaddr */ BUS_SPACE_MAXADDR, 13959078Smdodd /* filter */ NULL, 14059078Smdodd /* filterarg */ NULL, 14159078Smdodd /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, 14259078Smdodd /* nsegments */ BUS_SPACE_UNRESTRICTED, 14359078Smdodd /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 14459078Smdodd /* flags */0, 14559078Smdodd &dpt->parent_dmat) != 0) { 14639234Sgibbs dpt_free(dpt); 14759078Smdodd error = ENXIO; 14845791Speter goto bad; 14934480Sjulian } 15034480Sjulian 15159078Smdodd s = splcam(); 15234480Sjulian 15339234Sgibbs if (dpt_init(dpt) != 0) { 15439234Sgibbs dpt_free(dpt); 15559078Smdodd error = ENXIO; 15645791Speter goto bad; 15734480Sjulian } 15834480Sjulian 15939234Sgibbs /* Register with the XPT */ 16039234Sgibbs dpt_attach(dpt); 16145791Speter 16239234Sgibbs splx(s); 16334480Sjulian 16459078Smdodd if (bus_setup_intr(dev, irq, INTR_TYPE_CAM, dpt_intr, dpt, &ih)) { 16559078Smdodd device_printf(dev, "Unable to register interrupt handler\n"); 16659078Smdodd error = ENXIO; 16759078Smdodd goto bad; 16859078Smdodd } 16945791Speter 17059078Smdodd return (error); 17159078Smdodd 17245791Speter bad: 17345791Speter if (io) 17445791Speter bus_release_resource(dev, SYS_RES_IOPORT, 0, io); 17545791Speter if (irq) 17645791Speter bus_release_resource(dev, SYS_RES_IRQ, 0, irq); 17759078Smdodd 17859078Smdodd return (error); 17934480Sjulian} 18034480Sjulian 18134480Sjulianstatic const char * 18234480Sjuliandpt_eisa_match(type) 18334480Sjulian eisa_id_t type; 18434480Sjulian{ 18534480Sjulian switch (type) { 18659078Smdodd case DPT_EISA_DPT2402: 18759078Smdodd case DPT_EISA_DPTA401: 18859078Smdodd case DPT_EISA_DPTA402: 18959078Smdodd case DPT_EISA_DPTA410: 19059078Smdodd case DPT_EISA_DPTA411: 19159078Smdodd case DPT_EISA_DPTA412: 19259078Smdodd case DPT_EISA_DPTA420: 19359078Smdodd case DPT_EISA_DPTA501: 19459078Smdodd case DPT_EISA_DPTA502: 19559078Smdodd case DPT_EISA_DPTA701: 19659078Smdodd case DPT_EISA_DPTBC01: 19759078Smdodd case DPT_EISA_DPT8200: 19859078Smdodd case DPT_EISA_DPT2408: 19959078Smdodd return ("DPT SCSI Host Bus Adapter"); 20034480Sjulian break; 20134480Sjulian default: 20234480Sjulian break; 20334480Sjulian } 20434480Sjulian 20534480Sjulian return (NULL); 20634480Sjulian} 20734480Sjulian 20845791Speterstatic device_method_t dpt_eisa_methods[] = { 20945791Speter /* Device interface */ 21045791Speter DEVMETHOD(device_probe, dpt_eisa_probe), 21145791Speter DEVMETHOD(device_attach, dpt_eisa_attach), 21245791Speter 21345791Speter { 0, 0 } 21445791Speter}; 21545791Speter 21645791Speterstatic driver_t dpt_eisa_driver = { 21745791Speter "dpt", 21845791Speter dpt_eisa_methods, 21959078Smdodd sizeof(dpt_softc_t), 22045791Speter}; 22145791Speter 22245791Speterstatic devclass_t dpt_devclass; 22345791Speter 22445791SpeterDRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0); 225