Home | History | Annotate | Line # | Download | only in libsa
      1 /*	$NetBSD: promdev.c,v 1.7 2017/02/01 18:24:22 christos Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1995 Gordon W. Ross
      5  * Copyright (c) 1993 Paul Kranenburg
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *      This product includes software developed by Paul Kranenburg.
     19  * 4. The name of the author may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 #include <sys/types.h>
     35 #include <machine/mon.h>
     36 
     37 #include <stand.h>
     38 
     39 #include "libsa.h"
     40 #include "dvma.h"
     41 #include "saio.h"
     42 
     43 int promdev_inuse;
     44 
     45 #ifdef DEBUG_PROM
     46 # define DPRINTF(fmt, ...) \
     47 	do { \
     48 		if (debug) \
     49 			printf("%s: " fmt "\n", __func__, __VA_ARGS__); \
     50 	} while (/*CONSTCOND*/0)
     51 #else
     52 # define DPRINTF(fmt, ...)
     53 #endif
     54 
     55 /*
     56  * Note: caller sets the fields:
     57  *	si->si_boottab
     58  *	si->si_ctlr
     59  *	si->si_unit
     60  *	si->si_boff
     61  */
     62 
     63 int
     64 prom_iopen(struct saioreq *si)
     65 {
     66 	struct boottab *ops;
     67 	struct devinfo *dip;
     68 	int	ctlr, error;
     69 
     70 	if (promdev_inuse)
     71 		return EMFILE;
     72 
     73 	ops = si->si_boottab;
     74 	dip = ops->b_devinfo;
     75 	ctlr = si->si_ctlr;
     76 
     77 
     78 	DPRINTF("Boot device type: %s", ops->b_desc);
     79 
     80 	if (!_is2) {
     81 #ifdef DEBUG_PROM
     82 		if (debug) {
     83 			printf("d_devbytes=%d\n", dip->d_devbytes);
     84 			printf("d_dmabytes=%d\n", dip->d_dmabytes);
     85 			printf("d_localbytes=%d\n", dip->d_localbytes);
     86 			printf("d_devtype=%d\n", dip->d_devtype);
     87 			printf("d_maxiobytes=%d\n", dip->d_maxiobytes);
     88 			printf("d_stdcount=%d\n", dip->d_stdcount);
     89 			for (int i = 0; i < dip->d_stdcount; i++)
     90 				printf("d_stdaddrs[%d]=%#x\n",
     91 				    i, dip->d_stdaddrs[0]);
     92 		}
     93 #endif
     94 
     95 		if (dip->d_devbytes && dip->d_stdcount) {
     96 			if (ctlr >= dip->d_stdcount) {
     97 				putstr("Invalid controller number\n");
     98 				return ENXIO;
     99 			}
    100 			si->si_devaddr = dev_mapin(dip->d_devtype,
    101 			    dip->d_stdaddrs[ctlr], dip->d_devbytes);
    102 			DPRINTF("devaddr=%#x", si->si_devaddr);
    103 		}
    104 
    105 		if (dip->d_dmabytes) {
    106 			si->si_dmaaddr = dvma_alloc(dip->d_dmabytes);
    107 			DPRINTF("dmaaddr=%#x", si->si_dmaaddr);
    108 		}
    109 
    110 		if (dip->d_localbytes) {
    111 			si->si_devdata = alloc(dip->d_localbytes);
    112 			DPRINTF("devdata=%#x", si->si_devdata);
    113 		}
    114 	}
    115 
    116 	/* OK, call the PROM device open routine. */
    117 	DPRINTF("calling prom open... %p", si);
    118 	error = (*ops->b_open)(si);
    119 	DPRINTF("prom open returned %d", error);
    120 	if (error != 0) {
    121 #if 0		/* XXX: printf is too big for bootxx */
    122 		printf("%s: \"%s\" error=%d\n", __func__,
    123 		    ops->b_desc, error);
    124 #else
    125 		putstr("prom_iopen: prom open failed");
    126 #endif
    127 		return ENXIO;
    128 	}
    129 
    130 	promdev_inuse++;
    131 	return 0;
    132 }
    133 
    134 void
    135 prom_iclose(struct saioreq *si)
    136 {
    137 	struct boottab *ops;
    138 
    139 	if (promdev_inuse == 0)
    140 		return;
    141 
    142 	ops = si->si_boottab;
    143 
    144 	DPRINTF("calling prom close... %p", si);
    145 	(*ops->b_close)(si);
    146 
    147 	promdev_inuse = 0;
    148 }
    149