1/* $NetBSD: osiop_sbdio.c,v 1.3 2008/03/29 09:11:35 tsutsui Exp $ */ 2 3/*- 4 * Copyright (c) 2001, 2005 Izumi Tsutsui. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__KERNEL_RCSID(0, "$NetBSD: osiop_sbdio.c,v 1.3 2008/03/29 09:11:35 tsutsui Exp $"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/device.h> 33 34#include <machine/bus.h> 35#include <machine/sbdiovar.h> 36 37#include <dev/scsipi/scsi_all.h> 38#include <dev/scsipi/scsipi_all.h> 39#include <dev/scsipi/scsiconf.h> 40 41#include <dev/ic/osiopreg.h> 42#include <dev/ic/osiopvar.h> 43 44int osiop_sbdio_match(device_t, cfdata_t, void *); 45void osiop_sbdio_attach(device_t, device_t, void *); 46int osiop_sbdio_intr(void *); 47 48CFATTACH_DECL_NEW(osiop_sbdio, sizeof(struct osiop_softc), 49 osiop_sbdio_match, osiop_sbdio_attach, NULL, NULL); 50 51int 52osiop_sbdio_match(device_t parent, cfdata_t cf, void *aux) 53{ 54 struct sbdio_attach_args *sa = aux; 55 56 return strcmp(sa->sa_name, "osiop") ? 0 : 1; 57} 58 59void 60osiop_sbdio_attach(device_t parent, device_t self, void *aux) 61{ 62 struct osiop_softc *sc = device_private(self); 63 struct sbdio_attach_args *sa = aux; 64 int error, scid; 65 66 sc->sc_dev = self; 67 sc->sc_dmat = sa->sa_dmat; 68 sc->sc_bst = sa->sa_bust; 69 70 error = bus_space_map(sc->sc_bst, sa->sa_addr1, OSIOP_NREGS, 0, 71 &sc->sc_reg); 72 if (error != 0) { 73 aprint_error(": can't map registers, error = %d\n", error); 74 return; 75 } 76 77 sc->sc_clock_freq = 25; /* MHz */ 78 sc->sc_ctest7 = 0; 79 sc->sc_dcntl = OSIOP_DCNTL_EA; 80 if (sa->sa_flags == 0x0001) /* TR2A */ 81 sc->sc_ctest4 = OSIOP_CTEST4_MUX; /* Host bus multiplex mode */ 82 83 scid = ffs(osiop_read_1(sc, OSIOP_SCID)); 84 if (scid == 0) 85 scid = 7; 86 else 87 scid--; 88 sc->sc_id = scid; 89 90 intr_establish(sa->sa_irq, osiop_sbdio_intr, sc); 91 92 osiop_attach(sc); 93} 94 95int 96osiop_sbdio_intr(void *arg) 97{ 98 struct osiop_softc *sc = arg; 99 uint8_t istat; 100 101 if (sc->sc_flags & OSIOP_INTSOFF) 102 return 0; 103 104 istat = osiop_read_1(sc, OSIOP_ISTAT); 105 106 if ((istat & (OSIOP_ISTAT_SIP | OSIOP_ISTAT_DIP)) == 0) 107 return 0; 108 109 /* Save interrupt details for the back-end interrupt handler */ 110 sc->sc_sstat0 = osiop_read_1(sc, OSIOP_SSTAT0); 111 sc->sc_istat = istat; 112 sc->sc_dstat = osiop_read_1(sc, OSIOP_DSTAT); 113 114 osiop_intr(sc); 115 116 return 1; 117} 118