Commit 9873aed5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6

* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
  [S390] Fix sclp_vt220 error handling.
  [S390] cio: Reorganize initialization.
  [S390] cio: Make CIO_* macros safe if dbfs are not available.
  [S390] cio: Clean up messages.
  [S390] Fix IRQ tracing.
  [S390] vmur: fix diag14_read.
  [S390] Wire up sys_fallocate.
  [S390] add types.h include to s390_ext.h
  [S390] cio: Remove deprecated rdc/rcd.
  [S390] Get rid of new section mismatch warnings.
  [S390] sclp: kill unused SCLP config option.
  [S390] cio: Remove remains of _ccw_device_get_device_number().
  [S390] cio: css_sch_device_register() can be made static.
  [S390] Improve __smp_call_function_map.
  [S390] Convert to smp_call_function_single.
parents 7b557376 5aaaf9f0
......@@ -211,22 +211,6 @@ Who: Richard Purdie <rpurdie@rpsys.net>
---------------------------
What: read_dev_chars(), read_conf_data{,_lpm}() (s390 common I/O layer)
When: December 2007
Why: These functions are a leftover from 2.4 times. They have several
problems:
- Duplication of checks that are done in the device driver's
interrupt handler
- common I/O layer can't do device specific error recovery
- device driver can't be notified for conditions happening during
execution of the function
Device drivers should issue the read device characteristics and read
configuration data ccws and do the appropriate error handling
themselves.
Who: Cornelia Huck <cornelia.huck@de.ibm.com>
---------------------------
What: i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers
When: September 2007
Why: Obsolete. The new i2c-gpio driver replaces all hardware-specific
......
......@@ -173,7 +173,7 @@ int appldata_diag(char record_nr, u16 function, unsigned long buffer,
/*
* appldata_mod_vtimer_wrap()
*
* wrapper function for mod_virt_timer(), because smp_call_function_on()
* wrapper function for mod_virt_timer(), because smp_call_function_single()
* accepts only one parameter.
*/
static void __appldata_mod_vtimer_wrap(void *p) {
......@@ -208,9 +208,9 @@ __appldata_vtimer_setup(int cmd)
num_online_cpus()) * TOD_MICRO;
for_each_online_cpu(i) {
per_cpu(appldata_timer, i).expires = per_cpu_interval;
smp_call_function_on(add_virt_timer_periodic,
&per_cpu(appldata_timer, i),
0, 1, i);
smp_call_function_single(i, add_virt_timer_periodic,
&per_cpu(appldata_timer, i),
0, 1);
}
appldata_timer_active = 1;
P_INFO("Monitoring timer started.\n");
......@@ -236,8 +236,8 @@ __appldata_vtimer_setup(int cmd)
} args;
args.timer = &per_cpu(appldata_timer, i);
args.expires = per_cpu_interval;
smp_call_function_on(__appldata_mod_vtimer_wrap,
&args, 0, 1, i);
smp_call_function_single(i, __appldata_mod_vtimer_wrap,
&args, 0, 1);
}
}
}
......
......@@ -1710,3 +1710,13 @@ compat_sys_timerfd_wrapper:
sys_eventfd_wrapper:
llgfr %r2,%r2 # unsigned int
jg sys_eventfd
.globl sys_fallocate_wrapper
sys_fallocate_wrapper:
lgfr %r2,%r2 # int
lgfr %r3,%r3 # int
sllg %r4,%r4,32 # get high word of 64bit loff_t
lr %r4,%r5 # get low word of 64bit loff_t
sllg %r5,%r6,32 # get high word of 64bit loff_t
l %r5,164(%r15) # get low word of 64bit loff_t
jg sys_fallocate
......@@ -624,9 +624,11 @@ io_work_loop:
# _TIF_MCCK_PENDING is set, call handler
#
io_mcck_pending:
TRACE_IRQS_OFF
l %r1,BASED(.Ls390_handle_mcck)
la %r14,BASED(io_work_loop)
br %r1 # TIF bit will be cleared by handler
basr %r14,%r1 # TIF bit will be cleared by handler
TRACE_IRQS_ON
b BASED(io_work_loop)
#
# _TIF_NEED_RESCHED is set, call schedule
......
......@@ -611,8 +611,10 @@ io_work_loop:
# _TIF_MCCK_PENDING is set, call handler
#
io_mcck_pending:
larl %r14,io_work_loop
jg s390_handle_mcck # TIF bit will be cleared by handler
TRACE_IRQS_OFF
brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
TRACE_IRQS_ON
j io_work_loop
#
# _TIF_NEED_RESCHED is set, call schedule
......
......@@ -35,6 +35,7 @@
#define ARCH_OFFSET 0
#endif
.section ".text.head","ax"
#ifndef CONFIG_IPL
.org 0
.long 0x00080000,0x80000000+startup # Just a restart PSW
......
......@@ -120,7 +120,7 @@ static void __smp_call_function_map(void (*func) (void *info), void *info,
if (wait)
data.finished = CPU_MASK_NONE;
spin_lock_bh(&call_lock);
spin_lock(&call_lock);
call_data = &data;
for_each_cpu_mask(cpu, map)
......@@ -129,18 +129,16 @@ static void __smp_call_function_map(void (*func) (void *info), void *info,
/* Wait for response */
while (!cpus_equal(map, data.started))
cpu_relax();
if (wait)
while (!cpus_equal(map, data.finished))
cpu_relax();
spin_unlock_bh(&call_lock);
spin_unlock(&call_lock);
out:
local_irq_disable();
if (local)
if (local) {
local_irq_disable();
func(info);
local_irq_enable();
local_irq_enable();
}
}
/*
......@@ -170,30 +168,28 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
EXPORT_SYMBOL(smp_call_function);
/*
* smp_call_function_on:
* smp_call_function_single:
* @cpu: the CPU where func should run
* @func: the function to run; this must be fast and non-blocking
* @info: an arbitrary pointer to pass to the function
* @nonatomic: unused
* @wait: if true, wait (atomically) until function has completed on other CPUs
* @cpu: the CPU where func should run
*
* Run a function on one processor.
*
* You must not call this function with disabled interrupts, from a
* hardware interrupt handler or from a bottom half.
*/
int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic,
int wait, int cpu)
int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
int nonatomic, int wait)
{
cpumask_t map = CPU_MASK_NONE;
preempt_disable();
cpu_set(cpu, map);
__smp_call_function_map(func, info, nonatomic, wait, map);
__smp_call_function_map(func, info, nonatomic, wait,
cpumask_of_cpu(cpu));
preempt_enable();
return 0;
}
EXPORT_SYMBOL(smp_call_function_on);
EXPORT_SYMBOL(smp_call_function_single);
static void do_send_stop(void)
{
......
......@@ -265,3 +265,23 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args)
return -EFAULT;
return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
}
#ifndef CONFIG_64BIT
/*
* This is a wrapper to call sys_fallocate(). For 31 bit s390 the last
* 64 bit argument "len" is split into the upper and lower 32 bits. The
* system call wrapper in the user space loads the value to %r6/%r7.
* The code in entry.S keeps the values in %r2 - %r6 where they are and
* stores %r7 to 96(%r15). But the standard C linkage requires that
* the whole 64 bit value for len is stored on the stack and doesn't
* use %r6 at all. So s390_fallocate has to convert the arguments from
* %r2: fd, %r3: mode, %r4/%r5: offset, %r6/96(%r15)-99(%r15): len
* to
* %r2: fd, %r3: mode, %r4/%r5: offset, 96(%r15)-103(%r15): len
*/
asmlinkage long s390_fallocate(int fd, int mode, loff_t offset,
u32 len_high, u32 len_low)
{
return sys_fallocate(fd, mode, offset, ((u64)len_high << 32) | len_low);
}
#endif
......@@ -322,7 +322,7 @@ NI_SYSCALL /* 310 sys_move_pages */
SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper)
SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait_wrapper)
SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper)
NI_SYSCALL /* 314 sys_fallocate */
SYSCALL(s390_fallocate,sys_fallocate,sys_fallocate_wrapper)
SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */
SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd_wrapper)
SYSCALL(sys_timerfd,sys_timerfd,compat_sys_timerfd_wrapper)
......
......@@ -21,6 +21,7 @@ SECTIONS
. = 0x00000000;
_text = .; /* Text and read-only data */
.text : {
*(.text.head)
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
......
......@@ -415,7 +415,7 @@ EXPORT_SYMBOL(add_virt_timer_periodic);
/*
* If we change a pending timer the function must be called on the CPU
* where the timer is running on, e.g. by smp_call_function_on()
* where the timer is running on, e.g. by smp_call_function_single()
*
* The original mod_timer adds the timer if it is not pending. For compatibility
* we do the same. The timer will be added on the current CPU as a oneshot timer.
......
......@@ -29,8 +29,8 @@ struct memory_segment {
static LIST_HEAD(mem_segs);
void memmap_init(unsigned long size, int nid, unsigned long zone,
unsigned long start_pfn)
void __meminit memmap_init(unsigned long size, int nid, unsigned long zone,
unsigned long start_pfn)
{
struct page *start, *end;
struct page *map_start, *map_end;
......@@ -66,7 +66,7 @@ void memmap_init(unsigned long size, int nid, unsigned long zone,
}
}
static inline void *vmem_alloc_pages(unsigned int order)
static void __init_refok *vmem_alloc_pages(unsigned int order)
{
if (slab_is_available())
return (void *)__get_free_pages(GFP_KERNEL, order);
......
......@@ -44,15 +44,9 @@ config CCW_CONSOLE
depends on TN3215_CONSOLE || TN3270_CONSOLE
default y
config SCLP
bool "Support for SCLP"
depends on S390
help
Include support for the SCLP interface to the service element.
config SCLP_TTY
bool "Support for SCLP line mode terminal"
depends on SCLP
depends on S390
help
Include support for IBM SCLP line-mode terminals.
......@@ -65,7 +59,7 @@ config SCLP_CONSOLE
config SCLP_VT220_TTY
bool "Support for SCLP VT220-compatible terminal"
depends on SCLP
depends on S390
help
Include support for an IBM SCLP VT220-compatible terminal.
......@@ -78,7 +72,7 @@ config SCLP_VT220_CONSOLE
config SCLP_CPI
tristate "Control-Program Identification"
depends on SCLP
depends on S390
help
This option enables the hardware console interface for system
identification. This is commonly used for workload management and
......
......@@ -147,8 +147,7 @@ raw3270_request_alloc(size_t size)
* Allocate a new 3270 ccw request from bootmem. Only works very
* early in the boot process. Only con3270.c should be using this.
*/
struct raw3270_request *
raw3270_request_alloc_bootmem(size_t size)
struct raw3270_request __init *raw3270_request_alloc_bootmem(size_t size)
{
struct raw3270_request *rq;
......@@ -848,8 +847,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
/*
* Setup 3270 device configured as console.
*/
struct raw3270 *
raw3270_setup_console(struct ccw_device *cdev)
struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev)
{
struct raw3270 *rp;
char *ascebc;
......
......@@ -621,11 +621,24 @@ sclp_vt220_flush_buffer(struct tty_struct *tty)
/*
* Initialize all relevant components and register driver with system.
*/
static int
__sclp_vt220_init(int early)
static void __init __sclp_vt220_cleanup(void)
{
struct list_head *page, *p;
list_for_each_safe(page, p, &sclp_vt220_empty) {
list_del(page);
if (slab_is_available())
free_page((unsigned long) page);
else
free_bootmem((unsigned long) page, PAGE_SIZE);
}
}
static int __init __sclp_vt220_init(void)
{
void *page;
int i;
int num_pages;
if (sclp_vt220_initialized)
return 0;
......@@ -642,13 +655,16 @@ __sclp_vt220_init(int early)
sclp_vt220_flush_later = 0;
/* Allocate pages for output buffering */
for (i = 0; i < (early ? MAX_CONSOLE_PAGES : MAX_KMEM_PAGES); i++) {
if (early)
page = alloc_bootmem_low_pages(PAGE_SIZE);
else
num_pages = slab_is_available() ? MAX_KMEM_PAGES : MAX_CONSOLE_PAGES;
for (i = 0; i < num_pages; i++) {
if (slab_is_available())
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!page)
else
page = alloc_bootmem_low_pages(PAGE_SIZE);
if (!page) {
__sclp_vt220_cleanup();
return -ENOMEM;
}
list_add_tail((struct list_head *) page, &sclp_vt220_empty);
}
return 0;
......@@ -662,14 +678,13 @@ static const struct tty_operations sclp_vt220_ops = {
.flush_chars = sclp_vt220_flush_chars,
.write_room = sclp_vt220_write_room,
.chars_in_buffer = sclp_vt220_chars_in_buffer,
.flush_buffer = sclp_vt220_flush_buffer
.flush_buffer = sclp_vt220_flush_buffer,
};
/*
* Register driver with SCLP and Linux and initialize internal tty structures.
*/
static int __init
sclp_vt220_tty_init(void)
static int __init sclp_vt220_tty_init(void)
{
struct tty_driver *driver;
int rc;
......@@ -679,18 +694,15 @@ sclp_vt220_tty_init(void)
driver = alloc_tty_driver(1);
if (!driver)
return -ENOMEM;
rc = __sclp_vt220_init(0);
if (rc) {
put_tty_driver(driver);
return rc;
}
rc = __sclp_vt220_init();
if (rc)
goto out_driver;
rc = sclp_register(&sclp_vt220_register);
if (rc) {
printk(KERN_ERR SCLP_VT220_PRINT_HEADER
"could not register tty - "
"sclp_register returned %d\n", rc);
put_tty_driver(driver);
return rc;
goto out_init;
}
driver->owner = THIS_MODULE;
......@@ -709,14 +721,20 @@ sclp_vt220_tty_init(void)
printk(KERN_ERR SCLP_VT220_PRINT_HEADER
"could not register tty - "
"tty_register_driver returned %d\n", rc);
put_tty_driver(driver);
return rc;
goto out_sclp;
}
sclp_vt220_driver = driver;
return 0;
}
module_init(sclp_vt220_tty_init);
out_sclp:
sclp_unregister(&sclp_vt220_register);
out_init:
__sclp_vt220_cleanup();
out_driver:
put_tty_driver(driver);
return rc;
}
__initcall(sclp_vt220_tty_init);
#ifdef CONFIG_SCLP_VT220_CONSOLE
......@@ -762,7 +780,7 @@ sclp_vt220_con_init(void)
if (!CONSOLE_IS_SCLP)
return 0;
rc = __sclp_vt220_init(1);
rc = __sclp_vt220_init();
if (rc)
return rc;
/* Attach linux console */
......
......@@ -486,7 +486,7 @@ static ssize_t diag14_read(struct file *file, char __user *ubuf, size_t count,
}
if (rc)
goto fail;
if (reclen)
if (reclen && (copied == 0) && (*offs < PAGE_SIZE))
*((u16 *) &buf[FILE_RECLEN_OFFSET]) = reclen;
len = min(count - copied, PAGE_SIZE - res);
if (copy_to_user(ubuf + copied, buf + res, len)) {
......
......@@ -51,7 +51,7 @@ blacklist_range (range_action action, unsigned int from, unsigned int to,
to = from;
if (from > to || to > __MAX_SUBCHANNEL || ssid > __MAX_SSID) {
printk (KERN_WARNING "Invalid blacklist range "
printk (KERN_WARNING "cio: Invalid blacklist range "
"0.%x.%04x to 0.%x.%04x, skipping\n",
ssid, from, ssid, to);
return;
......@@ -119,7 +119,7 @@ blacklist_busid(char **str, int *id0, int *ssid, int *devno)
return 0;
confused:
strsep(str, ",\n");
printk(KERN_WARNING "Invalid cio_ignore parameter '%s'\n", sav);
printk(KERN_WARNING "cio: Invalid cio_ignore parameter '%s'\n", sav);
return 1;
}
......@@ -166,22 +166,19 @@ blacklist_parse_parameters (char *str, range_action action)
continue;
}
if (*str == '-') {
printk(KERN_WARNING "invalid cio_ignore "
printk(KERN_WARNING "cio: invalid cio_ignore "
"parameter '%s'\n",
strsep(&str, ",\n"));
continue;
}
if ((from_id0 != to_id0) ||
(from_ssid != to_ssid)) {
printk(KERN_WARNING "invalid cio_ignore range "
"%x.%x.%04x-%x.%x.%04x\n",
from_id0, from_ssid, from,
to_id0, to_ssid, to);
printk(KERN_WARNING "cio: invalid cio_ignore "
"range %x.%x.%04x-%x.%x.%04x\n",
from_id0, from_ssid, from,
to_id0, to_ssid, to);
continue;
}
pr_debug("blacklist_setup: adding range "
"from %x.%x.%04x to %x.%x.%04x\n",
from_id0, from_ssid, from, to_id0, to_ssid, to);
blacklist_range (ra, from, to, to_ssid);
}
}
......@@ -239,7 +236,7 @@ blacklist_parse_proc_parameters (char *buf)
*/
blacklist_parse_parameters (buf + 4, add);
} else {
printk (KERN_WARNING "cio_ignore: Parse error; \n"
printk (KERN_WARNING "cio: cio_ignore: Parse error; \n"
KERN_WARNING "try using 'free all|<devno-range>,"
"<devno-range>,...'\n"
KERN_WARNING "or 'add <devno-range>,"
......
......@@ -359,7 +359,6 @@ ccwgroup_probe (struct device *dev)
if ((ret = device_create_file(dev, &dev_attr_online)))
return ret;
pr_debug("%s: device %s\n", __func__, gdev->dev.bus_id);
ret = gdrv->probe ? gdrv->probe(gdev) : -ENODEV;
if (ret)
device_remove_file(dev, &dev_attr_online);
......@@ -376,8 +375,6 @@ ccwgroup_remove (struct device *dev)
gdev = to_ccwgroupdev(dev);
gdrv = to_ccwgroupdrv(dev->driver);
pr_debug("%s: device %s\n", __func__, gdev->dev.bus_id);
device_remove_file(dev, &dev_attr_online);
if (gdrv && gdrv->remove)
......
......@@ -121,14 +121,8 @@ static int s390_vary_chpid(struct chp_id chpid, int on)
CIO_TRACE_EVENT( 2, dbf_text);
status = chp_get_status(chpid);
if (status < 0) {
printk(KERN_ERR "Can't vary unknown chpid %x.%02x\n",
chpid.cssid, chpid.id);
return -EINVAL;
}
if (!on && !status) {
printk(KERN_ERR "chpid %x.%02x is already offline\n",
printk(KERN_ERR "cio: chpid %x.%02x is already offline\n",
chpid.cssid, chpid.id);
return -EINVAL;
}
......@@ -421,21 +415,14 @@ int chp_new(struct chp_id chpid)
if (ret)
goto out_free;
} else {
static int msg_done;
if (!msg_done) {
printk(KERN_WARNING "cio: Channel measurements not "
"available, continuing.\n");
msg_done = 1;
}
chp->cmg = -1;
}
/* make it known to the system */
ret = device_register(&chp->dev);
if (ret) {
printk(KERN_WARNING "%s: could not register %x.%02x\n",
__func__, chpid.cssid, chpid.id);
CIO_MSG_EVENT(0, "Could not register chp%x.%02x: %d\n",
chpid.cssid, chpid.id, ret);
goto out_free;
}
ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
......
......@@ -990,16 +990,20 @@ out:
return ret;
}
static int __init
chsc_alloc_sei_area(void)
int __init chsc_alloc_sei_area(void)
{
sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!sei_page)
printk(KERN_WARNING"Can't allocate page for processing of " \
"chsc machine checks!\n");
CIO_MSG_EVENT(0, "Can't allocate page for processing of "
"chsc machine checks!\n");
return (sei_page ? 0 : -ENOMEM);
}
void __init chsc_free_sei_area(void)
{
kfree(sei_page);
}
int __init
chsc_enable_facility(int operation_code)
{
......@@ -1051,8 +1055,6 @@ chsc_enable_facility(int operation_code)
return ret;
}
subsys_initcall(chsc_alloc_sei_area);
struct css_general_char css_general_characteristics;
struct css_chsc_char css_chsc_characteristics;
......@@ -1073,8 +1075,8 @@ chsc_determine_css_characteristics(void)
scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scsc_area) {
printk(KERN_WARNING"cio: Was not able to determine available" \
"CHSCs due to no memory.\n");
CIO_MSG_EVENT(0, "Was not able to determine available"
"CHSCs due to no memory.\n");
return -ENOMEM;
}
......@@ -1083,15 +1085,15 @@ chsc_determine_css_characteristics(void)
result = chsc(scsc_area);
if (result) {
printk(KERN_WARNING"cio: Was not able to determine " \
"available CHSCs, cc=%i.\n", result);
CIO_MSG_EVENT(0, "Was not able to determine available CHSCs, "
"cc=%i.\n", result);
result = -EIO;
goto exit;
}
if (scsc_area->response.code != 1) {
printk(KERN_WARNING"cio: Was not able to determine " \
"available CHSCs.\n");
CIO_MSG_EVENT(0, "Was not able to determine "
"available CHSCs.\n");
result = -EIO;
goto exit;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment