dpt_eisa.c revision 117126
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 117126 2003-07-01 15:52:06Z scottl $
2734480Sjulian */
2834480Sjulian
2934480Sjulian#include <sys/param.h>
3034480Sjulian#include <sys/systm.h>
3134480Sjulian#include <sys/kernel.h>
3245791Speter#include <sys/module.h>
33117126Sscottl#include <sys/lock.h>
34117126Sscottl#include <sys/mutex.h>
3545791Speter#include <sys/bus.h>
3634480Sjulian
3739234Sgibbs#include <machine/bus_pio.h>
3839234Sgibbs#include <machine/bus.h>
3945791Speter#include <machine/resource.h>
4045791Speter#include <sys/rman.h>
4134480Sjulian
4259078Smdodd#include <dev/eisa/eisaconf.h>
4359078Smdodd
4439234Sgibbs#include <cam/scsi/scsi_all.h>
4539234Sgibbs
4639234Sgibbs#include <dev/dpt/dpt.h>
4739234Sgibbs
48112780Smdodd#define DPT_EISA_IOSIZE			0x9
4952042Smdodd#define DPT_EISA_SLOT_OFFSET		0x0c00
5052042Smdodd#define DPT_EISA_EATA_REG_OFFSET	0x0088
5152042Smdodd
5259078Smdodd#define	DPT_EISA_DPT2402	0x12142402	/* DPT PM2012A/9X	*/
5359078Smdodd#define	DPT_EISA_DPTA401	0x1214A401	/* DPT PM2012B/9X	*/
5459078Smdodd#define	DPT_EISA_DPTA402	0x1214A402	/* DPT PM2012B2/9X	*/
5559078Smdodd#define	DPT_EISA_DPTA410	0x1214A410	/* DPT PM2x22A/9X	*/
5659078Smdodd#define	DPT_EISA_DPTA411	0x1214A411	/* DPT Spectre		*/
5759078Smdodd#define	DPT_EISA_DPTA412	0x1214A412	/* DPT PM2021A/9X	*/
5859078Smdodd#define	DPT_EISA_DPTA420	0x1214A420	/* DPT Smart Cache IV (PM2042) */
5959078Smdodd#define	DPT_EISA_DPTA501	0x1214A501	/* DPT PM2012B1/9X"	*/
6059078Smdodd#define	DPT_EISA_DPTA502	0x1214A502	/* DPT PM2012Bx/9X	*/
6159078Smdodd#define	DPT_EISA_DPTA701	0x1214A701	/* DPT PM2011B1/9X	*/
6259078Smdodd#define	DPT_EISA_DPTBC01	0x1214BC01	/* DPT PM3011/7X ESDI	*/
6359078Smdodd#define	DPT_EISA_DPT8200	0x12148200	/* NEC EATA SCSI	*/
6459078Smdodd#define	DPT_EISA_DPT2408	0x12142408	/* ATT EATA SCSI	*/
6552042Smdodd
6634480Sjulian/* Function Prototypes */
6734480Sjulian
6859078Smdoddstatic const char *	dpt_eisa_match	(eisa_id_t);
6959078Smdoddstatic int		dpt_eisa_probe	(device_t);
7059078Smdoddstatic int		dpt_eisa_attach	(device_t);
7134480Sjulian
7239234Sgibbsstatic int
7359078Smdodddpt_eisa_probe (device_t dev)
7434480Sjulian{
7552042Smdodd	const char *	desc;
7652042Smdodd	u_int32_t	io_base;
7752042Smdodd	dpt_conf_t *	conf;
7834480Sjulian
7945791Speter	desc = dpt_eisa_match(eisa_get_id(dev));
8045791Speter	if (!desc)
8145791Speter		return (ENXIO);
8245791Speter	device_set_desc(dev, desc);
8334480Sjulian
84112780Smdodd	io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) +
85112780Smdodd		DPT_EISA_SLOT_OFFSET +
86112780Smdodd		DPT_EISA_EATA_REG_OFFSET;
8745791Speter
88112780Smdodd	conf = dpt_pio_get_conf(io_base);
8952042Smdodd	if (!conf) {
9052042Smdodd		printf("dpt: dpt_pio_get_conf() failed.\n");
9152042Smdodd		return (ENXIO);
9245791Speter	}
9334480Sjulian
9452042Smdodd	eisa_add_iospace(dev, io_base, DPT_EISA_IOSIZE, RESVADDR_NONE);
9552042Smdodd	eisa_add_intr(dev, conf->IRQ,
9652042Smdodd		      (conf->IRQ_TR ? EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE));
9745791Speter
9845791Speter	return 0;
9934480Sjulian}
10034480Sjulian
10145791Speterstatic int
10259078Smdodddpt_eisa_attach (device_t dev)
10334480Sjulian{
104112780Smdodd	dpt_softc_t *	dpt;
10539234Sgibbs	int		s;
10659078Smdodd	int		error = 0;
10734480Sjulian
108112780Smdodd	dpt = device_get_softc(dev);
10934480Sjulian
110112780Smdodd	dpt->io_rid = 0;
111112780Smdodd	dpt->io_type = SYS_RES_IOPORT;
112112780Smdodd	dpt->irq_rid = 0;
11359078Smdodd
114112780Smdodd	error = dpt_alloc_resources(dev);
115112780Smdodd	if (error) {
11645791Speter		goto bad;
11759078Smdodd	}
11834480Sjulian
119112780Smdodd	dpt_alloc(dev);
120112780Smdodd
12139234Sgibbs	/* Allocate a dmatag representing the capabilities of this attachment */
12239234Sgibbs	/* XXX Should be a child of the EISA bus dma tag */
12359078Smdodd	if (bus_dma_tag_create(	/* parent    */	NULL,
12459078Smdodd				/* alignemnt */	1,
12559078Smdodd				/* boundary  */	0,
12659078Smdodd				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
12759078Smdodd				/* highaddr  */	BUS_SPACE_MAXADDR,
12859078Smdodd				/* filter    */	NULL,
12959078Smdodd				/* filterarg */	NULL,
13059078Smdodd				/* maxsize   */	BUS_SPACE_MAXSIZE_32BIT,
131104710Speter				/* nsegments */	~0,
13259078Smdodd				/* maxsegsz  */	BUS_SPACE_MAXSIZE_32BIT,
133117126Sscottl				/* flags     */ 0,
134117126Sscottl				/* lockfunc  */ busdma_lock_mutex,
135117126Sscottl				/* lockarg   */ &Giant,
13659078Smdodd				&dpt->parent_dmat) != 0) {
13759078Smdodd		error = ENXIO;
13845791Speter		goto bad;
13934480Sjulian	}
14034480Sjulian
14159078Smdodd	s = splcam();
14234480Sjulian
14339234Sgibbs	if (dpt_init(dpt) != 0) {
144112780Smdodd		splx(s);
14559078Smdodd		error = ENXIO;
14645791Speter		goto bad;
14734480Sjulian	}
14834480Sjulian
14939234Sgibbs	/* Register with the XPT */
15039234Sgibbs	dpt_attach(dpt);
15145791Speter
15239234Sgibbs	splx(s);
15334480Sjulian
154112780Smdodd	if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
155112780Smdodd			   dpt_intr, dpt, &dpt->ih)) {
15659078Smdodd		device_printf(dev, "Unable to register interrupt handler\n");
15759078Smdodd		error = ENXIO;
15859078Smdodd		goto bad;
15959078Smdodd	}
16045791Speter
16159078Smdodd	return (error);
16259078Smdodd
16345791Speter bad:
164112780Smdodd	dpt_release_resources(dev);
16559078Smdodd
166112780Smdodd	if (dpt)
167112780Smdodd		dpt_free(dpt);
168112780Smdodd
16959078Smdodd	return (error);
17034480Sjulian}
17134480Sjulian
17234480Sjulianstatic const char	*
17334480Sjuliandpt_eisa_match(type)
17434480Sjulian	eisa_id_t	type;
17534480Sjulian{
17634480Sjulian	switch (type) {
17759078Smdodd		case DPT_EISA_DPT2402:
17859078Smdodd		case DPT_EISA_DPTA401:
17959078Smdodd		case DPT_EISA_DPTA402:
18059078Smdodd		case DPT_EISA_DPTA410:
18159078Smdodd		case DPT_EISA_DPTA411:
18259078Smdodd		case DPT_EISA_DPTA412:
18359078Smdodd		case DPT_EISA_DPTA420:
18459078Smdodd		case DPT_EISA_DPTA501:
18559078Smdodd		case DPT_EISA_DPTA502:
18659078Smdodd		case DPT_EISA_DPTA701:
18759078Smdodd		case DPT_EISA_DPTBC01:
18859078Smdodd		case DPT_EISA_DPT8200:
18959078Smdodd		case DPT_EISA_DPT2408:
19059078Smdodd			return ("DPT SCSI Host Bus Adapter");
19134480Sjulian			break;
19234480Sjulian		default:
19334480Sjulian			break;
19434480Sjulian	}
19534480Sjulian
19634480Sjulian	return (NULL);
19734480Sjulian}
19834480Sjulian
19945791Speterstatic device_method_t dpt_eisa_methods[] = {
20045791Speter	/* Device interface */
20145791Speter	DEVMETHOD(device_probe,		dpt_eisa_probe),
20245791Speter	DEVMETHOD(device_attach,	dpt_eisa_attach),
203112780Smdodd	DEVMETHOD(device_detach,	dpt_detach),
20445791Speter
20545791Speter	{ 0, 0 }
20645791Speter};
20745791Speter
20845791Speterstatic driver_t dpt_eisa_driver = {
20945791Speter	"dpt",
21045791Speter	dpt_eisa_methods,
21159078Smdodd	sizeof(dpt_softc_t),
21245791Speter};
21345791Speter
21445791SpeterDRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0);
215