dpt_eisa.c revision 112780
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 112780 2003-03-29 08:30:45Z 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
46112780Smdodd#define DPT_EISA_IOSIZE			0x9
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
7039234Sgibbsstatic int
7159078Smdodddpt_eisa_probe (device_t dev)
7234480Sjulian{
7352042Smdodd	const char *	desc;
7452042Smdodd	u_int32_t	io_base;
7552042Smdodd	dpt_conf_t *	conf;
7634480Sjulian
7745791Speter	desc = dpt_eisa_match(eisa_get_id(dev));
7845791Speter	if (!desc)
7945791Speter		return (ENXIO);
8045791Speter	device_set_desc(dev, desc);
8134480Sjulian
82112780Smdodd	io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) +
83112780Smdodd		DPT_EISA_SLOT_OFFSET +
84112780Smdodd		DPT_EISA_EATA_REG_OFFSET;
8545791Speter
86112780Smdodd	conf = dpt_pio_get_conf(io_base);
8752042Smdodd	if (!conf) {
8852042Smdodd		printf("dpt: dpt_pio_get_conf() failed.\n");
8952042Smdodd		return (ENXIO);
9045791Speter	}
9134480Sjulian
9252042Smdodd	eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE);
9352042Smdodd	eisa_add_intr(dev, conf->IRQ,
9452042Smdodd		      (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE));
9545791Speter
9645791Speter	return 0;
9734480Sjulian}
9834480Sjulian
9945791Speterstatic int
10059078Smdodddpt_eisa_attach (device_t dev)
10134480Sjulian{
102112780Smdodd	dpt_softc_t *	dpt;
10339234Sgibbs	int		s;
10459078Smdodd	int		error = 0;
10534480Sjulian
106112780Smdodd	dpt = device_get_softc(dev);
10734480Sjulian
108112780Smdodd	dpt->io_rid = 0;
109112780Smdodd	dpt->io_type = SYS_RES_IOPORT;
110112780Smdodd	dpt->irq_rid = 0;
11159078Smdodd
112112780Smdodd	error = dpt_alloc_resources(dev);
113112780Smdodd	if (error) {
11445791Speter		goto bad;
11559078Smdodd	}
11634480Sjulian
117112780Smdodd	dpt_alloc(dev);
118112780Smdodd
11939234Sgibbs	/* Allocate a dmatag representing the capabilities of this attachment */
12039234Sgibbs	/* XXX Should be a child of the EISA bus dma tag */
12159078Smdodd	if (bus_dma_tag_create(	/* parent    */	NULL,
12259078Smdodd				/* alignemnt */	1,
12359078Smdodd				/* boundary  */	0,
12459078Smdodd				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
12559078Smdodd				/* highaddr  */	BUS_SPACE_MAXADDR,
12659078Smdodd				/* filter    */	NULL,
12759078Smdodd				/* filterarg */	NULL,
12859078Smdodd				/* maxsize   */	BUS_SPACE_MAXSIZE_32BIT,
129104710Speter				/* nsegments */	~0,
13059078Smdodd				/* maxsegsz  */	BUS_SPACE_MAXSIZE_32BIT,
13159078Smdodd				/* flags     */0,
13259078Smdodd				&dpt->parent_dmat) != 0) {
13359078Smdodd		error = ENXIO;
13445791Speter		goto bad;
13534480Sjulian	}
13634480Sjulian
13759078Smdodd	s = splcam();
13834480Sjulian
13939234Sgibbs	if (dpt_init(dpt) != 0) {
140112780Smdodd		splx(s);
14159078Smdodd		error = ENXIO;
14245791Speter		goto bad;
14334480Sjulian	}
14434480Sjulian
14539234Sgibbs	/* Register with the XPT */
14639234Sgibbs	dpt_attach(dpt);
14745791Speter
14839234Sgibbs	splx(s);
14934480Sjulian
150112780Smdodd	if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
151112780Smdodd			   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
162112780Smdodd	if (dpt)
163112780Smdodd		dpt_free(dpt);
164112780Smdodd
16559078Smdodd	return (error);
16634480Sjulian}
16734480Sjulian
16834480Sjulianstatic const char	*
16934480Sjuliandpt_eisa_match(type)
17034480Sjulian	eisa_id_t	type;
17134480Sjulian{
17234480Sjulian	switch (type) {
17359078Smdodd		case DPT_EISA_DPT2402:
17459078Smdodd		case DPT_EISA_DPTA401:
17559078Smdodd		case DPT_EISA_DPTA402:
17659078Smdodd		case DPT_EISA_DPTA410:
17759078Smdodd		case DPT_EISA_DPTA411:
17859078Smdodd		case DPT_EISA_DPTA412:
17959078Smdodd		case DPT_EISA_DPTA420:
18059078Smdodd		case DPT_EISA_DPTA501:
18159078Smdodd		case DPT_EISA_DPTA502:
18259078Smdodd		case DPT_EISA_DPTA701:
18359078Smdodd		case DPT_EISA_DPTBC01:
18459078Smdodd		case DPT_EISA_DPT8200:
18559078Smdodd		case DPT_EISA_DPT2408:
18659078Smdodd			return ("DPT SCSI Host Bus Adapter");
18734480Sjulian			break;
18834480Sjulian		default:
18934480Sjulian			break;
19034480Sjulian	}
19134480Sjulian
19234480Sjulian	return (NULL);
19334480Sjulian}
19434480Sjulian
19545791Speterstatic device_method_t dpt_eisa_methods[] = {
19645791Speter	/* Device interface */
19745791Speter	DEVMETHOD(device_probe,		dpt_eisa_probe),
19845791Speter	DEVMETHOD(device_attach,	dpt_eisa_attach),
199112780Smdodd	DEVMETHOD(device_detach,	dpt_detach),
20045791Speter
20145791Speter	{ 0, 0 }
20245791Speter};
20345791Speter
20445791Speterstatic driver_t dpt_eisa_driver = {
20545791Speter	"dpt",
20645791Speter	dpt_eisa_methods,
20759078Smdodd	sizeof(dpt_softc_t),
20845791Speter};
20945791Speter
21045791SpeterDRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0);
211