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