Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
a863aaa3
Commit
a863aaa3
authored
Apr 13, 2003
by
Martin Schwidefsky
Committed by
Linus Torvalds
Apr 13, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] s390: console changes.
s390 console fixes for 3215 and sclp.
parent
fefe4ef5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
153 additions
and
136 deletions
+153
-136
drivers/char/tty_io.c
drivers/char/tty_io.c
+1
-1
drivers/s390/char/con3215.c
drivers/s390/char/con3215.c
+7
-6
drivers/s390/char/sclp.c
drivers/s390/char/sclp.c
+92
-59
drivers/s390/char/sclp.h
drivers/s390/char/sclp.h
+1
-0
drivers/s390/char/sclp_con.c
drivers/s390/char/sclp_con.c
+8
-7
drivers/s390/char/sclp_cpi.c
drivers/s390/char/sclp_cpi.c
+1
-1
drivers/s390/char/sclp_rw.c
drivers/s390/char/sclp_rw.c
+6
-40
drivers/s390/char/sclp_tty.c
drivers/s390/char/sclp_tty.c
+37
-22
No files found.
drivers/char/tty_io.c
View file @
a863aaa3
...
@@ -151,7 +151,7 @@ static int tty_fasync(int fd, struct file * filp, int on);
...
@@ -151,7 +151,7 @@ static int tty_fasync(int fd, struct file * filp, int on);
extern
int
vme_scc_init
(
void
);
extern
int
vme_scc_init
(
void
);
extern
int
serial167_init
(
void
);
extern
int
serial167_init
(
void
);
extern
int
rs_8xx_init
(
void
);
extern
int
rs_8xx_init
(
void
);
extern
void
hwc
_tty_init
(
void
);
extern
void
sclp
_tty_init
(
void
);
extern
void
tty3215_init
(
void
);
extern
void
tty3215_init
(
void
);
extern
void
tub3270_init
(
void
);
extern
void
tub3270_init
(
void
);
extern
void
rs_360_init
(
void
);
extern
void
rs_360_init
(
void
);
...
...
drivers/s390/char/con3215.c
View file @
a863aaa3
...
@@ -872,7 +872,7 @@ con3215_consetup(struct console *co, char *options)
...
@@ -872,7 +872,7 @@ con3215_consetup(struct console *co, char *options)
* The console structure for the 3215 console
* The console structure for the 3215 console
*/
*/
static
struct
console
con3215
=
{
static
struct
console
con3215
=
{
.
name
=
"tty
3215
"
,
.
name
=
"tty
S
"
,
.
write
=
con3215_write
,
.
write
=
con3215_write
,
.
device
=
con3215_device
,
.
device
=
con3215_device
,
.
unblank
=
con3215_unblank
,
.
unblank
=
con3215_unblank
,
...
@@ -884,7 +884,7 @@ static struct console con3215 = {
...
@@ -884,7 +884,7 @@ static struct console con3215 = {
* 3215 console initialization code called from console_init().
* 3215 console initialization code called from console_init().
* NOTE: This is called before kmalloc is available.
* NOTE: This is called before kmalloc is available.
*/
*/
static
void
__init
static
int
__init
con3215_init
(
void
)
con3215_init
(
void
)
{
{
struct
ccw_device
*
cdev
;
struct
ccw_device
*
cdev
;
...
@@ -894,7 +894,7 @@ con3215_init(void)
...
@@ -894,7 +894,7 @@ con3215_init(void)
/* Check if 3215 is to be the console */
/* Check if 3215 is to be the console */
if
(
!
CONSOLE_IS_3215
)
if
(
!
CONSOLE_IS_3215
)
return
;
return
-
ENODEV
;
/* Set the console mode for VM */
/* Set the console mode for VM */
if
(
MACHINE_IS_VM
)
{
if
(
MACHINE_IS_VM
)
{
...
@@ -913,7 +913,7 @@ con3215_init(void)
...
@@ -913,7 +913,7 @@ con3215_init(void)
cdev
=
ccw_device_probe_console
();
cdev
=
ccw_device_probe_console
();
if
(
!
cdev
)
if
(
!
cdev
)
return
;
return
-
ENODEV
;
raw3215
[
0
]
=
raw
=
(
struct
raw3215_info
*
)
raw3215
[
0
]
=
raw
=
(
struct
raw3215_info
*
)
alloc_bootmem_low
(
sizeof
(
struct
raw3215_info
));
alloc_bootmem_low
(
sizeof
(
struct
raw3215_info
));
...
@@ -938,10 +938,12 @@ con3215_init(void)
...
@@ -938,10 +938,12 @@ con3215_init(void)
free_bootmem
((
unsigned
long
)
raw
,
sizeof
(
struct
raw3215_info
));
free_bootmem
((
unsigned
long
)
raw
,
sizeof
(
struct
raw3215_info
));
raw3215
[
0
]
=
NULL
;
raw3215
[
0
]
=
NULL
;
printk
(
"Couldn't find a 3215 console device
\n
"
);
printk
(
"Couldn't find a 3215 console device
\n
"
);
return
;
return
-
ENODEV
;
}
}
register_console
(
&
con3215
);
register_console
(
&
con3215
);
return
0
;
}
}
console_initcall
(
con3215_init
);
#endif
#endif
/*
/*
...
@@ -1122,7 +1124,6 @@ tty3215_unthrottle(struct tty_struct * tty)
...
@@ -1122,7 +1124,6 @@ tty3215_unthrottle(struct tty_struct * tty)
spin_unlock_irqrestore
(
raw
->
lock
,
flags
);
spin_unlock_irqrestore
(
raw
->
lock
,
flags
);
}
}
}
}
console_initcall
(
con3215_init
);
/*
/*
* Disable writing to a 3215 tty
* Disable writing to a 3215 tty
...
...
drivers/s390/char/sclp.c
View file @
a863aaa3
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/kmod.h>
#include <linux/bootmem.h>
#include <linux/bootmem.h>
...
@@ -25,14 +24,6 @@
...
@@ -25,14 +24,6 @@
#define SCLP_CORE_PRINT_HEADER "sclp low level driver: "
#define SCLP_CORE_PRINT_HEADER "sclp low level driver: "
/*
* decides whether we make use of the macro MACHINE_IS_VM to
* configure the driver for VM at run time (a little bit
* different behaviour); otherwise we use the default
* settings in sclp_data.init_ioctls
*/
#define USE_VM_DETECTION
/* Structure for register_early_external_interrupt. */
/* Structure for register_early_external_interrupt. */
static
ext_int_info_t
ext_int_info_hwc
;
static
ext_int_info_t
ext_int_info_hwc
;
...
@@ -111,30 +102,32 @@ __service_call(sclp_cmdw_t command, void *sccb)
...
@@ -111,30 +102,32 @@ __service_call(sclp_cmdw_t command, void *sccb)
}
}
static
int
static
int
__
sclp_start_request
(
void
)
sclp_start_request
(
void
)
{
{
struct
sclp_req
*
req
;
struct
sclp_req
*
req
;
int
rc
;
int
rc
;
unsigned
long
flags
;
/* quick exit if sclp is already in use */
/* quick exit if sclp is already in use */
if
(
test_bit
(
SCLP_RUNNING
,
&
sclp_status
))
if
(
test_bit
(
SCLP_RUNNING
,
&
sclp_status
))
return
-
EBUSY
;
return
-
EBUSY
;
/* quick exit if queue is empty */
spin_lock_irqsave
(
&
sclp_lock
,
flags
);
if
(
list_empty
(
&
sclp_req_queue
))
/* Get first request on queue if available */
return
-
EINVAL
;
req
=
NULL
;
/* try to start the first request on the request queue. */
if
(
!
list_empty
(
&
sclp_req_queue
))
req
=
list_entry
(
sclp_req_queue
.
next
,
struct
sclp_req
,
list
);
req
=
list_entry
(
sclp_req_queue
.
next
,
struct
sclp_req
,
list
);
rc
=
__service_call
(
req
->
command
,
req
->
sccb
);
if
(
req
)
{
switch
(
rc
)
{
rc
=
__service_call
(
req
->
command
,
req
->
sccb
);
case
0
:
if
(
rc
)
{
req
->
status
=
SCLP_REQ_RUNNING
;
req
->
status
=
SCLP_REQ_FAILED
;
break
;
list_del
(
&
req
->
list
);
case
-
EIO
:
}
else
req
->
status
=
SCLP_REQ_FAILED
;
req
->
status
=
SCLP_REQ_RUNNING
;
if
(
req
->
callback
!=
NULL
)
}
else
req
->
callback
(
req
,
req
->
callback_data
);
rc
=
-
EINVAL
;
break
;
spin_unlock_irqrestore
(
&
sclp_lock
,
flags
);
}
if
(
rc
==
-
EIO
&&
req
->
callback
!=
NULL
)
req
->
callback
(
req
,
req
->
callback_data
);
return
rc
;
return
rc
;
}
}
...
@@ -156,8 +149,12 @@ sclp_process_evbufs(struct sccb_header *sccb)
...
@@ -156,8 +149,12 @@ sclp_process_evbufs(struct sccb_header *sccb)
list_for_each
(
l
,
&
sclp_reg_list
)
{
list_for_each
(
l
,
&
sclp_reg_list
)
{
t
=
list_entry
(
l
,
struct
sclp_register
,
list
);
t
=
list_entry
(
l
,
struct
sclp_register
,
list
);
if
(
t
->
receive_mask
&
(
1
<<
(
32
-
evbuf
->
type
)))
{
if
(
t
->
receive_mask
&
(
1
<<
(
32
-
evbuf
->
type
)))
{
if
(
t
->
receiver_fn
!=
NULL
)
if
(
t
->
receiver_fn
!=
NULL
)
{
spin_unlock_irqrestore
(
&
sclp_lock
,
flags
);
t
->
receiver_fn
(
evbuf
);
t
->
receiver_fn
(
evbuf
);
spin_lock_irqsave
(
&
sclp_lock
,
flags
);
}
break
;
break
;
}
}
else
else
...
@@ -230,7 +227,7 @@ sclp_unconditional_read_cb(struct sclp_req *read_req, void *data)
...
@@ -230,7 +227,7 @@ sclp_unconditional_read_cb(struct sclp_req *read_req, void *data)
}
}
/*
/*
* Function to
iss
ue Read Event Data/Unconditional Read
* Function to
que
ue Read Event Data/Unconditional Read
*/
*/
static
void
static
void
__sclp_unconditional_read
(
void
)
__sclp_unconditional_read
(
void
)
...
@@ -278,45 +275,44 @@ sclp_interrupt_handler(struct pt_regs *regs, __u16 code)
...
@@ -278,45 +275,44 @@ sclp_interrupt_handler(struct pt_regs *regs, __u16 code)
struct
list_head
*
l
;
struct
list_head
*
l
;
struct
sclp_req
*
req
,
*
tmp
;
struct
sclp_req
*
req
,
*
tmp
;
/*
* Only process interrupt if sclp is initialized.
* This avoids strange effects for a pending request
* from before the last re-ipl.
*/
if
(
!
test_bit
(
SCLP_INIT
,
&
sclp_status
))
return
;
ext_int_param
=
S390_lowcore
.
ext_params
;
ext_int_param
=
S390_lowcore
.
ext_params
;
finished_sccb
=
ext_int_param
&
EXT_INT_SCCB_MASK
;
finished_sccb
=
ext_int_param
&
EXT_INT_SCCB_MASK
;
evbuf_pending
=
ext_int_param
&
(
EXT_INT_EVBUF_PENDING
|
evbuf_pending
=
ext_int_param
&
(
EXT_INT_EVBUF_PENDING
|
EXT_INT_STATECHANGE_PENDING
);
EXT_INT_STATECHANGE_PENDING
);
irq_enter
();
irq_enter
();
/*
req
=
NULL
;
* Only do request callbacks if sclp is initialized.
spin_lock
(
&
sclp_lock
);
* This avoids strange effects for a pending request
if
(
finished_sccb
!=
0U
)
{
* from before the last re-ipl.
list_for_each
(
l
,
&
sclp_req_queue
)
{
*/
tmp
=
list_entry
(
l
,
struct
sclp_req
,
list
);
if
(
test_bit
(
SCLP_INIT
,
&
sclp_status
))
{
if
(
finished_sccb
==
(
u32
)(
addr_t
)
tmp
->
sccb
)
{
spin_lock
(
&
sclp_lock
);
list_del
(
&
tmp
->
list
);
req
=
NULL
;
req
=
tmp
;
if
(
finished_sccb
!=
0U
)
{
break
;
list_for_each
(
l
,
&
sclp_req_queue
)
{
tmp
=
list_entry
(
l
,
struct
sclp_req
,
list
);
if
(
finished_sccb
==
(
u32
)(
addr_t
)
tmp
->
sccb
)
{
list_del
(
&
tmp
->
list
);
req
=
tmp
;
break
;
}
}
}
}
}
spin_unlock
(
&
sclp_lock
);
if
(
req
!=
NULL
)
{
req
->
status
=
SCLP_REQ_DONE
;
if
(
req
->
callback
!=
NULL
)
req
->
callback
(
req
,
req
->
callback_data
);
}
}
}
spin_lock
(
&
sclp_lock
);
/* Head queue a read sccb if an event buffer is pending */
/* Head queue a read sccb if an event buffer is pending */
if
(
evbuf_pending
)
if
(
evbuf_pending
)
__sclp_unconditional_read
();
__sclp_unconditional_read
();
spin_unlock
(
&
sclp_lock
);
/* Perform callback */
if
(
req
!=
NULL
)
{
req
->
status
=
SCLP_REQ_DONE
;
if
(
req
->
callback
!=
NULL
)
req
->
callback
(
req
,
req
->
callback_data
);
}
/* Now clear the running bit */
/* Now clear the running bit */
clear_bit
(
SCLP_RUNNING
,
&
sclp_status
);
clear_bit
(
SCLP_RUNNING
,
&
sclp_status
);
/* and start next request on the queue */
/* and start next request on the queue */
__sclp_start_request
();
sclp_start_request
();
spin_unlock
(
&
sclp_lock
);
irq_exit
();
irq_exit
();
}
}
...
@@ -368,15 +364,19 @@ sclp_add_request(struct sclp_req *req)
...
@@ -368,15 +364,19 @@ sclp_add_request(struct sclp_req *req)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
if
(
!
test_bit
(
SCLP_INIT
,
&
sclp_status
))
if
(
!
test_bit
(
SCLP_INIT
,
&
sclp_status
))
{
req
->
status
=
SCLP_REQ_FAILED
;
if
(
req
->
callback
!=
NULL
)
req
->
callback
(
req
,
req
->
callback_data
);
return
;
return
;
}
spin_lock_irqsave
(
&
sclp_lock
,
flags
);
spin_lock_irqsave
(
&
sclp_lock
,
flags
);
/* queue the request */
/* queue the request */
req
->
status
=
SCLP_REQ_QUEUED
;
req
->
status
=
SCLP_REQ_QUEUED
;
list_add_tail
(
&
req
->
list
,
&
sclp_req_queue
);
list_add_tail
(
&
req
->
list
,
&
sclp_req_queue
);
/* try to start the first request on the queue */
__sclp_start_request
();
spin_unlock_irqrestore
(
&
sclp_lock
,
flags
);
spin_unlock_irqrestore
(
&
sclp_lock
,
flags
);
/* try to start the first request on the queue */
sclp_start_request
();
}
}
/* state change notification */
/* state change notification */
...
@@ -566,10 +566,9 @@ sclp_init_mask(void)
...
@@ -566,10 +566,9 @@ sclp_init_mask(void)
if
(
test_bit
(
SCLP_INIT
,
&
sclp_status
))
{
if
(
test_bit
(
SCLP_INIT
,
&
sclp_status
))
{
/* add request to sclp queue */
/* add request to sclp queue */
list_add_tail
(
&
req
->
list
,
&
sclp_req_queue
);
list_add_tail
(
&
req
->
list
,
&
sclp_req_queue
);
/* and start if SCLP is idle */
if
(
!
test_bit
(
SCLP_RUNNING
,
&
sclp_status
))
__sclp_start_request
();
spin_unlock_irqrestore
(
&
sclp_lock
,
flags
);
spin_unlock_irqrestore
(
&
sclp_lock
,
flags
);
/* and start if SCLP is idle */
sclp_start_request
();
/* now wait for completion */
/* now wait for completion */
while
(
req
->
status
!=
SCLP_REQ_DONE
&&
while
(
req
->
status
!=
SCLP_REQ_DONE
&&
req
->
status
!=
SCLP_REQ_FAILED
)
req
->
status
!=
SCLP_REQ_FAILED
)
...
@@ -730,7 +729,41 @@ sclp_unregister(struct sclp_register *reg)
...
@@ -730,7 +729,41 @@ sclp_unregister(struct sclp_register *reg)
sclp_init_mask
();
sclp_init_mask
();
}
}
#define SCLP_EVBUF_PROCESSED 0x80
/*
* Traverse array of event buffers contained in SCCB and remove all buffers
* with a set "processed" flag. Return the number of unprocessed buffers.
*/
int
sclp_remove_processed
(
struct
sccb_header
*
sccb
)
{
struct
evbuf_header
*
evbuf
;
int
unprocessed
;
u16
remaining
;
evbuf
=
(
struct
evbuf_header
*
)
(
sccb
+
1
);
unprocessed
=
0
;
remaining
=
sccb
->
length
-
sizeof
(
struct
sccb_header
);
while
(
remaining
>
0
)
{
remaining
-=
evbuf
->
length
;
if
(
evbuf
->
flags
&
SCLP_EVBUF_PROCESSED
)
{
sccb
->
length
-=
evbuf
->
length
;
memcpy
((
void
*
)
evbuf
,
(
void
*
)
((
addr_t
)
evbuf
+
evbuf
->
length
),
remaining
);
}
else
{
unprocessed
++
;
evbuf
=
(
struct
evbuf_header
*
)
((
addr_t
)
evbuf
+
evbuf
->
length
);
}
}
return
unprocessed
;
}
EXPORT_SYMBOL
(
sclp_add_request
);
EXPORT_SYMBOL
(
sclp_add_request
);
EXPORT_SYMBOL
(
sclp_sync_wait
);
EXPORT_SYMBOL
(
sclp_sync_wait
);
EXPORT_SYMBOL
(
sclp_register
);
EXPORT_SYMBOL
(
sclp_register
);
EXPORT_SYMBOL
(
sclp_unregister
);
EXPORT_SYMBOL
(
sclp_unregister
);
EXPORT_SYMBOL
(
sclp_error_message
);
drivers/s390/char/sclp.h
View file @
a863aaa3
...
@@ -126,6 +126,7 @@ void sclp_sync_wait(void);
...
@@ -126,6 +126,7 @@ void sclp_sync_wait(void);
int
sclp_register
(
struct
sclp_register
*
reg
);
int
sclp_register
(
struct
sclp_register
*
reg
);
void
sclp_unregister
(
struct
sclp_register
*
reg
);
void
sclp_unregister
(
struct
sclp_register
*
reg
);
char
*
sclp_error_message
(
u16
response_code
);
char
*
sclp_error_message
(
u16
response_code
);
int
sclp_remove_processed
(
struct
sccb_header
*
sccb
);
/* useful inlines */
/* useful inlines */
...
...
drivers/s390/char/sclp_con.c
View file @
a863aaa3
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kmod.h>
#include <linux/kmod.h>
#include <linux/console.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/init.h>
...
@@ -24,7 +23,7 @@
...
@@ -24,7 +23,7 @@
#define sclp_console_major 4
/* TTYAUX_MAJOR */
#define sclp_console_major 4
/* TTYAUX_MAJOR */
#define sclp_console_minor 64
#define sclp_console_minor 64
#define sclp_console_name "
console
"
#define sclp_console_name "
ttyS
"
/* Lock to guard over changes to global variables */
/* Lock to guard over changes to global variables */
static
spinlock_t
sclp_con_lock
;
static
spinlock_t
sclp_con_lock
;
...
@@ -193,28 +192,29 @@ static struct console sclp_console =
...
@@ -193,28 +192,29 @@ static struct console sclp_console =
.
write
=
sclp_console_write
,
.
write
=
sclp_console_write
,
.
device
=
sclp_console_device
,
.
device
=
sclp_console_device
,
.
unblank
=
sclp_console_unblank
,
.
unblank
=
sclp_console_unblank
,
.
flags
=
CON_PRINTBUFFER
.
flags
=
CON_PRINTBUFFER
,
.
index
=
0
/* ttyS0 */
};
};
/*
/*
* called by console_init() in drivers/char/tty_io.c at boot-time.
* called by console_init() in drivers/char/tty_io.c at boot-time.
*/
*/
void
__init
static
int
__init
sclp_console_init
(
void
)
sclp_console_init
(
void
)
{
{
void
*
page
;
void
*
page
;
int
i
;
int
i
;
if
(
!
CONSOLE_IS_SCLP
)
if
(
!
CONSOLE_IS_SCLP
)
return
;
return
0
;
if
(
sclp_rw_init
()
!=
0
)
if
(
sclp_rw_init
()
!=
0
)
return
;
return
0
;
/* Allocate pages for output buffering */
/* Allocate pages for output buffering */
INIT_LIST_HEAD
(
&
sclp_con_pages
);
INIT_LIST_HEAD
(
&
sclp_con_pages
);
for
(
i
=
0
;
i
<
MAX_CONSOLE_PAGES
;
i
++
)
{
for
(
i
=
0
;
i
<
MAX_CONSOLE_PAGES
;
i
++
)
{
page
=
alloc_bootmem_low_pages
(
PAGE_SIZE
);
page
=
alloc_bootmem_low_pages
(
PAGE_SIZE
);
if
(
page
==
NULL
)
if
(
page
==
NULL
)
return
;
return
0
;
list_add_tail
((
struct
list_head
*
)
page
,
&
sclp_con_pages
);
list_add_tail
((
struct
list_head
*
)
page
,
&
sclp_con_pages
);
}
}
INIT_LIST_HEAD
(
&
sclp_con_outqueue
);
INIT_LIST_HEAD
(
&
sclp_con_outqueue
);
...
@@ -236,6 +236,7 @@ sclp_console_init(void)
...
@@ -236,6 +236,7 @@ sclp_console_init(void)
/* enable printk-access to this driver */
/* enable printk-access to this driver */
register_console
(
&
sclp_console
);
register_console
(
&
sclp_console
);
return
0
;
}
}
console_initcall
(
sclp_console_init
);
console_initcall
(
sclp_console_init
);
drivers/s390/char/sclp_cpi.c
View file @
a863aaa3
...
@@ -130,7 +130,7 @@ cpi_prepare_req(void)
...
@@ -130,7 +130,7 @@ cpi_prepare_req(void)
req
=
(
struct
sclp_req
*
)
kmalloc
(
sizeof
(
struct
sclp_req
),
GFP_KERNEL
);
req
=
(
struct
sclp_req
*
)
kmalloc
(
sizeof
(
struct
sclp_req
),
GFP_KERNEL
);
if
(
req
==
NULL
)
if
(
req
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
sccb
=
(
struct
cpi_sccb
*
)
__get_free_page
(
GFP_KERNEL
);
sccb
=
(
struct
cpi_sccb
*
)
__get_free_page
(
GFP_KERNEL
|
GFP_DMA
);
if
(
sccb
==
NULL
)
{
if
(
sccb
==
NULL
)
{
kfree
(
req
);
kfree
(
req
);
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
...
...
drivers/s390/char/sclp_rw.c
View file @
a863aaa3
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kmod.h>
#include <linux/kmod.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/err.h>
...
@@ -374,39 +373,6 @@ sclp_rw_init(void)
...
@@ -374,39 +373,6 @@ sclp_rw_init(void)
return
rc
;
return
rc
;
}
}
#define SCLP_EVBUF_PROCESSED 0x80
/*
* Traverse array of event buffers contained in SCCB and remove all buffers
* with a set "processed" flag. Return the number of unprocessed buffers.
*/
static
int
sclp_remove_processed
(
struct
sccb_header
*
sccb
)
{
struct
evbuf_header
*
evbuf
;
int
unprocessed
;
u16
remaining
;
evbuf
=
(
struct
evbuf_header
*
)
(
sccb
+
1
);
unprocessed
=
0
;
remaining
=
sccb
->
length
-
sizeof
(
struct
sccb_header
);
while
(
remaining
>
0
)
{
remaining
-=
evbuf
->
length
;
if
(
evbuf
->
flags
&
SCLP_EVBUF_PROCESSED
)
{
sccb
->
length
-=
evbuf
->
length
;
memcpy
((
void
*
)
evbuf
,
(
void
*
)
((
addr_t
)
evbuf
+
evbuf
->
length
),
remaining
);
}
else
{
unprocessed
++
;
evbuf
=
(
struct
evbuf_header
*
)
((
addr_t
)
evbuf
+
evbuf
->
length
);
}
}
return
unprocessed
;
}
static
void
static
void
sclp_buffer_retry
(
unsigned
long
data
)
sclp_buffer_retry
(
unsigned
long
data
)
{
{
...
@@ -480,10 +446,6 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
...
@@ -480,10 +446,6 @@ sclp_writedata_callback(struct sclp_req *request, void *data)
rc
=
-
ENOMEM
;
rc
=
-
ENOMEM
;
else
else
rc
=
-
EINVAL
;
rc
=
-
EINVAL
;
printk
(
KERN_WARNING
SCLP_RW_PRINT_HEADER
"sclp_writedata_callback: %s (response code=0x%x).
\n
"
,
sclp_error_message
(
sccb
->
header
.
response_code
),
sccb
->
header
.
response_code
);
break
;
break
;
}
}
if
(
buffer
->
callback
!=
NULL
)
if
(
buffer
->
callback
!=
NULL
)
...
@@ -505,8 +467,11 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
...
@@ -505,8 +467,11 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
sclp_finalize_mto
(
buffer
);
sclp_finalize_mto
(
buffer
);
/* Are there messages in the output buffer ? */
/* Are there messages in the output buffer ? */
if
(
buffer
->
mto_number
==
0
)
if
(
buffer
->
mto_number
==
0
)
{
if
(
callback
!=
NULL
)
callback
(
buffer
,
0
);
return
;
return
;
}
sccb
=
buffer
->
sccb
;
sccb
=
buffer
->
sccb
;
if
(
sclp_rw_event
.
sclp_send_mask
&
EvTyp_Msg_Mask
)
if
(
sclp_rw_event
.
sclp_send_mask
&
EvTyp_Msg_Mask
)
...
@@ -516,7 +481,8 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
...
@@ -516,7 +481,8 @@ sclp_emit_buffer(struct sclp_buffer *buffer,
/* Use write priority message */
/* Use write priority message */
sccb
->
msg_buf
.
header
.
type
=
EvTyp_PMsgCmd
;
sccb
->
msg_buf
.
header
.
type
=
EvTyp_PMsgCmd
;
else
{
else
{
callback
(
buffer
,
-
ENOSYS
);
if
(
callback
!=
NULL
)
callback
(
buffer
,
-
ENOSYS
);
return
;
return
;
}
}
buffer
->
request
.
command
=
SCLP_CMDW_WRITEDATA
;
buffer
->
request
.
command
=
SCLP_CMDW_WRITEDATA
;
...
...
drivers/s390/char/sclp_tty.c
View file @
a863aaa3
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#include <linux/
version
.h>
#include <linux/
module
.h>
#include <linux/kmod.h>
#include <linux/kmod.h>
#include <linux/tty.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_driver.h>
...
@@ -81,9 +81,6 @@ static struct sclp_ioctls sclp_ioctls_init =
...
@@ -81,9 +81,6 @@ static struct sclp_ioctls sclp_ioctls_init =
static
int
static
int
sclp_tty_open
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
sclp_tty_open
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
{
/* only 1 SCLP terminal supported */
if
(
minor
(
tty
->
device
)
!=
tty
->
driver
.
minor_start
)
return
-
ENODEV
;
sclp_tty
=
tty
;
sclp_tty
=
tty
;
tty
->
driver_data
=
NULL
;
tty
->
driver_data
=
NULL
;
tty
->
low_latency
=
0
;
tty
->
low_latency
=
0
;
...
@@ -94,9 +91,6 @@ sclp_tty_open(struct tty_struct *tty, struct file *filp)
...
@@ -94,9 +91,6 @@ sclp_tty_open(struct tty_struct *tty, struct file *filp)
static
void
static
void
sclp_tty_close
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
sclp_tty_close
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
{
/* only 1 SCLP terminal supported */
if
(
minor
(
tty
->
device
)
!=
tty
->
driver
.
minor_start
)
return
;
if
(
tty
->
count
>
1
)
if
(
tty
->
count
>
1
)
return
;
return
;
sclp_tty
=
NULL
;
sclp_tty
=
NULL
;
...
@@ -294,8 +288,15 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
...
@@ -294,8 +288,15 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
static
inline
void
static
inline
void
__sclp_ttybuf_emit
(
struct
sclp_buffer
*
buffer
)
__sclp_ttybuf_emit
(
struct
sclp_buffer
*
buffer
)
{
{
unsigned
long
flags
;
int
count
;
spin_lock_irqsave
(
&
sclp_tty_lock
,
flags
);
list_add_tail
(
&
buffer
->
list
,
&
sclp_tty_outqueue
);
list_add_tail
(
&
buffer
->
list
,
&
sclp_tty_outqueue
);
if
(
sclp_tty_buffer_count
++
==
0
)
count
=
sclp_tty_buffer_count
++
;
spin_unlock_irqrestore
(
&
sclp_tty_lock
,
flags
);
if
(
count
==
0
)
sclp_emit_buffer
(
buffer
,
sclp_ttybuf_callback
);
sclp_emit_buffer
(
buffer
,
sclp_ttybuf_callback
);
}
}
...
@@ -307,13 +308,16 @@ static void
...
@@ -307,13 +308,16 @@ static void
sclp_tty_timeout
(
unsigned
long
data
)
sclp_tty_timeout
(
unsigned
long
data
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
struct
sclp_buffer
*
buf
;
spin_lock_irqsave
(
&
sclp_tty_lock
,
flags
);
spin_lock_irqsave
(
&
sclp_tty_lock
,
flags
);
if
(
sclp_ttybuf
!=
NULL
)
{
buf
=
sclp_ttybuf
;
__sclp_ttybuf_emit
(
sclp_ttybuf
);
sclp_ttybuf
=
NULL
;
sclp_ttybuf
=
NULL
;
}
spin_unlock_irqrestore
(
&
sclp_tty_lock
,
flags
);
spin_unlock_irqrestore
(
&
sclp_tty_lock
,
flags
);
if
(
buf
!=
NULL
)
{
__sclp_ttybuf_emit
(
buf
);
}
}
}
/*
/*
...
@@ -325,6 +329,7 @@ sclp_tty_write_string(const unsigned char *str, int count, int from_user)
...
@@ -325,6 +329,7 @@ sclp_tty_write_string(const unsigned char *str, int count, int from_user)
unsigned
long
flags
;
unsigned
long
flags
;
void
*
page
;
void
*
page
;
int
written
;
int
written
;
struct
sclp_buffer
*
buf
;
if
(
count
<=
0
)
if
(
count
<=
0
)
return
;
return
;
...
@@ -353,8 +358,11 @@ sclp_tty_write_string(const unsigned char *str, int count, int from_user)
...
@@ -353,8 +358,11 @@ sclp_tty_write_string(const unsigned char *str, int count, int from_user)
* output buffer. Emit the buffer, create a new buffer
* output buffer. Emit the buffer, create a new buffer
* and then output the rest of the string.
* and then output the rest of the string.
*/
*/
__sclp_ttybuf_emit
(
sclp_ttybuf
)
;
buf
=
sclp_ttybuf
;
sclp_ttybuf
=
NULL
;
sclp_ttybuf
=
NULL
;
spin_unlock_irqrestore
(
&
sclp_tty_lock
,
flags
);
__sclp_ttybuf_emit
(
buf
);
spin_lock_irqsave
(
&
sclp_tty_lock
,
flags
);
str
+=
written
;
str
+=
written
;
count
-=
written
;
count
-=
written
;
}
while
(
count
>
0
);
}
while
(
count
>
0
);
...
@@ -466,7 +474,8 @@ sclp_tty_flush_buffer(struct tty_struct *tty)
...
@@ -466,7 +474,8 @@ sclp_tty_flush_buffer(struct tty_struct *tty)
/*
/*
* push input to tty
* push input to tty
*/
*/
static
void
sclp_tty_input
(
unsigned
char
*
buf
,
unsigned
int
count
)
static
void
sclp_tty_input
(
unsigned
char
*
buf
,
unsigned
int
count
)
{
{
unsigned
int
cchar
;
unsigned
int
cchar
;
...
@@ -706,15 +715,21 @@ sclp_tty_init(void)
...
@@ -706,15 +715,21 @@ sclp_tty_init(void)
{
{
void
*
page
;
void
*
page
;
int
i
;
int
i
;
int
rc
;
if
(
!
CONSOLE_IS_SCLP
)
if
(
!
CONSOLE_IS_SCLP
)
return
;
return
;
if
(
sclp_rw_init
()
!=
0
)
rc
=
sclp_rw_init
();
if
(
rc
!=
0
)
{
printk
(
KERN_ERR
SCLP_TTY_PRINT_HEADER
"could not register tty - "
"sclp_rw_init returned %d
\n
"
,
rc
);
return
;
return
;
}
/* Allocate pages for output buffering */
/* Allocate pages for output buffering */
INIT_LIST_HEAD
(
&
sclp_tty_pages
);
INIT_LIST_HEAD
(
&
sclp_tty_pages
);
for
(
i
=
0
;
i
<
MAX_KMEM_PAGES
;
i
++
)
{
for
(
i
=
0
;
i
<
MAX_KMEM_PAGES
;
i
++
)
{
page
=
(
void
*
)
get_zeroed_page
(
GFP_KERNEL
);
page
=
(
void
*
)
get_zeroed_page
(
GFP_KERNEL
|
GFP_DMA
);
if
(
page
==
NULL
)
if
(
page
==
NULL
)
return
;
return
;
list_add_tail
((
struct
list_head
*
)
page
,
&
sclp_tty_pages
);
list_add_tail
((
struct
list_head
*
)
page
,
&
sclp_tty_pages
);
...
@@ -744,7 +759,7 @@ sclp_tty_init(void)
...
@@ -744,7 +759,7 @@ sclp_tty_init(void)
memset
(
&
sclp_tty_driver
,
0
,
sizeof
(
struct
tty_driver
));
memset
(
&
sclp_tty_driver
,
0
,
sizeof
(
struct
tty_driver
));
sclp_tty_driver
.
magic
=
TTY_DRIVER_MAGIC
;
sclp_tty_driver
.
magic
=
TTY_DRIVER_MAGIC
;
sclp_tty_driver
.
owner
=
THIS_MODULE
;
sclp_tty_driver
.
owner
=
THIS_MODULE
;
sclp_tty_driver
.
driver_name
=
"
tty_sclp
"
;
sclp_tty_driver
.
driver_name
=
"
sclp_line
"
;
sclp_tty_driver
.
name
=
"ttyS"
;
sclp_tty_driver
.
name
=
"ttyS"
;
sclp_tty_driver
.
name_base
=
0
;
sclp_tty_driver
.
name_base
=
0
;
sclp_tty_driver
.
major
=
TTY_MAJOR
;
sclp_tty_driver
.
major
=
TTY_MAJOR
;
...
@@ -795,9 +810,9 @@ sclp_tty_init(void)
...
@@ -795,9 +810,9 @@ sclp_tty_init(void)
sclp_tty_driver
.
read_proc
=
NULL
;
sclp_tty_driver
.
read_proc
=
NULL
;
sclp_tty_driver
.
write_proc
=
NULL
;
sclp_tty_driver
.
write_proc
=
NULL
;
if
(
tty_register_driver
(
&
sclp_tty_driver
))
rc
=
tty_register_driver
(
&
sclp_tty_driver
);
panic
(
"Couldn't register sclp_tty driver
\n
"
);
if
(
rc
!=
0
)
printk
(
KERN_ERR
SCLP_TTY_PRINT_HEADER
"could not register tty - "
"sclp_drv_register returned %d
\n
"
,
rc
);
}
}
console_initcall
(
sclp_tty_init
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment