aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/hp/sim/simserial.c160
1 files changed, 63 insertions, 97 deletions
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 8b5a1342e119..7b6e60e9167b 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -163,7 +163,7 @@ static void receive_chars(struct tty_struct *tty)
163 */ 163 */
164static irqreturn_t rs_interrupt_single(int irq, void *dev_id) 164static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
165{ 165{
166 struct async_struct *info = dev_id; 166 struct serial_state *info = dev_id;
167 167
168 if (!info->tty) { 168 if (!info->tty) {
169 printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info); 169 printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
@@ -185,7 +185,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
185 185
186static int rs_put_char(struct tty_struct *tty, unsigned char ch) 186static int rs_put_char(struct tty_struct *tty, unsigned char ch)
187{ 187{
188 struct async_struct *info = (struct async_struct *)tty->driver_data; 188 struct serial_state *info = tty->driver_data;
189 unsigned long flags; 189 unsigned long flags;
190 190
191 if (!tty || !info->xmit.buf) 191 if (!tty || !info->xmit.buf)
@@ -202,12 +202,11 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch)
202 return 1; 202 return 1;
203} 203}
204 204
205static void transmit_chars(struct async_struct *info, int *intr_done) 205static void transmit_chars(struct serial_state *info, int *intr_done)
206{ 206{
207 int count; 207 int count;
208 unsigned long flags; 208 unsigned long flags;
209 209
210
211 local_irq_save(flags); 210 local_irq_save(flags);
212 211
213 if (info->x_char) { 212 if (info->x_char) {
@@ -215,7 +214,7 @@ static void transmit_chars(struct async_struct *info, int *intr_done)
215 214
216 console->write(console, &c, 1); 215 console->write(console, &c, 1);
217 216
218 info->state->icount.tx++; 217 info->icount.tx++;
219 info->x_char = 0; 218 info->x_char = 0;
220 219
221 goto out; 220 goto out;
@@ -256,7 +255,7 @@ out:
256 255
257static void rs_flush_chars(struct tty_struct *tty) 256static void rs_flush_chars(struct tty_struct *tty)
258{ 257{
259 struct async_struct *info = (struct async_struct *)tty->driver_data; 258 struct serial_state *info = tty->driver_data;
260 259
261 if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped || 260 if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped ||
262 !info->xmit.buf) 261 !info->xmit.buf)
@@ -269,8 +268,8 @@ static void rs_flush_chars(struct tty_struct *tty)
269static int rs_write(struct tty_struct * tty, 268static int rs_write(struct tty_struct * tty,
270 const unsigned char *buf, int count) 269 const unsigned char *buf, int count)
271{ 270{
271 struct serial_state *info = tty->driver_data;
272 int c, ret = 0; 272 int c, ret = 0;
273 struct async_struct *info = (struct async_struct *)tty->driver_data;
274 unsigned long flags; 273 unsigned long flags;
275 274
276 if (!tty || !info->xmit.buf || !tmp_buf) return 0; 275 if (!tty || !info->xmit.buf || !tmp_buf) return 0;
@@ -303,21 +302,21 @@ static int rs_write(struct tty_struct * tty,
303 302
304static int rs_write_room(struct tty_struct *tty) 303static int rs_write_room(struct tty_struct *tty)
305{ 304{
306 struct async_struct *info = (struct async_struct *)tty->driver_data; 305 struct serial_state *info = tty->driver_data;
307 306
308 return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 307 return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
309} 308}
310 309
311static int rs_chars_in_buffer(struct tty_struct *tty) 310static int rs_chars_in_buffer(struct tty_struct *tty)
312{ 311{
313 struct async_struct *info = (struct async_struct *)tty->driver_data; 312 struct serial_state *info = tty->driver_data;
314 313
315 return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); 314 return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
316} 315}
317 316
318static void rs_flush_buffer(struct tty_struct *tty) 317static void rs_flush_buffer(struct tty_struct *tty)
319{ 318{
320 struct async_struct *info = (struct async_struct *)tty->driver_data; 319 struct serial_state *info = tty->driver_data;
321 unsigned long flags; 320 unsigned long flags;
322 321
323 local_irq_save(flags); 322 local_irq_save(flags);
@@ -333,7 +332,7 @@ static void rs_flush_buffer(struct tty_struct *tty)
333 */ 332 */
334static void rs_send_xchar(struct tty_struct *tty, char ch) 333static void rs_send_xchar(struct tty_struct *tty, char ch)
335{ 334{
336 struct async_struct *info = (struct async_struct *)tty->driver_data; 335 struct serial_state *info = tty->driver_data;
337 336
338 info->x_char = ch; 337 info->x_char = ch;
339 if (ch) { 338 if (ch) {
@@ -362,7 +361,7 @@ static void rs_throttle(struct tty_struct * tty)
362 361
363static void rs_unthrottle(struct tty_struct * tty) 362static void rs_unthrottle(struct tty_struct * tty)
364{ 363{
365 struct async_struct *info = (struct async_struct *)tty->driver_data; 364 struct serial_state *info = tty->driver_data;
366 365
367 if (I_IXOFF(tty)) { 366 if (I_IXOFF(tty)) {
368 if (info->x_char) 367 if (info->x_char)
@@ -443,23 +442,22 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
443 * This routine will shutdown a serial port; interrupts are disabled, and 442 * This routine will shutdown a serial port; interrupts are disabled, and
444 * DTR is dropped if the hangup on close termio flag is on. 443 * DTR is dropped if the hangup on close termio flag is on.
445 */ 444 */
446static void shutdown(struct async_struct * info) 445static void shutdown(struct serial_state *info)
447{ 446{
448 unsigned long flags; 447 unsigned long flags;
449 struct serial_state *state = info->state;
450 448
451 if (!(state->flags & ASYNC_INITIALIZED)) 449 if (!(info->flags & ASYNC_INITIALIZED))
452 return; 450 return;
453 451
454#ifdef SIMSERIAL_DEBUG 452#ifdef SIMSERIAL_DEBUG
455 printk("Shutting down serial port %d (irq %d)....", info->line, 453 printk("Shutting down serial port %d (irq %d)...\n", info->line,
456 state->irq); 454 info->irq);
457#endif 455#endif
458 456
459 local_irq_save(flags); 457 local_irq_save(flags);
460 { 458 {
461 if (state->irq) 459 if (info->irq)
462 free_irq(state->irq, info); 460 free_irq(info->irq, info);
463 461
464 if (info->xmit.buf) { 462 if (info->xmit.buf) {
465 free_page((unsigned long) info->xmit.buf); 463 free_page((unsigned long) info->xmit.buf);
@@ -468,7 +466,7 @@ static void shutdown(struct async_struct * info)
468 466
469 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); 467 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
470 468
471 state->flags &= ~ASYNC_INITIALIZED; 469 info->flags &= ~ASYNC_INITIALIZED;
472 } 470 }
473 local_irq_restore(flags); 471 local_irq_restore(flags);
474} 472}
@@ -485,13 +483,11 @@ static void shutdown(struct async_struct * info)
485 */ 483 */
486static void rs_close(struct tty_struct *tty, struct file * filp) 484static void rs_close(struct tty_struct *tty, struct file * filp)
487{ 485{
488 struct async_struct * info = (struct async_struct *)tty->driver_data; 486 struct serial_state *info = tty->driver_data;
489 struct serial_state *state;
490 unsigned long flags; 487 unsigned long flags;
491 488
492 if (!info ) return; 489 if (!info)
493 490 return;
494 state = info->state;
495 491
496 local_irq_save(flags); 492 local_irq_save(flags);
497 if (tty_hung_up_p(filp)) { 493 if (tty_hung_up_p(filp)) {
@@ -502,30 +498,30 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
502 return; 498 return;
503 } 499 }
504#ifdef SIMSERIAL_DEBUG 500#ifdef SIMSERIAL_DEBUG
505 printk("rs_close ttys%d, count = %d\n", info->line, state->count); 501 printk("rs_close ttys%d, count = %d\n", info->line, info->count);
506#endif 502#endif
507 if ((tty->count == 1) && (state->count != 1)) { 503 if ((tty->count == 1) && (info->count != 1)) {
508 /* 504 /*
509 * Uh, oh. tty->count is 1, which means that the tty 505 * Uh, oh. tty->count is 1, which means that the tty
510 * structure will be freed. state->count should always 506 * structure will be freed. info->count should always
511 * be one in these conditions. If it's greater than 507 * be one in these conditions. If it's greater than
512 * one, we've got real problems, since it means the 508 * one, we've got real problems, since it means the
513 * serial port won't be shutdown. 509 * serial port won't be shutdown.
514 */ 510 */
515 printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " 511 printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, "
516 "state->count is %d\n", state->count); 512 "info->count is %d\n", info->count);
517 state->count = 1; 513 info->count = 1;
518 } 514 }
519 if (--state->count < 0) { 515 if (--info->count < 0) {
520 printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", 516 printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
521 state->line, state->count); 517 info->line, info->count);
522 state->count = 0; 518 info->count = 0;
523 } 519 }
524 if (state->count) { 520 if (info->count) {
525 local_irq_restore(flags); 521 local_irq_restore(flags);
526 return; 522 return;
527 } 523 }
528 state->flags |= ASYNC_CLOSING; 524 info->flags |= ASYNC_CLOSING;
529 local_irq_restore(flags); 525 local_irq_restore(flags);
530 526
531 /* 527 /*
@@ -537,11 +533,11 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
537 tty_ldisc_flush(tty); 533 tty_ldisc_flush(tty);
538 info->tty = NULL; 534 info->tty = NULL;
539 if (info->blocked_open) { 535 if (info->blocked_open) {
540 if (state->close_delay) 536 if (info->close_delay)
541 schedule_timeout_interruptible(state->close_delay); 537 schedule_timeout_interruptible(info->close_delay);
542 wake_up_interruptible(&info->open_wait); 538 wake_up_interruptible(&info->open_wait);
543 } 539 }
544 state->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 540 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
545 wake_up_interruptible(&info->close_wait); 541 wake_up_interruptible(&info->close_wait);
546} 542}
547 543
@@ -558,59 +554,28 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
558 */ 554 */
559static void rs_hangup(struct tty_struct *tty) 555static void rs_hangup(struct tty_struct *tty)
560{ 556{
561 struct async_struct * info = (struct async_struct *)tty->driver_data; 557 struct serial_state *info = tty->driver_data;
562 struct serial_state *state = info->state;
563 558
564#ifdef SIMSERIAL_DEBUG 559#ifdef SIMSERIAL_DEBUG
565 printk("rs_hangup: called\n"); 560 printk("rs_hangup: called\n");
566#endif 561#endif
567 562
568 rs_flush_buffer(tty); 563 rs_flush_buffer(tty);
569 if (state->flags & ASYNC_CLOSING) 564 if (info->flags & ASYNC_CLOSING)
570 return; 565 return;
571 shutdown(info); 566 shutdown(info);
572 567
573 state->count = 0; 568 info->count = 0;
574 state->flags &= ~ASYNC_NORMAL_ACTIVE; 569 info->flags &= ~ASYNC_NORMAL_ACTIVE;
575 info->tty = NULL; 570 info->tty = NULL;
576 wake_up_interruptible(&info->open_wait); 571 wake_up_interruptible(&info->open_wait);
577} 572}
578 573
579 574
580static int get_async_struct(int line, struct async_struct **ret_info) 575static int startup(struct serial_state *state)
581{
582 struct async_struct *info;
583 struct serial_state *sstate;
584
585 sstate = rs_table + line;
586 sstate->count++;
587 if (sstate->info) {
588 *ret_info = sstate->info;
589 return 0;
590 }
591 info = kzalloc(sizeof(struct async_struct), GFP_KERNEL);
592 if (!info) {
593 sstate->count--;
594 return -ENOMEM;
595 }
596 init_waitqueue_head(&info->open_wait);
597 init_waitqueue_head(&info->close_wait);
598 info->state = sstate;
599 if (sstate->info) {
600 kfree(info);
601 *ret_info = sstate->info;
602 return 0;
603 }
604 *ret_info = sstate->info = info;
605 return 0;
606}
607
608static int
609startup(struct async_struct *info)
610{ 576{
611 unsigned long flags; 577 unsigned long flags;
612 int retval=0; 578 int retval=0;
613 struct serial_state *state= info->state;
614 unsigned long page; 579 unsigned long page;
615 580
616 page = get_zeroed_page(GFP_KERNEL); 581 page = get_zeroed_page(GFP_KERNEL);
@@ -625,17 +590,18 @@ startup(struct async_struct *info)
625 } 590 }
626 591
627 if (!state->port || !state->type) { 592 if (!state->port || !state->type) {
628 if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); 593 if (state->tty)
594 set_bit(TTY_IO_ERROR, &state->tty->flags);
629 free_page(page); 595 free_page(page);
630 goto errout; 596 goto errout;
631 } 597 }
632 if (info->xmit.buf) 598 if (state->xmit.buf)
633 free_page(page); 599 free_page(page);
634 else 600 else
635 info->xmit.buf = (unsigned char *) page; 601 state->xmit.buf = (unsigned char *) page;
636 602
637#ifdef SIMSERIAL_DEBUG 603#ifdef SIMSERIAL_DEBUG
638 printk("startup: ttys%d (irq %d)...", info->line, state->irq); 604 printk("startup: ttys%d (irq %d)...", state->line, state->irq);
639#endif 605#endif
640 606
641 /* 607 /*
@@ -643,14 +609,15 @@ startup(struct async_struct *info)
643 */ 609 */
644 if (state->irq) { 610 if (state->irq) {
645 retval = request_irq(state->irq, rs_interrupt_single, 0, 611 retval = request_irq(state->irq, rs_interrupt_single, 0,
646 "simserial", info); 612 "simserial", state);
647 if (retval) 613 if (retval)
648 goto errout; 614 goto errout;
649 } 615 }
650 616
651 if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); 617 if (state->tty)
618 clear_bit(TTY_IO_ERROR, &state->tty->flags);
652 619
653 info->xmit.head = info->xmit.tail = 0; 620 state->xmit.head = state->xmit.tail = 0;
654 621
655#if 0 622#if 0
656 /* 623 /*
@@ -663,15 +630,15 @@ startup(struct async_struct *info)
663 /* 630 /*
664 * Set up the tty->alt_speed kludge 631 * Set up the tty->alt_speed kludge
665 */ 632 */
666 if (info->tty) { 633 if (state->tty) {
667 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 634 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
668 info->tty->alt_speed = 57600; 635 state->tty->alt_speed = 57600;
669 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 636 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
670 info->tty->alt_speed = 115200; 637 state->tty->alt_speed = 115200;
671 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 638 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
672 info->tty->alt_speed = 230400; 639 state->tty->alt_speed = 230400;
673 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 640 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
674 info->tty->alt_speed = 460800; 641 state->tty->alt_speed = 460800;
675 } 642 }
676 643
677 state->flags |= ASYNC_INITIALIZED; 644 state->flags |= ASYNC_INITIALIZED;
@@ -692,20 +659,18 @@ errout:
692 */ 659 */
693static int rs_open(struct tty_struct *tty, struct file * filp) 660static int rs_open(struct tty_struct *tty, struct file * filp)
694{ 661{
695 struct async_struct *info; 662 struct serial_state *info = rs_table + tty->index;
696 int retval; 663 int retval;
697 unsigned long page; 664 unsigned long page;
698 665
699 retval = get_async_struct(tty->index, &info); 666 info->count++;
700 if (retval)
701 return retval;
702 tty->driver_data = info;
703 info->tty = tty; 667 info->tty = tty;
668 tty->driver_data = info;
704 669
705#ifdef SIMSERIAL_DEBUG 670#ifdef SIMSERIAL_DEBUG
706 printk("rs_open %s, count = %d\n", tty->name, info->state->count); 671 printk("rs_open %s, count = %d\n", tty->name, info->count);
707#endif 672#endif
708 info->tty->low_latency = (info->state->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 673 tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
709 674
710 if (!tmp_buf) { 675 if (!tmp_buf) {
711 page = get_zeroed_page(GFP_KERNEL); 676 page = get_zeroed_page(GFP_KERNEL);
@@ -720,12 +685,11 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
720 /* 685 /*
721 * If the port is the middle of closing, bail out now 686 * If the port is the middle of closing, bail out now
722 */ 687 */
723 if (tty_hung_up_p(filp) || 688 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
724 (info->state->flags & ASYNC_CLOSING)) { 689 if (info->flags & ASYNC_CLOSING)
725 if (info->state->flags & ASYNC_CLOSING)
726 interruptible_sleep_on(&info->close_wait); 690 interruptible_sleep_on(&info->close_wait);
727#ifdef SERIAL_DO_RESTART 691#ifdef SERIAL_DO_RESTART
728 return ((info->state->flags & ASYNC_HUP_NOTIFY) ? 692 return ((info->flags & ASYNC_HUP_NOTIFY) ?
729 -EAGAIN : -ERESTARTSYS); 693 -EAGAIN : -ERESTARTSYS);
730#else 694#else
731 return -EAGAIN; 695 return -EAGAIN;
@@ -865,6 +829,8 @@ simrs_init (void)
865 * Let's have a little bit of fun ! 829 * Let's have a little bit of fun !
866 */ 830 */
867 for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { 831 for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
832 init_waitqueue_head(&state->open_wait);
833 init_waitqueue_head(&state->close_wait);
868 834
869 if (state->type == PORT_UNKNOWN) continue; 835 if (state->type == PORT_UNKNOWN) continue;
870 836