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