pci_up1000.c revision 1.16
1139776Simp/*	$OpenBSD: pci_up1000.c,v 1.16 2015/07/26 05:09:44 miod Exp $	*/
2130678Sphk/* $NetBSD: pci_up1000.c,v 1.6 2000/12/28 22:59:07 sommerfeld Exp $ */
364880Sphk
464880Sphk/*-
564880Sphk * Copyright (c) 2000 The NetBSD Foundation, Inc.
664880Sphk * All rights reserved.
764880Sphk *
864880Sphk * This code is derived from software contributed to The NetBSD Foundation
964880Sphk * by Jason R. Thorpe.
1064880Sphk *
1164880Sphk * Redistribution and use in source and binary forms, with or without
1264880Sphk * modification, are permitted provided that the following conditions
1364880Sphk * are met:
1464880Sphk * 1. Redistributions of source code must retain the above copyright
1564880Sphk *    notice, this list of conditions and the following disclaimer.
1664880Sphk * 2. Redistributions in binary form must reproduce the above copyright
1764880Sphk *    notice, this list of conditions and the following disclaimer in the
1864880Sphk *    documentation and/or other materials provided with the distribution.
1964880Sphk *
2064880Sphk * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2164880Sphk * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2264880Sphk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2364880Sphk * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2464880Sphk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2564880Sphk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2664880Sphk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2764880Sphk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2864880Sphk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2964880Sphk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3064880Sphk * POSSIBILITY OF SUCH DAMAGE.
3164880Sphk */
3264880Sphk
3376166Smarkm#include <sys/types.h>
3464880Sphk#include <sys/param.h>
3576166Smarkm#include <sys/time.h>
36150342Sphk#include <sys/systm.h>
3776166Smarkm#include <sys/errno.h>
3864880Sphk#include <sys/device.h>
3976166Smarkm
40150342Sphk#include <uvm/uvm_extern.h>
4165515Sphk
4276166Smarkm#include <machine/autoconf.h>
4364880Sphk#include <machine/bus.h>
44150342Sphk#include <machine/intr.h>
4565515Sphk
4664880Sphk#include <dev/isa/isavar.h>
47149144Sphk
4864880Sphk#include <dev/pci/pcireg.h>
49163606Srwatson#include <dev/pci/pcivar.h>
50163606Srwatson#include <dev/pci/ppbreg.h>
51150342Sphk#include <dev/pci/pciidereg.h>
52150342Sphk#include <dev/pci/pciidevar.h>
53150342Sphk
54150342Sphk#include <alpha/pci/irongatevar.h>
55163481Skib
5665515Sphk#include <alpha/pci/pci_up1000.h>
57150342Sphk#include <alpha/pci/siovar.h>
5869767Sphk#include <alpha/pci/sioreg.h>
59150342Sphk
60150342Sphk#include "sio.h"
61150342Sphk
62150342Sphkint     api_up1000_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
63150342Sphkconst char *api_up1000_intr_string(void *, pci_intr_handle_t);
64281255Skibint	api_up1000_intr_line(void *, pci_intr_handle_t);
65150342Sphkvoid    *api_up1000_intr_establish(void *, pci_intr_handle_t,
66150342Sphk	    int, int (*func)(void *), void *, const char *);
6765515Sphkvoid    api_up1000_intr_disestablish(void *, void *);
6865515Sphk
6965515Sphkvoid	*api_up1000_pciide_compat_intr_establish(void *, struct device *,
70150147Sphk	    struct pci_attach_args *, int, int (*)(void *), void *);
71150147Sphkvoid    api_up1000_pciide_compat_intr_disestablish(void *, void *);
72150342Sphk
73150147Sphkvoid
74149146Sphkpci_up1000_pickintr(struct irongate_config *icp)
75203292Sed{
76203292Sed	bus_space_tag_t iot = &icp->ic_iot;
77149146Sphk	pci_chipset_tag_t pc = &icp->ic_pc;
78149146Sphk
79149146Sphk	pc->pc_intr_v = icp;
80149146Sphk	pc->pc_intr_map = api_up1000_intr_map;
81149146Sphk	pc->pc_intr_string = api_up1000_intr_string;
82149146Sphk	pc->pc_intr_line = api_up1000_intr_line;
83150342Sphk	pc->pc_intr_establish = api_up1000_intr_establish;
84203292Sed	pc->pc_intr_disestablish = api_up1000_intr_disestablish;
85149146Sphk
86149146Sphk	pc->pc_pciide_compat_intr_establish =
87149146Sphk	    api_up1000_pciide_compat_intr_establish;
88149146Sphk	pc->pc_pciide_compat_intr_disestablish =
89149146Sphk	    api_up1000_pciide_compat_intr_disestablish;
90203292Sed
91203292Sed#if NSIO
92150342Sphk	sio_intr_setup(pc, iot);
93150342Sphk#else
94203292Sed	panic("pci_up1000_pickintr: no I/O interrupt handler (no sio)");
95203292Sed#endif
96203292Sed}
97150342Sphk
98203292Sedint
99150342Sphkapi_up1000_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
100203292Sed{
101203292Sed	int buspin, line = pa->pa_intrline;
102203292Sed
103203292Sed	/*
104149146Sphk	 * The console places the interrupt mapping in the "line" value.
105149146Sphk	 * We trust it whenever possible.
106149146Sphk	 */
107187864Sed	if (line >= 0 && line <= 15) {
108187864Sed		if (line == 2) {
109187864Sed#ifdef DEBUG
110149146Sphk			printf("api_up1000_intr_map: changed IRQ 2 to IRQ 9\n");
111149146Sphk#endif
112273736Shselasky			line = 9;
113149146Sphk		}
114150342Sphk
115273736Shselasky		*ihp = line;
11665515Sphk		return 0;
117150342Sphk	}
118207729Skib
11965515Sphk	if (pa->pa_bridgetag) {
120150342Sphk		buspin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin,
121150342Sphk		    pa->pa_device);
122183230Sed		if (pa->pa_bridgeih[buspin - 1] != 0) {
12365515Sphk			*ihp = pa->pa_bridgeih[buspin - 1];
124243039Skib			return 0;
125207729Skib		}
126207729Skib	}
127207729Skib
12865515Sphk	return 1;
129150342Sphk}
130150342Sphk
131150342Sphkconst char *
132207729Skibapi_up1000_intr_string(void *icv, pci_intr_handle_t ih)
13365515Sphk{
134150342Sphk#if 0
13565515Sphk	struct irongate_config *icp = icv;
136150342Sphk#endif
137183230Sed
138183230Sed	return sio_intr_string(NULL /*XXX*/, ih);
139207729Skib}
140183230Sed
141150342Sphkint
14265515Sphkapi_up1000_intr_line(void *icv, pci_intr_handle_t ih)
14365515Sphk{
144213221Sjh	return sio_intr_line(NULL /*XXX*/, ih);
145213221Sjh}
146213221Sjh
147213221Sjhvoid *
148213221Sjhapi_up1000_intr_establish(void *icv, pci_intr_handle_t ih, int level,
149213221Sjh    int (*func)(void *), void *arg, const char *name)
150213221Sjh{
151213221Sjh#if 0
152213221Sjh	struct irongate_config *icp = icv;
153213221Sjh#endif
154213221Sjh
155213221Sjh	return sio_intr_establish(NULL /*XXX*/, ih, IST_LEVEL, level, func,
156213221Sjh	    arg, name);
157213221Sjh}
158213221Sjh
159213221Sjhvoid
160213221Sjhapi_up1000_intr_disestablish(void *icv, void *cookie)
161213221Sjh{
162213221Sjh#if 0
163213221Sjh	struct irongate_config *icp = icv;
164213221Sjh#endif
165150342Sphk
166150342Sphk	sio_intr_disestablish(NULL /*XXX*/, cookie);
16765515Sphk}
168150342Sphk
16965515Sphkvoid *
170179828Skibapi_up1000_pciide_compat_intr_establish(void *icv, struct device *dev,
171150342Sphk    struct pci_attach_args *pa, int chan, int (*func)(void *), void *arg)
172150342Sphk{
173226041Skib	pci_chipset_tag_t pc = pa->pa_pc;
174150342Sphk	void *cookie = NULL;
175150342Sphk	int bus, irq;
176150342Sphk
17765515Sphk	pci_decompose_tag(pc, pa->pa_tag, &bus, NULL, NULL);
17865515Sphk
179150342Sphk	/*
180211226Sjh	 * If this isn't PCI bus #0, all bets are off.
18165132Sphk	 */
18265132Sphk	if (bus != 0)
18365132Sphk		return (NULL);
18465132Sphk
18565132Sphk	irq = PCIIDE_COMPAT_IRQ(chan);
18665132Sphk#if NSIO
187211226Sjh	cookie = sio_intr_establish(NULL /*XXX*/, irq, IST_EDGE, IPL_BIO,
188211226Sjh	    func, arg, dev->dv_xname);
189277746Skib	if (cookie == NULL)
190277746Skib		return (NULL);
191277746Skib#endif
192277746Skib	return (cookie);
193277746Skib}
194277746Skib
195277746Skibvoid
196277746Skibapi_up1000_pciide_compat_intr_disestablish(void *v, void *cookie)
197277746Skib{
198277746Skib	sio_intr_disestablish(NULL, cookie);
19965132Sphk}
20065132Sphk