ppi.c revision 42475
1/*- 2 * Copyright (c) 1997, 1998 Nicolas Souchu, Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id: ppi.c,v 1.8 1998/12/07 21:58:16 archie Exp $ 27 * 28 */ 29#include "ppi.h" 30 31#if NPPI > 0 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/conf.h> 36#include <sys/kernel.h> 37#include <sys/uio.h> 38#include <sys/malloc.h> 39#include <sys/fcntl.h> 40 41#include <machine/clock.h> 42 43#include <dev/ppbus/ppbconf.h> 44#include <dev/ppbus/ppb_msq.h> 45 46#include "opt_ppb_1284.h" 47 48#ifdef PERIPH_1284 49#include <dev/ppbus/ppb_1284.h> 50#endif 51 52#include <dev/ppbus/ppi.h> 53 54#define BUFSIZE 512 55 56struct ppi_data { 57 58 int ppi_unit; 59 int ppi_flags; 60#define HAVE_PPBUS (1<<0) 61#define HAD_PPBUS (1<<1) 62 63 int ppi_count; 64 int ppi_mode; /* IEEE1284 mode */ 65 char ppi_buffer[BUFSIZE]; 66 67 struct ppb_device ppi_dev; 68}; 69 70#define MAXPPI 8 /* XXX not much better! */ 71static int nppi = 0; 72static struct ppi_data *ppidata[MAXPPI]; 73 74/* 75 * Make ourselves visible as a ppbus driver 76 */ 77 78static struct ppb_device *ppiprobe(struct ppb_data *ppb); 79static int ppiattach(struct ppb_device *dev); 80static void ppiintr(int unit); 81 82static struct ppb_driver ppidriver = { 83 ppiprobe, ppiattach, "ppi" 84}; 85DATA_SET(ppbdriver_set, ppidriver); 86 87static d_open_t ppiopen; 88static d_close_t ppiclose; 89static d_ioctl_t ppiioctl; 90static d_write_t ppiwrite; 91static d_read_t ppiread; 92 93#define CDEV_MAJOR 82 94static struct cdevsw ppi_cdevsw = 95 { ppiopen, ppiclose, ppiread, ppiwrite, /* 82 */ 96 ppiioctl, nullstop, nullreset, nodevtotty, 97 seltrue, nommap, nostrat, "ppi", NULL, -1 }; 98 99#ifdef PERIPH_1284 100 101static void 102ppi_enable_intr(struct ppi_data *ppi) 103{ 104 char r; 105 106 r = ppb_rctr(&ppi->ppi_dev); 107 ppb_wctr(&ppi->ppi_dev, r | IRQENABLE); 108 109 return; 110} 111 112static void 113ppi_disable_intr(struct ppi_data *ppi) 114{ 115 char r; 116 117 r = ppb_rctr(&ppi->ppi_dev); 118 ppb_wctr(&ppi->ppi_dev, r & ~IRQENABLE); 119 120 return; 121} 122 123#endif /* PERIPH_1284 */ 124 125/* 126 * ppiprobe() 127 */ 128static struct ppb_device * 129ppiprobe(struct ppb_data *ppb) 130{ 131 struct ppi_data *ppi; 132 133 ppi = (struct ppi_data *) malloc(sizeof(struct ppi_data), 134 M_TEMP, M_NOWAIT); 135 if (!ppi) { 136 printf("ppi: cannot malloc!\n"); 137 return 0; 138 } 139 bzero(ppi, sizeof(struct ppi_data)); 140 141 ppidata[nppi] = ppi; 142 143 /* 144 * ppi dependent initialisation. 145 */ 146 ppi->ppi_unit = nppi; 147 148 /* 149 * ppbus dependent initialisation. 150 */ 151 ppi->ppi_dev.id_unit = ppi->ppi_unit; 152 ppi->ppi_dev.ppb = ppb; 153 ppi->ppi_dev.intr = ppiintr; 154 155 /* Ok, go to next device on next probe */ 156 nppi ++; 157 158 return &ppi->ppi_dev; 159} 160 161static int 162ppiattach(struct ppb_device *dev) 163{ 164 /* 165 * Report ourselves 166 */ 167 printf("ppi%d: <generic parallel i/o> on ppbus %d\n", 168 dev->id_unit, dev->ppb->ppb_link->adapter_unit); 169 170 return (1); 171} 172 173/* 174 * Cable 175 * ----- 176 * 177 * Use an IEEE1284 compliant (DB25/DB25) cable with the following tricks: 178 * 179 * nStrobe <-> nAck 1 <-> 10 180 * nAutofd <-> Busy 11 <-> 14 181 * nSelectin <-> Select 17 <-> 13 182 * nInit <-> nFault 15 <-> 16 183 * 184 */ 185static void 186ppiintr(int unit) 187{ 188#ifdef PERIPH_1284 189 struct ppi_data *ppi = ppidata[unit]; 190 191 ppi_disable_intr(ppi); 192 193 switch (ppi->ppi_dev.ppb->state) { 194 195 /* accept IEEE1284 negociation then wakeup an waiting process to 196 * continue negociation at process level */ 197 case PPB_FORWARD_IDLE: 198 /* Event 1 */ 199 if ((ppb_rstr(&ppi->ppi_dev) & (SELECT | nBUSY)) == 200 (SELECT | nBUSY)) { 201 /* IEEE1284 negociation */ 202#ifdef DEBUG_1284 203 printf("N"); 204#endif 205 206 /* Event 2 - prepare for reading the ext. value */ 207 ppb_wctr(&ppi->ppi_dev, (PCD | STROBE | nINIT) & ~SELECTIN); 208 209 ppi->ppi_dev.ppb->state = PPB_NEGOCIATION; 210 211 } else { 212#ifdef DEBUG_1284 213 printf("0x%x", ppb_rstr(&ppi->ppi_dev)); 214#endif 215 ppb_peripheral_terminate(&ppi->ppi_dev, PPB_DONTWAIT); 216 break; 217 } 218 219 /* wake up any process waiting for negociation from 220 * remote master host */ 221 222 /* XXX should set a variable to warn the process about 223 * the interrupt */ 224 225 wakeup(ppi); 226 break; 227 default: 228#ifdef DEBUG_1284 229 printf("?%d", ppi->ppi_dev.ppb->state); 230#endif 231 ppi->ppi_dev.ppb->state = PPB_FORWARD_IDLE; 232 ppb_set_mode(&ppi->ppi_dev, PPB_COMPATIBLE); 233 break; 234 } 235 236 ppi_enable_intr(ppi); 237#endif /* PERIPH_1284 */ 238 239 return; 240} 241 242static int 243ppiopen(dev_t dev, int flags, int fmt, struct proc *p) 244{ 245 u_int unit = minor(dev); 246 struct ppi_data *ppi = ppidata[unit]; 247 int res; 248 249 if (unit >= nppi) 250 return (ENXIO); 251 252 if (!(ppi->ppi_flags & HAVE_PPBUS)) { 253 if ((res = ppb_request_bus(&ppi->ppi_dev, 254 (flags & O_NONBLOCK) ? PPB_DONTWAIT : 255 (PPB_WAIT | PPB_INTR)))) 256 return (res); 257 258 ppi->ppi_flags |= HAVE_PPBUS; 259 } 260 ppi->ppi_count += 1; 261 262 return (0); 263} 264 265static int 266ppiclose(dev_t dev, int flags, int fmt, struct proc *p) 267{ 268 u_int unit = minor(dev); 269 struct ppi_data *ppi = ppidata[unit]; 270 271 ppi->ppi_count --; 272 if (!ppi->ppi_count) { 273 274#ifdef PERIPH_1284 275 switch (ppi->ppi_dev.ppb->state) { 276 case PPB_PERIPHERAL_IDLE: 277 ppb_peripheral_terminate(&ppi->ppi_dev, 0); 278 break; 279 case PPB_REVERSE_IDLE: 280 case PPB_EPP_IDLE: 281 case PPB_ECP_FORWARD_IDLE: 282 default: 283 ppb_1284_terminate(&ppi->ppi_dev); 284 break; 285 } 286#endif /* PERIPH_1284 */ 287 288 ppb_release_bus(&ppi->ppi_dev); 289 ppi->ppi_flags &= ~HAVE_PPBUS; 290 } 291 292 return (0); 293} 294 295/* 296 * ppiread() 297 * 298 * IEEE1284 compliant read. 299 * 300 * First, try negociation to BYTE then NIBBLE mode 301 * If no data is available, wait for it otherwise transfer as much as possible 302 */ 303static int 304ppiread(dev_t dev, struct uio *uio, int ioflag) 305{ 306#ifdef PERIPH_1284 307 u_int unit = minor(dev); 308 struct ppi_data *ppi = ppidata[unit]; 309 int len, error = 0; 310 311 switch (ppi->ppi_dev.ppb->state) { 312 case PPB_PERIPHERAL_IDLE: 313 ppb_peripheral_terminate(&ppi->ppi_dev, 0); 314 /* fall throught */ 315 316 case PPB_FORWARD_IDLE: 317 /* if can't negociate NIBBLE mode then try BYTE mode, 318 * the peripheral may be a computer 319 */ 320 if ((ppb_1284_negociate(&ppi->ppi_dev, 321 ppi->ppi_mode = PPB_NIBBLE, 0))) { 322 323 /* XXX Wait 2 seconds to let the remote host some 324 * time to terminate its interrupt 325 */ 326 tsleep(ppi, PPBPRI, "ppiread", 2*hz); 327 328 if ((error = ppb_1284_negociate(&ppi->ppi_dev, 329 ppi->ppi_mode = PPB_BYTE, 0))) 330 return (error); 331 } 332 break; 333 334 case PPB_REVERSE_IDLE: 335 case PPB_EPP_IDLE: 336 case PPB_ECP_FORWARD_IDLE: 337 default: 338 break; 339 } 340 341#ifdef DEBUG_1284 342 printf("N"); 343#endif 344 /* read data */ 345 len = 0; 346 while (uio->uio_resid) { 347 if ((error = ppb_1284_read(&ppi->ppi_dev, ppi->ppi_mode, 348 ppi->ppi_buffer, min(BUFSIZE, uio->uio_resid), 349 &len))) { 350 goto error; 351 } 352 353 if (!len) 354 goto error; /* no more data */ 355 356#ifdef DEBUG_1284 357 printf("d"); 358#endif 359 if ((error = uiomove(ppi->ppi_buffer, len, uio))) 360 goto error; 361 } 362 363error: 364 365#else /* PERIPH_1284 */ 366 int error = ENODEV; 367#endif 368 369 return (error); 370} 371 372/* 373 * ppiwrite() 374 * 375 * IEEE1284 compliant write 376 * 377 * Actually, this is the peripheral side of a remote IEEE1284 read 378 * 379 * The first part of the negociation (IEEE1284 device detection) is 380 * done at interrupt level, then the remaining is done by the writing 381 * process 382 * 383 * Once negociation done, transfer data 384 */ 385static int 386ppiwrite(dev_t dev, struct uio *uio, int ioflag) 387{ 388#ifdef PERIPH_1284 389 u_int unit = minor(dev); 390 struct ppi_data *ppi = ppidata[unit]; 391 struct ppb_data *ppb = ppi->ppi_dev.ppb; 392 int len, error = 0, sent; 393 394#if 0 395 int ret; 396 397 #define ADDRESS MS_PARAM(0, 0, MS_TYP_PTR) 398 #define LENGTH MS_PARAM(0, 1, MS_TYP_INT) 399 400 struct ppb_microseq msq[] = { 401 { MS_OP_PUT, { MS_UNKNOWN, MS_UNKNOWN, MS_UNKNOWN } }, 402 MS_RET(0) 403 }; 404 405 /* negociate ECP mode */ 406 if (ppb_1284_negociate(&ppi->ppi_dev, PPB_ECP, 0)) { 407 printf("ppiwrite: ECP negociation failed\n"); 408 } 409 410 while (!error && (len = min(uio->uio_resid, BUFSIZE))) { 411 uiomove(ppi->ppi_buffer, len, uio); 412 413 ppb_MS_init_msq(msq, 2, ADDRESS, ppi->ppi_buffer, LENGTH, len); 414 415 error = ppb_MS_microseq(&ppi->ppi_dev, msq, &ret); 416 } 417#endif 418 419 /* we have to be peripheral to be able to send data, so 420 * wait for the appropriate state 421 */ 422 if (ppb->state < PPB_PERIPHERAL_NEGOCIATION) 423 ppb_1284_terminate(&ppi->ppi_dev); 424 425 while (ppb->state != PPB_PERIPHERAL_IDLE) { 426 /* XXX should check a variable before sleeping */ 427#ifdef DEBUG_1284 428 printf("s"); 429#endif 430 431 ppi_enable_intr(ppi); 432 433 /* sleep until IEEE1284 negociation starts */ 434 error = tsleep(ppi, PCATCH | PPBPRI, "ppiwrite", 0); 435 436 switch (error) { 437 case 0: 438 /* negociate peripheral side with BYTE mode */ 439 ppb_peripheral_negociate(&ppi->ppi_dev, PPB_BYTE, 0); 440 break; 441 case EWOULDBLOCK: 442 break; 443 default: 444 goto error; 445 } 446 } 447#ifdef DEBUG_1284 448 printf("N"); 449#endif 450 451 /* negociation done, write bytes to master host */ 452 while (len = min(uio->uio_resid, BUFSIZE)) { 453 uiomove(ppi->ppi_buffer, len, uio); 454 if ((error = byte_peripheral_write(&ppi->ppi_dev, 455 ppi->ppi_buffer, len, &sent))) 456 goto error; 457#ifdef DEBUG_1284 458 printf("d"); 459#endif 460 } 461 462error: 463 464#else /* PERIPH_1284 */ 465 int error = ENODEV; 466#endif 467 468 return (error); 469} 470 471static int 472ppiioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 473{ 474 u_int unit = minor(dev); 475 struct ppi_data *ppi = ppidata[unit]; 476 int error = 0; 477 u_int8_t *val = (u_int8_t *)data; 478 479 switch (cmd) { 480 481 case PPIGDATA: /* get data register */ 482 *val = ppb_rdtr(&ppi->ppi_dev); 483 break; 484 case PPIGSTATUS: /* get status bits */ 485 *val = ppb_rstr(&ppi->ppi_dev); 486 break; 487 case PPIGCTRL: /* get control bits */ 488 *val = ppb_rctr(&ppi->ppi_dev); 489 break; 490 case PPIGEPP: /* get EPP bits */ 491 *val = ppb_repp(&ppi->ppi_dev); 492 break; 493 case PPIGECR: /* get ECP bits */ 494 *val = ppb_recr(&ppi->ppi_dev); 495 break; 496 case PPIGFIFO: /* read FIFO */ 497 *val = ppb_rfifo(&ppi->ppi_dev); 498 break; 499 500 case PPISDATA: /* set data register */ 501 ppb_wdtr(&ppi->ppi_dev, *val); 502 break; 503 case PPISSTATUS: /* set status bits */ 504 ppb_wstr(&ppi->ppi_dev, *val); 505 break; 506 case PPISCTRL: /* set control bits */ 507 ppb_wctr(&ppi->ppi_dev, *val); 508 break; 509 case PPISEPP: /* set EPP bits */ 510 ppb_wepp(&ppi->ppi_dev, *val); 511 break; 512 case PPISECR: /* set ECP bits */ 513 ppb_wecr(&ppi->ppi_dev, *val); 514 break; 515 case PPISFIFO: /* write FIFO */ 516 ppb_wfifo(&ppi->ppi_dev, *val); 517 break; 518 default: 519 error = ENOTTY; 520 break; 521 } 522 523 return (error); 524} 525 526#ifdef PPI_MODULE 527 528MOD_DEV(ppi, LM_DT_CHAR, CDEV_MAJOR, &ppi_cdevsw); 529 530static int 531ppi_load(struct lkm_table *lkmtp, int cmd) 532{ 533 struct ppb_data *ppb; 534 struct ppb_device *dev; 535 int i; 536 537 for (ppb = ppb_next_bus(NULL); ppb; ppb = ppb_next_bus(ppb)) { 538 539 dev = ppiprobe(ppb); 540 ppiattach(dev); 541 542 ppb_attach_device(dev); 543 } 544 545 return (0); 546} 547 548static int 549ppi_unload(struct lkm_table *lkmtp, int cmd) 550{ 551 int i; 552 553 for (i = nppi-1; i > 0; i--) { 554 ppb_remove_device(&ppidata[i]->ppi_dev); 555 free(ppidata[i], M_TEMP); 556 } 557 558 return (0); 559} 560 561int 562ppi_mod(struct lkm_table *lkmtp, int cmd, int ver) 563{ 564 DISPATCH(lkmtp, cmd, ver, ppi_load, ppi_unload, lkm_nullcmd); 565} 566 567#endif /* PPI_MODULE */ 568 569static ppi_devsw_installed = 0; 570 571static void ppi_drvinit(void *unused) 572{ 573 dev_t dev; 574 575 if (!ppi_devsw_installed ) { 576 dev = makedev(CDEV_MAJOR, 0); 577 cdevsw_add(&dev, &ppi_cdevsw, NULL); 578 ppi_devsw_installed = 1; 579 } 580} 581 582SYSINIT(ppidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ppi_drvinit,NULL) 583 584#endif /* NPPI */ 585