1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * HDLC protocol handler for Z8530 SCC. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/types.h> 36 #include <sys/sysmacros.h> 37 #include <sys/kmem.h> 38 #include <sys/stropts.h> 39 #include <sys/stream.h> 40 #include <sys/strsun.h> 41 #include <sys/stat.h> 42 #include <sys/cred.h> 43 #include <sys/user.h> 44 #include <sys/proc.h> 45 #include <sys/file.h> 46 #include <sys/uio.h> 47 #include <sys/buf.h> 48 #include <sys/mkdev.h> 49 #include <sys/cmn_err.h> 50 #include <sys/errno.h> 51 #include <sys/fcntl.h> 52 53 #include <sys/zsdev.h> 54 #include <sys/ser_sync.h> 55 #include <sys/conf.h> 56 #include <sys/ddi.h> 57 #include <sys/sunddi.h> 58 #include <sys/dlpi.h> 59 60 #define ZSH_TRACING 61 #ifdef ZSH_TRACING 62 #include <sys/vtrace.h> 63 64 /* 65 * Temp tracepoint definitions 66 */ 67 #define TR_ZSH 50 68 69 #define TR_ZSH_TXINT 1 70 #define TR_ZSH_XSINT 2 71 #define TR_ZSH_RXINT 3 72 #define TR_ZSH_SRINT 4 73 74 #define TR_ZSH_WPUT_START 5 75 #define TR_ZSH_WPUT_END 6 76 #define TR_ZSH_START_START 7 77 #define TR_ZSH_START_END 8 78 #define TR_ZSH_SOFT_START 9 79 #define TR_ZSH_SOFT_END 10 80 81 #define TR_ZSH_OPEN 11 82 #define TR_ZSH_CLOSE 12 83 84 #endif /* ZSH_TRACING */ 85 86 /* 87 * Logging definitions 88 */ 89 90 /* 91 * #define ZSH_DEBUG 92 */ 93 #ifdef ZSH_DEBUG 94 95 #ifdef ZS_DEBUG_ALL 96 extern char zs_h_log[]; 97 extern int zs_h_log_n; 98 #define zsh_h_log_add(c) \ 99 { \ 100 if (zs_h_log_n >= ZS_H_LOG_MAX) \ 101 zs_h_log_n = 0; \ 102 zs_h_log[zs_h_log_n++] = 'A' + zs->zs_unit; \ 103 zs_h_log[zs_h_log_n++] = c; \ 104 zs_h_log[zs_h_log_n] = '\0'; \ 105 } 106 #define zsh_h_log_clear 107 #else 108 #define ZSH_H_LOG_MAX 0x8000 109 char zsh_h_log[2][ZSH_H_LOG_MAX +10]; 110 int zsh_h_log_n[2]; 111 #define zsh_h_log_add(c) \ 112 { \ 113 if (zsh_h_log_n[zs->zs_unit] >= ZSH_H_LOG_MAX) \ 114 zsh_h_log_n[zs->zs_unit] = 0; \ 115 zsh_h_log[zs->zs_unit][zsh_h_log_n[zs->zs_unit]++] = c; \ 116 zsh_h_log[zs->zs_unit][zsh_h_log_n[zs->zs_unit]] = '\0'; \ 117 } 118 119 #define zsh_h_log_clear \ 120 { register char *p; \ 121 for (p = &zsh_h_log[zs->zs_unit][ZSH_H_LOG_MAX]; \ 122 p >= &zsh_h_log[zs->zs_unit][0]; p--) \ 123 *p = '\0'; \ 124 zsh_h_log_n[zs->zs_unit] = 0; \ 125 } 126 #endif 127 128 #define ZSH_R0_LOG(r0) { \ 129 if (r0 & ZSRR0_RX_READY) zsh_h_log_add('R'); \ 130 if (r0 & ZSRR0_TIMER) zsh_h_log_add('Z'); \ 131 if (r0 & ZSRR0_TX_READY) zsh_h_log_add('T'); \ 132 if (r0 & ZSRR0_CD) zsh_h_log_add('D'); \ 133 if (r0 & ZSRR0_SYNC) zsh_h_log_add('S'); \ 134 if (r0 & ZSRR0_CTS) zsh_h_log_add('C'); \ 135 if (r0 & ZSRR0_TXUNDER) zsh_h_log_add('U'); \ 136 if (r0 & ZSRR0_BREAK) zsh_h_log_add('B'); \ 137 } 138 #endif 139 140 141 char _depends_on[] = "drv/zs"; 142 143 #ifndef MAXZSH 144 #define MAXZSH 2 145 #define MAXZSHCLONES (80) /* three clone opens per instance */ 146 #endif /* MAXZSH */ 147 148 int maxzsh = MAXZSH; 149 150 int zsh_timer_count = 10; 151 int zsh_default_mru = 1024; 152 153 struct ser_str *zsh_str = NULL; 154 unsigned char zsh_usedminor[MAXZSHCLONES]; 155 156 157 /* 158 * The HDLC protocol 159 */ 160 int zsh_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result); 161 static int zsh_probe(dev_info_t *dev); 162 static int zsh_attach(dev_info_t *dev, ddi_attach_cmd_t cmd); 163 static int zsh_detach(dev_info_t *dev, ddi_detach_cmd_t cmd); 164 static int zsh_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr); 165 static int zsh_close(queue_t *rq, int flag); 166 static void zsh_wput(queue_t *wq, mblk_t *mp); 167 static int zsh_start(struct zscom *zs, struct syncline *zss); 168 static void zsh_ioctl(queue_t *wq, mblk_t *mp); 169 170 static struct module_info hdlc_minfo = { 171 0x5a48, /* module ID number: "ZH" */ 172 "zsh", /* module name */ 173 0, /* minimum packet size accepted */ 174 INFPSZ, /* maximum packet size accepted */ 175 12*1024, /* queue high water mark (bytes) */ 176 4*1024 /* queue low water mark (bytes) */ 177 }; 178 179 static struct qinit hdlc_rinit = { 180 putq, /* input put procedure */ 181 NULL, /* input service procedure */ 182 zsh_open, /* open procedure */ 183 zsh_close, /* close procedure */ 184 NULL, /* reserved */ 185 &hdlc_minfo, /* module info */ 186 NULL /* reserved */ 187 }; 188 189 static struct qinit hdlc_winit = { 190 (int (*)())zsh_wput, /* output put procedure */ 191 NULL, /* output service procedure */ 192 NULL, /* open procedure */ 193 NULL, /* close procedure */ 194 NULL, /* reserved */ 195 &hdlc_minfo, /* module info */ 196 NULL /* reserved */ 197 }; 198 199 struct streamtab hdlctab = { 200 &hdlc_rinit, /* initialize read queue */ 201 &hdlc_winit, /* initialize write queue */ 202 NULL, /* mux read qinit */ 203 NULL /* mux write qinit */ 204 }; 205 206 DDI_DEFINE_STREAM_OPS(zsh_ops, nulldev, zsh_probe, zsh_attach, 207 zsh_detach, nodev, zsh_info, D_MP, &hdlctab); 208 209 /* 210 * This is the loadable module wrapper. 211 */ 212 213 #include <sys/errno.h> 214 #include <sys/modctl.h> 215 216 /* 217 * Module linkage information for the kernel. 218 */ 219 220 static struct modldrv modldrv = { 221 &mod_driverops, /* Type of module. This one is a driver */ 222 "Z8530 serial HDLC drv V%I%", 223 &zsh_ops, /* our own ops for this module */ 224 }; 225 226 static struct modlinkage modlinkage = { 227 MODREV_1, 228 (void *)&modldrv, 229 NULL 230 }; 231 232 int 233 _init(void) 234 { 235 return (mod_install(&modlinkage)); 236 } 237 238 int 239 _fini(void) 240 { 241 return (mod_remove(&modlinkage)); 242 } 243 244 int 245 _info(struct modinfo *modinfop) 246 { 247 return (mod_info(&modlinkage, modinfop)); 248 } 249 250 251 /* 252 * The HDLC interrupt entry points. 253 */ 254 static void zsh_txint(struct zscom *zs); 255 static void zsh_xsint(struct zscom *zs); 256 static void zsh_rxint(struct zscom *zs); 257 static void zsh_srint(struct zscom *zs); 258 static int zsh_softint(struct zscom *zs); 259 260 struct zsops zsops_hdlc = { 261 zsh_txint, 262 zsh_xsint, 263 zsh_rxint, 264 zsh_srint, 265 zsh_softint, 266 NULL, 267 NULL 268 }; 269 270 static int zsh_program(struct zscom *zs, struct scc_mode *sm); 271 static void zsh_setmstat(struct zscom *zs, int event); 272 static void zsh_rxbad(struct zscom *zs, struct syncline *zss); 273 static void zsh_txbad(struct zscom *zs, struct syncline *zss); 274 static void zsh_watchdog(void *); 275 static void zsh_callback(void *); 276 static int zsh_hdp_ok_or_rts_state(struct zscom *zs, struct syncline *zss); 277 static void zsh_init_port(struct zscom *zs, struct syncline *zss); 278 static int zsh_setmode(struct zscom *zs, struct syncline *zss, 279 struct scc_mode *sm); 280 281 282 /* 283 * The HDLC Driver. 284 */ 285 286 287 /* 288 * Special macros to handle STREAMS operations. 289 * These are required to address memory leakage problems. 290 * WARNING : the macro do NOT call ZSSETSOFT 291 */ 292 293 /* 294 * Should be called holding only the adaptive (zs_excl) mutex. 295 */ 296 #define ZSH_GETBLOCK(zs, allocbcount) \ 297 { \ 298 register int n = ZSH_MAX_RSTANDBY; \ 299 while (--n >= 0) { \ 300 if (!zss->sl_rstandby[n]) { \ 301 if ((zss->sl_rstandby[n] = \ 302 allocb(zss->sl_mru, BPRI_MED)) == NULL) { \ 303 if (zss->sl_bufcid == 0) { \ 304 mutex_enter(zs->zs_excl_hi); \ 305 if (zss->sl_txstate != TX_OFF) { \ 306 mutex_exit(zs->zs_excl_hi); \ 307 zss->sl_bufcid = bufcall(zss->sl_mru, \ 308 BPRI_MED, zsh_callback, zs); \ 309 break; \ 310 } else \ 311 mutex_exit(zs->zs_excl_hi); \ 312 } \ 313 } \ 314 allocbcount--; \ 315 } \ 316 } \ 317 } 318 319 /* 320 * Should be called holding the spin (zs_excl_hi) mutex. 321 */ 322 #define ZSH_ALLOCB(mp) \ 323 { \ 324 register int n = ZSH_MAX_RSTANDBY; \ 325 mp = NULL; \ 326 while (--n >= 0) { \ 327 if ((mp = zss->sl_rstandby[n]) != NULL) { \ 328 zss->sl_rstandby[n] = NULL; \ 329 break; \ 330 } \ 331 } \ 332 } 333 334 #define ZSH_PUTQ(mp) \ 335 { \ 336 register int wptr, rptr; \ 337 wptr = zss->sl_rdone_wptr; \ 338 rptr = zss->sl_rdone_rptr; \ 339 zss->sl_rdone[wptr] = mp; \ 340 if ((wptr) + 1 == ZSH_RDONE_MAX) \ 341 zss->sl_rdone_wptr = wptr = 0; \ 342 else \ 343 zss->sl_rdone_wptr = ++wptr; \ 344 if (wptr == rptr) { /* Should never occur */ \ 345 SCC_BIC(1, ZSWR1_INIT); \ 346 zss->sl_m_error = ENOSR; \ 347 ZSSETSOFT(zs); \ 348 } \ 349 } 350 351 #define ZSH_FREEMSG(mp) \ 352 { \ 353 ZSH_PUTQ(mp); \ 354 } 355 356 357 /* 358 * Should be called holding only the adaptive (zs_excl) mutex. 359 */ 360 #define ZSH_GETQ(mp) \ 361 { \ 362 if (zss->sl_rdone_rptr != zss->sl_rdone_wptr) { \ 363 mp = zss->sl_rdone[zss->sl_rdone_rptr++]; \ 364 if (zss->sl_rdone_rptr == ZSH_RDONE_MAX) \ 365 zss->sl_rdone_rptr = 0; \ 366 } else \ 367 mp = NULL; \ 368 } 369 370 #define ZSH_FLUSHQ \ 371 { \ 372 register mblk_t *tmp; \ 373 for (;;) { \ 374 ZSH_GETQ(tmp); \ 375 if (!(tmp)) \ 376 break; \ 377 freemsg(tmp); \ 378 } \ 379 } 380 381 /*ARGSUSED*/ 382 static int 383 zsh_probe(dev_info_t *dev) 384 { 385 return (DDI_PROBE_DONTCARE); 386 } 387 388 /*ARGSUSED*/ 389 static int 390 zsh_attach(dev_info_t *dev, ddi_attach_cmd_t cmd) 391 { 392 register int unit; 393 char name[3] = { 394 '\0', '\0', '\0' }; 395 396 /* 397 * Since zsh is a child of the "pseudo" nexus, we can expect the 398 * attach routine to be called only once. We need to create all 399 * necessary devices in one shot. There is never more than one 400 * SCC chip that supports zsh devices. 401 */ 402 403 if (cmd != DDI_ATTACH) 404 return (DDI_FAILURE); 405 if (zscom == NULL) 406 return (DDI_FAILURE); /* zsattach not done */ 407 unit = 2 * ddi_get_instance(dev); 408 if (unit > 1) 409 return (DDI_FAILURE); /* only use cpu ports */ 410 411 if (ddi_create_minor_node(dev, "zsh", S_IFCHR, 412 NULL, DDI_PSEUDO, CLONE_DEV) == DDI_FAILURE) { 413 ddi_remove_minor_node(dev, NULL); 414 cmn_err(CE_WARN, "zsh clone device creation failed."); 415 return (DDI_FAILURE); 416 } 417 418 for (; unit < maxzsh/2; unit++) { 419 zscom[unit].zs_hdlc_dip = dev; 420 421 (void) sprintf(name, "%d", unit); 422 if (ddi_create_minor_node(dev, name, S_IFCHR, 423 2*unit, DDI_PSEUDO, NULL) == DDI_FAILURE) { 424 ddi_remove_minor_node(dev, NULL); 425 return (DDI_FAILURE); 426 } 427 unit++; 428 (void) sprintf(name, "%d", unit); 429 if (ddi_create_minor_node(dev, name, S_IFCHR, 430 2*(unit-1)+1, DDI_PSEUDO, NULL) == DDI_FAILURE) { 431 ddi_remove_minor_node(dev, NULL); 432 return (DDI_FAILURE); 433 } 434 } 435 436 return (DDI_SUCCESS); 437 } 438 439 /* ARGSUSED */ 440 int 441 zsh_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 442 void **result) 443 { 444 register dev_t dev = (dev_t)arg; 445 register int unit, error; 446 register struct zscom *zs; 447 448 if ((unit = UNIT(dev)) >= nzs) 449 return (DDI_FAILURE); 450 451 switch (infocmd) { 452 case DDI_INFO_DEVT2DEVINFO: 453 if (zscom == NULL) { 454 error = DDI_FAILURE; 455 } else { 456 zs = &zscom[unit]; 457 *result = zs->zs_hdlc_dip; 458 error = DDI_SUCCESS; 459 } 460 break; 461 case DDI_INFO_DEVT2INSTANCE: 462 *result = (void *)(unit / 2); 463 error = DDI_SUCCESS; 464 break; 465 default: 466 error = DDI_FAILURE; 467 } 468 return (error); 469 } 470 471 static int 472 zsh_detach(dev_info_t *dev, ddi_detach_cmd_t cmd) 473 { 474 if (cmd != DDI_DETACH) 475 return (DDI_FAILURE); 476 477 ddi_remove_minor_node(dev, NULL); 478 479 return (DDI_SUCCESS); 480 } 481 482 static void 483 zsh_init_port(struct zscom *zs, struct syncline *zss) 484 { 485 register uchar_t s0; 486 487 SCC_WRITE(3, (ZSWR3_RX_ENABLE | ZSWR3_RXCRC_ENABLE | ZSWR3_RX_8)); 488 SCC_WRITE(5, (ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_TXCRC_ENABLE)); 489 zss->sl_rr0 = SCC_READ0(); 490 if (zss->sl_flags & SF_FDXPTP) { 491 SCC_BIS(5, ZSWR5_TX_ENABLE); 492 SCC_BIS(5, ZSWR5_RTS); 493 s0 = SCC_READ0(); 494 if ((s0 & ZSRR0_CTS) || 495 !(zss->sl_mode.sm_config & (CONN_SIGNAL | CONN_IBM))) { 496 /* 497 * send msg that CTS is up 498 */ 499 zss->sl_rr0 |= ZSRR0_CTS; 500 zss->sl_txstate = TX_IDLE; 501 } else { 502 zss->sl_flags |= SF_XMT_INPROG; 503 zss->sl_txstate = TX_RTS; 504 zss->sl_rr0 &= ~ZSRR0_CTS; 505 zss->sl_wd_count = zsh_timer_count; 506 if (!zss->sl_wd_id) 507 zss->sl_wd_id = timeout(zsh_watchdog, 508 zs, SIO_WATCHDOG_TICK); 509 } 510 } else { 511 SCC_BIC(15, ZSR15_CTS); 512 SCC_BIC(5, ZSWR5_TX_ENABLE); 513 SCC_BIC(5, ZSWR5_RTS); 514 zss->sl_flags &= ~SF_FLUSH_WQ; 515 } 516 } 517 518 /* 519 * Open routine. 520 */ 521 522 /*ARGSUSED*/ 523 static int 524 zsh_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr) 525 { 526 register struct zscom *zs; 527 register struct syncline *zss; 528 register struct ser_str *stp; 529 register int unit; 530 register int tmp; 531 532 if (sflag != CLONEOPEN) { 533 if (rq->q_ptr) 534 return (EBUSY); /* We got a stream that is in use */ 535 536 unit = UNIT(*dev); 537 if (unit >= maxzsh) 538 return (ENXIO); /* unit not configured */ 539 540 if (zscom == NULL) 541 return (ENXIO); /* device not found by autoconfig */ 542 zs = &zscom[unit]; 543 544 if (zs->zs_ops == NULL) { 545 return (ENXIO); /* device not found by autoconfig */ 546 } 547 548 TRACE_1(TR_ZSH, TR_ZSH_OPEN, "zsh_open:unit = %d", unit); 549 550 mutex_enter(zs->zs_excl); 551 if ((zs->zs_ops != &zsops_null) && 552 (zs->zs_ops != &zsops_hdlc)) { 553 mutex_exit(zs->zs_excl); 554 return (EBUSY); /* another protocol got here first */ 555 } 556 557 /* Mark device as busy (for power management) */ 558 (void) pm_busy_component(zs->zs_dip, unit%2+1); 559 (void) ddi_dev_is_needed(zs->zs_dip, unit%2+1, 1); 560 561 zsopinit(zs, &zsops_hdlc); 562 563 zss = (struct syncline *)&zscom[unit].zs_priv_str; 564 stp = &zss->sl_stream; 565 stp->str_state = NULL; 566 stp->str_com = (caddr_t)zs; 567 568 zss->sl_xhead = NULL; 569 zss->sl_xactb = NULL; 570 zs->zs_wr_cur = NULL; 571 zs->zs_wr_lim = NULL; 572 zs->zs_wr_cur = NULL; 573 zs->zs_wr_lim = NULL; 574 zss->sl_rhead = NULL; 575 zss->sl_ractb = NULL; 576 zs->zs_rd_cur = NULL; 577 zs->zs_rd_lim = NULL; 578 zss->sl_mstat = NULL; 579 zss->sl_xstandby = NULL; 580 zss->sl_wd_id = 0; 581 zss->sl_soft_active = 0; 582 zss->sl_stream.str_rq = NULL; 583 584 zs->zs_priv = (caddr_t)zss; 585 586 zss->sl_mru = zsh_default_mru; 587 tmp = ZSH_MAX_RSTANDBY; 588 ZSH_GETBLOCK(zs, tmp); 589 if (zss->sl_rstandby[0] == NULL) { 590 cmn_err(CE_WARN, "zsh_open: can't alloc message block"); 591 mutex_exit(zs->zs_excl); 592 return (ENOSR); 593 } 594 mutex_enter(zs->zs_excl_hi); 595 ZSH_ALLOCB(zss->sl_ractb); 596 zss->sl_txstate = TX_OFF; 597 zss->sl_rr0 = SCC_READ0(); 598 zss->sl_flags &= (SF_INITIALIZED | SF_FDXPTP); 599 if (zss->sl_flags & SF_INITIALIZED) 600 zsh_init_port(zs, zss); 601 mutex_exit(zs->zs_excl_hi); 602 mutex_exit(zs->zs_excl); 603 } else { /* CLONEOPEN */ 604 mutex_enter(&zs_curr_lock); 605 for (unit = maxzsh; unit < MAXZSHCLONES; unit++) 606 if (!zsh_usedminor[unit]) { 607 zsh_usedminor[unit] = (unsigned char)unit; 608 break; 609 } 610 mutex_exit(&zs_curr_lock); 611 if (unit >= MAXZSHCLONES) /* no slots available */ 612 return (ENODEV); 613 *dev = makedevice(getmajor(*dev), unit); 614 615 stp = kmem_zalloc(sizeof (struct ser_str), KM_NOSLEEP); 616 if (stp == NULL) { 617 cmn_err(CE_WARN, 618 "zsh clone open failed, no memory, rq=%p\n", 619 (void *)rq); 620 return (ENOMEM); 621 } 622 stp->str_state = STR_CLONE; 623 stp->str_com = NULL; /* can't determine without ppa */ 624 } 625 stp->str_rq = rq; 626 stp->str_inst = unit; 627 628 rq->q_ptr = WR(rq)->q_ptr = (caddr_t)stp; 629 qprocson(rq); 630 return (0); 631 } 632 633 /* 634 * Close routine. 635 */ 636 int zsh_tx_enable_in_close = 0; 637 638 /*ARGSUSED*/ 639 static int 640 zsh_close(queue_t *rq, int flag) 641 { 642 struct ser_str *stp; 643 struct zscom *zs; 644 struct syncline *zss; 645 mblk_t *mp; 646 int i; 647 timeout_id_t sl_wd_id; 648 bufcall_id_t sl_bufcid; 649 650 /* 651 * Note that a close is only called on the last close of a 652 * particular stream. Assume that we need to do it all. 653 */ 654 qprocsoff(rq); /* no new business after this */ 655 656 stp = (struct ser_str *)rq->q_ptr; 657 if (stp == NULL) 658 return (0); /* already been closed once */ 659 660 if (stp->str_state == STR_CLONE) { 661 zsh_usedminor[stp->str_inst] = 0; 662 } else { 663 zs = (struct zscom *)stp->str_com; 664 if (zs == NULL) 665 goto out; 666 667 TRACE_1(TR_ZSH, TR_ZSH_CLOSE, "zs = %p", zs); 668 669 zss = (struct syncline *)zs->zs_priv; 670 mutex_enter(zs->zs_excl); 671 flushq(WR(rq), FLUSHALL); 672 mutex_enter(zs->zs_excl_hi); 673 if (zss->sl_xstandby) { 674 zss->sl_xstandby->b_wptr = zss->sl_xstandby->b_rptr; 675 ZSH_FREEMSG(zss->sl_xstandby); 676 zss->sl_xstandby = NULL; 677 } 678 mutex_exit(zs->zs_excl_hi); 679 680 ZSH_FLUSHQ; 681 682 /* 683 * Stop the Watchdog Timer. 684 */ 685 if ((sl_wd_id = zss->sl_wd_id) != 0) 686 zss->sl_wd_id = 0; 687 688 /* 689 * Cancel outstanding "bufcall" request. 690 */ 691 if ((sl_bufcid = zss->sl_bufcid) != 0) 692 zss->sl_bufcid = 0; 693 694 mutex_enter(zs->zs_excl_hi); 695 if (zs->zs_wr_cur) { 696 zs->zs_wr_cur = NULL; 697 zs->zs_wr_lim = NULL; 698 SCC_WRITE0(ZSWR0_SEND_ABORT); 699 ZSDELAY(); 700 ZSDELAY(); 701 } 702 zss->sl_txstate = TX_OFF; /* so it can't rearm in close */ 703 704 zs->zs_wr_cur = NULL; 705 zs->zs_wr_lim = NULL; 706 SCC_BIC(15, 707 (ZSR15_TX_UNDER | ZSR15_BREAK | ZSR15_SYNC | ZSR15_CTS)); 708 SCC_WRITE(3, 0); /* Quiesce receiver */ 709 if (zsh_tx_enable_in_close && !(zss->sl_flags & SF_FDXPTP)) { 710 SCC_BIS(5, ZSWR5_TX_ENABLE); 711 } else 712 SCC_BIC(5, ZSWR5_TX_ENABLE); 713 714 SCC_BIC(5, (ZSWR5_DTR | ZSWR5_RTS | ZSWR5_TXCRC_ENABLE)); 715 SCC_WRITE0(ZSWR0_RESET_TXINT); /* reset TX */ 716 SCC_WRITE0(ZSWR0_RESET_STATUS); /* reset XS */ 717 SCC_WRITE0(ZSWR0_RESET_ERRORS); 718 (void) SCC_READDATA(); /* reset RX */ 719 ZSDELAY(); 720 (void) SCC_READDATA(); 721 ZSDELAY(); 722 (void) SCC_READDATA(); 723 ZSDELAY(); 724 725 726 /* 727 * Free up everything we ever allocated. 728 */ 729 if ((mp = zss->sl_rhead) != NULL) { 730 zss->sl_ractb = NULL; /* already freed */ 731 zs->zs_rd_cur = NULL; 732 zs->zs_rd_lim = NULL; 733 zss->sl_rhead = NULL; 734 } 735 mutex_exit(zs->zs_excl_hi); 736 if (mp) 737 freemsg(mp); 738 739 mutex_enter(zs->zs_excl_hi); 740 if ((mp = zss->sl_ractb) != NULL) { 741 zs->zs_rd_cur = NULL; 742 zs->zs_rd_lim = NULL; 743 zss->sl_ractb = NULL; 744 } 745 mutex_exit(zs->zs_excl_hi); 746 if (mp) 747 freemsg(mp); 748 749 for (i = 0; i < ZSH_MAX_RSTANDBY; i++) { 750 mutex_enter(zs->zs_excl_hi); 751 mp = zss->sl_rstandby[i]; 752 zss->sl_rstandby[i] = NULL; 753 mutex_exit(zs->zs_excl_hi); 754 if (mp) 755 freemsg(mp); 756 } 757 758 mutex_enter(zs->zs_excl_hi); 759 if ((mp = zss->sl_xhead) != NULL) { 760 zss->sl_xhead = NULL; 761 zss->sl_xactb = NULL; 762 } 763 mutex_exit(zs->zs_excl_hi); 764 if (mp) 765 freemsg(mp); 766 767 ZSH_FLUSHQ; 768 769 mutex_enter(zs->zs_excl_hi); 770 if ((mp = zss->sl_xstandby) != NULL) 771 zss->sl_xstandby = NULL; 772 mutex_exit(zs->zs_excl_hi); 773 if (mp) 774 freemsg(mp); 775 776 mutex_enter(zs->zs_excl_hi); 777 if ((mp = zss->sl_mstat) != NULL) 778 zss->sl_mstat = NULL; 779 zss->sl_txstate = TX_OFF; /* so it can't rearm in close */ 780 mutex_exit(zs->zs_excl_hi); 781 if (mp) 782 freemsg(mp); 783 784 zss->sl_stream.str_rq = NULL; 785 zsopinit(zs, &zsops_null); 786 mutex_exit(zs->zs_excl); 787 if (sl_wd_id) 788 (void) untimeout(sl_wd_id); 789 if (sl_bufcid) 790 unbufcall(sl_bufcid); 791 while (zss->sl_soft_active) 792 drv_usecwait(1); 793 794 /* Mark device as available for power management */ 795 (void) pm_idle_component(zs->zs_dip, zs->zs_unit%2+1); 796 } 797 798 if (stp->str_state == STR_CLONE) 799 kmem_free(stp, sizeof (struct ser_str)); 800 801 out: 802 rq->q_ptr = WR(rq)->q_ptr = NULL; 803 804 return (0); 805 } 806 807 static int 808 zsh_hdp_ok_or_rts_state(struct zscom *zs, struct syncline *zss) 809 { 810 register uchar_t s0; 811 812 SCC_BIS(15, ZSR15_CTS); 813 SCC_BIS(5, ZSWR5_RTS); 814 s0 = SCC_READ0(); 815 if (s0 & ZSRR0_CTS) { 816 SCC_BIS(5, ZSWR5_TX_ENABLE); 817 zss->sl_rr0 |= ZSRR0_CTS; 818 return (1); 819 } 820 zss->sl_flags |= SF_XMT_INPROG; 821 zss->sl_txstate = TX_RTS; 822 zss->sl_rr0 &= ~ZSRR0_CTS; 823 zss->sl_wd_count = zsh_timer_count; 824 return (0); 825 } 826 827 /* 828 * Put procedure for write queue. 829 */ 830 static void 831 zsh_wput(queue_t *wq, mblk_t *mp) 832 { 833 register struct ser_str *stp = (struct ser_str *)wq->q_ptr; 834 register struct zscom *zs; 835 register struct syncline *zss = NULL; 836 register ulong_t prim, error = 0; 837 register union DL_primitives *dlp; 838 register int ppa; 839 register mblk_t *tmp; 840 register struct copyresp *resp; 841 842 /* 843 * stp->str_com supplied by open or DLPI attach. 844 */ 845 if (stp == NULL) { 846 freemsg(mp); 847 return; 848 } 849 zs = (struct zscom *)stp->str_com; 850 851 TRACE_0(TR_ZSH, TR_ZSH_WPUT_START, "zsh_wput start"); 852 853 if ((mp->b_datap->db_type == M_FLUSH) && 854 (stp->str_state == STR_CLONE)) { 855 if (*mp->b_rptr & FLUSHW) { 856 flushq(wq, FLUSHDATA); 857 *mp->b_rptr &= ~FLUSHW; 858 } 859 if (*mp->b_rptr & FLUSHR) 860 qreply(wq, mp); /* let the read queues have at it */ 861 else 862 freemsg(mp); 863 return; 864 } 865 866 if ((zs == NULL) && (mp->b_datap->db_type != M_PROTO)) { 867 freemsg(mp); 868 cmn_err(CE_WARN, 869 "zsh: clone device %d must be attached before use!", 870 stp->str_inst); 871 (void) putnextctl1(RD(wq), M_ERROR, EPROTO); 872 return; 873 } 874 875 if (stp->str_state == STR_CLONE) { /* Clone opened, limited. */ 876 if ((mp->b_datap->db_type != M_PROTO) && 877 (mp->b_datap->db_type != M_IOCTL) && 878 (mp->b_datap->db_type != M_IOCDATA)) { 879 freemsg(mp); 880 cmn_err(CE_WARN, 881 "zsh%x: invalid operation for clone dev.\n", 882 stp->str_inst); 883 (void) putnextctl1(RD(wq), M_ERROR, EPROTO); 884 return; 885 } 886 } else { 887 zss = (struct syncline *)zs->zs_priv; 888 } 889 890 switch (mp->b_datap->db_type) { 891 892 case M_DATA: 893 /* 894 * Queue the message up to be transmitted. 895 * Set "in progress" flag and call the start routine. 896 */ 897 mutex_enter(zs->zs_excl_hi); 898 if (!(zss->sl_flags & SF_INITIALIZED)) { 899 mutex_exit(zs->zs_excl_hi); 900 cmn_err(CE_WARN, 901 "zsh%x not initialized, can't send message", 902 zs->zs_unit); 903 freemsg(mp); 904 (void) putnextctl1(RD(wq), M_ERROR, ECOMM); 905 return; 906 } 907 mutex_exit(zs->zs_excl_hi); 908 if (zs->zs_flags & ZS_NEEDSOFT) { 909 zs->zs_flags &= ~ZS_NEEDSOFT; 910 (void) zsh_softint(zs); 911 } 912 while (mp->b_wptr == mp->b_rptr) { 913 register mblk_t *mp1; 914 mp1 = unlinkb(mp); 915 freemsg(mp); 916 mp = mp1; 917 if (mp == NULL) 918 return; 919 } 920 mutex_enter(zs->zs_excl); 921 (void) putq(wq, mp); 922 mutex_enter(zs->zs_excl_hi); 923 if (zss->sl_flags & SF_FLUSH_WQ) { 924 mutex_exit(zs->zs_excl_hi); 925 flushq(wq, FLUSHDATA); 926 mutex_exit(zs->zs_excl); 927 928 TRACE_1(TR_ZSH, TR_ZSH_WPUT_END, 929 "zsh_wput end: zs = %p", zs); 930 931 return; 932 } 933 tmp = NULL; 934 again: 935 if (!zss->sl_xstandby) { 936 if (tmp) 937 zss->sl_xstandby = tmp; 938 else { 939 mutex_exit(zs->zs_excl_hi); 940 tmp = getq(wq); 941 mutex_enter(zs->zs_excl_hi); 942 if (tmp) 943 goto again; 944 } 945 } else if (tmp) { 946 mutex_exit(zs->zs_excl_hi); 947 (void) putbq(wq, tmp); 948 mutex_enter(zs->zs_excl_hi); 949 } 950 951 if (zss->sl_flags & SF_XMT_INPROG) { 952 mutex_exit(zs->zs_excl_hi); 953 mutex_exit(zs->zs_excl); 954 955 TRACE_1(TR_ZSH, TR_ZSH_WPUT_END, 956 "zsh_wput end: zs = %p", zs); 957 958 return; 959 } 960 961 if (!zss->sl_wd_id) { 962 zss->sl_wd_count = zsh_timer_count; 963 zss->sl_txstate = TX_IDLE; 964 mutex_exit(zs->zs_excl_hi); 965 zss->sl_wd_id = timeout(zsh_watchdog, zs, 966 SIO_WATCHDOG_TICK); 967 mutex_enter(zs->zs_excl_hi); 968 } 969 970 zss->sl_flags |= SF_XMT_INPROG; 971 if ((zss->sl_flags & SF_FDXPTP) || 972 zsh_hdp_ok_or_rts_state(zs, zss)) 973 (void) zsh_start(zs, zss); 974 mutex_exit(zs->zs_excl_hi); 975 mutex_exit(zs->zs_excl); 976 break; 977 978 case M_PROTO: 979 /* 980 * Here is where a clone device finds out about the 981 * hardware it is going to attach to. The request is 982 * validated and a ppa is extracted from it and validated. 983 * This number is used to index the hardware data structure 984 * and the protocol data structure, in case the latter 985 * was not provided by a data-path open before this. 986 */ 987 if (stp->str_state != STR_CLONE) { 988 freemsg(mp); 989 return; 990 } 991 992 if (MBLKL(mp) < DL_ATTACH_REQ_SIZE) { 993 prim = DL_ATTACH_REQ; 994 error = DL_BADPRIM; 995 goto end_proto; 996 } 997 dlp = (union DL_primitives *)mp->b_rptr; 998 prim = dlp->dl_primitive; 999 if (prim != DL_ATTACH_REQ) { 1000 error = DL_BADPRIM; 1001 goto end_proto; 1002 } 1003 ppa = dlp->attach_req.dl_ppa; 1004 ppa = (ppa%2) ? ((ppa-1)*2 +1) : (ppa*2); 1005 if (ppa >= maxzsh) { 1006 error = DL_BADPPA; 1007 goto end_proto; 1008 } 1009 zs = &zscom[ppa]; 1010 if (zs->zs_ops == NULL) { 1011 error = ENXIO; 1012 goto end_proto; 1013 } 1014 mutex_enter(zs->zs_excl); 1015 if ((zs->zs_ops != &zsops_null) && 1016 (zs->zs_ops != &zsops_hdlc)) { 1017 /* 1018 * another protocol got here first 1019 */ 1020 error = (EBUSY); 1021 mutex_exit(zs->zs_excl); 1022 goto end_proto; 1023 1024 } 1025 1026 stp->str_com = (caddr_t)zs; 1027 mutex_exit(zs->zs_excl); 1028 end_proto: 1029 if (error) 1030 dlerrorack(wq, mp, prim, error, 0); 1031 else 1032 dlokack(wq, mp, DL_ATTACH_REQ); 1033 break; 1034 1035 case M_IOCTL: 1036 zsh_ioctl(wq, mp); 1037 break; 1038 1039 case M_IOCDATA: 1040 resp = (struct copyresp *)mp->b_rptr; 1041 if (resp->cp_rval) { 1042 /* 1043 * Just free message on failure. 1044 */ 1045 freemsg(mp); 1046 break; 1047 } 1048 1049 switch (resp->cp_cmd) { 1050 1051 case S_IOCGETMODE: 1052 case S_IOCGETSTATS: 1053 case S_IOCGETSPEED: 1054 case S_IOCGETMCTL: 1055 case S_IOCGETMRU: 1056 mioc2ack(mp, NULL, 0, 0); 1057 qreply(wq, mp); 1058 break; 1059 1060 case S_IOCSETMODE: 1061 zss = (struct syncline *)&zs->zs_priv_str; 1062 mutex_enter(zs->zs_excl); 1063 error = zsh_setmode(zs, zss, 1064 (struct scc_mode *)mp->b_cont->b_rptr); 1065 if (error) { 1066 register struct iocblk *iocp = 1067 (struct iocblk *)mp->b_rptr; 1068 mp->b_datap->db_type = M_IOCNAK; 1069 iocp->ioc_error = error; 1070 } else 1071 mioc2ack(mp, NULL, 0, 0); 1072 mutex_exit(zs->zs_excl); 1073 qreply(wq, mp); 1074 break; 1075 1076 case S_IOCSETMRU: 1077 zss = (struct syncline *)&zs->zs_priv_str; 1078 mutex_enter(zs->zs_excl); 1079 zss->sl_mru = *(int *)mp->b_cont->b_rptr; 1080 mutex_exit(zs->zs_excl); 1081 mioc2ack(mp, NULL, 0, 0); 1082 qreply(wq, mp); 1083 break; 1084 default: 1085 freemsg(mp); 1086 } 1087 break; 1088 1089 /* 1090 * We're at the bottom of the food chain, so we flush our 1091 * write queue, clear the FLUSHW bit so it doesn't go round 1092 * and round forever, then flush our read queue (since there's 1093 * no read put procedure down here) and pass it up for any 1094 * higher modules to deal with in their own way. 1095 */ 1096 case M_FLUSH: 1097 if (*mp->b_rptr & FLUSHW) { 1098 mutex_enter(zs->zs_excl); 1099 flushq(wq, FLUSHDATA); 1100 mutex_enter(zs->zs_excl_hi); 1101 tmp = zss->sl_xstandby; 1102 zss->sl_xstandby = NULL; 1103 mutex_exit(zs->zs_excl_hi); 1104 if (tmp) 1105 freemsg(tmp); 1106 mutex_exit(zs->zs_excl); 1107 *mp->b_rptr &= ~FLUSHW; 1108 } 1109 1110 if (*mp->b_rptr & FLUSHR) { 1111 mutex_enter(zs->zs_excl); 1112 ZSH_FLUSHQ; 1113 mutex_exit(zs->zs_excl); 1114 qreply(wq, mp); /* let the read queues have at it */ 1115 } else 1116 freemsg(mp); 1117 break; 1118 1119 default: 1120 /* 1121 * "No, I don't want a subscription to Chain Store Age, 1122 * thank you anyway." 1123 */ 1124 freemsg(mp); 1125 break; 1126 } 1127 1128 TRACE_1(TR_ZSH, TR_ZSH_WPUT_END, "zsh_wput end: zs = %p", zs); 1129 } 1130 1131 /* 1132 * Get the next message from the write queue, set up the necessary pointers, 1133 * state info, etc., and start the transmit "engine" by sending the first 1134 * character. We'll then rotate through txint until done, then get an xsint. 1135 */ 1136 static int 1137 zsh_start(struct zscom *zs, struct syncline *zss) 1138 { 1139 register mblk_t *mp; 1140 register uchar_t *wptr; 1141 register uchar_t *rptr; 1142 register uchar_t sl_flags = zss->sl_flags; 1143 1144 /* 1145 * Attempt to grab the next M_DATA message off the queue (that's 1146 * all that will be left after wput) and begin transmission. 1147 * This routine is normally called after completion of a previous 1148 * frame, or when zsh_wput gets a new message. If we are in a 1149 * mode that put us in the TX_RTS state, waiting for CTS, and CTS 1150 * is not up yet, we have no business here. Ditto if we're in 1151 * either the TX_ACTIVE or TX_CRC states. In these cases we 1152 * don't clear SF_CALLSTART, so we don't forget there's work to do. 1153 */ 1154 1155 TRACE_1(TR_ZSH, TR_ZSH_START_START, 1156 "zsh_start start: zs = %p", zs); 1157 1158 if (sl_flags & SF_PHONY) { 1159 sl_flags &= ~SF_PHONY; 1160 SCC_BIC(15, ZSR15_CTS); 1161 SCC_BIC(5, ZSWR5_RTS); 1162 SCC_WRITE0(ZSWR0_RESET_TXINT); 1163 SCC_BIC(5, ZSWR5_TX_ENABLE); 1164 zss->sl_rr0 &= ~ZSRR0_CTS; 1165 zss->sl_txstate = TX_IDLE; 1166 /* 1167 * if we get another msg by chance zsh_watchog will start 1168 */ 1169 sl_flags &= ~SF_XMT_INPROG; 1170 zss->sl_flags = sl_flags; 1171 1172 TRACE_1(TR_ZSH, TR_ZSH_START_END, 1173 "zsh_start end: zs = %d", zs); 1174 1175 return (0); 1176 } 1177 mp = zss->sl_xstandby; 1178 if (mp == NULL) { 1179 if (!(sl_flags & SF_FDXPTP)) { 1180 sl_flags |= SF_PHONY; 1181 ZSH_ALLOCB(mp); 1182 if (!mp) 1183 return (0); 1184 mp->b_datap->db_type = M_RSE; 1185 mp->b_wptr = mp->b_rptr + 1; 1186 goto transmit; 1187 } 1188 sl_flags &= ~SF_XMT_INPROG; 1189 zss->sl_flags = sl_flags; 1190 1191 TRACE_1(TR_ZSH, TR_ZSH_START_END, 1192 "zsh_start end: zs = %p", zs); 1193 1194 return (0); 1195 } 1196 1197 transmit: 1198 zss->sl_xstandby = NULL; 1199 rptr = mp->b_rptr; 1200 wptr = mp->b_wptr; 1201 ZSSETSOFT(zs); 1202 1203 #ifdef ZSH_DEBUG 1204 if (zss->sl_xhead || zss->sl_xactb) { 1205 debug_enter("xhead1"); 1206 } 1207 #endif 1208 1209 zss->sl_xhead = mp; 1210 zss->sl_xactb = mp; 1211 zss->sl_wd_count = zsh_timer_count; 1212 zss->sl_txstate = TX_ACTIVE; 1213 zss->sl_ocnt = 0; 1214 SCC_BIS(10, ZSWR10_UNDERRUN_ABORT); /* abort on underrun */ 1215 SCC_WRITE0(ZSWR0_RESET_TXCRC); /* reset transmit CRC */ 1216 zss->sl_ocnt = wptr - rptr; 1217 mp->b_wptr = rptr; /* to tell soft to free this msg */ 1218 SCC_WRITEDATA(*rptr++); /* resets TXINT */ 1219 zs->zs_wr_cur = rptr; 1220 zs->zs_wr_lim = wptr; 1221 1222 SCC_WRITE0(ZSWR0_RESET_EOM); 1223 1224 TRACE_1(TR_ZSH, TR_ZSH_START_END, 1225 "zsh_start end: zs = %p", zs); 1226 1227 zss->sl_flags = sl_flags; 1228 return (1); 1229 } 1230 1231 1232 /* 1233 * Process an "ioctl" message sent down to us. 1234 */ 1235 static void 1236 zsh_ioctl(queue_t *wq, mblk_t *mp) 1237 { 1238 register struct ser_str *stp = (struct ser_str *)wq->q_ptr; 1239 register struct zscom *zs = (struct zscom *)stp->str_com; 1240 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1241 register struct iocblk *iocp = (struct iocblk *)mp->b_rptr; 1242 register struct scc_mode *sm; 1243 register struct sl_stats *st; 1244 register uchar_t *msignals; 1245 register mblk_t *tmp; 1246 register int error = 0; 1247 1248 mutex_enter(zs->zs_excl); 1249 if ((zs->zs_ops != &zsops_null) && 1250 (zs->zs_ops != &zsops_hdlc)) { 1251 /* 1252 * another protocol got here first 1253 */ 1254 error = (EBUSY); 1255 goto end_zsh_ioctl; 1256 } 1257 1258 1259 switch (iocp->ioc_cmd) { 1260 1261 case S_IOCGETMODE: 1262 tmp = allocb(sizeof (struct scc_mode), BPRI_MED); 1263 if (tmp == NULL) { 1264 error = EAGAIN; 1265 break; 1266 } 1267 if (iocp->ioc_count != TRANSPARENT) 1268 mioc2ack(mp, tmp, sizeof (struct scc_mode), 0); 1269 else 1270 mcopyout(mp, NULL, sizeof (struct scc_mode), NULL, tmp); 1271 sm = (struct scc_mode *)mp->b_cont->b_rptr; 1272 bcopy(&zss->sl_mode, sm, sizeof (struct scc_mode)); 1273 break; 1274 1275 case S_IOCGETSTATS: 1276 tmp = allocb(sizeof (struct sl_stats), BPRI_MED); 1277 if (tmp == NULL) { 1278 error = EAGAIN; 1279 break; 1280 } 1281 if (iocp->ioc_count != TRANSPARENT) 1282 mioc2ack(mp, tmp, sizeof (struct sl_stats), 0); 1283 else 1284 mcopyout(mp, NULL, sizeof (struct sl_stats), NULL, tmp); 1285 st = (struct sl_stats *)mp->b_cont->b_rptr; 1286 bcopy(&zss->sl_st, st, sizeof (struct sl_stats)); 1287 break; 1288 1289 case S_IOCGETSPEED: 1290 tmp = allocb(sizeof (int), BPRI_MED); 1291 if (tmp == NULL) { 1292 error = EAGAIN; 1293 break; 1294 } 1295 if (iocp->ioc_count != TRANSPARENT) 1296 mioc2ack(mp, tmp, sizeof (int), 0); 1297 else 1298 mcopyout(mp, NULL, sizeof (int), NULL, tmp); 1299 *(int *)mp->b_cont->b_rptr = zss->sl_mode.sm_baudrate; 1300 break; 1301 1302 case S_IOCGETMCTL: 1303 tmp = allocb(sizeof (char), BPRI_MED); 1304 if (tmp == NULL) { 1305 error = EAGAIN; 1306 break; 1307 } 1308 if (iocp->ioc_count != TRANSPARENT) 1309 mioc2ack(mp, tmp, sizeof (char), 0); 1310 else 1311 mcopyout(mp, NULL, sizeof (char), NULL, tmp); 1312 msignals = (uchar_t *)mp->b_cont->b_rptr; 1313 *msignals = zss->sl_rr0 & (ZSRR0_CD | ZSRR0_CTS); 1314 break; 1315 1316 case S_IOCGETMRU: 1317 tmp = allocb(sizeof (int), BPRI_MED); 1318 if (tmp == NULL) { 1319 error = EAGAIN; 1320 break; 1321 } 1322 if (iocp->ioc_count != TRANSPARENT) 1323 mioc2ack(mp, tmp, sizeof (int), 0); 1324 else 1325 mcopyout(mp, NULL, sizeof (int), NULL, tmp); 1326 *(int *)mp->b_cont->b_rptr = zss->sl_mru; 1327 break; 1328 1329 case S_IOCSETMODE: 1330 if (iocp->ioc_count != TRANSPARENT) { 1331 error = miocpullup(mp, sizeof (struct scc_mode)); 1332 if (error != 0) 1333 break; 1334 error = zsh_setmode(zs, zss, 1335 (struct scc_mode *)mp->b_cont->b_rptr); 1336 if (error == 0) 1337 mioc2ack(mp, NULL, 0, 0); 1338 } else 1339 mcopyin(mp, NULL, sizeof (struct scc_mode), NULL); 1340 break; 1341 1342 case S_IOCCLRSTATS: 1343 mutex_enter(zs->zs_excl_hi); 1344 bzero(&zss->sl_st, sizeof (struct sl_stats)); 1345 mutex_exit(zs->zs_excl_hi); 1346 mioc2ack(mp, NULL, 0, 0); 1347 break; 1348 1349 case S_IOCSETMRU: 1350 if (iocp->ioc_count != TRANSPARENT) { 1351 error = miocpullup(mp, sizeof (int)); 1352 if (error != 0) 1353 break; 1354 zss->sl_mru = *(int *)mp->b_cont->b_rptr; 1355 mioc2ack(mp, NULL, 0, 0); 1356 } else 1357 mcopyin(mp, NULL, sizeof (int), NULL); 1358 break; 1359 1360 case S_IOCSETDTR: 1361 /* 1362 * The first integer of the M_DATA block that should 1363 * follow indicate if DTR must be set or reset 1364 */ 1365 error = miocpullup(mp, sizeof (int)); 1366 if (error != 0) 1367 break; 1368 1369 mutex_enter(zs->zs_excl_hi); 1370 if (*(int *)mp->b_cont->b_rptr != 0) 1371 (void) zsmctl(zs, ZSWR5_DTR, DMBIS); 1372 else 1373 (void) zsmctl(zs, ZSWR5_DTR, DMBIC); 1374 mutex_exit(zs->zs_excl_hi); 1375 break; 1376 1377 default: 1378 error = EINVAL; 1379 1380 } 1381 end_zsh_ioctl: 1382 iocp->ioc_error = error; 1383 mp->b_datap->db_type = (error) ? M_IOCNAK : M_IOCACK; 1384 mutex_exit(zs->zs_excl); 1385 qreply(wq, mp); 1386 } 1387 1388 /* 1389 * Set the mode of the zsh port 1390 */ 1391 1392 int 1393 zsh_setmode(struct zscom *zs, struct syncline *zss, struct scc_mode *sm) 1394 { 1395 register int error = 0; 1396 register mblk_t *mp; 1397 1398 mutex_enter(zs->zs_excl_hi); 1399 if (sm->sm_rxclock == RXC_IS_PLL) { 1400 zss->sl_mode.sm_retval = SMERR_RXC; 1401 mutex_exit(zs->zs_excl_hi); 1402 return (EINVAL); /* not supported */ 1403 } else { 1404 if (((zss->sl_mode.sm_config ^ sm->sm_config) & 1405 CONN_SIGNAL) != 0) { /* Changing, going... */ 1406 if (sm->sm_config & CONN_SIGNAL) { /* ...up. */ 1407 if (zss->sl_mstat == NULL) { 1408 mutex_exit(zs->zs_excl_hi); 1409 mp = allocb( 1410 sizeof (struct sl_status), BPRI_MED); 1411 mutex_enter(zs->zs_excl_hi); 1412 zss->sl_mstat = mp; 1413 } 1414 } else { /* ...down. */ 1415 if ((mp = zss->sl_mstat) != NULL) 1416 zss->sl_mstat = NULL; 1417 mutex_exit(zs->zs_excl_hi); 1418 if (mp) 1419 freemsg(mp); 1420 mutex_enter(zs->zs_excl_hi); 1421 } 1422 } 1423 if (!(sm->sm_config & CONN_IBM)) { 1424 if (sm->sm_config & CONN_HDX) { 1425 zss->sl_mode.sm_retval = SMERR_HDX; 1426 mutex_exit(zs->zs_excl_hi); 1427 return (EINVAL); 1428 } 1429 if (sm->sm_config & CONN_MPT) { 1430 zss->sl_mode.sm_retval = SMERR_MPT; 1431 mutex_exit(zs->zs_excl_hi); 1432 return (EINVAL); 1433 } 1434 } 1435 zss->sl_flags &= ~SF_FDXPTP; /* "conmode" */ 1436 if ((sm->sm_config & (CONN_HDX | CONN_MPT)) == 0) 1437 zss->sl_flags |= SF_FDXPTP; 1438 1439 error = zsh_program(zs, sm); 1440 if (!error && (zs->zs_ops != &zsops_null)) 1441 zsh_init_port(zs, zss); 1442 } 1443 mutex_exit(zs->zs_excl_hi); 1444 1445 return (error); 1446 } 1447 1448 /* 1449 * Transmit interrupt service procedure 1450 */ 1451 1452 static void 1453 zsh_txint(struct zscom *zs) 1454 { 1455 register struct syncline *zss; 1456 register mblk_t *mp; 1457 register int tmp; 1458 register uchar_t *wr_cur; 1459 1460 TRACE_1(TR_ZSH, TR_ZSH_TXINT, "zsh_txint: zs = %p", zs); 1461 1462 if ((wr_cur = zs->zs_wr_cur) != NULL && (wr_cur < zs->zs_wr_lim)) { 1463 SCC_WRITEDATA(*wr_cur++); 1464 zs->zs_wr_cur = wr_cur; 1465 return; 1466 } 1467 1468 1469 zss = (struct syncline *)&zs->zs_priv_str; 1470 1471 switch (zss->sl_txstate) { 1472 1473 /* 1474 * we here because end of message block lim = cur 1475 */ 1476 case TX_ACTIVE: 1477 1478 mp = zss->sl_xactb; 1479 1480 again_txint: 1481 mp = mp->b_cont; 1482 if (mp) { 1483 zss->sl_xactb = mp; 1484 zss->sl_ocnt += tmp = mp->b_wptr - mp->b_rptr; 1485 if (!tmp) 1486 goto again_txint; 1487 zs->zs_wr_cur = mp->b_rptr; 1488 zs->zs_wr_lim = mp->b_wptr; 1489 SCC_WRITEDATA(*zs->zs_wr_cur++); 1490 return; 1491 } 1492 1493 /* 1494 * This is where the fun starts. At this point the 1495 * last character in the frame has been sent. We 1496 * issue a RESET_TXINT so we won't get another txint 1497 * until the CRC has been completely sent. Also we 1498 * reset the Abort-On-Underrun bit so that CRC is 1499 * sent at EOM, rather than an Abort. 1500 */ 1501 zs->zs_wr_cur = zs->zs_wr_lim = NULL; 1502 zss->sl_txstate = TX_CRC; 1503 SCC_WRITE0(ZSWR0_RESET_TXINT); 1504 if (!(zss->sl_flags & SF_PHONY)) { 1505 SCC_BIC(10, ZSWR10_UNDERRUN_ABORT); 1506 zss->sl_st.opack++; 1507 zss->sl_st.ochar += zss->sl_ocnt; 1508 } 1509 zss->sl_ocnt = 0; 1510 ZSH_FREEMSG(zss->sl_xhead); 1511 zss->sl_xhead = zss->sl_xactb = NULL; 1512 ZSSETSOFT(zs); 1513 break; 1514 /* 1515 * This txint means we have sent the CRC bytes at EOF. 1516 * The next txint will mean we are sending or have sent the 1517 * flag character at EOF, but we handle that differently, and 1518 * enter different states,depending on whether we're IBM or not. 1519 */ 1520 case TX_CRC: 1521 if (!(zss->sl_flags & SF_FDXPTP)) { 1522 zss->sl_txstate = TX_FLAG; /* HDX path */ 1523 } else { /* FDX path */ 1524 if (!zsh_start(zs, zss)) { 1525 zss->sl_txstate = TX_IDLE; 1526 SCC_WRITE0(ZSWR0_RESET_TXINT); 1527 } 1528 } 1529 break; 1530 1531 /* 1532 * This txint means the closing flag byte is going out the door. 1533 * We use this state to allow this to complete before dropping RTS. 1534 */ 1535 case TX_FLAG: 1536 zss->sl_txstate = TX_LAST; 1537 (void) zsh_start(zs, zss); 1538 break; 1539 1540 /* 1541 * Arriving here means the flag should be out and it's finally 1542 * time to close the barn door. 1543 */ 1544 case TX_LAST: 1545 zss->sl_txstate = TX_IDLE; 1546 SCC_WRITE0(ZSWR0_RESET_TXINT); 1547 break; 1548 1549 /* 1550 * If transmit was aborted, do nothing - watchdog will recover. 1551 */ 1552 case TX_ABORTED: 1553 SCC_WRITE0(ZSWR0_RESET_TXINT); 1554 break; 1555 1556 default: 1557 SCC_WRITE0(ZSWR0_RESET_TXINT); 1558 break; 1559 } 1560 } 1561 1562 /* 1563 * External Status Change interrupt service procedure 1564 */ 1565 static void 1566 zsh_xsint(struct zscom *zs) 1567 { 1568 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1569 register uchar_t s0, x0; 1570 1571 TRACE_1(TR_ZSH, TR_ZSH_XSINT, "zsh_xsint: zs = %p", zs); 1572 1573 s0 = SCC_READ0(); 1574 x0 = s0 ^ zss->sl_rr0; 1575 zss->sl_rr0 = s0; 1576 SCC_WRITE0(ZSWR0_RESET_STATUS); 1577 1578 if (s0 & ZSRR0_TXUNDER) { 1579 switch (zss->sl_txstate) { 1580 /* 1581 * A transmitter underrun has occurred. If we are not 1582 * here as the result of an abort sent by the watchdog 1583 * timeout routine, we need to send an abort to flush 1584 * the transmitter. Otherwise there is a danger of 1585 * trashing the next frame but still sending a good crc. 1586 * The TX_ABORTED flag is set so that the watchdog 1587 * routine can initiate recovery. 1588 */ 1589 case TX_ACTIVE: 1590 SCC_WRITE0(ZSWR0_SEND_ABORT); 1591 SCC_WRITE0(ZSWR0_RESET_TXINT); 1592 zss->sl_st.underrun++; 1593 zsh_txbad(zs, zss); 1594 1595 zss->sl_txstate = TX_ABORTED; 1596 zss->sl_wd_count = 0; 1597 break; 1598 1599 case TX_CRC: 1600 break; 1601 1602 case TX_FLAG: 1603 break; 1604 1605 case TX_ABORTED: 1606 break; 1607 1608 case TX_OFF: 1609 break; 1610 1611 case TX_LAST: 1612 break; 1613 1614 default: 1615 break; 1616 } 1617 } 1618 1619 if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) && zs->zs_rd_cur) { 1620 zss->sl_st.abort++; 1621 zsh_rxbad(zs, zss); 1622 } else if ((s0 & ZSRR0_SYNC) && (zs->zs_rd_cur)) { 1623 /* 1624 * Tricky code to avoid disaster in the case where 1625 * an abort was detected while receiving a packet, 1626 * but the abort did not last long enough to be 1627 * detected by zsh_xsint - this can happen since 1628 * the ZSRR0_BREAK is not latched. Since an abort 1629 * will automatically cause the SCC to enter 1630 * hunt mode, hopefully, the sync/hunt bit will be 1631 * set in this case (although if the interrupt is 1632 * sufficiently delayed, the SCC may have sync'ed 1633 * in again if it has detected a flag). 1634 */ 1635 zss->sl_st.abort++; 1636 zsh_rxbad(zs, zss); 1637 } 1638 1639 if (x0 & s0 & ZSRR0_CTS) { 1640 if (zss->sl_txstate == TX_RTS) { 1641 if (!(zss->sl_flags & SF_FDXPTP)) { 1642 SCC_BIS(5, ZSWR5_TX_ENABLE); 1643 } 1644 (void) zsh_start(zs, zss); 1645 } else if ((zss->sl_mode.sm_config & (CONN_IBM | CONN_SIGNAL))) { 1646 zss->sl_flags &= ~SF_FLUSH_WQ; 1647 zsh_setmstat(zs, CS_CTS_UP); 1648 } 1649 } 1650 1651 /* 1652 * We don't care about CTS transitions unless we are in either 1653 * IBM or SIGNAL mode, or both. So, if we see CTS drop, and we 1654 * care, and we are not idle, send up a report message. 1655 */ 1656 if ((x0 & ZSRR0_CTS) && ((s0 & ZSRR0_CTS) == 0) && 1657 (zss->sl_txstate != TX_OFF) && 1658 (zss->sl_mode.sm_config & (CONN_IBM | CONN_SIGNAL))) { 1659 SCC_BIC(15, ZSR15_CTS); 1660 zsh_setmstat(zs, CS_CTS_DOWN); 1661 zss->sl_flags &= ~SF_XMT_INPROG; 1662 zss->sl_flags |= SF_FLUSH_WQ; 1663 zss->sl_st.cts++; 1664 if (zss->sl_txstate != TX_IDLE) 1665 SCC_WRITE0(ZSWR0_SEND_ABORT); 1666 SCC_WRITE0(ZSWR0_RESET_ERRORS); 1667 SCC_WRITE0(ZSWR0_RESET_TXINT); 1668 zss->sl_wd_count = 0; 1669 zsh_txbad(zs, zss); 1670 } 1671 } 1672 1673 1674 /* 1675 * Receive interrupt service procedure 1676 */ 1677 static void 1678 zsh_rxint(struct zscom *zs) 1679 { 1680 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1681 register mblk_t *bp = zss->sl_ractb; 1682 unsigned char *rd_cur; 1683 1684 TRACE_1(TR_ZSH, TR_ZSH_RXINT, "zsh_rxint: zs = %p", zs); 1685 1686 if (((rd_cur = zs->zs_rd_cur) != NULL) && rd_cur < zs->zs_rd_lim) { 1687 *rd_cur++ = SCC_READDATA(); 1688 zs->zs_rd_cur = rd_cur; 1689 return; 1690 } 1691 1692 if (!rd_cur) { /* Beginning of frame */ 1693 if (!bp) { 1694 ZSH_ALLOCB(bp); 1695 zss->sl_ractb = bp; 1696 } 1697 zss->sl_rhead = bp; 1698 } else { /* end of data block should be cur==lim */ 1699 bp->b_wptr = zs->zs_rd_cur; 1700 ZSH_ALLOCB(bp->b_cont); 1701 bp = zss->sl_ractb = bp->b_cont; 1702 } 1703 if (!bp) { 1704 zss->sl_st.nobuffers++; 1705 zsh_rxbad(zs, zss); 1706 return; 1707 } 1708 zs->zs_rd_cur = bp->b_wptr; 1709 zs->zs_rd_lim = bp->b_datap->db_lim; 1710 *zs->zs_rd_cur++ = SCC_READDATA(); /* Also resets interrupt */ 1711 } 1712 1713 1714 /* 1715 * Special Receive Condition Interrupt routine 1716 */ 1717 static void 1718 zsh_srint(struct zscom *zs) 1719 { 1720 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1721 register uchar_t s1; 1722 register uchar_t *rd_cur; 1723 1724 TRACE_1(TR_ZSH, TR_ZSH_SRINT, "zsh_srint: zs = %p", zs); 1725 1726 SCC_READ(1, s1); 1727 1728 if (s1 & ZSRR1_RXEOF) { /* end of frame */ 1729 (void) SCC_READDATA(); 1730 SCC_WRITE0(ZSWR0_RESET_ERRORS); 1731 if (s1 & ZSRR1_FE) { /* bad CRC */ 1732 zss->sl_st.crc++; 1733 zsh_rxbad(zs, zss); 1734 return; 1735 } 1736 1737 if ((rd_cur = zs->zs_rd_cur) == NULL) 1738 return; 1739 1740 /* 1741 * Drop one CRC byte from length because it came in 1742 * before the special interrupt got here. 1743 */ 1744 zss->sl_ractb->b_wptr = rd_cur - 1; 1745 1746 /* 1747 * put on done queue 1748 */ 1749 ZSH_PUTQ(zss->sl_rhead); 1750 zss->sl_rhead = NULL; 1751 zss->sl_ractb = NULL; 1752 zs->zs_rd_cur = NULL; 1753 zs->zs_rd_lim = NULL; 1754 ZSSETSOFT(zs); 1755 1756 } else if (s1 & ZSRR1_DO) { 1757 (void) SCC_READDATA(); 1758 SCC_WRITE0(ZSWR0_RESET_ERRORS); 1759 zss->sl_st.overrun++; 1760 zsh_rxbad(zs, zss); 1761 } else 1762 SCC_WRITE0(ZSWR0_RESET_ERRORS); 1763 } 1764 1765 /* 1766 * Handle a second stage interrupt. 1767 * Does mostly lower priority buffer management stuff. 1768 */ 1769 static int 1770 zsh_softint(struct zscom *zs) 1771 { 1772 register struct syncline *zss; 1773 register queue_t *q; 1774 register mblk_t *mp, *tmp; 1775 register mblk_t *head = NULL, *tail = NULL; 1776 register int allocbcount = 0; 1777 int m_error; 1778 1779 TRACE_1(TR_ZSH, TR_ZSH_SOFT_START, "zsh_soft start: zs = %p", zs); 1780 1781 mutex_enter(zs->zs_excl); 1782 zss = (struct syncline *)zs->zs_priv; 1783 if (!zss || (q = zss->sl_stream.str_rq) == NULL) { 1784 mutex_exit(zs->zs_excl); 1785 return (0); 1786 } 1787 m_error = zss->sl_m_error; 1788 1789 zss->sl_m_error = 0; 1790 1791 1792 if (!zss->sl_mstat) 1793 zss->sl_mstat = allocb(sizeof (struct sl_status), BPRI_MED); 1794 1795 mutex_enter(zs->zs_excl_hi); 1796 if (zss->sl_flags & SF_FLUSH_WQ) { 1797 if (!(zss->sl_flags & SF_FDXPTP)) { 1798 zss->sl_flags &= ~SF_FLUSH_WQ; 1799 } else { 1800 register uchar_t s0; 1801 1802 s0 = SCC_READ0(); 1803 if (s0 & ZSRR0_CTS) { 1804 zss->sl_rr0 |= ZSRR0_CTS; 1805 SCC_BIS(15, ZSR15_CTS); 1806 zss->sl_flags &= ~SF_FLUSH_WQ; 1807 zsh_setmstat(zs, CS_CTS_UP); 1808 } 1809 if (zss->sl_flags & SF_FLUSH_WQ) { 1810 mutex_exit(zs->zs_excl_hi); 1811 flushq(WR(q), FLUSHDATA); 1812 goto next; 1813 } 1814 } 1815 } 1816 mutex_exit(zs->zs_excl_hi); 1817 1818 next: 1819 for (;;) { 1820 ZSH_GETQ(mp); 1821 if (!mp) 1822 break; 1823 1824 if (mp->b_rptr == mp->b_wptr) { 1825 if (mp->b_datap->db_type == M_RSE) { 1826 allocbcount++; 1827 } 1828 freemsg(mp); 1829 continue; 1830 } 1831 if (mp->b_datap->db_type == M_DATA) { 1832 zss->sl_st.ichar += msgdsize(mp); 1833 zss->sl_st.ipack++; 1834 if (!(canputnext(q))) { 1835 zss->sl_st.ierror++; 1836 allocbcount++; 1837 freemsg(mp); 1838 continue; 1839 } 1840 } else if (mp->b_datap->db_type == M_PROTO) { 1841 if (!(canputnext(q))) { 1842 freemsg(mp); 1843 continue; 1844 } 1845 } 1846 if (!head) { 1847 allocbcount++; 1848 zss->sl_soft_active = 1; 1849 head = mp; 1850 } else { 1851 if (!tail) 1852 tail = head; 1853 tail->b_next = mp; 1854 tail = mp; 1855 } 1856 } 1857 if (allocbcount) 1858 ZSH_GETBLOCK(zs, allocbcount); 1859 1860 tmp = NULL; 1861 again: 1862 mutex_enter(zs->zs_excl_hi); 1863 if (!zss->sl_xstandby) { 1864 if (tmp) { 1865 zss->sl_xstandby = tmp; 1866 mutex_exit(zs->zs_excl_hi); 1867 } else { 1868 mutex_exit(zs->zs_excl_hi); 1869 if (tmp = getq(WR(q))) 1870 goto again; 1871 } 1872 } else { 1873 mutex_exit(zs->zs_excl_hi); 1874 if (tmp) 1875 (void) putbq(WR(q), tmp); 1876 } 1877 1878 mutex_exit(zs->zs_excl); 1879 1880 while (head) { 1881 if (!tail) { 1882 putnext(q, head); 1883 break; 1884 } 1885 mp = head; 1886 head = head->b_next; 1887 mp->b_next = NULL; 1888 putnext(q, mp); 1889 1890 } 1891 1892 if (m_error) 1893 (void) putnextctl1(q, M_ERROR, m_error); 1894 1895 zss->sl_soft_active = 0; 1896 1897 TRACE_1(TR_ZSH, TR_ZSH_SOFT_END, "zsh_soft end: zs = %p", zs); 1898 1899 return (0); 1900 } 1901 1902 /* 1903 * Initialization routine. 1904 * Sets Clock sources, baud rate, modes and miscellaneous parameters. 1905 */ 1906 static int 1907 zsh_program(struct zscom *zs, struct scc_mode *sm) 1908 { 1909 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1910 register struct zs_prog *zspp; 1911 register ushort_t tconst = 0; 1912 register int wr11 = 0; 1913 register int baud = 0; 1914 register int pll = 0; 1915 register int speed = 0; 1916 register int flags = ZSP_SYNC; 1917 int err = 0; 1918 1919 ZSSETSOFT(zs); /* get our house in order */ 1920 1921 switch (sm->sm_txclock) { 1922 case TXC_IS_TXC: 1923 wr11 |= ZSWR11_TXCLK_TRXC; 1924 break; 1925 case TXC_IS_RXC: 1926 wr11 |= ZSWR11_TXCLK_RTXC; 1927 break; 1928 case TXC_IS_BAUD: 1929 wr11 |= ZSWR11_TXCLK_BAUD; 1930 wr11 |= ZSWR11_TRXC_OUT_ENA + ZSWR11_TRXC_XMIT; 1931 baud++; 1932 break; 1933 case TXC_IS_PLL: 1934 wr11 |= ZSWR11_TXCLK_DPLL; 1935 pll++; 1936 break; 1937 default: 1938 zss->sl_mode.sm_retval = SMERR_TXC; 1939 err = EINVAL; 1940 goto out; 1941 } 1942 switch (sm->sm_rxclock) { 1943 case RXC_IS_RXC: 1944 wr11 |= ZSWR11_RXCLK_RTXC; 1945 break; 1946 case RXC_IS_TXC: 1947 wr11 |= ZSWR11_RXCLK_TRXC; 1948 break; 1949 case RXC_IS_BAUD: 1950 wr11 |= ZSWR11_RXCLK_BAUD; 1951 baud++; 1952 break; 1953 case RXC_IS_PLL: 1954 wr11 |= ZSWR11_RXCLK_DPLL; 1955 pll++; 1956 break; 1957 default: 1958 zss->sl_mode.sm_retval = SMERR_RXC; 1959 err = EINVAL; 1960 goto out; 1961 } 1962 if (baud && pll) { 1963 zss->sl_mode.sm_retval = SMERR_PLL; 1964 err = EINVAL; 1965 goto out; 1966 } 1967 if (pll && !(sm->sm_config & CONN_NRZI)) { 1968 zss->sl_mode.sm_retval = SMERR_PLL; 1969 err = EINVAL; 1970 goto out; 1971 } 1972 1973 /* 1974 * If we're going to use the BRG and the speed we want is != 0... 1975 */ 1976 if (baud && (speed = sm->sm_baudrate)) { 1977 tconst = (PCLK + speed) / (2 * speed) - 2; 1978 if (tconst == 0) { 1979 zss->sl_mode.sm_retval = SMERR_BAUDRATE; 1980 err = EINVAL; 1981 goto out; 1982 } 1983 sm->sm_baudrate = PCLK / (2 * ((int)tconst + 2)); 1984 } else { 1985 tconst = 0; /* Stop BRG. Also quiesces pin 24. */ 1986 } 1987 1988 if (pll) { 1989 if ((speed = sm->sm_baudrate * 32) != 0) 1990 tconst = (PCLK + speed) / (2 * speed) - 2; 1991 else 1992 tconst = 0; 1993 if (tconst == 0) { 1994 zss->sl_mode.sm_retval = SMERR_BAUDRATE; 1995 err = EINVAL; 1996 goto out; 1997 } 1998 speed = PCLK / (2 * ((int)tconst + 2)); 1999 sm->sm_baudrate = speed / 32; 2000 flags |= ZSP_PLL; 2001 } 2002 2003 if ((sm->sm_config & (CONN_LPBK|CONN_ECHO)) == (CONN_LPBK|CONN_ECHO)) { 2004 zss->sl_mode.sm_retval = SMERR_LPBKS; 2005 err = EINVAL; 2006 goto out; 2007 } 2008 if (sm->sm_config & CONN_LPBK) 2009 flags |= ZSP_LOOP; 2010 if (sm->sm_config & CONN_NRZI) 2011 flags |= ZSP_NRZI; 2012 if (sm->sm_config & CONN_ECHO) 2013 flags |= ZSP_ECHO; 2014 2015 zspp = &zs_prog[zs->zs_unit]; 2016 2017 zspp->zs = zs; 2018 zspp->flags = (uchar_t)flags; 2019 zspp->wr4 = ZSWR4_SDLC; 2020 zspp->wr11 = (uchar_t)wr11; 2021 zspp->wr12 = (uchar_t)(tconst & 0xff); 2022 zspp->wr13 = (uchar_t)((tconst >> 8) & 0xff); 2023 zspp->wr3 = (uchar_t)(ZSWR3_RX_ENABLE | ZSWR3_RXCRC_ENABLE | 2024 ZSWR3_RX_8); 2025 zspp->wr5 = (uchar_t)(ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_TXCRC_ENABLE); 2026 2027 if (zss->sl_flags & SF_FDXPTP) { 2028 zspp->wr5 |= ZSWR5_RTS; 2029 zss->sl_rr0 |= ZSRR0_CTS; /* Assume CTS is high */ 2030 } 2031 if (sm->sm_config & CONN_IBM) { 2032 zspp->wr15 = (uchar_t) 2033 (ZSR15_TX_UNDER | ZSR15_BREAK | ZSR15_SYNC | ZSR15_CTS); 2034 if (!(zss->sl_flags & SF_FDXPTP)) 2035 zspp->wr15 &= ~ZSR15_CTS; 2036 } else { 2037 zspp->wr5 |= ZSWR5_TX_ENABLE; 2038 zspp->wr15 = (uchar_t) 2039 (ZSR15_TX_UNDER | ZSR15_BREAK | ZSR15_SYNC); 2040 if (sm->sm_config & CONN_SIGNAL) 2041 zspp->wr15 |= ZSR15_CTS; 2042 } 2043 2044 zs_program(zspp); 2045 SCC_WRITE0(ZSWR0_RESET_STATUS); /* reset XS */ 2046 SCC_WRITE0(ZSWR0_RESET_STATUS); /* reset XS */ 2047 zss->sl_flags |= SF_INITIALIZED; 2048 bzero(&zss->sl_st, sizeof (struct sl_stats)); 2049 bcopy(sm, &zss->sl_mode, sizeof (struct scc_mode)); 2050 zss->sl_mode.sm_retval = 0; /* successful */ 2051 out: 2052 return (err); 2053 } 2054 2055 /* 2056 * Function to store modem signal changes in sl_mstat field. 2057 * Note that these events are supposed to be so far apart in time that 2058 * we should always be able to send up the event and allocate a message 2059 * block before another one happens. If not, we'll overwrite this one. 2060 */ 2061 static void 2062 zsh_setmstat(struct zscom *zs, int event) 2063 { 2064 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 2065 register struct sl_status *mstat; 2066 register mblk_t *mp; 2067 2068 if (((mp = zss->sl_mstat) != NULL) && 2069 (zss->sl_mode.sm_config & (CONN_SIGNAL))) { 2070 mstat = (struct sl_status *)mp->b_wptr; 2071 mstat->type = (zss->sl_mode.sm_config & CONN_IBM) ? 2072 SLS_LINKERR : SLS_MDMSTAT; 2073 mstat->status = event; 2074 gethrestime(&mstat->tstamp); 2075 mp->b_wptr += sizeof (struct sl_status); 2076 mp->b_datap->db_type = M_PROTO; 2077 ZSH_PUTQ(mp); 2078 zss->sl_mstat = NULL; 2079 ZSSETSOFT(zs); 2080 } 2081 } 2082 2083 /* 2084 * Received Bad Frame procedure 2085 */ 2086 static void 2087 zsh_rxbad(struct zscom *zs, struct syncline *zss) 2088 { 2089 /* 2090 * swallow bad characters 2091 */ 2092 (void) SCC_READDATA(); 2093 (void) SCC_READDATA(); 2094 (void) SCC_READDATA(); 2095 2096 SCC_BIS(3, ZSWR3_HUNT); /* enter hunt mode - ignores rest of frame */ 2097 2098 zss->sl_st.ierror++; 2099 2100 /* 2101 * Free active receive message. 2102 */ 2103 if (zss->sl_rhead) { 2104 zss->sl_rhead->b_wptr = zss->sl_rhead->b_rptr; 2105 zss->sl_rhead->b_datap->db_type = M_RSE; 2106 ZSH_FREEMSG(zss->sl_rhead); 2107 zss->sl_ractb = NULL; 2108 zs->zs_rd_cur = NULL; 2109 zs->zs_rd_lim = NULL; 2110 } 2111 if (zss->sl_rhead) { 2112 zss->sl_rhead = NULL; 2113 ZSH_ALLOCB(zss->sl_ractb); 2114 zs->zs_rd_cur = NULL; 2115 zs->zs_rd_lim = NULL; 2116 } 2117 2118 ZSSETSOFT(zs); 2119 } 2120 2121 /* 2122 * Transmit error procedure 2123 */ 2124 static void 2125 zsh_txbad(struct zscom *zs, struct syncline *zss) 2126 { 2127 if (zss->sl_xhead) { /* free the message we were sending */ 2128 zss->sl_xhead->b_wptr = zss->sl_xhead->b_rptr; 2129 ZSH_FREEMSG(zss->sl_xhead); 2130 zss->sl_xactb = NULL; 2131 zs->zs_wr_cur = NULL; 2132 zs->zs_wr_lim = NULL; 2133 } 2134 zss->sl_xhead = NULL; 2135 2136 if (!(zss->sl_flags & SF_FDXPTP)) { 2137 /* 2138 * drop RTS and our notion of CTS 2139 */ 2140 SCC_BIC(5, ZSWR5_RTS); 2141 SCC_BIC(5, ZSWR5_TX_ENABLE); 2142 zss->sl_rr0 &= ~ZSRR0_CTS; 2143 } 2144 zss->sl_txstate = TX_IDLE; 2145 if (!(zss->sl_flags & SF_PHONY)) 2146 zss->sl_st.oerror++; 2147 } 2148 2149 /* 2150 * Transmitter watchdog timeout routine 2151 */ 2152 static void 2153 zsh_watchdog(void *arg) 2154 { 2155 struct zscom *zs = arg; 2156 struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 2157 queue_t *wq; 2158 mblk_t *mp; 2159 int warning = 0; 2160 uchar_t s0; 2161 int do_flushwq = 0; 2162 2163 /* 2164 * The main reason for this routine is because, under some 2165 * circumstances, a transmit interrupt may get lost (ie., if 2166 * underrun occurs after the last character has been sent, and 2167 * the tx interrupt following the abort gets scheduled before 2168 * the current tx interrupt has been serviced). Transmit can 2169 * also get hung if the cable is pulled out and the clock was 2170 * coming in from the modem. 2171 */ 2172 2173 mutex_enter(zs->zs_excl); 2174 if (zss->sl_stream.str_rq) 2175 wq = WR(zss->sl_stream.str_rq); 2176 else { 2177 mutex_exit(zs->zs_excl); 2178 return; /* guard against close/callback race */ 2179 } 2180 2181 mutex_enter(zs->zs_excl_hi); 2182 if (!(zss->sl_flags & SF_XMT_INPROG) && wq->q_first) { 2183 zss->sl_flags |= SF_XMT_INPROG; 2184 if ((zss->sl_flags & SF_FDXPTP) || 2185 zsh_hdp_ok_or_rts_state(zs, zss)) 2186 (void) zsh_start(zs, zss); 2187 goto end_watchdog; 2188 } 2189 2190 if (zss->sl_wd_count-- > 0) 2191 goto end_watchdog; 2192 2193 if (zss->sl_flags & SF_FLUSH_WQ) { 2194 if (!(zss->sl_flags & SF_FDXPTP)) 2195 zss->sl_flags &= ~SF_FLUSH_WQ; 2196 else { 2197 s0 = SCC_READ0(); 2198 if (s0 & ZSRR0_CTS) { 2199 zss->sl_rr0 |= ZSRR0_CTS; 2200 SCC_BIS(15, ZSR15_CTS); 2201 zss->sl_flags &= ~SF_FLUSH_WQ; 2202 zsh_setmstat(zs, CS_CTS_UP); 2203 } 2204 } 2205 } 2206 2207 switch (zss->sl_txstate) { 2208 2209 case TX_ABORTED: 2210 /* 2211 * Transmitter was hung ... try restarting it. 2212 */ 2213 if (zss->sl_flags & SF_FDXPTP) { 2214 zss->sl_flags |= SF_XMT_INPROG; 2215 (void) zsh_start(zs, zss); 2216 } else 2217 do_flushwq = 1; 2218 break; 2219 2220 case TX_ACTIVE: 2221 case TX_CRC: 2222 /* 2223 * Transmit is hung for some reason. Reset tx interrupt. 2224 * Flush transmit fifo by sending an abort command 2225 * which also sets the Underrun/EOM latch in WR0 and in 2226 * turn generates an External Status interrupt that 2227 * will reset the necessary message buffer pointers. 2228 * The watchdog timer will cycle again to allow the SCC 2229 * to settle down after the abort command. The next 2230 * time through we'll see that the state is now TX_ABORTED 2231 * and call zsh_start to grab a new message. 2232 */ 2233 if (--zss->sl_wd_count <= 0) { 2234 SCC_WRITE0(ZSWR0_SEND_ABORT); 2235 SCC_WRITE0(ZSWR0_RESET_ERRORS); 2236 SCC_WRITE0(ZSWR0_RESET_TXINT); 2237 zsh_txbad(zs, zss); 2238 zss->sl_txstate = TX_ABORTED; /* must be after txbad */ 2239 warning = 1; 2240 } 2241 break; 2242 2243 case TX_RTS: 2244 /* 2245 * Timer expired after we raised RTS. CTS never came up. 2246 */ 2247 zss->sl_st.cts++; 2248 2249 zsh_setmstat(zs, CS_CTS_TO); 2250 zss->sl_flags &= ~SF_XMT_INPROG; 2251 zss->sl_flags |= SF_FLUSH_WQ; 2252 ZSSETSOFT(zs); 2253 break; 2254 2255 default: 2256 /* 2257 * If we time out in an inactive state we set a soft 2258 * interrupt. This will call zsh_start which will 2259 * clear SF_XMT_INPROG if the queue is empty. 2260 */ 2261 break; 2262 } 2263 end_watchdog: 2264 if (zss->sl_txstate != TX_OFF) { 2265 mutex_exit(zs->zs_excl_hi); 2266 zss->sl_wd_id = timeout(zsh_watchdog, zs, SIO_WATCHDOG_TICK); 2267 } else { 2268 zss->sl_wd_id = 0; /* safety */ 2269 mutex_exit(zs->zs_excl_hi); 2270 } 2271 if (warning || do_flushwq) { 2272 flushq(wq, FLUSHDATA); 2273 mutex_enter(zs->zs_excl_hi); 2274 if ((mp = zss->sl_xstandby) != NULL) 2275 zss->sl_xstandby = NULL; 2276 mutex_exit(zs->zs_excl_hi); 2277 if (mp) 2278 freemsg(mp); 2279 } 2280 mutex_exit(zs->zs_excl); 2281 if (warning) 2282 cmn_err(CE_WARN, "zsh%x: transmit hung", zs->zs_unit); 2283 } 2284 2285 static void 2286 zsh_callback(void *arg) 2287 { 2288 struct zscom *zs = arg; 2289 struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 2290 int tmp = ZSH_MAX_RSTANDBY; 2291 2292 mutex_enter(zs->zs_excl); 2293 if (zss->sl_bufcid) { 2294 zss->sl_bufcid = 0; 2295 ZSH_GETBLOCK(zs, tmp); 2296 } 2297 mutex_exit(zs->zs_excl); 2298 } 2299