upd7210.c revision 141398
1141398Sphk/*- 2141398Sphk * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org> 3141398Sphk * All rights reserved. 4141398Sphk * 5141398Sphk * Redistribution and use in source and binary forms, with or without 6141398Sphk * modification, are permitted provided that the following conditions 7141398Sphk * are met: 8141398Sphk * 1. Redistributions of source code must retain the above copyright 9141398Sphk * notice, this list of conditions and the following disclaimer. 10141398Sphk * 2. Redistributions in binary form must reproduce the above copyright 11141398Sphk * notice, this list of conditions and the following disclaimer in the 12141398Sphk * documentation and/or other materials provided with the distribution. 13141398Sphk * 14141398Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15141398Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16141398Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17141398Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18141398Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19141398Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20141398Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21141398Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22141398Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23141398Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24141398Sphk * SUCH DAMAGE. 25141398Sphk * 26141398Sphk * High-level driver for �PD7210 based GPIB cards. 27141398Sphk * 28141398Sphk */ 29141398Sphk 30141398Sphk#include <sys/cdefs.h> 31141398Sphk__FBSDID("$FreeBSD: head/sys/dev/ieee488/upd7210.c 141398 2005-02-06 15:22:23Z phk $"); 32141398Sphk 33141398Sphk# define GPIB_DEBUG 34141398Sphk# undef GPIB_DEBUG 35141398Sphk 36141398Sphk#include <sys/param.h> 37141398Sphk#include <sys/systm.h> 38141398Sphk#include <sys/conf.h> 39141398Sphk#include <sys/malloc.h> 40141398Sphk#include <sys/kernel.h> 41141398Sphk#include <sys/limits.h> 42141398Sphk#include <sys/module.h> 43141398Sphk#include <sys/bus.h> 44141398Sphk#include <sys/lock.h> 45141398Sphk#include <sys/mutex.h> 46141398Sphk#include <sys/uio.h> 47141398Sphk#include <sys/time.h> 48141398Sphk#include <machine/bus.h> 49141398Sphk#include <machine/resource.h> 50141398Sphk#include <isa/isavar.h> 51141398Sphk 52141398Sphk#include <dev/ieee488/upd7210.h> 53141398Sphk#include <dev/ieee488/ugpib.h> 54141398Sphk 55141398SphkMALLOC_DEFINE(M_GPIB, "GPIB", "GPIB"); 56141398Sphk 57141398Sphk/* upd7210 generic stuff */ 58141398Sphk 59141398Sphkstatic void 60141398Sphkprint_isr(u_int isr1, u_int isr2) 61141398Sphk{ 62141398Sphk printf("isr1=0x%b isr2=0x%b", 63141398Sphk isr1, "\20\10CPT\7APT\6DET\5ENDRX\4DEC\3ERR\2DO\1DI", 64141398Sphk isr2, "\20\10INT\7SRQI\6LOK\5REM\4CO\3LOKC\2REMC\1ADSC"); 65141398Sphk} 66141398Sphk 67141398Sphkstatic u_int 68141398Sphkread_reg(struct upd7210 *u, enum upd7210_rreg reg) 69141398Sphk{ 70141398Sphk u_int r; 71141398Sphk 72141398Sphk r = bus_space_read_1( 73141398Sphk u->reg_tag[reg], 74141398Sphk u->reg_handle[reg], 75141398Sphk u->reg_offset[reg]); 76141398Sphk u->rreg[reg] = r; 77141398Sphk return (r); 78141398Sphk} 79141398Sphk 80141398Sphkstatic void 81141398Sphkwrite_reg(struct upd7210 *u, enum upd7210_wreg reg, u_int val) 82141398Sphk{ 83141398Sphk bus_space_write_1( 84141398Sphk u->reg_tag[reg], 85141398Sphk u->reg_handle[reg], 86141398Sphk u->reg_offset[reg], val); 87141398Sphk u->wreg[reg] = val; 88141398Sphk if (reg == AUXMR) 89141398Sphk u->wreg[8 + (val >> 5)] = val & 0x1f; 90141398Sphk} 91141398Sphk 92141398Sphkvoid 93141398Sphkupd7210intr(void *arg) 94141398Sphk{ 95141398Sphk u_int isr1, isr2; 96141398Sphk struct upd7210 *u; 97141398Sphk 98141398Sphk u = arg; 99141398Sphk mtx_lock(&u->mutex); 100141398Sphk isr1 = read_reg(u, ISR1); 101141398Sphk isr2 = read_reg(u, ISR2); 102141398Sphk if (u->busy == 0 || u->irq == NULL || !u->irq(u)) { 103141398Sphk printf("upd7210intr [%02x %02x %02x", 104141398Sphk read_reg(u, DIR), isr1, isr2); 105141398Sphk printf(" %02x %02x %02x %02x %02x] ", 106141398Sphk read_reg(u, SPSR), 107141398Sphk read_reg(u, ADSR), 108141398Sphk read_reg(u, CPTR), 109141398Sphk read_reg(u, ADR0), 110141398Sphk read_reg(u, ADR1)); 111141398Sphk print_isr(isr1, isr2); 112141398Sphk printf("\n"); 113141398Sphk write_reg(u, IMR1, 0); 114141398Sphk write_reg(u, IMR2, 0); 115141398Sphk } 116141398Sphk mtx_unlock(&u->mutex); 117141398Sphk} 118141398Sphk 119141398Sphkstatic int 120141398Sphkupd7210_take_ctrl_async(struct upd7210 *u) 121141398Sphk{ 122141398Sphk int i; 123141398Sphk 124141398Sphk write_reg(u, AUXMR, AUXMR_TCA); 125141398Sphk 126141398Sphk if (!(read_reg(u, ADSR) & ADSR_ATN)) 127141398Sphk return (0); 128141398Sphk for (i = 0; i < 20; i++) { 129141398Sphk DELAY(1); 130141398Sphk if (!(read_reg(u, ADSR) & ADSR_ATN)) 131141398Sphk return (0); 132141398Sphk } 133141398Sphk return (1); 134141398Sphk} 135141398Sphk 136141398Sphkstatic int 137141398Sphkupd7210_goto_standby(struct upd7210 *u) 138141398Sphk{ 139141398Sphk int i; 140141398Sphk 141141398Sphk write_reg(u, AUXMR, AUXMR_GTS); 142141398Sphk 143141398Sphk if (read_reg(u, ADSR) & ADSR_ATN) 144141398Sphk return (0); 145141398Sphk for (i = 0; i < 20; i++) { 146141398Sphk DELAY(1); 147141398Sphk if (read_reg(u, ADSR) & ADSR_ATN) 148141398Sphk return (0); 149141398Sphk } 150141398Sphk return (1); 151141398Sphk} 152141398Sphk 153141398Sphkstatic int 154141398Sphkdeadyet(struct upd7210 *u) 155141398Sphk{ 156141398Sphk struct timeval tv; 157141398Sphk 158141398Sphk if (!timevalisset(&u->deadline)) 159141398Sphk return (0); 160141398Sphk 161141398Sphk getmicrouptime(&tv); 162141398Sphk if (timevalcmp(&u->deadline, &tv, <)) { 163141398Sphkprintf("DEADNOW\n"); 164141398Sphk return (1); 165141398Sphk } 166141398Sphk 167141398Sphk return (0); 168141398Sphk} 169141398Sphk 170141398Sphk/* Unaddressed Listen Only mode */ 171141398Sphk 172141398Sphkstatic int 173141398Sphkgpib_l_irq(struct upd7210 *u) 174141398Sphk{ 175141398Sphk int i; 176141398Sphk 177141398Sphk if (u->rreg[ISR1] & 1) { 178141398Sphk i = read_reg(u, DIR); 179141398Sphk u->buf[u->buf_wp++] = i; 180141398Sphk u->buf_wp &= (u->bufsize - 1); 181141398Sphk i = (u->buf_rp + u->bufsize - u->buf_wp) & (u->bufsize - 1); 182141398Sphk if (i < 8) 183141398Sphk write_reg(u, IMR1, 0); 184141398Sphk wakeup(u->buf); 185141398Sphk return (1); 186141398Sphk } 187141398Sphk return (0); 188141398Sphk} 189141398Sphk 190141398Sphkstatic int 191141398Sphkgpib_l_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 192141398Sphk{ 193141398Sphk struct upd7210 *u; 194141398Sphk 195141398Sphk u = dev->si_drv1; 196141398Sphk 197141398Sphk mtx_lock(&u->mutex); 198141398Sphk if (u->busy) 199141398Sphk return (EBUSY); 200141398Sphk u->busy = 1; 201141398Sphk u->irq = gpib_l_irq; 202141398Sphk mtx_unlock(&u->mutex); 203141398Sphk 204141398Sphk u->buf = malloc(PAGE_SIZE, M_GPIB, M_WAITOK); 205141398Sphk u->bufsize = PAGE_SIZE; 206141398Sphk u->buf_wp = 0; 207141398Sphk u->buf_rp = 0; 208141398Sphk 209141398Sphk write_reg(u, AUXMR, AUXMR_CRST); 210141398Sphk DELAY(10000); 211141398Sphk write_reg(u, AUXMR, C_ICR | 8); 212141398Sphk DELAY(1000); 213141398Sphk write_reg(u, ADR, 0x60); 214141398Sphk write_reg(u, ADR, 0xe0); 215141398Sphk write_reg(u, ADMR, 0x70); 216141398Sphk write_reg(u, AUXMR, AUXMR_PON); 217141398Sphk write_reg(u, IMR1, 0x01); 218141398Sphk return (0); 219141398Sphk} 220141398Sphk 221141398Sphkstatic int 222141398Sphkgpib_l_close(struct cdev *dev, int oflags, int devtype, struct thread *td) 223141398Sphk{ 224141398Sphk struct upd7210 *u; 225141398Sphk 226141398Sphk u = dev->si_drv1; 227141398Sphk 228141398Sphk mtx_lock(&u->mutex); 229141398Sphk u->busy = 0; 230141398Sphk write_reg(u, AUXMR, AUXMR_CRST); 231141398Sphk DELAY(10000); 232141398Sphk write_reg(u, IMR1, 0x00); 233141398Sphk write_reg(u, IMR2, 0x00); 234141398Sphk free(u->buf, M_GPIB); 235141398Sphk u->buf = NULL; 236141398Sphk mtx_unlock(&u->mutex); 237141398Sphk return (0); 238141398Sphk} 239141398Sphk 240141398Sphkstatic int 241141398Sphkgpib_l_read(struct cdev *dev, struct uio *uio, int ioflag) 242141398Sphk{ 243141398Sphk struct upd7210 *u; 244141398Sphk int error; 245141398Sphk size_t z; 246141398Sphk 247141398Sphk u = dev->si_drv1; 248141398Sphk error = 0; 249141398Sphk 250141398Sphk mtx_lock(&u->mutex); 251141398Sphk while (u->buf_wp == u->buf_rp) { 252141398Sphk error = msleep(u->buf, &u->mutex, PZERO | PCATCH, 253141398Sphk "gpibrd", hz); 254141398Sphk if (error && error != EWOULDBLOCK) { 255141398Sphk mtx_unlock(&u->mutex); 256141398Sphk return (error); 257141398Sphk } 258141398Sphk } 259141398Sphk while (uio->uio_resid > 0 && u->buf_wp != u->buf_rp) { 260141398Sphk if (u->buf_wp < u->buf_rp) 261141398Sphk z = u->bufsize - u->buf_rp; 262141398Sphk else 263141398Sphk z = u->buf_wp - u->buf_rp; 264141398Sphk if (z > uio->uio_resid) 265141398Sphk z = uio->uio_resid; 266141398Sphk mtx_unlock(&u->mutex); 267141398Sphk error = uiomove(u->buf + u->buf_rp, z, uio); 268141398Sphk mtx_lock(&u->mutex); 269141398Sphk if (error) 270141398Sphk break; 271141398Sphk u->buf_rp += z; 272141398Sphk u->buf_rp &= (u->bufsize - 1); 273141398Sphk } 274141398Sphk if (u->wreg[IMR1] == 0) 275141398Sphk write_reg(u, IMR1, 0x01); 276141398Sphk mtx_unlock(&u->mutex); 277141398Sphk return (error); 278141398Sphk} 279141398Sphk 280141398Sphkstruct cdevsw gpib_l_cdevsw = { 281141398Sphk .d_version = D_VERSION, 282141398Sphk .d_name = "gpib_l", 283141398Sphk .d_open = gpib_l_open, 284141398Sphk .d_close = gpib_l_close, 285141398Sphk .d_read = gpib_l_read, 286141398Sphk}; 287141398Sphk 288141398Sphk/* ibfoo API */ 289141398Sphk 290141398Sphk#include <dev/ieee488/ibfoo_int.h> 291141398Sphk 292141398Sphkstruct handle { 293141398Sphk LIST_ENTRY(handle) list; 294141398Sphk int handle; 295141398Sphk int pad; 296141398Sphk int sad; 297141398Sphk struct timeval timeout; 298141398Sphk int eot; 299141398Sphk int eos; 300141398Sphk}; 301141398Sphk 302141398Sphkstruct ibfoo { 303141398Sphk struct upd7210 *upd7210; 304141398Sphk LIST_HEAD(,handle) handles; 305141398Sphk struct unrhdr *unrhdr; 306141398Sphk 307141398Sphk u_char *cmdbuf; 308141398Sphk u_int cmdlen; 309141398Sphk 310141398Sphk struct handle *rdh; /* addressed for read */ 311141398Sphk struct handle *wrh; /* addressed for write */ 312141398Sphk 313141398Sphk u_char *dobuf; 314141398Sphk u_int dolen; 315141398Sphk int doeoi; 316141398Sphk}; 317141398Sphk 318141398Sphkstatic struct timeval timeouts[] = { 319141398Sphk [TNONE] = { 0, 0}, 320141398Sphk [T10us] = { 0, 10}, 321141398Sphk [T30us] = { 0, 30}, 322141398Sphk [T100us] = { 0, 100}, 323141398Sphk [T300us] = { 0, 300}, 324141398Sphk [T1ms] = { 0, 1000}, 325141398Sphk [T3ms] = { 0, 3000}, 326141398Sphk [T10ms] = { 0, 10000}, 327141398Sphk [T30ms] = { 0, 30000}, 328141398Sphk [T100ms] = { 0, 100000}, 329141398Sphk [T300ms] = { 0, 300000}, 330141398Sphk [T1s] = { 1, 0}, 331141398Sphk [T3s] = { 3, 0}, 332141398Sphk [T10s] = { 10, 0}, 333141398Sphk [T30s] = { 30, 0}, 334141398Sphk [T100s] = { 100, 0}, 335141398Sphk [T300s] = { 300, 0}, 336141398Sphk [T1000s] = { 1000, 0} 337141398Sphk}; 338141398Sphk 339141398Sphkstatic u_int max_timeouts = sizeof timeouts / sizeof timeouts[0]; 340141398Sphk 341141398Sphktypedef int ibhandler_t(struct upd7210 *u, struct ibfoo_iocarg *ap); 342141398Sphk 343141398Sphkstatic int 344141398Sphkgpib_ib_irq(struct upd7210 *u) 345141398Sphk{ 346141398Sphk struct ibfoo *ib; 347141398Sphk 348141398Sphk ib = u->ibfoo; 349141398Sphk 350141398Sphk if ((u->rreg[ISR2] & IXR2_CO) && ib->cmdlen > 0) { 351141398Sphk write_reg(u, CDOR, *ib->cmdbuf); 352141398Sphk ib->cmdbuf++; 353141398Sphk ib->cmdlen--; 354141398Sphk if (ib->cmdlen == 0) { 355141398Sphk wakeup(ib); 356141398Sphk write_reg(u, IMR2, 0); 357141398Sphk } 358141398Sphk return (1); 359141398Sphk } 360141398Sphk if ((u->rreg[ISR1] & IXR1_DO) && ib->dolen > 0) { 361141398Sphk if (ib->dolen == 1 && ib->doeoi) 362141398Sphk write_reg(u, AUXMR, AUXMR_SEOI); 363141398Sphk write_reg(u, CDOR, *ib->dobuf); 364141398Sphk ib->dobuf++; 365141398Sphk ib->dolen--; 366141398Sphk if (ib->dolen == 0) { 367141398Sphk wakeup(ib); 368141398Sphk write_reg(u, IMR1, 0); 369141398Sphk } 370141398Sphk return (1); 371141398Sphk } 372141398Sphk if (u->rreg[ISR1] & IXR1_ENDRX) { 373141398Sphk write_reg(u, IMR1, 0); 374141398Sphk wakeup(ib); 375141398Sphk return (1); 376141398Sphk } 377141398Sphk 378141398Sphk return (0); 379141398Sphk} 380141398Sphk 381141398Sphkstatic void 382141398Sphkconfig_eos(struct upd7210 *u, struct handle *h) 383141398Sphk{ 384141398Sphk int i; 385141398Sphk 386141398Sphk i = 0; 387141398Sphk if (h->eos & 0x0400) { 388141398Sphk write_reg(u, EOSR, h->eos & 0xff); 389141398Sphk i |= AUXA_REOS; 390141398Sphk } 391141398Sphk if (h->eos & 0x1000) 392141398Sphk i |= AUXA_BIN; 393141398Sphk write_reg(u, AUXRA, C_AUXA | i); 394141398Sphk} 395141398Sphk 396141398Sphk/* 397141398Sphk * Look up the handle, and set the deadline if the handle has a timeout. 398141398Sphk */ 399141398Sphkstatic int 400141398Sphkgethandle(struct upd7210 *u, struct ibfoo_iocarg *ap, struct handle **hp) 401141398Sphk{ 402141398Sphk struct ibfoo *ib; 403141398Sphk struct handle *h; 404141398Sphk 405141398Sphk KASSERT(ap->__field & __F_HANDLE, ("gethandle without __F_HANDLE")); 406141398Sphk ib = u->ibfoo; 407141398Sphk LIST_FOREACH(h, &ib->handles, list) { 408141398Sphk if (h->handle == ap->handle) { 409141398Sphk *hp = h; 410141398Sphk if (timevalisset(&h->timeout)) { 411141398Sphk getmicrouptime(&u->deadline); 412141398Sphk timevaladd(&u->deadline, &h->timeout); 413141398Sphk } else { 414141398Sphk timevalclear(&u->deadline); 415141398Sphk } 416141398Sphk return (0); 417141398Sphk } 418141398Sphk } 419141398Sphk ap->__iberr = EARG; 420141398Sphk return (1); 421141398Sphk} 422141398Sphk 423141398Sphkstatic int 424141398Sphkdo_cmd(struct upd7210 *u, u_char *cmd, int len) 425141398Sphk{ 426141398Sphk int i, i1, i2; 427141398Sphk struct ibfoo *ib; 428141398Sphk 429141398Sphk ib = u->ibfoo; 430141398Sphk 431141398Sphk if (ib->rdh != NULL || ib->wrh != NULL) { 432141398Sphk upd7210_take_ctrl_async(u); 433141398Sphk ib->rdh = NULL; 434141398Sphk ib->wrh = NULL; 435141398Sphk } 436141398Sphk mtx_lock(&u->mutex); 437141398Sphk ib->cmdbuf = cmd; 438141398Sphk ib->cmdlen = len; 439141398Sphk 440141398Sphk if (!(u->rreg[ISR2] & IXR2_CO)) { 441141398Sphk i1 = read_reg(u, ISR1); 442141398Sphk i2 = read_reg(u, ISR2); 443141398Sphk#ifdef GPIB_DEBUG 444141398Sphk print_isr(i1, i2); 445141398Sphk printf("\n"); 446141398Sphk#endif 447141398Sphk } 448141398Sphk write_reg(u, IMR2, IXR2_CO); 449141398Sphk if (u->rreg[ISR2] & IXR2_CO) { 450141398Sphk write_reg(u, CDOR, *ib->cmdbuf); 451141398Sphk ib->cmdbuf++; 452141398Sphk ib->cmdlen--; 453141398Sphk } 454141398Sphk 455141398Sphk while (1) { 456141398Sphk i = msleep(ib, &u->mutex, PZERO | PCATCH, "gpib_cmd", hz/10); 457141398Sphk if (i == EINTR) 458141398Sphk break; 459141398Sphk if (u->rreg[ISR1] & IXR1_ERR) 460141398Sphk break; 461141398Sphk if (!ib->cmdlen) 462141398Sphk break; 463141398Sphk if (deadyet(u)) 464141398Sphk break; 465141398Sphk } 466141398Sphk write_reg(u, IMR2, 0); 467141398Sphk mtx_unlock(&u->mutex); 468141398Sphk return (0); 469141398Sphk} 470141398Sphk 471141398Sphkstatic int 472141398Sphkdo_odata(struct upd7210 *u, u_char *data, int len, int eos) 473141398Sphk{ 474141398Sphk int i1, i2, i; 475141398Sphk struct ibfoo *ib; 476141398Sphk 477141398Sphk ib = u->ibfoo; 478141398Sphk 479141398Sphk mtx_lock(&u->mutex); 480141398Sphk ib->dobuf = data; 481141398Sphk ib->dolen = len; 482141398Sphk ib->doeoi = 1; 483141398Sphk 484141398Sphk if (!(u->rreg[ISR1] & IXR1_DO)) { 485141398Sphk i1 = read_reg(u, ISR1); 486141398Sphk i2 = read_reg(u, ISR2); 487141398Sphk#ifdef GPIB_DEBUG 488141398Sphk print_isr(i1, i2); 489141398Sphk printf("\n"); 490141398Sphk#endif 491141398Sphk } 492141398Sphk write_reg(u, IMR1, IXR1_DO); 493141398Sphk if (u->rreg[ISR1] & IXR1_DO) { 494141398Sphk write_reg(u, CDOR, *ib->dobuf); 495141398Sphk ib->dobuf++; 496141398Sphk ib->dolen--; 497141398Sphk } 498141398Sphk while (1) { 499141398Sphk i = msleep(ib, &u->mutex, PZERO | PCATCH, "gpib_out", hz/100); 500141398Sphk if (i == EINTR) 501141398Sphk break; 502141398Sphk if (u->rreg[ISR1] & IXR1_ERR) 503141398Sphk break; 504141398Sphk if (!ib->dolen) 505141398Sphk break; 506141398Sphk if (deadyet(u)) 507141398Sphk break; 508141398Sphk } 509141398Sphk write_reg(u, IMR2, 0); 510141398Sphk mtx_unlock(&u->mutex); 511141398Sphk return (len - ib->dolen); 512141398Sphk} 513141398Sphk 514141398Sphkstatic int 515141398Sphkdo_idata(struct upd7210 *u, u_char *data, int len, int eos) 516141398Sphk{ 517141398Sphk int i1, i2, i, j; 518141398Sphk 519141398Sphk write_reg(u, IMR1, IXR1_ENDRX); 520141398Sphk mtx_lock(&Giant); 521141398Sphk isa_dmastart(ISADMA_READ, data, len, u->dmachan); 522141398Sphk mtx_unlock(&Giant); 523141398Sphk mtx_lock(&u->mutex); 524141398Sphk write_reg(u, IMR2, IMR2_DMAI); 525141398Sphk while (1) { 526141398Sphk i = msleep(u->ibfoo, &u->mutex, PZERO | PCATCH, 527141398Sphk "gpib_idata", hz/100); 528141398Sphk if (i == EINTR) 529141398Sphk break; 530141398Sphk if (isa_dmatc(u->dmachan)) 531141398Sphk break; 532141398Sphk if (i == EWOULDBLOCK) { 533141398Sphk i1 = read_reg(u, ISR1); 534141398Sphk i2 = read_reg(u, ISR2); 535141398Sphk } else { 536141398Sphk i1 = u->rreg[ISR1]; 537141398Sphk i2 = u->rreg[ISR2]; 538141398Sphk } 539141398Sphk if (i1 & IXR1_ENDRX) 540141398Sphk break; 541141398Sphk if (deadyet(u)) 542141398Sphk break; 543141398Sphk } 544141398Sphk write_reg(u, IMR1, 0); 545141398Sphk write_reg(u, IMR2, 0); 546141398Sphk mtx_unlock(&u->mutex); 547141398Sphk mtx_lock(&Giant); 548141398Sphk j = isa_dmastatus(u->dmachan); 549141398Sphk isa_dmadone(ISADMA_READ, data, len, u->dmachan); 550141398Sphk mtx_unlock(&Giant); 551141398Sphk if (deadyet(u)) { 552141398Sphk return (-1); 553141398Sphk } else { 554141398Sphk return (len - j); 555141398Sphk } 556141398Sphk} 557141398Sphk 558141398Sphk#define ibask NULL 559141398Sphk#define ibbna NULL 560141398Sphk#define ibcac NULL 561141398Sphk#define ibclr NULL 562141398Sphk#define ibcmd NULL 563141398Sphk#define ibcmda NULL 564141398Sphk#define ibconfig NULL 565141398Sphk 566141398Sphkstatic int 567141398Sphkibdev(struct upd7210 *u, struct ibfoo_iocarg *ap) 568141398Sphk{ 569141398Sphk struct handle *h; 570141398Sphk struct ibfoo *ib; 571141398Sphk 572141398Sphk if (ap->pad < 0 || 573141398Sphk ap->pad > 30 || 574141398Sphk (ap->sad != 0 && ap->sad < 0x60) || 575141398Sphk ap->sad > 126) { 576141398Sphk ap->__retval = -1; 577141398Sphk ap->__iberr = EARG; 578141398Sphk return (0); 579141398Sphk } 580141398Sphk 581141398Sphk ib = u->ibfoo; 582141398Sphk h = malloc(sizeof *h, M_GPIB, M_ZERO | M_WAITOK); 583141398Sphk h->handle = alloc_unr(ib->unrhdr); 584141398Sphk LIST_INSERT_HEAD(&ib->handles, h, list); 585141398Sphk h->pad = ap->pad; 586141398Sphk h->sad = ap->sad; 587141398Sphk h->timeout = timeouts[ap->tmo]; 588141398Sphk h->eot = ap->eot; 589141398Sphk h->eos = ap->eos; 590141398Sphk ap->__retval = h->handle; 591141398Sphk return (0); 592141398Sphk} 593141398Sphk 594141398Sphk#define ibdiag NULL 595141398Sphk#define ibdma NULL 596141398Sphk 597141398Sphkstatic int 598141398Sphkibeos(struct upd7210 *u, struct ibfoo_iocarg *ap) 599141398Sphk{ 600141398Sphk struct handle *h; 601141398Sphk struct ibfoo *ib; 602141398Sphk 603141398Sphk if (gethandle(u, ap, &h)) 604141398Sphk return (0); 605141398Sphk ib = u->ibfoo; 606141398Sphk h->eos = ap->eos; 607141398Sphk if (ib->rdh == h) 608141398Sphk config_eos(u, h); 609141398Sphk ap->__retval = 0; 610141398Sphk return (0); 611141398Sphk} 612141398Sphk 613141398Sphk#define ibeot NULL 614141398Sphk#define ibevent NULL 615141398Sphk#define ibfind NULL 616141398Sphk#define ibgts NULL 617141398Sphk#define ibist NULL 618141398Sphk#define iblines NULL 619141398Sphk#define ibllo NULL 620141398Sphk#define ibln NULL 621141398Sphk#define ibloc NULL 622141398Sphk#define ibonl NULL 623141398Sphk#define ibpad NULL 624141398Sphk#define ibpct NULL 625141398Sphk#define ibpoke NULL 626141398Sphk#define ibppc NULL 627141398Sphk 628141398Sphkstatic int 629141398Sphkibrd(struct upd7210 *u, struct ibfoo_iocarg *ap) 630141398Sphk{ 631141398Sphk struct ibfoo *ib; 632141398Sphk struct handle *h; 633141398Sphk u_char buf[10], *bp; 634141398Sphk int i, j, error, bl, bc; 635141398Sphk u_char *dp; 636141398Sphk 637141398Sphk ib = u->ibfoo; 638141398Sphk if (gethandle(u, ap, &h)) 639141398Sphk return (0); 640141398Sphk bl = ap->cnt; 641141398Sphk if (bl > PAGE_SIZE) 642141398Sphk bl = PAGE_SIZE; 643141398Sphk bp = malloc(bl, M_GPIB, M_WAITOK); 644141398Sphk 645141398Sphk if (ib->rdh != h) { 646141398Sphk i = 0; 647141398Sphk buf[i++] = UNT; 648141398Sphk buf[i++] = UNL; 649141398Sphk buf[i++] = LAD | 0; 650141398Sphk buf[i++] = TAD | h->pad; 651141398Sphk if (h->sad) 652141398Sphk buf[i++] = h->sad; 653141398Sphk i = do_cmd(u, buf, i); 654141398Sphk config_eos(u, h); 655141398Sphk ib->rdh = h; 656141398Sphk ib->wrh = NULL; 657141398Sphk upd7210_goto_standby(u); 658141398Sphk } 659141398Sphk ap->__ibcnt = 0; 660141398Sphk dp = ap->buffer; 661141398Sphk bc = ap->cnt; 662141398Sphk error = 0; 663141398Sphk while (bc > 0) { 664141398Sphk j = imin(bc, PAGE_SIZE); 665141398Sphk i = do_idata(u, bp, j, 1); 666141398Sphk if (i <= 0) 667141398Sphk break; 668141398Sphk error = copyout(bp, dp , i); 669141398Sphk if (error) 670141398Sphk break; 671141398Sphk ap->__ibcnt += i; 672141398Sphk if (i != j) 673141398Sphk break; 674141398Sphk bc -= i; 675141398Sphk dp += i; 676141398Sphk } 677141398Sphk free(bp, M_GPIB); 678141398Sphk ap->__retval = 0; 679141398Sphk return (error); 680141398Sphk} 681141398Sphk 682141398Sphk#define ibrda NULL 683141398Sphk#define ibrdf NULL 684141398Sphk#define ibrdkey NULL 685141398Sphk#define ibrpp NULL 686141398Sphk#define ibrsc NULL 687141398Sphk#define ibrsp NULL 688141398Sphk#define ibrsv NULL 689141398Sphk#define ibsad NULL 690141398Sphk#define ibsgnl NULL 691141398Sphk#define ibsic NULL 692141398Sphk#define ibsre NULL 693141398Sphk#define ibsrq NULL 694141398Sphk#define ibstop NULL 695141398Sphk 696141398Sphkstatic int 697141398Sphkibtmo(struct upd7210 *u, struct ibfoo_iocarg *ap) 698141398Sphk{ 699141398Sphk struct handle *h; 700141398Sphk 701141398Sphk if (gethandle(u, ap, &h)) 702141398Sphk return (0); 703141398Sphk h->timeout = timeouts[ap->tmo]; 704141398Sphk return (0); 705141398Sphk} 706141398Sphk 707141398Sphk#define ibtrap NULL 708141398Sphk#define ibtrg NULL 709141398Sphk#define ibwait NULL 710141398Sphk 711141398Sphkstatic int 712141398Sphkibwrt(struct upd7210 *u, struct ibfoo_iocarg *ap) 713141398Sphk{ 714141398Sphk struct ibfoo *ib; 715141398Sphk struct handle *h; 716141398Sphk u_char buf[10], *bp; 717141398Sphk int i; 718141398Sphk 719141398Sphk ib = u->ibfoo; 720141398Sphk if (gethandle(u, ap, &h)) 721141398Sphk return (0); 722141398Sphk bp = malloc(ap->cnt, M_GPIB, M_WAITOK); 723141398Sphk i = copyin(ap->buffer, bp, ap->cnt); 724141398Sphk if (i) { 725141398Sphk free(bp, M_GPIB); 726141398Sphk return (i); 727141398Sphk } 728141398Sphk if (ib->wrh != h) { 729141398Sphk i = 0; 730141398Sphk buf[i++] = UNT; 731141398Sphk buf[i++] = UNL; 732141398Sphk buf[i++] = LAD | h->pad; 733141398Sphk if (h->sad) 734141398Sphk buf[i++] = LAD | TAD | h->sad; 735141398Sphk buf[i++] = TAD | 0; 736141398Sphk i = do_cmd(u, buf, i); 737141398Sphk ib->rdh = NULL; 738141398Sphk ib->wrh = h; 739141398Sphk upd7210_goto_standby(u); 740141398Sphk } 741141398Sphk i = do_odata(u, bp, ap->cnt, 1); 742141398Sphk ap->__ibcnt = i; 743141398Sphk ap->__retval = 0; 744141398Sphk free(bp, M_GPIB); 745141398Sphk return (0); 746141398Sphk} 747141398Sphk 748141398Sphk#define ibwrta NULL 749141398Sphk#define ibwrtf NULL 750141398Sphk#define ibwrtkey NULL 751141398Sphk#define ibxtrc NULL 752141398Sphk 753141398Sphkstatic struct ibhandler { 754141398Sphk const char *name; 755141398Sphk ibhandler_t *func; 756141398Sphk u_int args; 757141398Sphk} ibhandlers[] = { 758141398Sphk [__ID_IBASK] = { "ibask", ibask, __F_HANDLE | __F_OPTION | __F_RETVAL }, 759141398Sphk [__ID_IBBNA] = { "ibbna", ibbna, __F_HANDLE | __F_BDNAME }, 760141398Sphk [__ID_IBCAC] = { "ibcac", ibcac, __F_HANDLE | __F_V }, 761141398Sphk [__ID_IBCLR] = { "ibclr", ibclr, __F_HANDLE }, 762141398Sphk [__ID_IBCMDA] = { "ibcmda", ibcmda, __F_HANDLE | __F_BUFFER | __F_CNT }, 763141398Sphk [__ID_IBCMD] = { "ibcmd", ibcmd, __F_HANDLE | __F_BUFFER | __F_CNT }, 764141398Sphk [__ID_IBCONFIG] = { "ibconfig", ibconfig, __F_HANDLE | __F_OPTION | __F_VALUE }, 765141398Sphk [__ID_IBDEV] = { "ibdev", ibdev, __F_BOARDID | __F_PAD | __F_SAD | __F_TMO | __F_EOT | __F_EOS }, 766141398Sphk [__ID_IBDIAG] = { "ibdiag", ibdiag, __F_HANDLE | __F_BUFFER | __F_CNT }, 767141398Sphk [__ID_IBDMA] = { "ibdma", ibdma, __F_HANDLE | __F_V }, 768141398Sphk [__ID_IBEOS] = { "ibeos", ibeos, __F_HANDLE | __F_EOS }, 769141398Sphk [__ID_IBEOT] = { "ibeot", ibeot, __F_HANDLE | __F_V }, 770141398Sphk [__ID_IBEVENT] = { "ibevent", ibevent, __F_HANDLE | __F_EVENT }, 771141398Sphk [__ID_IBFIND] = { "ibfind", ibfind, __F_BDNAME }, 772141398Sphk [__ID_IBGTS] = { "ibgts", ibgts, __F_HANDLE | __F_V }, 773141398Sphk [__ID_IBIST] = { "ibist", ibist, __F_HANDLE | __F_V }, 774141398Sphk [__ID_IBLINES] = { "iblines", iblines, __F_HANDLE | __F_LINES }, 775141398Sphk [__ID_IBLLO] = { "ibllo", ibllo, __F_HANDLE }, 776141398Sphk [__ID_IBLN] = { "ibln", ibln, __F_HANDLE | __F_PADVAL | __F_SADVAL | __F_LISTENFLAG }, 777141398Sphk [__ID_IBLOC] = { "ibloc", ibloc, __F_HANDLE }, 778141398Sphk [__ID_IBONL] = { "ibonl", ibonl, __F_HANDLE | __F_V }, 779141398Sphk [__ID_IBPAD] = { "ibpad", ibpad, __F_HANDLE | __F_V }, 780141398Sphk [__ID_IBPCT] = { "ibpct", ibpct, __F_HANDLE }, 781141398Sphk [__ID_IBPOKE] = { "ibpoke", ibpoke, __F_HANDLE | __F_OPTION | __F_VALUE }, 782141398Sphk [__ID_IBPPC] = { "ibppc", ibppc, __F_HANDLE | __F_V }, 783141398Sphk [__ID_IBRDA] = { "ibrda", ibrda, __F_HANDLE | __F_BUFFER | __F_CNT }, 784141398Sphk [__ID_IBRDF] = { "ibrdf", ibrdf, __F_HANDLE | __F_FLNAME }, 785141398Sphk [__ID_IBRDKEY] = { "ibrdkey", ibrdkey, __F_HANDLE | __F_BUFFER | __F_CNT }, 786141398Sphk [__ID_IBRD] = { "ibrd", ibrd, __F_HANDLE | __F_BUFFER | __F_CNT }, 787141398Sphk [__ID_IBRPP] = { "ibrpp", ibrpp, __F_HANDLE | __F_PPR }, 788141398Sphk [__ID_IBRSC] = { "ibrsc", ibrsc, __F_HANDLE | __F_V }, 789141398Sphk [__ID_IBRSP] = { "ibrsp", ibrsp, __F_HANDLE | __F_SPR }, 790141398Sphk [__ID_IBRSV] = { "ibrsv", ibrsv, __F_HANDLE | __F_V }, 791141398Sphk [__ID_IBSAD] = { "ibsad", ibsad, __F_HANDLE | __F_V }, 792141398Sphk [__ID_IBSGNL] = { "ibsgnl", ibsgnl, __F_HANDLE | __F_V }, 793141398Sphk [__ID_IBSIC] = { "ibsic", ibsic, __F_HANDLE }, 794141398Sphk [__ID_IBSRE] = { "ibsre", ibsre, __F_HANDLE | __F_V }, 795141398Sphk [__ID_IBSRQ] = { "ibsrq", ibsrq, __F_FUNC }, 796141398Sphk [__ID_IBSTOP] = { "ibstop", ibstop, __F_HANDLE }, 797141398Sphk [__ID_IBTMO] = { "ibtmo", ibtmo, __F_HANDLE | __F_TMO }, 798141398Sphk [__ID_IBTRAP] = { "ibtrap", ibtrap, __F_MASK | __F_MODE }, 799141398Sphk [__ID_IBTRG] = { "ibtrg", ibtrg, __F_HANDLE }, 800141398Sphk [__ID_IBWAIT] = { "ibwait", ibwait, __F_HANDLE | __F_MASK }, 801141398Sphk [__ID_IBWRTA] = { "ibwrta", ibwrta, __F_HANDLE | __F_BUFFER | __F_CNT }, 802141398Sphk [__ID_IBWRTF] = { "ibwrtf", ibwrtf, __F_HANDLE | __F_FLNAME }, 803141398Sphk [__ID_IBWRTKEY] = { "ibwrtkey", ibwrtkey, __F_HANDLE | __F_BUFFER | __F_CNT }, 804141398Sphk [__ID_IBWRT] = { "ibwrt", ibwrt, __F_HANDLE | __F_BUFFER | __F_CNT }, 805141398Sphk [__ID_IBXTRC] = { "ibxtrc", ibxtrc, __F_HANDLE | __F_BUFFER | __F_CNT }, 806141398Sphk}; 807141398Sphk 808141398Sphkstatic u_int max_ibhandler = sizeof ibhandlers / sizeof ibhandlers[0]; 809141398Sphk 810141398Sphkstatic int 811141398Sphkgpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 812141398Sphk{ 813141398Sphk struct upd7210 *u; 814141398Sphk struct ibfoo *ib; 815141398Sphk int error; 816141398Sphk 817141398Sphk u = dev->si_drv1; 818141398Sphk 819141398Sphk mtx_lock(&u->mutex); 820141398Sphk if (u->busy) { 821141398Sphk mtx_unlock(&u->mutex); 822141398Sphk return (EBUSY); 823141398Sphk } 824141398Sphk u->busy = 1; 825141398Sphk mtx_unlock(&u->mutex); 826141398Sphk 827141398Sphk mtx_lock(&Giant); 828141398Sphk error = isa_dma_acquire(u->dmachan); 829141398Sphk if (!error) { 830141398Sphk error = isa_dma_init(u->dmachan, PAGE_SIZE, M_WAITOK); 831141398Sphk if (error) 832141398Sphk isa_dma_release(u->dmachan); 833141398Sphk } 834141398Sphk mtx_unlock(&Giant); 835141398Sphk if (error) { 836141398Sphk mtx_lock(&u->mutex); 837141398Sphk u->busy = 0; 838141398Sphk mtx_unlock(&u->mutex); 839141398Sphk return (error); 840141398Sphk } 841141398Sphk 842141398Sphk ib = malloc(sizeof *ib, M_GPIB, M_WAITOK | M_ZERO); 843141398Sphk LIST_INIT(&ib->handles); 844141398Sphk ib->unrhdr = new_unrhdr(0, INT_MAX); 845141398Sphk dev->si_drv2 = ib; 846141398Sphk ib->upd7210 = u; 847141398Sphk u->ibfoo = ib; 848141398Sphk u->irq = gpib_ib_irq; 849141398Sphk 850141398Sphk write_reg(u, AUXMR, AUXMR_CRST); 851141398Sphk DELAY(10000); 852141398Sphk DELAY(1000); 853141398Sphk write_reg(u, IMR1, 0x00); 854141398Sphk write_reg(u, IMR2, 0x00); 855141398Sphk write_reg(u, SPMR, 0x00); 856141398Sphk write_reg(u, ADR, 0x00); 857141398Sphk write_reg(u, ADR, ADR_ARS | ADR_DL | ADR_DT); 858141398Sphk write_reg(u, ADMR, ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1); 859141398Sphk write_reg(u, EOSR, 0x00); 860141398Sphk write_reg(u, AUXMR, C_ICR | 8); 861141398Sphk write_reg(u, AUXMR, C_PPR | PPR_U); 862141398Sphk write_reg(u, AUXMR, C_AUXA); 863141398Sphk write_reg(u, AUXMR, C_AUXB + 3); 864141398Sphk write_reg(u, AUXMR, C_AUXE + 0); 865141398Sphk write_reg(u, AUXMR, AUXMR_PON); 866141398Sphk write_reg(u, AUXMR, AUXMR_CIFC); 867141398Sphk DELAY(100); 868141398Sphk write_reg(u, AUXMR, AUXMR_SIFC); 869141398Sphk write_reg(u, AUXMR, AUXMR_SREN); 870141398Sphk return (0); 871141398Sphk} 872141398Sphk 873141398Sphkstatic int 874141398Sphkgpib_ib_close(struct cdev *dev, int oflags, int devtype, struct thread *td) 875141398Sphk{ 876141398Sphk struct upd7210 *u; 877141398Sphk struct ibfoo *ib; 878141398Sphk 879141398Sphk u = dev->si_drv1; 880141398Sphk ib = dev->si_drv2; 881141398Sphk /* XXX: assert pointer consistency */ 882141398Sphk 883141398Sphk u->ibfoo = NULL; 884141398Sphk /* XXX: free handles */ 885141398Sphk dev->si_drv2 = NULL; 886141398Sphk free(ib, M_GPIB); 887141398Sphk 888141398Sphk mtx_lock(&Giant); 889141398Sphk isa_dma_release(u->dmachan); 890141398Sphk mtx_unlock(&Giant); 891141398Sphk mtx_lock(&u->mutex); 892141398Sphk u->busy = 0; 893141398Sphk write_reg(u, IMR1, 0x00); 894141398Sphk write_reg(u, IMR2, 0x00); 895141398Sphk write_reg(u, AUXMR, AUXMR_CRST); 896141398Sphk DELAY(10000); 897141398Sphk mtx_unlock(&u->mutex); 898141398Sphk return (0); 899141398Sphk} 900141398Sphk 901141398Sphkstatic int 902141398Sphkgpib_ib_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) 903141398Sphk{ 904141398Sphk struct ibfoo_iocarg *ap; 905141398Sphk struct ibhandler *ih; 906141398Sphk struct upd7210 *u; 907141398Sphk int error; 908141398Sphk 909141398Sphk u = dev->si_drv1; 910141398Sphk 911141398Sphk if (cmd != GPIB_IBFOO) 912141398Sphk return (ENOIOCTL); 913141398Sphk 914141398Sphk ap = (void *)data; 915141398Sphk if (ap->__ident < 0 || ap->__ident >= max_ibhandler) 916141398Sphk return (EINVAL); 917141398Sphk ih = &ibhandlers[ap->__ident]; 918141398Sphk if (ap->__field != ih->args) 919141398Sphk return (EINVAL); 920141398Sphk 921141398Sphk if (ap->__field & __F_TMO) { 922141398Sphk if (ap->tmo < 0 || ap->tmo >= max_timeouts) { 923141398Sphk ap->__retval = -1; 924141398Sphk ap->__iberr = EARG; 925141398Sphk return (0); 926141398Sphk } 927141398Sphk } 928141398Sphk 929141398Sphk if (ap->__field & __F_EOS) { 930141398Sphk if (ap->eos & ~(REOS | XEOS | BIN | 0xff)) { 931141398Sphk ap->__retval = -1; 932141398Sphk ap->__iberr = EARG; 933141398Sphk return (0); 934141398Sphk } 935141398Sphk if (ap->eos & (REOS | XEOS)) { 936141398Sphk if ((ap->eos & (BIN | 0x80)) == 0x80) { 937141398Sphk ap->__retval = -1; 938141398Sphk ap->__iberr = EARG; 939141398Sphk return (0); 940141398Sphk } 941141398Sphk } else if (ap->eos != 0) { 942141398Sphk ap->__retval = -1; 943141398Sphk ap->__iberr = EARG; 944141398Sphk return (0); 945141398Sphk } 946141398Sphk } 947141398Sphk 948141398Sphk mtx_lock(&u->mutex); 949141398Sphk while(u->busy != 1) { 950141398Sphk error = msleep(u->ibfoo, &u->mutex, PZERO | PCATCH, 951141398Sphk "gpib_ibioctl", 0); 952141398Sphk if (error) { 953141398Sphk mtx_unlock(&u->mutex); 954141398Sphk return (EINTR); 955141398Sphk } 956141398Sphk } 957141398Sphk u->busy = 2; 958141398Sphk mtx_unlock(&u->mutex); 959141398Sphk 960141398Sphk#ifdef GPIB_DEBUG 961141398Sphk if (ih->name != NULL) 962141398Sphk printf("%s(", ih->name); 963141398Sphk else 964141398Sphk printf("ibinvalid("); 965141398Sphk printf("[0x%x]", ap->__field); 966141398Sphk if (ap->__field & __F_HANDLE) printf(" handle=%d", ap->handle); 967141398Sphk if (ap->__field & __F_EOS) printf(" eos=%d", ap->eos); 968141398Sphk if (ap->__field & __F_EOT) printf(" eot=%d", ap->eot); 969141398Sphk if (ap->__field & __F_TMO) printf(" tmo=%d", ap->tmo); 970141398Sphk if (ap->__field & __F_PAD) printf(" pad=%d", ap->pad); 971141398Sphk if (ap->__field & __F_SAD) printf(" sad=%d", ap->sad); 972141398Sphk if (ap->__field & __F_BUFFER) printf(" buffer=%p", ap->buffer); 973141398Sphk if (ap->__field & __F_CNT) printf(" cnt=%ld", ap->cnt); 974141398Sphk /* XXX more ... */ 975141398Sphk printf(")\n"); 976141398Sphk#endif 977141398Sphk 978141398Sphk ap->__iberr = 0; 979141398Sphk error = EOPNOTSUPP; 980141398Sphk if (ih->func != NULL) 981141398Sphk error = ih->func(u, ap); 982141398Sphk if (error) { 983141398Sphk ap->__retval = EDVR; 984141398Sphk ap->__iberr = EDVR; 985141398Sphk ap->__ibcnt = error; 986141398Sphk } else if (ap->__iberr) { 987141398Sphk ap->__retval = -1; 988141398Sphk } 989141398Sphk#ifdef GPIB_DEBUG 990141398Sphk printf("%s(...) = %d (error=%d)\n", ih->name, ap->__retval, error); 991141398Sphk#endif 992141398Sphk mtx_lock(&u->mutex); 993141398Sphk u->busy = 1; 994141398Sphk wakeup(u->ibfoo); 995141398Sphk mtx_unlock(&u->mutex); 996141398Sphk return (error); 997141398Sphk} 998141398Sphk 999141398Sphkstruct cdevsw gpib_ib_cdevsw = { 1000141398Sphk .d_version = D_VERSION, 1001141398Sphk .d_name = "gpib_ib", 1002141398Sphk .d_open = gpib_ib_open, 1003141398Sphk .d_ioctl = gpib_ib_ioctl, 1004141398Sphk .d_close = gpib_ib_close, 1005141398Sphk}; 1006141398Sphk 1007141398Sphk/* Housekeeping */ 1008141398Sphk 1009141398Sphkvoid 1010141398Sphkupd7210attach(struct upd7210 *u) 1011141398Sphk{ 1012141398Sphk int unit = 0; 1013141398Sphk struct cdev *dev; 1014141398Sphk 1015141398Sphk mtx_init(&u->mutex, "gpib", NULL, MTX_DEF); 1016141398Sphk u->cdev = make_dev(&gpib_l_cdevsw, unit, 1017141398Sphk UID_ROOT, GID_WHEEL, 0444, 1018141398Sphk "gpib%ul", unit); 1019141398Sphk u->cdev->si_drv1 = u; 1020141398Sphk 1021141398Sphk dev = make_dev(&gpib_ib_cdevsw, unit, 1022141398Sphk UID_ROOT, GID_WHEEL, 0444, 1023141398Sphk "gpib%uib", unit); 1024141398Sphk dev->si_drv1 = u; 1025141398Sphk dev_depends(u->cdev, dev); 1026141398Sphk} 1027