diff options
-rw-r--r-- | drivers/s390/cio/cio.c | 75 |
1 files changed, 37 insertions, 38 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 3db2c386546f..8047800e9a0c 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -104,44 +104,6 @@ cio_get_options (struct subchannel *sch) | |||
104 | return flags; | 104 | return flags; |
105 | } | 105 | } |
106 | 106 | ||
107 | /* | ||
108 | * Use tpi to get a pending interrupt, call the interrupt handler and | ||
109 | * return a pointer to the subchannel structure. | ||
110 | */ | ||
111 | static int | ||
112 | cio_tpi(void) | ||
113 | { | ||
114 | struct tpi_info *tpi_info; | ||
115 | struct subchannel *sch; | ||
116 | struct irb *irb; | ||
117 | int irq_context; | ||
118 | |||
119 | tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID; | ||
120 | if (tpi (NULL) != 1) | ||
121 | return 0; | ||
122 | irb = (struct irb *) __LC_IRB; | ||
123 | /* Store interrupt response block to lowcore. */ | ||
124 | if (tsch (tpi_info->schid, irb) != 0) | ||
125 | /* Not status pending or not operational. */ | ||
126 | return 1; | ||
127 | sch = (struct subchannel *)(unsigned long)tpi_info->intparm; | ||
128 | if (!sch) | ||
129 | return 1; | ||
130 | irq_context = in_interrupt(); | ||
131 | if (!irq_context) | ||
132 | local_bh_disable(); | ||
133 | irq_enter (); | ||
134 | spin_lock(sch->lock); | ||
135 | memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); | ||
136 | if (sch->driver && sch->driver->irq) | ||
137 | sch->driver->irq(sch); | ||
138 | spin_unlock(sch->lock); | ||
139 | irq_exit (); | ||
140 | if (!irq_context) | ||
141 | _local_bh_enable(); | ||
142 | return 1; | ||
143 | } | ||
144 | |||
145 | static int | 107 | static int |
146 | cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) | 108 | cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) |
147 | { | 109 | { |
@@ -687,6 +649,43 @@ static char console_sch_name[10] = "0.x.xxxx"; | |||
687 | static struct io_subchannel_private console_priv; | 649 | static struct io_subchannel_private console_priv; |
688 | static int console_subchannel_in_use; | 650 | static int console_subchannel_in_use; |
689 | 651 | ||
652 | /* | ||
653 | * Use tpi to get a pending interrupt, call the interrupt handler and | ||
654 | * return a pointer to the subchannel structure. | ||
655 | */ | ||
656 | static int cio_tpi(void) | ||
657 | { | ||
658 | struct tpi_info *tpi_info; | ||
659 | struct subchannel *sch; | ||
660 | struct irb *irb; | ||
661 | int irq_context; | ||
662 | |||
663 | tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID; | ||
664 | if (tpi(NULL) != 1) | ||
665 | return 0; | ||
666 | irb = (struct irb *) __LC_IRB; | ||
667 | /* Store interrupt response block to lowcore. */ | ||
668 | if (tsch(tpi_info->schid, irb) != 0) | ||
669 | /* Not status pending or not operational. */ | ||
670 | return 1; | ||
671 | sch = (struct subchannel *)(unsigned long)tpi_info->intparm; | ||
672 | if (!sch) | ||
673 | return 1; | ||
674 | irq_context = in_interrupt(); | ||
675 | if (!irq_context) | ||
676 | local_bh_disable(); | ||
677 | irq_enter(); | ||
678 | spin_lock(sch->lock); | ||
679 | memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); | ||
680 | if (sch->driver && sch->driver->irq) | ||
681 | sch->driver->irq(sch); | ||
682 | spin_unlock(sch->lock); | ||
683 | irq_exit(); | ||
684 | if (!irq_context) | ||
685 | _local_bh_enable(); | ||
686 | return 1; | ||
687 | } | ||
688 | |||
690 | void *cio_get_console_priv(void) | 689 | void *cio_get_console_priv(void) |
691 | { | 690 | { |
692 | return &console_priv; | 691 | return &console_priv; |