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