Home | History | Annotate | Line # | Download | only in gpib
gpib.c revision 1.1.2.1
      1  1.1.2.1     skrll /*	$NetBSD: gpib.c,v 1.1.2.1 2004/09/18 14:45:39 skrll Exp $	*/
      2      1.1  gmcgarry 
      3      1.1  gmcgarry /*-
      4      1.1  gmcgarry  * Copyright (c) 2003 The NetBSD Foundation, Inc.
      5      1.1  gmcgarry  * All rights reserved.
      6      1.1  gmcgarry  *
      7      1.1  gmcgarry  * This code is derived from software contributed to The NetBSD Foundation
      8      1.1  gmcgarry  * by Gregory McGarry.
      9      1.1  gmcgarry  *
     10      1.1  gmcgarry  * Redistribution and use in source and binary forms, with or without
     11      1.1  gmcgarry  * modification, are permitted provided that the following conditions
     12      1.1  gmcgarry  * are met:
     13      1.1  gmcgarry  * 1. Redistributions of source code must retain the above copyright
     14      1.1  gmcgarry  *    notice, this list of conditions and the following disclaimer.
     15      1.1  gmcgarry  * 2. Redistributions in binary form must reproduce the above copyright
     16      1.1  gmcgarry  *    notice, this list of conditions and the following disclaimer in the
     17      1.1  gmcgarry  *    documentation and/or other materials provided with the distribution.
     18      1.1  gmcgarry  * 3. All advertising materials mentioning features or use of this software
     19      1.1  gmcgarry  *    must display the following acknowledgement:
     20      1.1  gmcgarry  *	This product includes software developed by the NetBSD
     21      1.1  gmcgarry  *	Foundation, Inc. and its contributors.
     22      1.1  gmcgarry  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23      1.1  gmcgarry  *    contributors may be used to endorse or promote products derived
     24      1.1  gmcgarry  *    from this software without specific prior written permission.
     25      1.1  gmcgarry  *
     26      1.1  gmcgarry  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27      1.1  gmcgarry  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28      1.1  gmcgarry  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29      1.1  gmcgarry  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30      1.1  gmcgarry  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31      1.1  gmcgarry  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32      1.1  gmcgarry  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33      1.1  gmcgarry  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34      1.1  gmcgarry  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35      1.1  gmcgarry  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36      1.1  gmcgarry  * POSSIBILITY OF SUCH DAMAGE.
     37      1.1  gmcgarry  */
     38      1.1  gmcgarry 
     39      1.1  gmcgarry #include <sys/cdefs.h>
     40  1.1.2.1     skrll __KERNEL_RCSID(0, "$NetBSD: gpib.c,v 1.1.2.1 2004/09/18 14:45:39 skrll Exp $");
     41      1.1  gmcgarry 
     42      1.1  gmcgarry #include <sys/param.h>
     43      1.1  gmcgarry #include <sys/systm.h>
     44      1.1  gmcgarry #include <sys/conf.h>
     45      1.1  gmcgarry #include <sys/device.h>
     46      1.1  gmcgarry #include <sys/ioctl.h>
     47      1.1  gmcgarry #include <sys/malloc.h>
     48      1.1  gmcgarry #include <sys/proc.h>
     49      1.1  gmcgarry 
     50      1.1  gmcgarry #include <dev/gpib/gpibvar.h>
     51      1.1  gmcgarry 
     52      1.1  gmcgarry #include <dev/gpib/gpibio.h>		/* XXX */
     53      1.1  gmcgarry 
     54      1.1  gmcgarry #include "locators.h"
     55      1.1  gmcgarry 
     56      1.1  gmcgarry #define DEBUG
     57      1.1  gmcgarry 
     58      1.1  gmcgarry #ifdef DEBUG
     59      1.1  gmcgarry int gpibdebug = 0xff;
     60      1.1  gmcgarry #define DBG_FOLLOW	0x01
     61      1.1  gmcgarry #define DBG_INTR	0x02
     62      1.1  gmcgarry #define DBG_FAIL	0x04
     63      1.1  gmcgarry #define DPRINTF(mask, str)	if (gpibdebug & (mask)) printf str
     64      1.1  gmcgarry #else
     65      1.1  gmcgarry #define DPRINTF(mask, str)	/* nothing */
     66      1.1  gmcgarry #endif
     67      1.1  gmcgarry 
     68      1.1  gmcgarry int	gpibmatch __P((struct device *, struct cfdata *, void *));
     69      1.1  gmcgarry void	gpibattach __P((struct device *, struct device *, void *));
     70      1.1  gmcgarry 
     71      1.1  gmcgarry CFATTACH_DECL(gpib, sizeof(struct gpib_softc),
     72      1.1  gmcgarry 	gpibmatch, gpibattach, NULL, NULL);
     73      1.1  gmcgarry 
     74  1.1.2.1     skrll static int	gpibsubmatch1(struct device *, struct cfdata *,
     75  1.1.2.1     skrll 			      const locdesc_t *, void *);
     76  1.1.2.1     skrll static int	gpibsubmatch2(struct device *, struct cfdata *,
     77  1.1.2.1     skrll 			      const locdesc_t *, void *);
     78      1.1  gmcgarry static int	gpibprint(void *, const char *);
     79      1.1  gmcgarry 
     80      1.1  gmcgarry dev_type_open(gpibopen);
     81      1.1  gmcgarry dev_type_close(gpibclose);
     82      1.1  gmcgarry dev_type_read(gpibread);
     83      1.1  gmcgarry dev_type_write(gpibwrite);
     84      1.1  gmcgarry dev_type_ioctl(gpibioctl);
     85      1.1  gmcgarry dev_type_poll(gpibpoll);
     86      1.1  gmcgarry 
     87      1.1  gmcgarry const struct cdevsw gpib_cdevsw = {
     88      1.1  gmcgarry 	gpibopen, gpibclose, gpibread, gpibwrite, gpibioctl,
     89      1.1  gmcgarry 	nostop, notty, gpibpoll, nommap, nokqfilter,
     90      1.1  gmcgarry };
     91      1.1  gmcgarry 
     92      1.1  gmcgarry extern struct cfdriver gpib_cd;
     93      1.1  gmcgarry 
     94      1.1  gmcgarry #define GPIBUNIT(dev)		(minor(dev) & 0x0f)
     95      1.1  gmcgarry 
     96      1.1  gmcgarry int gpibtimeout = 100000;	/* # of status tests before we give up */
     97      1.1  gmcgarry 
     98      1.1  gmcgarry int
     99      1.1  gmcgarry gpibmatch(parent, match, aux)
    100      1.1  gmcgarry 	struct device *parent;
    101      1.1  gmcgarry 	struct cfdata *match;
    102      1.1  gmcgarry 	void *aux;
    103      1.1  gmcgarry {
    104      1.1  gmcgarry 
    105      1.1  gmcgarry 	return (1);
    106      1.1  gmcgarry }
    107      1.1  gmcgarry 
    108      1.1  gmcgarry void
    109      1.1  gmcgarry gpibattach(parent, self, aux)
    110      1.1  gmcgarry 	struct device *parent, *self;
    111      1.1  gmcgarry 	void *aux;
    112      1.1  gmcgarry {
    113      1.1  gmcgarry 	struct gpib_softc *sc = (struct gpib_softc *)self;
    114      1.1  gmcgarry 	struct cfdata *cf = sc->sc_dev.dv_cfdata;
    115      1.1  gmcgarry 	struct gpibdev_attach_args *gda = aux;
    116      1.1  gmcgarry 	struct gpib_attach_args ga;
    117      1.1  gmcgarry 	int address;
    118      1.1  gmcgarry 
    119      1.1  gmcgarry 	sc->sc_ic = gda->ga_ic;
    120      1.1  gmcgarry 
    121      1.1  gmcgarry 	/*
    122      1.1  gmcgarry 	 * If the configuration file specified a host address, then
    123      1.1  gmcgarry 	 * use it in favour of registers/switches or the default (30).
    124      1.1  gmcgarry 	 */
    125      1.1  gmcgarry 	if (cf->cf_loc[GPIBDEVCF_ADDRESS] != GPIBDEVCF_ADDRESS_DEFAULT)
    126      1.1  gmcgarry 		sc->sc_myaddr = cf->cf_loc[GPIBDEVCF_ADDRESS];
    127      1.1  gmcgarry 	else if (gda->ga_address != GPIBDEVCF_ADDRESS_DEFAULT)
    128      1.1  gmcgarry 		sc->sc_myaddr = gda->ga_address;
    129      1.1  gmcgarry 	else
    130      1.1  gmcgarry 		sc->sc_myaddr = 30;
    131      1.1  gmcgarry 
    132      1.1  gmcgarry 	printf(": host address %d\n", sc->sc_myaddr);
    133      1.1  gmcgarry 
    134      1.1  gmcgarry 	/* record our softc pointer */
    135      1.1  gmcgarry 	sc->sc_ic->bus = sc;
    136      1.1  gmcgarry 
    137      1.1  gmcgarry 	/* Initialize the slave request queue */
    138      1.1  gmcgarry 	TAILQ_INIT(&sc->sc_queue);
    139      1.1  gmcgarry 
    140      1.1  gmcgarry 	/* attach addressed devices */
    141      1.1  gmcgarry 	for (address=0; address<GPIB_NDEVS; address++) {
    142      1.1  gmcgarry 		ga.ga_ic = sc->sc_ic;
    143      1.1  gmcgarry 		ga.ga_address = address;
    144  1.1.2.1     skrll 		(void) config_search_ia(gpibsubmatch1, &sc->sc_dev, "gpib", &ga);
    145      1.1  gmcgarry 	}
    146      1.1  gmcgarry 
    147      1.1  gmcgarry 	/* attach the wild-carded devices - probably protocol busses */
    148      1.1  gmcgarry 	ga.ga_ic = sc->sc_ic;
    149  1.1.2.1     skrll 	(void) config_search_ia(gpibsubmatch2,  &sc->sc_dev, "gpib", &ga);
    150      1.1  gmcgarry }
    151      1.1  gmcgarry 
    152      1.1  gmcgarry int
    153  1.1.2.1     skrll gpibsubmatch1(parent, cf, ldesc, aux)
    154      1.1  gmcgarry 	struct device *parent;
    155      1.1  gmcgarry 	struct cfdata *cf;
    156  1.1.2.1     skrll 	const locdesc_t *ldesc;
    157      1.1  gmcgarry 	void *aux;
    158      1.1  gmcgarry {
    159      1.1  gmcgarry 	struct gpib_softc *sc = (struct gpib_softc *)parent;
    160      1.1  gmcgarry 	struct gpib_attach_args *ga = aux;
    161      1.1  gmcgarry 
    162      1.1  gmcgarry 	if (cf->cf_loc[GPIBCF_ADDRESS] != ga->ga_address)
    163      1.1  gmcgarry 		return (0);
    164      1.1  gmcgarry 
    165      1.1  gmcgarry 	if (cf->cf_loc[GPIBCF_ADDRESS] == sc->sc_myaddr)
    166      1.1  gmcgarry 		return (0);
    167      1.1  gmcgarry 
    168      1.1  gmcgarry 	if (config_match(parent, cf, ga) > 0) {
    169      1.1  gmcgarry 		if (gpib_alloc(sc, ga->ga_address))
    170      1.1  gmcgarry 			return (0);
    171      1.1  gmcgarry 		config_attach(parent, cf, ga, gpibprint);
    172      1.1  gmcgarry 		return (0);
    173      1.1  gmcgarry 	}
    174      1.1  gmcgarry 	return (0);
    175      1.1  gmcgarry }
    176      1.1  gmcgarry 
    177      1.1  gmcgarry int
    178      1.1  gmcgarry gpibsubmatch2(parent, cf, aux)
    179      1.1  gmcgarry 	struct device *parent;
    180      1.1  gmcgarry 	struct cfdata *cf;
    181  1.1.2.1     skrll 	const locdesc_t *ldesc;
    182      1.1  gmcgarry 	void *aux;
    183      1.1  gmcgarry {
    184      1.1  gmcgarry 	struct gpib_attach_args *ga = aux;
    185      1.1  gmcgarry 
    186      1.1  gmcgarry 	if (cf->cf_loc[GPIBCF_ADDRESS] != GPIBCF_ADDRESS_DEFAULT)
    187      1.1  gmcgarry 		return (0);
    188      1.1  gmcgarry 
    189      1.1  gmcgarry 	ga->ga_address = GPIBCF_ADDRESS_DEFAULT;
    190      1.1  gmcgarry 	if (config_match(parent, cf, ga) > 0) {
    191      1.1  gmcgarry 		config_attach(parent, cf, ga, gpibdevprint);
    192      1.1  gmcgarry 		return (0);
    193      1.1  gmcgarry 	}
    194      1.1  gmcgarry 	return (0);
    195      1.1  gmcgarry }
    196      1.1  gmcgarry 
    197      1.1  gmcgarry int
    198      1.1  gmcgarry gpibprint(aux, pnp)
    199      1.1  gmcgarry 	void *aux;
    200      1.1  gmcgarry 	const char *pnp;
    201      1.1  gmcgarry {
    202      1.1  gmcgarry 	struct gpib_attach_args *ga = aux;
    203      1.1  gmcgarry 
    204      1.1  gmcgarry 	if (ga->ga_address != GPIBCF_ADDRESS_DEFAULT)
    205      1.1  gmcgarry 		printf(" address %d", ga->ga_address);
    206      1.1  gmcgarry 	return (UNCONF);
    207      1.1  gmcgarry }
    208      1.1  gmcgarry 
    209      1.1  gmcgarry int
    210      1.1  gmcgarry gpibdevprint(aux, pnp)
    211      1.1  gmcgarry 	void *aux;
    212      1.1  gmcgarry 	const char *pnp;
    213      1.1  gmcgarry {
    214      1.1  gmcgarry 
    215      1.1  gmcgarry 	if (pnp != NULL)
    216      1.1  gmcgarry 		printf("gpib at %s", pnp);
    217      1.1  gmcgarry 	return (UNCONF);
    218      1.1  gmcgarry }
    219      1.1  gmcgarry 
    220      1.1  gmcgarry /*
    221      1.1  gmcgarry  * Called by hardware driver, pass to device driver.
    222      1.1  gmcgarry  */
    223      1.1  gmcgarry int
    224      1.1  gmcgarry gpibintr(v)
    225      1.1  gmcgarry 	void *v;
    226      1.1  gmcgarry {
    227      1.1  gmcgarry 	struct gpib_softc *sc = v;
    228      1.1  gmcgarry 	gpib_handle_t hdl;
    229      1.1  gmcgarry 
    230      1.1  gmcgarry 	DPRINTF(DBG_INTR, ("gpibintr: sc=%p\n", sc));
    231      1.1  gmcgarry 
    232      1.1  gmcgarry 	hdl = TAILQ_FIRST(&sc->sc_queue);
    233      1.1  gmcgarry 	(hdl->hq_callback)(hdl->hq_softc, GPIBCBF_INTR);
    234      1.1  gmcgarry 	return (0);
    235      1.1  gmcgarry }
    236      1.1  gmcgarry 
    237      1.1  gmcgarry /*
    238      1.1  gmcgarry  * Create a callback handle.
    239      1.1  gmcgarry  */
    240      1.1  gmcgarry int
    241      1.1  gmcgarry _gpibregister(sc, slave, callback, arg, hdl)
    242      1.1  gmcgarry 	struct gpib_softc *sc;
    243      1.1  gmcgarry 	int slave;
    244      1.1  gmcgarry 	gpib_callback_t callback;
    245      1.1  gmcgarry 	void *arg;
    246      1.1  gmcgarry 	gpib_handle_t *hdl;
    247      1.1  gmcgarry {
    248      1.1  gmcgarry 
    249      1.1  gmcgarry 	MALLOC(*hdl, gpib_handle_t, sizeof(struct gpibqueue),
    250      1.1  gmcgarry 	    M_DEVBUF, M_NOWAIT);
    251      1.1  gmcgarry 	if (*hdl == NULL) {
    252      1.1  gmcgarry 		DPRINTF(DBG_FAIL, ("_gpibregister: can't allocate queue\n"));
    253      1.1  gmcgarry 		return (1);
    254      1.1  gmcgarry 	}
    255      1.1  gmcgarry 
    256      1.1  gmcgarry 	(*hdl)->hq_slave = slave;
    257      1.1  gmcgarry 	(*hdl)->hq_callback = callback;
    258      1.1  gmcgarry 	(*hdl)->hq_softc = arg;
    259      1.1  gmcgarry 
    260      1.1  gmcgarry 	return (0);
    261      1.1  gmcgarry }
    262      1.1  gmcgarry 
    263      1.1  gmcgarry /*
    264      1.1  gmcgarry  * Request exclusive access to the GPIB bus.
    265      1.1  gmcgarry  */
    266      1.1  gmcgarry int
    267      1.1  gmcgarry _gpibrequest(sc, hdl)
    268      1.1  gmcgarry 	struct gpib_softc *sc;
    269      1.1  gmcgarry 	gpib_handle_t hdl;
    270      1.1  gmcgarry {
    271      1.1  gmcgarry 
    272      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("_gpibrequest: sc=%p hdl=%p\n", sc, hdl));
    273      1.1  gmcgarry 
    274      1.1  gmcgarry 	TAILQ_INSERT_TAIL(&sc->sc_queue, hdl, hq_list);
    275      1.1  gmcgarry 	if (TAILQ_FIRST(&sc->sc_queue) == hdl)
    276      1.1  gmcgarry 		return (1);
    277      1.1  gmcgarry 
    278      1.1  gmcgarry 	return (0);
    279      1.1  gmcgarry }
    280      1.1  gmcgarry 
    281      1.1  gmcgarry /*
    282      1.1  gmcgarry  * Release exclusive access to the GPIB bus.
    283      1.1  gmcgarry  */
    284      1.1  gmcgarry void
    285      1.1  gmcgarry _gpibrelease(sc, hdl)
    286      1.1  gmcgarry 	struct gpib_softc *sc;
    287      1.1  gmcgarry 	gpib_handle_t hdl;
    288      1.1  gmcgarry {
    289      1.1  gmcgarry 
    290      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("_gpibrelease: sc=%p hdl=%p\n", sc, hdl));
    291      1.1  gmcgarry 
    292      1.1  gmcgarry 	TAILQ_REMOVE(&sc->sc_queue, hdl, hq_list);
    293      1.1  gmcgarry 	if ((hdl = TAILQ_FIRST(&sc->sc_queue)) != NULL)
    294      1.1  gmcgarry 		(*hdl->hq_callback)(hdl->hq_softc, GPIBCBF_START);
    295      1.1  gmcgarry }
    296      1.1  gmcgarry 
    297      1.1  gmcgarry 
    298      1.1  gmcgarry /*
    299      1.1  gmcgarry  * Asynchronous wait.
    300      1.1  gmcgarry  */
    301      1.1  gmcgarry void
    302      1.1  gmcgarry _gpibawait(sc)
    303      1.1  gmcgarry 	struct gpib_softc *sc;
    304      1.1  gmcgarry {
    305      1.1  gmcgarry 	int slave;
    306      1.1  gmcgarry 
    307      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("_gpibawait: sc=%p\n", sc));
    308      1.1  gmcgarry 
    309      1.1  gmcgarry 	slave = TAILQ_FIRST(&sc->sc_queue)->hq_slave;
    310      1.1  gmcgarry 	(*sc->sc_ic->ppwatch)(sc->sc_ic->cookie, slave);
    311      1.1  gmcgarry }
    312      1.1  gmcgarry 
    313      1.1  gmcgarry /*
    314      1.1  gmcgarry  * Synchronous (spin) wait.
    315      1.1  gmcgarry  */
    316      1.1  gmcgarry int
    317      1.1  gmcgarry _gpibswait(sc, slave)
    318      1.1  gmcgarry 	struct gpib_softc *sc;
    319      1.1  gmcgarry 	int slave;
    320      1.1  gmcgarry {
    321      1.1  gmcgarry 	int timo = gpibtimeout;
    322      1.1  gmcgarry 	int (*pptest)(void *, int);
    323      1.1  gmcgarry 
    324      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("_gpibswait: sc=%p\n", sc));
    325      1.1  gmcgarry 
    326      1.1  gmcgarry 	pptest = sc->sc_ic->pptest;
    327      1.1  gmcgarry 	while ((*pptest)(sc->sc_ic->cookie, slave) == 0) {
    328      1.1  gmcgarry 		if (--timo == 0) {
    329      1.1  gmcgarry 			printf("%s: swait timeout\n", sc->sc_dev.dv_xname);
    330      1.1  gmcgarry 			return(-1);
    331      1.1  gmcgarry 		}
    332      1.1  gmcgarry 	}
    333      1.1  gmcgarry 	return (0);
    334      1.1  gmcgarry }
    335      1.1  gmcgarry 
    336      1.1  gmcgarry /*
    337      1.1  gmcgarry  * Resource accounting: check if the address has already been
    338      1.1  gmcgarry  * claimed and allocated.
    339      1.1  gmcgarry  */
    340      1.1  gmcgarry int
    341      1.1  gmcgarry gpib_isalloc(sc, address)
    342      1.1  gmcgarry 	struct gpib_softc *sc;
    343      1.1  gmcgarry 	u_int8_t address;
    344      1.1  gmcgarry {
    345      1.1  gmcgarry 
    346      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpib_isalloc: sc=%p address=%d\n", sc, address));
    347      1.1  gmcgarry 
    348      1.1  gmcgarry #ifdef DIAGNOSTIC
    349      1.1  gmcgarry 	if (address >= GPIB_NDEVS)
    350      1.1  gmcgarry 		panic("gpib_isalloc: device address out of range");
    351      1.1  gmcgarry #endif
    352      1.1  gmcgarry 
    353      1.1  gmcgarry 	return ((sc->sc_rmap & (1 << address)) != 0);
    354      1.1  gmcgarry }
    355      1.1  gmcgarry 
    356      1.1  gmcgarry /*
    357      1.1  gmcgarry  * Resource accounting: allocate the address.
    358      1.1  gmcgarry  */
    359      1.1  gmcgarry int
    360      1.1  gmcgarry gpib_alloc(sc, address)
    361      1.1  gmcgarry 	struct gpib_softc *sc;
    362      1.1  gmcgarry 	u_int8_t address;
    363      1.1  gmcgarry {
    364      1.1  gmcgarry 
    365      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpib_alloc: sc=%p address=%d\n", sc, address));
    366      1.1  gmcgarry 
    367      1.1  gmcgarry #ifdef DIAGNOSTIC
    368      1.1  gmcgarry 	if (address >= GPIB_NDEVS)
    369      1.1  gmcgarry 		panic("gpib_alloc: device address out of range");
    370      1.1  gmcgarry #endif
    371      1.1  gmcgarry 
    372      1.1  gmcgarry 	if (!gpib_isalloc(sc, address)) {
    373      1.1  gmcgarry 		sc->sc_rmap |= (1 << address);
    374      1.1  gmcgarry 		return (0);
    375      1.1  gmcgarry 	}
    376      1.1  gmcgarry 	return (1);
    377      1.1  gmcgarry }
    378      1.1  gmcgarry 
    379      1.1  gmcgarry /*
    380      1.1  gmcgarry  * Resource accounting: deallocate the address.
    381      1.1  gmcgarry  */
    382      1.1  gmcgarry void
    383      1.1  gmcgarry gpib_dealloc(sc, address)
    384      1.1  gmcgarry 	struct gpib_softc *sc;
    385      1.1  gmcgarry 	u_int8_t address;
    386      1.1  gmcgarry {
    387      1.1  gmcgarry 
    388      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpib_free: sc=%p address=%d\n", sc, address));
    389      1.1  gmcgarry 
    390      1.1  gmcgarry #ifdef DIAGNOSTIC
    391      1.1  gmcgarry 	if (address >= GPIB_NDEVS)
    392      1.1  gmcgarry 		panic("gpib_free: device address out of range");
    393      1.1  gmcgarry 
    394      1.1  gmcgarry 	if (!gpib_isalloc(sc, address))
    395      1.1  gmcgarry 		panic("gpib_free: not allocated");
    396      1.1  gmcgarry #endif
    397      1.1  gmcgarry 
    398      1.1  gmcgarry 	sc->sc_rmap &= ~(1 << address);
    399      1.1  gmcgarry }
    400      1.1  gmcgarry 
    401      1.1  gmcgarry int
    402      1.1  gmcgarry _gpibsend(sc, slave, sec, ptr, origcnt)
    403      1.1  gmcgarry 	struct gpib_softc *sc;
    404      1.1  gmcgarry 	int slave;
    405      1.1  gmcgarry 	int sec;
    406      1.1  gmcgarry 	void *ptr;
    407      1.1  gmcgarry 	int origcnt;
    408      1.1  gmcgarry {
    409      1.1  gmcgarry 	int rv;
    410      1.1  gmcgarry 	int cnt = 0;
    411      1.1  gmcgarry 	u_int8_t cmds[4];
    412      1.1  gmcgarry 	int i = 0;
    413      1.1  gmcgarry 
    414      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW,
    415      1.1  gmcgarry 	    ("_gpibsend: sc=%p slave %d sec=%d ptr=%p cnt=%d\n",
    416      1.1  gmcgarry 	    sc, slave, sec, ptr, origcnt));
    417      1.1  gmcgarry 
    418      1.1  gmcgarry 	/*
    419      1.1  gmcgarry 	 * For compatibility, call the hardware driver directly.
    420      1.1  gmcgarry 	 */
    421      1.1  gmcgarry 	if (sc->sc_ic->send != NULL) {
    422      1.1  gmcgarry 		rv = (*sc->sc_ic->send)(sc->sc_ic->cookie,
    423      1.1  gmcgarry 			slave, sec, ptr, origcnt);
    424      1.1  gmcgarry 		return (rv);
    425      1.1  gmcgarry 	}
    426      1.1  gmcgarry 
    427      1.1  gmcgarry 	if ((*sc->sc_ic->tc)(sc->sc_ic->cookie, 0))
    428      1.1  gmcgarry 		goto senderror;
    429      1.1  gmcgarry 	cmds[i++] = GPIBCMD_UNL;
    430      1.1  gmcgarry 	cmds[i++] = GPIBCMD_TAG | sc->sc_myaddr;
    431      1.1  gmcgarry 	cmds[i++] = GPIBCMD_LAG | slave;
    432      1.1  gmcgarry 	if (sec >= 0 || sec == -2) {
    433      1.1  gmcgarry 		if (sec == -2)		/* selected device clear KLUDGE */
    434      1.1  gmcgarry 			cmds[i++] = GPIBCMD_SDC;
    435      1.1  gmcgarry 		else
    436      1.1  gmcgarry 			cmds[i++] = GPIBCMD_SCG | sec;
    437      1.1  gmcgarry 	}
    438      1.1  gmcgarry 	if ((*sc->sc_ic->sendcmds)(sc->sc_ic->cookie, cmds, i) != i)
    439      1.1  gmcgarry 		goto senderror;
    440      1.1  gmcgarry 	if ((*sc->sc_ic->gts)(sc->sc_ic->cookie))
    441      1.1  gmcgarry 		goto senderror;
    442      1.1  gmcgarry 	if (origcnt) {
    443      1.1  gmcgarry 		cnt = (*sc->sc_ic->senddata)(sc->sc_ic->cookie, ptr, origcnt);
    444      1.1  gmcgarry 		if (cnt != origcnt)
    445      1.1  gmcgarry 			goto senderror;
    446      1.1  gmcgarry 		if ((*sc->sc_ic->tc)(sc->sc_ic->cookie, 0))
    447      1.1  gmcgarry 			goto senderror;
    448      1.1  gmcgarry 	}
    449      1.1  gmcgarry 	return (origcnt);
    450      1.1  gmcgarry 
    451      1.1  gmcgarry senderror:
    452      1.1  gmcgarry 	(*sc->sc_ic->ifc)(sc->sc_ic->cookie);
    453      1.1  gmcgarry 	DPRINTF(DBG_FAIL,
    454      1.1  gmcgarry 	    ("%s: _gpibsend failed: slave %d, sec %x, sent %d of %d bytes\n",
    455      1.1  gmcgarry 	    sc->sc_dev.dv_xname, slave, sec, cnt, origcnt));
    456      1.1  gmcgarry 	return (cnt);
    457      1.1  gmcgarry }
    458      1.1  gmcgarry 
    459      1.1  gmcgarry int
    460      1.1  gmcgarry _gpibrecv(sc, slave, sec, ptr, origcnt)
    461      1.1  gmcgarry 	struct gpib_softc *sc;
    462      1.1  gmcgarry 	int slave;
    463      1.1  gmcgarry 	int sec;
    464      1.1  gmcgarry 	void *ptr;
    465      1.1  gmcgarry 	int origcnt;
    466      1.1  gmcgarry {
    467      1.1  gmcgarry 	int rv;
    468      1.1  gmcgarry 	u_int8_t cmds[4];
    469      1.1  gmcgarry 	int cnt = 0;
    470      1.1  gmcgarry 	int i = 0;
    471      1.1  gmcgarry 
    472      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW,
    473      1.1  gmcgarry 	    ("_gpibrecv: sc=%p slave=%d sec=%d buf=%p cnt=%d\n",
    474      1.1  gmcgarry 	    sc, slave, sec, ptr, origcnt));
    475      1.1  gmcgarry 
    476      1.1  gmcgarry 	/*
    477      1.1  gmcgarry 	 * For compatibility, call the hardware driver directly.
    478      1.1  gmcgarry 	 */
    479      1.1  gmcgarry 	if (sc->sc_ic->recv != NULL) {
    480      1.1  gmcgarry 		rv = (*sc->sc_ic->recv)(sc->sc_ic->cookie,
    481      1.1  gmcgarry 			slave, sec, ptr, origcnt);
    482      1.1  gmcgarry 		return (rv);
    483      1.1  gmcgarry 	}
    484      1.1  gmcgarry 
    485      1.1  gmcgarry 	/*
    486      1.1  gmcgarry 	 * slave < 0 implies continuation of a previous receive
    487      1.1  gmcgarry 	 * that probably timed out.
    488      1.1  gmcgarry 	 */
    489      1.1  gmcgarry 	if (slave >= 0) {
    490      1.1  gmcgarry 		if ((*sc->sc_ic->tc)(sc->sc_ic->cookie, 0))
    491      1.1  gmcgarry 			goto recverror;
    492      1.1  gmcgarry 		cmds[i++] = GPIBCMD_UNL;
    493      1.1  gmcgarry 		cmds[i++] = GPIBCMD_LAG | sc->sc_myaddr;
    494      1.1  gmcgarry 		cmds[i++] = GPIBCMD_TAG | slave;
    495      1.1  gmcgarry 		if (sec >= 0)
    496      1.1  gmcgarry 			cmds[i++] = GPIBCMD_SCG | sec;
    497      1.1  gmcgarry 		if ((*sc->sc_ic->sendcmds)(sc->sc_ic->cookie, cmds, i) != i)
    498      1.1  gmcgarry 			goto recverror;
    499      1.1  gmcgarry 		if ((*sc->sc_ic->gts)(sc->sc_ic->cookie))
    500      1.1  gmcgarry 			goto recverror;
    501      1.1  gmcgarry 	}
    502      1.1  gmcgarry 	if (origcnt) {
    503      1.1  gmcgarry 		cnt = (*sc->sc_ic->recvdata)(sc->sc_ic->cookie, ptr, origcnt);
    504      1.1  gmcgarry 		if (cnt != origcnt)
    505      1.1  gmcgarry 			goto recverror;
    506      1.1  gmcgarry 		if ((sc->sc_ic->tc)(sc->sc_ic->cookie, 0))
    507      1.1  gmcgarry 			goto recverror;
    508      1.1  gmcgarry 		cmds[0] = (slave == GPIB_BROADCAST_ADDR) ?
    509      1.1  gmcgarry 		    GPIBCMD_UNA : GPIBCMD_UNT;
    510      1.1  gmcgarry 		if ((*sc->sc_ic->sendcmds)(sc->sc_ic->cookie, cmds, 1) != 1)
    511      1.1  gmcgarry 			goto recverror;
    512      1.1  gmcgarry 	}
    513      1.1  gmcgarry 	return (origcnt);
    514      1.1  gmcgarry 
    515      1.1  gmcgarry recverror:
    516      1.1  gmcgarry 	(*sc->sc_ic->ifc)(sc->sc_ic->cookie);
    517      1.1  gmcgarry 	DPRINTF(DBG_FAIL,
    518      1.1  gmcgarry 	    ("_gpibrecv: failed, sc=%p slave %d, sec %x, got %d of %d bytes\n",
    519      1.1  gmcgarry 	    sc, slave, sec, cnt, origcnt));
    520      1.1  gmcgarry 	return (cnt);
    521      1.1  gmcgarry }
    522      1.1  gmcgarry 
    523      1.1  gmcgarry /*
    524      1.1  gmcgarry  * /dev/gpib? interface
    525      1.1  gmcgarry  */
    526      1.1  gmcgarry 
    527      1.1  gmcgarry int
    528      1.1  gmcgarry gpibopen(dev, flags, mode, p)
    529      1.1  gmcgarry 	dev_t dev;
    530      1.1  gmcgarry 	int flags, mode;
    531      1.1  gmcgarry 	struct proc *p;
    532      1.1  gmcgarry {
    533      1.1  gmcgarry 	struct gpib_softc *sc;
    534      1.1  gmcgarry 
    535      1.1  gmcgarry 	sc = device_lookup(&gpib_cd, GPIBUNIT(dev));
    536      1.1  gmcgarry 	if (sc == NULL)
    537      1.1  gmcgarry 		return (ENXIO);
    538      1.1  gmcgarry 
    539      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpibopen: sc=%p\n", sc));
    540      1.1  gmcgarry 
    541      1.1  gmcgarry 	if (sc->sc_flags & GPIBF_ACTIVE)
    542      1.1  gmcgarry 		return (EBUSY);
    543      1.1  gmcgarry 	sc->sc_flags |= GPIBF_ACTIVE;
    544      1.1  gmcgarry 
    545      1.1  gmcgarry 	return (0);
    546      1.1  gmcgarry }
    547      1.1  gmcgarry 
    548      1.1  gmcgarry int
    549      1.1  gmcgarry gpibclose(dev, flag, mode, p)
    550      1.1  gmcgarry 	dev_t dev;
    551      1.1  gmcgarry 	int flag, mode;
    552      1.1  gmcgarry 	struct proc *p;
    553      1.1  gmcgarry {
    554      1.1  gmcgarry 	struct gpib_softc *sc;
    555      1.1  gmcgarry 
    556      1.1  gmcgarry 	sc = device_lookup(&gpib_cd, GPIBUNIT(dev));
    557      1.1  gmcgarry 	if (sc == NULL)
    558      1.1  gmcgarry 		return (ENXIO);
    559      1.1  gmcgarry 
    560      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpibclose: sc=%p\n", sc));
    561      1.1  gmcgarry 
    562      1.1  gmcgarry 	sc->sc_flags &= ~GPIBF_ACTIVE;
    563      1.1  gmcgarry 
    564      1.1  gmcgarry 	return (0);
    565      1.1  gmcgarry }
    566      1.1  gmcgarry 
    567      1.1  gmcgarry int
    568      1.1  gmcgarry gpibread(dev, uio, flags)
    569      1.1  gmcgarry 	dev_t dev;
    570      1.1  gmcgarry 	struct uio *uio;
    571      1.1  gmcgarry 	int flags;
    572      1.1  gmcgarry {
    573      1.1  gmcgarry 	struct gpib_softc *sc;
    574      1.1  gmcgarry 
    575      1.1  gmcgarry 	sc = device_lookup(&gpib_cd, GPIBUNIT(dev));
    576      1.1  gmcgarry 	if (sc == NULL)
    577      1.1  gmcgarry 		return (ENXIO);
    578      1.1  gmcgarry 
    579      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpibread: sc=%p\n", sc));
    580      1.1  gmcgarry 
    581      1.1  gmcgarry 	return (EOPNOTSUPP);
    582      1.1  gmcgarry }
    583      1.1  gmcgarry 
    584      1.1  gmcgarry int
    585      1.1  gmcgarry gpibwrite(dev, uio, flags)
    586      1.1  gmcgarry 	dev_t dev;
    587      1.1  gmcgarry 	struct uio *uio;
    588      1.1  gmcgarry 	int flags;
    589      1.1  gmcgarry {
    590      1.1  gmcgarry 	struct gpib_softc *sc;
    591      1.1  gmcgarry 
    592      1.1  gmcgarry 	sc = device_lookup(&gpib_cd, GPIBUNIT(dev));
    593      1.1  gmcgarry 	if (sc == NULL)
    594      1.1  gmcgarry 		return (ENXIO);
    595      1.1  gmcgarry 
    596      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpibwrite: sc=%p\n", sc));
    597      1.1  gmcgarry 
    598      1.1  gmcgarry 	return (EOPNOTSUPP);
    599      1.1  gmcgarry }
    600      1.1  gmcgarry 
    601      1.1  gmcgarry int
    602      1.1  gmcgarry gpibioctl(dev, cmd, data, flag, p)
    603      1.1  gmcgarry 	dev_t dev;
    604      1.1  gmcgarry 	u_long cmd;
    605      1.1  gmcgarry 	caddr_t data;
    606      1.1  gmcgarry 	int flag;
    607      1.1  gmcgarry 	struct proc *p;
    608      1.1  gmcgarry {
    609      1.1  gmcgarry 	struct gpib_softc *sc;
    610      1.1  gmcgarry 
    611      1.1  gmcgarry 	sc = device_lookup(&gpib_cd, GPIBUNIT(dev));
    612      1.1  gmcgarry 	if (sc == NULL)
    613      1.1  gmcgarry 		return (ENXIO);
    614      1.1  gmcgarry 
    615      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpibioctl(%lu, '%c',%lu): sc=%p\n",
    616      1.1  gmcgarry 	    IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), cmd & 0xff, sc));
    617      1.1  gmcgarry 
    618      1.1  gmcgarry 	switch (cmd) {
    619      1.1  gmcgarry 	case GPIB_INFO:
    620      1.1  gmcgarry 		(*(int *)data) = 0xa5a5a5a5;
    621      1.1  gmcgarry 		break;
    622      1.1  gmcgarry 	}
    623      1.1  gmcgarry 
    624      1.1  gmcgarry 	return (EINVAL);
    625      1.1  gmcgarry }
    626      1.1  gmcgarry 
    627      1.1  gmcgarry int
    628      1.1  gmcgarry gpibpoll(dev, events, p)
    629      1.1  gmcgarry 	dev_t dev;
    630      1.1  gmcgarry 	int events;
    631      1.1  gmcgarry 	struct proc *p;
    632      1.1  gmcgarry {
    633      1.1  gmcgarry 	struct gpib_softc *sc;
    634      1.1  gmcgarry 
    635      1.1  gmcgarry 	sc = device_lookup(&gpib_cd, GPIBUNIT(dev));
    636      1.1  gmcgarry 	if (sc == NULL)
    637      1.1  gmcgarry 		return (ENXIO);
    638      1.1  gmcgarry 
    639      1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("gpibpoll: sc=%p\n", sc));
    640      1.1  gmcgarry 
    641      1.1  gmcgarry 	return (0);
    642      1.1  gmcgarry }
    643