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