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 { 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 #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 void 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 (int (*)())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 register int n = ZSH_MAX_RSTANDBY; \ 296 while (--n >= 0) { \ 297 if (!zss->sl_rstandby[n]) { \ 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 register 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 register 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 register mblk_t *tmp; \ 370 for (;;) { \ 371 ZSH_GETQ(tmp); \ 372 if (!(tmp)) \ 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 register int unit; 390 char name[3] = { 391 '\0', '\0', '\0' }; 392 393 /* 394 * Since zsh is a child of the "pseudo" nexus, we can expect the 395 * attach routine to be called only once. We need to create all 396 * necessary devices in one shot. There is never more than one 397 * SCC chip that supports zsh devices. 398 */ 399 400 if (cmd != DDI_ATTACH) 401 return (DDI_FAILURE); 402 if (zscom == NULL) 403 return (DDI_FAILURE); /* zsattach not done */ 404 unit = 2 * ddi_get_instance(dev); 405 if (unit > 1) 406 return (DDI_FAILURE); /* only use cpu ports */ 407 408 if (ddi_create_minor_node(dev, "zsh", S_IFCHR, 409 NULL, DDI_PSEUDO, CLONE_DEV) == DDI_FAILURE) { 410 ddi_remove_minor_node(dev, NULL); 411 cmn_err(CE_WARN, "zsh clone device creation failed."); 412 return (DDI_FAILURE); 413 } 414 415 for (; unit < maxzsh/2; unit++) { 416 zscom[unit].zs_hdlc_dip = dev; 417 418 (void) sprintf(name, "%d", unit); 419 if (ddi_create_minor_node(dev, name, S_IFCHR, 420 2*unit, DDI_PSEUDO, NULL) == DDI_FAILURE) { 421 ddi_remove_minor_node(dev, NULL); 422 return (DDI_FAILURE); 423 } 424 unit++; 425 (void) sprintf(name, "%d", unit); 426 if (ddi_create_minor_node(dev, name, S_IFCHR, 427 2*(unit-1)+1, DDI_PSEUDO, NULL) == DDI_FAILURE) { 428 ddi_remove_minor_node(dev, NULL); 429 return (DDI_FAILURE); 430 } 431 } 432 433 return (DDI_SUCCESS); 434 } 435 436 /* ARGSUSED */ 437 int 438 zsh_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 439 void **result) 440 { 441 register dev_t dev = (dev_t)arg; 442 register int unit, error; 443 register struct zscom *zs; 444 445 if ((unit = UNIT(dev)) >= nzs) 446 return (DDI_FAILURE); 447 448 switch (infocmd) { 449 case DDI_INFO_DEVT2DEVINFO: 450 if (zscom == NULL) { 451 error = DDI_FAILURE; 452 } else { 453 zs = &zscom[unit]; 454 *result = zs->zs_hdlc_dip; 455 error = DDI_SUCCESS; 456 } 457 break; 458 case DDI_INFO_DEVT2INSTANCE: 459 *result = (void *)(uintptr_t)(unit / 2); 460 error = DDI_SUCCESS; 461 break; 462 default: 463 error = DDI_FAILURE; 464 } 465 return (error); 466 } 467 468 static int 469 zsh_detach(dev_info_t *dev, ddi_detach_cmd_t cmd) 470 { 471 if (cmd != DDI_DETACH) 472 return (DDI_FAILURE); 473 474 ddi_remove_minor_node(dev, NULL); 475 476 return (DDI_SUCCESS); 477 } 478 479 static void 480 zsh_init_port(struct zscom *zs, struct syncline *zss) 481 { 482 register uchar_t s0; 483 484 SCC_WRITE(3, (ZSWR3_RX_ENABLE | ZSWR3_RXCRC_ENABLE | ZSWR3_RX_8)); 485 SCC_WRITE(5, (ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_TXCRC_ENABLE)); 486 zss->sl_rr0 = SCC_READ0(); 487 if (zss->sl_flags & SF_FDXPTP) { 488 SCC_BIS(5, ZSWR5_TX_ENABLE); 489 SCC_BIS(5, ZSWR5_RTS); 490 s0 = SCC_READ0(); 491 if ((s0 & ZSRR0_CTS) || 492 !(zss->sl_mode.sm_config & (CONN_SIGNAL | CONN_IBM))) { 493 /* 494 * send msg that CTS is up 495 */ 496 zss->sl_rr0 |= ZSRR0_CTS; 497 zss->sl_txstate = TX_IDLE; 498 } else { 499 zss->sl_flags |= SF_XMT_INPROG; 500 zss->sl_txstate = TX_RTS; 501 zss->sl_rr0 &= ~ZSRR0_CTS; 502 zss->sl_wd_count = zsh_timer_count; 503 if (!zss->sl_wd_id) 504 zss->sl_wd_id = timeout(zsh_watchdog, 505 zs, SIO_WATCHDOG_TICK); 506 } 507 } else { 508 SCC_BIC(15, ZSR15_CTS); 509 SCC_BIC(5, ZSWR5_TX_ENABLE); 510 SCC_BIC(5, ZSWR5_RTS); 511 zss->sl_flags &= ~SF_FLUSH_WQ; 512 } 513 } 514 515 /* 516 * Open routine. 517 */ 518 519 /*ARGSUSED*/ 520 static int 521 zsh_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr) 522 { 523 register struct zscom *zs; 524 register struct syncline *zss; 525 register struct ser_str *stp; 526 register int unit; 527 register int tmp; 528 529 if (sflag != CLONEOPEN) { 530 if (rq->q_ptr) 531 return (EBUSY); /* We got a stream that is in use */ 532 533 unit = UNIT(*dev); 534 if (unit >= maxzsh) 535 return (ENXIO); /* unit not configured */ 536 537 if (zscom == NULL) 538 return (ENXIO); /* device not found by autoconfig */ 539 zs = &zscom[unit]; 540 541 if (zs->zs_ops == NULL) { 542 return (ENXIO); /* device not found by autoconfig */ 543 } 544 545 TRACE_1(TR_ZSH, TR_ZSH_OPEN, "zsh_open:unit = %d", unit); 546 547 mutex_enter(zs->zs_excl); 548 if ((zs->zs_ops != &zsops_null) && 549 (zs->zs_ops != &zsops_hdlc)) { 550 mutex_exit(zs->zs_excl); 551 return (EBUSY); /* another protocol got here first */ 552 } 553 554 /* Mark device as busy (for power management) */ 555 (void) pm_busy_component(zs->zs_dip, unit%2+1); 556 (void) ddi_dev_is_needed(zs->zs_dip, unit%2+1, 1); 557 558 zsopinit(zs, &zsops_hdlc); 559 560 zss = (struct syncline *)&zscom[unit].zs_priv_str; 561 stp = &zss->sl_stream; 562 stp->str_state = NULL; 563 stp->str_com = (caddr_t)zs; 564 565 zss->sl_xhead = NULL; 566 zss->sl_xactb = NULL; 567 zs->zs_wr_cur = NULL; 568 zs->zs_wr_lim = NULL; 569 zs->zs_wr_cur = NULL; 570 zs->zs_wr_lim = NULL; 571 zss->sl_rhead = NULL; 572 zss->sl_ractb = NULL; 573 zs->zs_rd_cur = NULL; 574 zs->zs_rd_lim = NULL; 575 zss->sl_mstat = NULL; 576 zss->sl_xstandby = NULL; 577 zss->sl_wd_id = 0; 578 zss->sl_soft_active = 0; 579 zss->sl_stream.str_rq = NULL; 580 581 zs->zs_priv = (caddr_t)zss; 582 583 zss->sl_mru = zsh_default_mru; 584 tmp = ZSH_MAX_RSTANDBY; 585 ZSH_GETBLOCK(zs, tmp); 586 if (zss->sl_rstandby[0] == NULL) { 587 cmn_err(CE_WARN, "zsh_open: can't alloc message block"); 588 mutex_exit(zs->zs_excl); 589 return (ENOSR); 590 } 591 mutex_enter(zs->zs_excl_hi); 592 ZSH_ALLOCB(zss->sl_ractb); 593 zss->sl_txstate = TX_OFF; 594 zss->sl_rr0 = SCC_READ0(); 595 zss->sl_flags &= (SF_INITIALIZED | SF_FDXPTP); 596 if (zss->sl_flags & SF_INITIALIZED) 597 zsh_init_port(zs, zss); 598 mutex_exit(zs->zs_excl_hi); 599 mutex_exit(zs->zs_excl); 600 } else { /* CLONEOPEN */ 601 mutex_enter(&zs_curr_lock); 602 for (unit = maxzsh; unit < MAXZSHCLONES; unit++) 603 if (!zsh_usedminor[unit]) { 604 zsh_usedminor[unit] = (unsigned char)unit; 605 break; 606 } 607 mutex_exit(&zs_curr_lock); 608 if (unit >= MAXZSHCLONES) /* no slots available */ 609 return (ENODEV); 610 *dev = makedevice(getmajor(*dev), unit); 611 612 stp = kmem_zalloc(sizeof (struct ser_str), KM_NOSLEEP); 613 if (stp == NULL) { 614 cmn_err(CE_WARN, 615 "zsh clone open failed, no memory, rq=%p\n", 616 (void *)rq); 617 return (ENOMEM); 618 } 619 stp->str_state = STR_CLONE; 620 stp->str_com = NULL; /* can't determine without ppa */ 621 } 622 stp->str_rq = rq; 623 stp->str_inst = unit; 624 625 rq->q_ptr = WR(rq)->q_ptr = (caddr_t)stp; 626 qprocson(rq); 627 return (0); 628 } 629 630 /* 631 * Close routine. 632 */ 633 int zsh_tx_enable_in_close = 0; 634 635 /*ARGSUSED*/ 636 static int 637 zsh_close(queue_t *rq, int flag, cred_t *cr __unused) 638 { 639 struct ser_str *stp; 640 struct zscom *zs; 641 struct syncline *zss; 642 mblk_t *mp; 643 int i; 644 timeout_id_t sl_wd_id; 645 bufcall_id_t sl_bufcid; 646 647 /* 648 * Note that a close is only called on the last close of a 649 * particular stream. Assume that we need to do it all. 650 */ 651 qprocsoff(rq); /* no new business after this */ 652 653 stp = (struct ser_str *)rq->q_ptr; 654 if (stp == NULL) 655 return (0); /* already been closed once */ 656 657 if (stp->str_state == STR_CLONE) { 658 zsh_usedminor[stp->str_inst] = 0; 659 } else { 660 zs = (struct zscom *)stp->str_com; 661 if (zs == NULL) 662 goto out; 663 664 TRACE_1(TR_ZSH, TR_ZSH_CLOSE, "zs = %p", zs); 665 666 zss = (struct syncline *)zs->zs_priv; 667 mutex_enter(zs->zs_excl); 668 flushq(WR(rq), FLUSHALL); 669 mutex_enter(zs->zs_excl_hi); 670 if (zss->sl_xstandby) { 671 zss->sl_xstandby->b_wptr = zss->sl_xstandby->b_rptr; 672 ZSH_FREEMSG(zss->sl_xstandby); 673 zss->sl_xstandby = NULL; 674 } 675 mutex_exit(zs->zs_excl_hi); 676 677 ZSH_FLUSHQ; 678 679 /* 680 * Stop the Watchdog Timer. 681 */ 682 if ((sl_wd_id = zss->sl_wd_id) != 0) 683 zss->sl_wd_id = 0; 684 685 /* 686 * Cancel outstanding "bufcall" request. 687 */ 688 if ((sl_bufcid = zss->sl_bufcid) != 0) 689 zss->sl_bufcid = 0; 690 691 mutex_enter(zs->zs_excl_hi); 692 if (zs->zs_wr_cur) { 693 zs->zs_wr_cur = NULL; 694 zs->zs_wr_lim = NULL; 695 SCC_WRITE0(ZSWR0_SEND_ABORT); 696 ZSDELAY(); 697 ZSDELAY(); 698 } 699 zss->sl_txstate = TX_OFF; /* so it can't rearm in close */ 700 701 zs->zs_wr_cur = NULL; 702 zs->zs_wr_lim = NULL; 703 SCC_BIC(15, 704 (ZSR15_TX_UNDER | ZSR15_BREAK | ZSR15_SYNC | ZSR15_CTS)); 705 SCC_WRITE(3, 0); /* Quiesce receiver */ 706 if (zsh_tx_enable_in_close && !(zss->sl_flags & SF_FDXPTP)) { 707 SCC_BIS(5, ZSWR5_TX_ENABLE); 708 } else 709 SCC_BIC(5, ZSWR5_TX_ENABLE); 710 711 SCC_BIC(5, (ZSWR5_DTR | ZSWR5_RTS | ZSWR5_TXCRC_ENABLE)); 712 SCC_WRITE0(ZSWR0_RESET_TXINT); /* reset TX */ 713 SCC_WRITE0(ZSWR0_RESET_STATUS); /* reset XS */ 714 SCC_WRITE0(ZSWR0_RESET_ERRORS); 715 (void) SCC_READDATA(); /* reset RX */ 716 ZSDELAY(); 717 (void) SCC_READDATA(); 718 ZSDELAY(); 719 (void) SCC_READDATA(); 720 ZSDELAY(); 721 722 723 /* 724 * Free up everything we ever allocated. 725 */ 726 if ((mp = zss->sl_rhead) != NULL) { 727 zss->sl_ractb = NULL; /* already freed */ 728 zs->zs_rd_cur = NULL; 729 zs->zs_rd_lim = NULL; 730 zss->sl_rhead = NULL; 731 } 732 mutex_exit(zs->zs_excl_hi); 733 if (mp) 734 freemsg(mp); 735 736 mutex_enter(zs->zs_excl_hi); 737 if ((mp = zss->sl_ractb) != NULL) { 738 zs->zs_rd_cur = NULL; 739 zs->zs_rd_lim = NULL; 740 zss->sl_ractb = NULL; 741 } 742 mutex_exit(zs->zs_excl_hi); 743 if (mp) 744 freemsg(mp); 745 746 for (i = 0; i < ZSH_MAX_RSTANDBY; i++) { 747 mutex_enter(zs->zs_excl_hi); 748 mp = zss->sl_rstandby[i]; 749 zss->sl_rstandby[i] = NULL; 750 mutex_exit(zs->zs_excl_hi); 751 if (mp) 752 freemsg(mp); 753 } 754 755 mutex_enter(zs->zs_excl_hi); 756 if ((mp = zss->sl_xhead) != NULL) { 757 zss->sl_xhead = NULL; 758 zss->sl_xactb = NULL; 759 } 760 mutex_exit(zs->zs_excl_hi); 761 if (mp) 762 freemsg(mp); 763 764 ZSH_FLUSHQ; 765 766 mutex_enter(zs->zs_excl_hi); 767 if ((mp = zss->sl_xstandby) != NULL) 768 zss->sl_xstandby = NULL; 769 mutex_exit(zs->zs_excl_hi); 770 if (mp) 771 freemsg(mp); 772 773 mutex_enter(zs->zs_excl_hi); 774 if ((mp = zss->sl_mstat) != NULL) 775 zss->sl_mstat = NULL; 776 zss->sl_txstate = TX_OFF; /* so it can't rearm in close */ 777 mutex_exit(zs->zs_excl_hi); 778 if (mp) 779 freemsg(mp); 780 781 zss->sl_stream.str_rq = NULL; 782 zsopinit(zs, &zsops_null); 783 mutex_exit(zs->zs_excl); 784 if (sl_wd_id) 785 (void) untimeout(sl_wd_id); 786 if (sl_bufcid) 787 unbufcall(sl_bufcid); 788 while (zss->sl_soft_active) 789 drv_usecwait(1); 790 791 /* Mark device as available for power management */ 792 (void) pm_idle_component(zs->zs_dip, zs->zs_unit%2+1); 793 } 794 795 if (stp->str_state == STR_CLONE) 796 kmem_free(stp, sizeof (struct ser_str)); 797 798 out: 799 rq->q_ptr = WR(rq)->q_ptr = NULL; 800 801 return (0); 802 } 803 804 static int 805 zsh_hdp_ok_or_rts_state(struct zscom *zs, struct syncline *zss) 806 { 807 register uchar_t s0; 808 809 SCC_BIS(15, ZSR15_CTS); 810 SCC_BIS(5, ZSWR5_RTS); 811 s0 = SCC_READ0(); 812 if (s0 & ZSRR0_CTS) { 813 SCC_BIS(5, ZSWR5_TX_ENABLE); 814 zss->sl_rr0 |= ZSRR0_CTS; 815 return (1); 816 } 817 zss->sl_flags |= SF_XMT_INPROG; 818 zss->sl_txstate = TX_RTS; 819 zss->sl_rr0 &= ~ZSRR0_CTS; 820 zss->sl_wd_count = zsh_timer_count; 821 return (0); 822 } 823 824 /* 825 * Put procedure for write queue. 826 */ 827 static void 828 zsh_wput(queue_t *wq, mblk_t *mp) 829 { 830 register struct ser_str *stp = (struct ser_str *)wq->q_ptr; 831 register struct zscom *zs; 832 register struct syncline *zss = NULL; 833 register ulong_t prim, error = 0; 834 register union DL_primitives *dlp; 835 register int ppa; 836 register mblk_t *tmp; 837 register struct copyresp *resp; 838 839 /* 840 * stp->str_com supplied by open or DLPI attach. 841 */ 842 if (stp == NULL) { 843 freemsg(mp); 844 return; 845 } 846 zs = (struct zscom *)stp->str_com; 847 848 TRACE_0(TR_ZSH, TR_ZSH_WPUT_START, "zsh_wput start"); 849 850 if ((mp->b_datap->db_type == M_FLUSH) && 851 (stp->str_state == STR_CLONE)) { 852 if (*mp->b_rptr & FLUSHW) { 853 flushq(wq, FLUSHDATA); 854 *mp->b_rptr &= ~FLUSHW; 855 } 856 if (*mp->b_rptr & FLUSHR) 857 qreply(wq, mp); /* let the read queues have at it */ 858 else 859 freemsg(mp); 860 return; 861 } 862 863 if ((zs == NULL) && (mp->b_datap->db_type != M_PROTO)) { 864 freemsg(mp); 865 cmn_err(CE_WARN, 866 "zsh: clone device %d must be attached before use!", 867 stp->str_inst); 868 (void) putnextctl1(RD(wq), M_ERROR, EPROTO); 869 return; 870 } 871 872 if (stp->str_state == STR_CLONE) { /* Clone opened, limited. */ 873 if ((mp->b_datap->db_type != M_PROTO) && 874 (mp->b_datap->db_type != M_IOCTL) && 875 (mp->b_datap->db_type != M_IOCDATA)) { 876 freemsg(mp); 877 cmn_err(CE_WARN, 878 "zsh%x: invalid operation for clone dev.\n", 879 stp->str_inst); 880 (void) putnextctl1(RD(wq), M_ERROR, EPROTO); 881 return; 882 } 883 } else { 884 zss = (struct syncline *)zs->zs_priv; 885 } 886 887 switch (mp->b_datap->db_type) { 888 889 case M_DATA: 890 /* 891 * Queue the message up to be transmitted. 892 * Set "in progress" flag and call the start routine. 893 */ 894 mutex_enter(zs->zs_excl_hi); 895 if (!(zss->sl_flags & SF_INITIALIZED)) { 896 mutex_exit(zs->zs_excl_hi); 897 cmn_err(CE_WARN, 898 "zsh%x not initialized, can't send message", 899 zs->zs_unit); 900 freemsg(mp); 901 (void) putnextctl1(RD(wq), M_ERROR, ECOMM); 902 return; 903 } 904 mutex_exit(zs->zs_excl_hi); 905 if (zs->zs_flags & ZS_NEEDSOFT) { 906 zs->zs_flags &= ~ZS_NEEDSOFT; 907 (void) zsh_softint(zs); 908 } 909 while (mp->b_wptr == mp->b_rptr) { 910 register mblk_t *mp1; 911 mp1 = unlinkb(mp); 912 freemsg(mp); 913 mp = mp1; 914 if (mp == NULL) 915 return; 916 } 917 mutex_enter(zs->zs_excl); 918 (void) putq(wq, mp); 919 mutex_enter(zs->zs_excl_hi); 920 if (zss->sl_flags & SF_FLUSH_WQ) { 921 mutex_exit(zs->zs_excl_hi); 922 flushq(wq, FLUSHDATA); 923 mutex_exit(zs->zs_excl); 924 925 TRACE_1(TR_ZSH, TR_ZSH_WPUT_END, 926 "zsh_wput end: zs = %p", zs); 927 928 return; 929 } 930 tmp = NULL; 931 again: 932 if (!zss->sl_xstandby) { 933 if (tmp) 934 zss->sl_xstandby = tmp; 935 else { 936 mutex_exit(zs->zs_excl_hi); 937 tmp = getq(wq); 938 mutex_enter(zs->zs_excl_hi); 939 if (tmp) 940 goto again; 941 } 942 } else if (tmp) { 943 mutex_exit(zs->zs_excl_hi); 944 (void) putbq(wq, tmp); 945 mutex_enter(zs->zs_excl_hi); 946 } 947 948 if (zss->sl_flags & SF_XMT_INPROG) { 949 mutex_exit(zs->zs_excl_hi); 950 mutex_exit(zs->zs_excl); 951 952 TRACE_1(TR_ZSH, TR_ZSH_WPUT_END, 953 "zsh_wput end: zs = %p", zs); 954 955 return; 956 } 957 958 if (!zss->sl_wd_id) { 959 zss->sl_wd_count = zsh_timer_count; 960 zss->sl_txstate = TX_IDLE; 961 mutex_exit(zs->zs_excl_hi); 962 zss->sl_wd_id = timeout(zsh_watchdog, zs, 963 SIO_WATCHDOG_TICK); 964 mutex_enter(zs->zs_excl_hi); 965 } 966 967 zss->sl_flags |= SF_XMT_INPROG; 968 if ((zss->sl_flags & SF_FDXPTP) || 969 zsh_hdp_ok_or_rts_state(zs, zss)) 970 (void) zsh_start(zs, zss); 971 mutex_exit(zs->zs_excl_hi); 972 mutex_exit(zs->zs_excl); 973 break; 974 975 case M_PROTO: 976 /* 977 * Here is where a clone device finds out about the 978 * hardware it is going to attach to. The request is 979 * validated and a ppa is extracted from it and validated. 980 * This number is used to index the hardware data structure 981 * and the protocol data structure, in case the latter 982 * was not provided by a data-path open before this. 983 */ 984 if (stp->str_state != STR_CLONE) { 985 freemsg(mp); 986 return; 987 } 988 989 if (MBLKL(mp) < DL_ATTACH_REQ_SIZE) { 990 prim = DL_ATTACH_REQ; 991 error = DL_BADPRIM; 992 goto end_proto; 993 } 994 dlp = (union DL_primitives *)mp->b_rptr; 995 prim = dlp->dl_primitive; 996 if (prim != DL_ATTACH_REQ) { 997 error = DL_BADPRIM; 998 goto end_proto; 999 } 1000 ppa = dlp->attach_req.dl_ppa; 1001 ppa = (ppa%2) ? ((ppa-1)*2 +1) : (ppa*2); 1002 if (ppa >= maxzsh) { 1003 error = DL_BADPPA; 1004 goto end_proto; 1005 } 1006 zs = &zscom[ppa]; 1007 if (zs->zs_ops == NULL) { 1008 error = ENXIO; 1009 goto end_proto; 1010 } 1011 mutex_enter(zs->zs_excl); 1012 if ((zs->zs_ops != &zsops_null) && 1013 (zs->zs_ops != &zsops_hdlc)) { 1014 /* 1015 * another protocol got here first 1016 */ 1017 error = (EBUSY); 1018 mutex_exit(zs->zs_excl); 1019 goto end_proto; 1020 1021 } 1022 1023 stp->str_com = (caddr_t)zs; 1024 mutex_exit(zs->zs_excl); 1025 end_proto: 1026 if (error) 1027 dlerrorack(wq, mp, prim, error, 0); 1028 else 1029 dlokack(wq, mp, DL_ATTACH_REQ); 1030 break; 1031 1032 case M_IOCTL: 1033 zsh_ioctl(wq, mp); 1034 break; 1035 1036 case M_IOCDATA: 1037 resp = (struct copyresp *)mp->b_rptr; 1038 if (resp->cp_rval) { 1039 /* 1040 * Just free message on failure. 1041 */ 1042 freemsg(mp); 1043 break; 1044 } 1045 1046 switch (resp->cp_cmd) { 1047 1048 case S_IOCGETMODE: 1049 case S_IOCGETSTATS: 1050 case S_IOCGETSPEED: 1051 case S_IOCGETMCTL: 1052 case S_IOCGETMRU: 1053 mioc2ack(mp, NULL, 0, 0); 1054 qreply(wq, mp); 1055 break; 1056 1057 case S_IOCSETMODE: 1058 zss = (struct syncline *)&zs->zs_priv_str; 1059 mutex_enter(zs->zs_excl); 1060 error = zsh_setmode(zs, zss, 1061 (struct scc_mode *)mp->b_cont->b_rptr); 1062 if (error) { 1063 register struct iocblk *iocp = 1064 (struct iocblk *)mp->b_rptr; 1065 mp->b_datap->db_type = M_IOCNAK; 1066 iocp->ioc_error = error; 1067 } else 1068 mioc2ack(mp, NULL, 0, 0); 1069 mutex_exit(zs->zs_excl); 1070 qreply(wq, mp); 1071 break; 1072 1073 case S_IOCSETMRU: 1074 zss = (struct syncline *)&zs->zs_priv_str; 1075 mutex_enter(zs->zs_excl); 1076 zss->sl_mru = *(int *)mp->b_cont->b_rptr; 1077 mutex_exit(zs->zs_excl); 1078 mioc2ack(mp, NULL, 0, 0); 1079 qreply(wq, mp); 1080 break; 1081 default: 1082 freemsg(mp); 1083 } 1084 break; 1085 1086 /* 1087 * We're at the bottom of the food chain, so we flush our 1088 * write queue, clear the FLUSHW bit so it doesn't go round 1089 * and round forever, then flush our read queue (since there's 1090 * no read put procedure down here) and pass it up for any 1091 * higher modules to deal with in their own way. 1092 */ 1093 case M_FLUSH: 1094 if (*mp->b_rptr & FLUSHW) { 1095 mutex_enter(zs->zs_excl); 1096 flushq(wq, FLUSHDATA); 1097 mutex_enter(zs->zs_excl_hi); 1098 tmp = zss->sl_xstandby; 1099 zss->sl_xstandby = NULL; 1100 mutex_exit(zs->zs_excl_hi); 1101 if (tmp) 1102 freemsg(tmp); 1103 mutex_exit(zs->zs_excl); 1104 *mp->b_rptr &= ~FLUSHW; 1105 } 1106 1107 if (*mp->b_rptr & FLUSHR) { 1108 mutex_enter(zs->zs_excl); 1109 ZSH_FLUSHQ; 1110 mutex_exit(zs->zs_excl); 1111 qreply(wq, mp); /* let the read queues have at it */ 1112 } else 1113 freemsg(mp); 1114 break; 1115 1116 default: 1117 /* 1118 * "No, I don't want a subscription to Chain Store Age, 1119 * thank you anyway." 1120 */ 1121 freemsg(mp); 1122 break; 1123 } 1124 1125 TRACE_1(TR_ZSH, TR_ZSH_WPUT_END, "zsh_wput end: zs = %p", zs); 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 register mblk_t *mp; 1137 register uchar_t *wptr; 1138 register uchar_t *rptr; 1139 register 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) 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 register struct ser_str *stp = (struct ser_str *)wq->q_ptr; 1236 register struct zscom *zs = (struct zscom *)stp->str_com; 1237 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1238 register struct iocblk *iocp = (struct iocblk *)mp->b_rptr; 1239 register struct scc_mode *sm; 1240 register struct sl_stats *st; 1241 register uchar_t *msignals; 1242 register mblk_t *tmp; 1243 register 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 register int error = 0; 1393 register 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 register struct syncline *zss; 1454 register mblk_t *mp; 1455 register int tmp; 1456 register 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) 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 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1567 register 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 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1680 register 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) { /* Beginning of frame */ 1692 if (!bp) { 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) { 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 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1720 register uchar_t s1; 1721 register 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 register struct syncline *zss; 1772 register queue_t *q; 1773 register mblk_t *mp, *tmp; 1774 register mblk_t *head = NULL, *tail = NULL; 1775 register 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 || (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) 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 register 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) 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) { 1846 allocbcount++; 1847 zss->sl_soft_active = 1; 1848 head = mp; 1849 } else { 1850 if (!tail) 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) { 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) { 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 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 1909 register struct zs_prog *zspp; 1910 register ushort_t tconst = 0; 1911 register int wr11 = 0; 1912 register int baud = 0; 1913 register int pll = 0; 1914 register int speed = 0; 1915 register 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 register struct syncline *zss = (struct syncline *)&zs->zs_priv_str; 2064 register struct sl_status *mstat; 2065 register 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