Skip to content
Snippets Groups Projects
Commit c1101cbc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Martin Schwidefsky:
 "This is the bulk of the s390 patches for the 3.11 merge window.

  Notable enhancements are: the block timeout patches for dasd from
  Hannes, and more work on the PCI support front.  In addition some
  cleanup and the usual bug fixing."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (42 commits)
  s390/dasd: Fail all requests when DASD_FLAG_ABORTIO is set
  s390/dasd: Add 'timeout' attribute
  block: check for timeout function in blk_rq_timed_out()
  block/dasd: detailed I/O errors
  s390/dasd: Reduce amount of messages for specific errors
  s390/dasd: Implement block timeout handling
  s390/dasd: process all requests in the device tasklet
  s390/dasd: make number of retries configurable
  s390/dasd: Clarify comment
  s390/hwsampler: Updated misleading member names in hws_data_entry
  s390/appldata_net_sum: do not use static data
  s390/appldata_mem: do not use static data
  s390/vmwatchdog: do not use static data
  s390/airq: simplify adapter interrupt code
  s390/pci: remove per device debug attribute
  s390/dma: remove gratuitous brackets
  s390/facility: decompose test_facility()
  s390/sclp: remove duplicated include from sclp_ctl.c
  s390/irq: store interrupt information in pt_regs
  s390/drivers: Cocci spatch "ptr_ret.spatch"
  ...
parents 1873e500 5ea34a01
No related merge requests found
Showing
with 130 additions and 58 deletions
...@@ -72,6 +72,7 @@ Code Seq#(hex) Include File Comments ...@@ -72,6 +72,7 @@ Code Seq#(hex) Include File Comments
0x06 all linux/lp.h 0x06 all linux/lp.h
0x09 all linux/raid/md_u.h 0x09 all linux/raid/md_u.h
0x10 00-0F drivers/char/s390/vmcp.h 0x10 00-0F drivers/char/s390/vmcp.h
0x10 10-1F arch/s390/include/uapi/sclp_ctl.h
0x12 all linux/fs.h 0x12 all linux/fs.h
linux/blkpg.h linux/blkpg.h
0x1b all InfiniBand Subsystem <http://infiniband.sourceforge.net/> 0x1b all InfiniBand Subsystem <http://infiniband.sourceforge.net/>
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* book: * book:
* http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml * http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml
*/ */
static struct appldata_mem_data { struct appldata_mem_data {
u64 timestamp; u64 timestamp;
u32 sync_count_1; /* after VM collected the record data, */ u32 sync_count_1; /* after VM collected the record data, */
u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the
...@@ -63,7 +63,7 @@ static struct appldata_mem_data { ...@@ -63,7 +63,7 @@ static struct appldata_mem_data {
u64 pgmajfault; /* page faults (major only) */ u64 pgmajfault; /* page faults (major only) */
// <-- New in 2.6 // <-- New in 2.6
} __attribute__((packed)) appldata_mem_data; } __packed;
/* /*
...@@ -118,7 +118,6 @@ static struct appldata_ops ops = { ...@@ -118,7 +118,6 @@ static struct appldata_ops ops = {
.record_nr = APPLDATA_RECORD_MEM_ID, .record_nr = APPLDATA_RECORD_MEM_ID,
.size = sizeof(struct appldata_mem_data), .size = sizeof(struct appldata_mem_data),
.callback = &appldata_get_mem_data, .callback = &appldata_get_mem_data,
.data = &appldata_mem_data,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */
}; };
...@@ -131,7 +130,17 @@ static struct appldata_ops ops = { ...@@ -131,7 +130,17 @@ static struct appldata_ops ops = {
*/ */
static int __init appldata_mem_init(void) static int __init appldata_mem_init(void)
{ {
return appldata_register_ops(&ops); int ret;
ops.data = kzalloc(sizeof(struct appldata_mem_data), GFP_KERNEL);
if (!ops.data)
return -ENOMEM;
ret = appldata_register_ops(&ops);
if (ret)
kfree(ops.data);
return ret;
} }
/* /*
...@@ -142,6 +151,7 @@ static int __init appldata_mem_init(void) ...@@ -142,6 +151,7 @@ static int __init appldata_mem_init(void)
static void __exit appldata_mem_exit(void) static void __exit appldata_mem_exit(void)
{ {
appldata_unregister_ops(&ops); appldata_unregister_ops(&ops);
kfree(ops.data);
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
* book: * book:
* http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml * http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml
*/ */
static struct appldata_net_sum_data { struct appldata_net_sum_data {
u64 timestamp; u64 timestamp;
u32 sync_count_1; /* after VM collected the record data, */ u32 sync_count_1; /* after VM collected the record data, */
u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the u32 sync_count_2; /* sync_count_1 and sync_count_2 should be the
...@@ -51,7 +51,7 @@ static struct appldata_net_sum_data { ...@@ -51,7 +51,7 @@ static struct appldata_net_sum_data {
u64 rx_dropped; /* no space in linux buffers */ u64 rx_dropped; /* no space in linux buffers */
u64 tx_dropped; /* no space available in linux */ u64 tx_dropped; /* no space available in linux */
u64 collisions; /* collisions while transmitting */ u64 collisions; /* collisions while transmitting */
} __attribute__((packed)) appldata_net_sum_data; } __packed;
/* /*
...@@ -121,7 +121,6 @@ static struct appldata_ops ops = { ...@@ -121,7 +121,6 @@ static struct appldata_ops ops = {
.record_nr = APPLDATA_RECORD_NET_SUM_ID, .record_nr = APPLDATA_RECORD_NET_SUM_ID,
.size = sizeof(struct appldata_net_sum_data), .size = sizeof(struct appldata_net_sum_data),
.callback = &appldata_get_net_sum_data, .callback = &appldata_get_net_sum_data,
.data = &appldata_net_sum_data,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */
}; };
...@@ -134,7 +133,17 @@ static struct appldata_ops ops = { ...@@ -134,7 +133,17 @@ static struct appldata_ops ops = {
*/ */
static int __init appldata_net_init(void) static int __init appldata_net_init(void)
{ {
return appldata_register_ops(&ops); int ret;
ops.data = kzalloc(sizeof(struct appldata_net_sum_data), GFP_KERNEL);
if (!ops.data)
return -ENOMEM;
ret = appldata_register_ops(&ops);
if (ret)
kfree(ops.data);
return ret;
} }
/* /*
...@@ -145,6 +154,7 @@ static int __init appldata_net_init(void) ...@@ -145,6 +154,7 @@ static int __init appldata_net_init(void)
static void __exit appldata_net_exit(void) static void __exit appldata_net_exit(void)
{ {
appldata_unregister_ops(&ops); appldata_unregister_ops(&ops);
kfree(ops.data);
} }
......
...@@ -651,9 +651,7 @@ static int hypfs_create_cpu_files(struct super_block *sb, ...@@ -651,9 +651,7 @@ static int hypfs_create_cpu_files(struct super_block *sb,
} }
diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer); diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer);
rc = hypfs_create_str(sb, cpu_dir, "type", buffer); rc = hypfs_create_str(sb, cpu_dir, "type", buffer);
if (IS_ERR(rc)) return PTR_RET(rc);
return PTR_ERR(rc);
return 0;
} }
static void *hypfs_create_lpar_files(struct super_block *sb, static void *hypfs_create_lpar_files(struct super_block *sb,
...@@ -702,9 +700,7 @@ static int hypfs_create_phys_cpu_files(struct super_block *sb, ...@@ -702,9 +700,7 @@ static int hypfs_create_phys_cpu_files(struct super_block *sb,
return PTR_ERR(rc); return PTR_ERR(rc);
diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer); diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer);
rc = hypfs_create_str(sb, cpu_dir, "type", buffer); rc = hypfs_create_str(sb, cpu_dir, "type", buffer);
if (IS_ERR(rc)) return PTR_RET(rc);
return PTR_ERR(rc);
return 0;
} }
static void *hypfs_create_phys_files(struct super_block *sb, static void *hypfs_create_phys_files(struct super_block *sb,
......
...@@ -9,9 +9,18 @@ ...@@ -9,9 +9,18 @@
#ifndef _ASM_S390_AIRQ_H #ifndef _ASM_S390_AIRQ_H
#define _ASM_S390_AIRQ_H #define _ASM_S390_AIRQ_H
typedef void (*adapter_int_handler_t)(void *, void *); struct airq_struct {
struct hlist_node list; /* Handler queueing. */
void (*handler)(struct airq_struct *); /* Thin-interrupt handler */
u8 *lsi_ptr; /* Local-Summary-Indicator pointer */
u8 lsi_mask; /* Local-Summary-Indicator mask */
u8 isc; /* Interrupt-subclass */
u8 flags;
};
void *s390_register_adapter_interrupt(adapter_int_handler_t, void *, u8); #define AIRQ_PTR_ALLOCATED 0x01
void s390_unregister_adapter_interrupt(void *, u8);
int register_adapter_interrupt(struct airq_struct *airq);
void unregister_adapter_interrupt(struct airq_struct *airq);
#endif /* _ASM_S390_AIRQ_H */ #endif /* _ASM_S390_AIRQ_H */
...@@ -53,7 +53,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) ...@@ -53,7 +53,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
debug_dma_mapping_error(dev, dma_addr); debug_dma_mapping_error(dev, dma_addr);
if (dma_ops->mapping_error) if (dma_ops->mapping_error)
return dma_ops->mapping_error(dev, dma_addr); return dma_ops->mapping_error(dev, dma_addr);
return (dma_addr == DMA_ERROR_CODE); return dma_addr == DMA_ERROR_CODE;
} }
static inline void *dma_alloc_coherent(struct device *dev, size_t size, static inline void *dma_alloc_coherent(struct device *dev, size_t size,
......
...@@ -13,6 +13,16 @@ ...@@ -13,6 +13,16 @@
#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ #define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */
static inline int __test_facility(unsigned long nr, void *facilities)
{
unsigned char *ptr;
if (nr >= MAX_FACILITY_BIT)
return 0;
ptr = (unsigned char *) facilities + (nr >> 3);
return (*ptr & (0x80 >> (nr & 7))) != 0;
}
/* /*
* The test_facility function uses the bit odering where the MSB is bit 0. * The test_facility function uses the bit odering where the MSB is bit 0.
* That makes it easier to query facility bits with the bit number as * That makes it easier to query facility bits with the bit number as
...@@ -20,12 +30,7 @@ ...@@ -20,12 +30,7 @@
*/ */
static inline int test_facility(unsigned long nr) static inline int test_facility(unsigned long nr)
{ {
unsigned char *ptr; return __test_facility(nr, &S390_lowcore.stfle_fac_list);
if (nr >= MAX_FACILITY_BIT)
return 0;
ptr = (unsigned char *) &S390_lowcore.stfle_fac_list + (nr >> 3);
return (*ptr & (0x80 >> (nr & 7))) != 0;
} }
/** /**
......
...@@ -13,28 +13,6 @@ ...@@ -13,28 +13,6 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/pci_io.h> #include <asm/pci_io.h>
/*
* Change virtual addresses to physical addresses and vv.
* These are pretty trivial
*/
static inline unsigned long virt_to_phys(volatile void * address)
{
unsigned long real_address;
asm volatile(
" lra %0,0(%1)\n"
" jz 0f\n"
" la %0,0\n"
"0:"
: "=a" (real_address) : "a" (address) : "cc");
return real_address;
}
#define virt_to_phys virt_to_phys
static inline void * phys_to_virt(unsigned long address)
{
return (void *) address;
}
void *xlate_dev_mem_ptr(unsigned long phys); void *xlate_dev_mem_ptr(unsigned long phys);
#define xlate_dev_mem_ptr xlate_dev_mem_ptr #define xlate_dev_mem_ptr xlate_dev_mem_ptr
void unxlate_dev_mem_ptr(unsigned long phys, void *addr); void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
......
...@@ -120,7 +120,6 @@ struct zpci_dev { ...@@ -120,7 +120,6 @@ struct zpci_dev {
struct dentry *debugfs_dev; struct dentry *debugfs_dev;
struct dentry *debugfs_perf; struct dentry *debugfs_perf;
struct dentry *debugfs_debug;
}; };
struct pci_hp_callback_ops { struct pci_hp_callback_ops {
...@@ -143,7 +142,6 @@ int zpci_enable_device(struct zpci_dev *); ...@@ -143,7 +142,6 @@ int zpci_enable_device(struct zpci_dev *);
int zpci_disable_device(struct zpci_dev *); int zpci_disable_device(struct zpci_dev *);
void zpci_stop_device(struct zpci_dev *); void zpci_stop_device(struct zpci_dev *);
void zpci_free_device(struct zpci_dev *); void zpci_free_device(struct zpci_dev *);
int zpci_scan_device(struct zpci_dev *);
int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
int zpci_unregister_ioat(struct zpci_dev *, u8); int zpci_unregister_ioat(struct zpci_dev *, u8);
......
...@@ -22,6 +22,9 @@ unsigned long *page_table_alloc(struct mm_struct *, unsigned long); ...@@ -22,6 +22,9 @@ unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
void page_table_free(struct mm_struct *, unsigned long *); void page_table_free(struct mm_struct *, unsigned long *);
void page_table_free_rcu(struct mmu_gather *, unsigned long *); void page_table_free_rcu(struct mmu_gather *, unsigned long *);
int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
unsigned long key, bool nq);
static inline void clear_table(unsigned long *s, unsigned long val, size_t n) static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
{ {
typedef struct { char _[n]; } addrtype; typedef struct { char _[n]; } addrtype;
......
...@@ -24,6 +24,7 @@ struct pt_regs ...@@ -24,6 +24,7 @@ struct pt_regs
unsigned long gprs[NUM_GPRS]; unsigned long gprs[NUM_GPRS];
unsigned long orig_gpr2; unsigned long orig_gpr2;
unsigned int int_code; unsigned int int_code;
unsigned int int_parm;
unsigned long int_parm_long; unsigned long int_parm_long;
}; };
......
...@@ -35,6 +35,7 @@ header-y += siginfo.h ...@@ -35,6 +35,7 @@ header-y += siginfo.h
header-y += signal.h header-y += signal.h
header-y += socket.h header-y += socket.h
header-y += sockios.h header-y += sockios.h
header-y += sclp_ctl.h
header-y += stat.h header-y += stat.h
header-y += statfs.h header-y += statfs.h
header-y += swab.h header-y += swab.h
......
...@@ -29,6 +29,16 @@ struct chsc_async_area { ...@@ -29,6 +29,16 @@ struct chsc_async_area {
__u8 data[CHSC_SIZE - sizeof(struct chsc_async_header)]; __u8 data[CHSC_SIZE - sizeof(struct chsc_async_header)];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct chsc_header {
__u16 length;
__u16 code;
} __attribute__ ((packed));
struct chsc_sync_area {
struct chsc_header header;
__u8 data[CHSC_SIZE - sizeof(struct chsc_header)];
} __attribute__ ((packed));
struct chsc_response_struct { struct chsc_response_struct {
__u16 length; __u16 length;
__u16 code; __u16 code;
...@@ -126,5 +136,8 @@ struct chsc_cpd_info { ...@@ -126,5 +136,8 @@ struct chsc_cpd_info {
#define CHSC_INFO_CCL _IOWR(CHSC_IOCTL_MAGIC, 0x86, struct chsc_comp_list) #define CHSC_INFO_CCL _IOWR(CHSC_IOCTL_MAGIC, 0x86, struct chsc_comp_list)
#define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info)
#define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal)
#define CHSC_START_SYNC _IOWR(CHSC_IOCTL_MAGIC, 0x89, struct chsc_sync_area)
#define CHSC_ON_CLOSE_SET _IOWR(CHSC_IOCTL_MAGIC, 0x8a, struct chsc_async_area)
#define CHSC_ON_CLOSE_REMOVE _IO(CHSC_IOCTL_MAGIC, 0x8b)
#endif #endif
...@@ -261,6 +261,10 @@ struct dasd_snid_ioctl_data { ...@@ -261,6 +261,10 @@ struct dasd_snid_ioctl_data {
#define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6) #define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6)
/* Resume IO on device */ /* Resume IO on device */
#define BIODASDRESUME _IO(DASD_IOCTL_LETTER,7) #define BIODASDRESUME _IO(DASD_IOCTL_LETTER,7)
/* Abort all I/O on a device */
#define BIODASDABORTIO _IO(DASD_IOCTL_LETTER, 240)
/* Allow I/O on a device */
#define BIODASDALLOWIO _IO(DASD_IOCTL_LETTER, 241)
/* retrieve API version number */ /* retrieve API version number */
......
/*
* IOCTL interface for SCLP
*
* Copyright IBM Corp. 2012
*
* Author: Michael Holzheu <holzheu@linux.vnet.ibm.com>
*/
#ifndef _ASM_SCLP_CTL_H
#define _ASM_SCLP_CTL_H
#include <linux/types.h>
struct sclp_ctl_sccb {
__u32 cmdw;
__u64 sccb;
} __attribute__((packed));
#define SCLP_CTL_IOCTL_MAGIC 0x10
#define SCLP_CTL_SCCB \
_IOWR(SCLP_CTL_IOCTL_MAGIC, 0x10, struct sclp_ctl_sccb)
#endif
...@@ -47,6 +47,7 @@ int main(void) ...@@ -47,6 +47,7 @@ int main(void)
DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs)); DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2)); DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
DEFINE(__PT_INT_CODE, offsetof(struct pt_regs, int_code)); DEFINE(__PT_INT_CODE, offsetof(struct pt_regs, int_code));
DEFINE(__PT_INT_PARM, offsetof(struct pt_regs, int_parm));
DEFINE(__PT_INT_PARM_LONG, offsetof(struct pt_regs, int_parm_long)); DEFINE(__PT_INT_PARM_LONG, offsetof(struct pt_regs, int_parm_long));
DEFINE(__PT_SIZE, sizeof(struct pt_regs)); DEFINE(__PT_SIZE, sizeof(struct pt_regs));
BLANK(); BLANK();
......
...@@ -429,11 +429,19 @@ io_skip: ...@@ -429,11 +429,19 @@ io_skip:
stm %r0,%r7,__PT_R0(%r11) stm %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
stm %r8,%r9,__PT_PSW(%r11) stm %r8,%r9,__PT_PSW(%r11)
mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
TRACE_IRQS_OFF TRACE_IRQS_OFF
xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
io_loop:
l %r1,BASED(.Ldo_IRQ) l %r1,BASED(.Ldo_IRQ)
lr %r2,%r11 # pass pointer to pt_regs lr %r2,%r11 # pass pointer to pt_regs
basr %r14,%r1 # call do_IRQ basr %r14,%r1 # call do_IRQ
tm __LC_MACHINE_FLAGS+2,0x10 # MACHINE_FLAG_LPAR
jz io_return
tpi 0
jz io_return
mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
j io_loop
io_return: io_return:
LOCKDEP_SYS_EXIT LOCKDEP_SYS_EXIT
TRACE_IRQS_ON TRACE_IRQS_ON
...@@ -573,10 +581,10 @@ ext_skip: ...@@ -573,10 +581,10 @@ ext_skip:
stm %r0,%r7,__PT_R0(%r11) stm %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
stm %r8,%r9,__PT_PSW(%r11) stm %r8,%r9,__PT_PSW(%r11)
mvc __PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
TRACE_IRQS_OFF TRACE_IRQS_OFF
lr %r2,%r11 # pass pointer to pt_regs lr %r2,%r11 # pass pointer to pt_regs
l %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code
l %r4,__LC_EXT_PARAMS # get external parameters
l %r1,BASED(.Ldo_extint) l %r1,BASED(.Ldo_extint)
basr %r14,%r1 # call do_extint basr %r14,%r1 # call do_extint
j io_return j io_return
......
...@@ -54,7 +54,7 @@ void handle_signal32(unsigned long sig, struct k_sigaction *ka, ...@@ -54,7 +54,7 @@ void handle_signal32(unsigned long sig, struct k_sigaction *ka,
void do_notify_resume(struct pt_regs *regs); void do_notify_resume(struct pt_regs *regs);
struct ext_code; struct ext_code;
void do_extint(struct pt_regs *regs, struct ext_code, unsigned int, unsigned long); void do_extint(struct pt_regs *regs);
void do_restart(void); void do_restart(void);
void __init startup_init(void); void __init startup_init(void);
void die(struct pt_regs *regs, const char *str); void die(struct pt_regs *regs, const char *str);
......
...@@ -460,10 +460,18 @@ io_skip: ...@@ -460,10 +460,18 @@ io_skip:
stmg %r0,%r7,__PT_R0(%r11) stmg %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
stmg %r8,%r9,__PT_PSW(%r11) stmg %r8,%r9,__PT_PSW(%r11)
mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
TRACE_IRQS_OFF TRACE_IRQS_OFF
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
io_loop:
lgr %r2,%r11 # pass pointer to pt_regs lgr %r2,%r11 # pass pointer to pt_regs
brasl %r14,do_IRQ brasl %r14,do_IRQ
tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR
jz io_return
tpi 0
jz io_return
mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
j io_loop
io_return: io_return:
LOCKDEP_SYS_EXIT LOCKDEP_SYS_EXIT
TRACE_IRQS_ON TRACE_IRQS_ON
...@@ -605,13 +613,13 @@ ext_skip: ...@@ -605,13 +613,13 @@ ext_skip:
stmg %r0,%r7,__PT_R0(%r11) stmg %r0,%r7,__PT_R0(%r11)
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
stmg %r8,%r9,__PT_PSW(%r11) stmg %r8,%r9,__PT_PSW(%r11)
lghi %r1,__LC_EXT_PARAMS2
mvc __PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
mvc __PT_INT_PARM_LONG(8,%r11),0(%r1)
TRACE_IRQS_OFF TRACE_IRQS_OFF
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
lghi %r1,4096
lgr %r2,%r11 # pass pointer to pt_regs lgr %r2,%r11 # pass pointer to pt_regs
llgf %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code
llgf %r4,__LC_EXT_PARAMS # get external parameter
lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
brasl %r14,do_extint brasl %r14,do_extint
j io_return j io_return
......
...@@ -234,9 +234,9 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) ...@@ -234,9 +234,9 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
} }
EXPORT_SYMBOL(unregister_external_interrupt); EXPORT_SYMBOL(unregister_external_interrupt);
void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, void __irq_entry do_extint(struct pt_regs *regs)
unsigned int param32, unsigned long param64)
{ {
struct ext_code ext_code;
struct pt_regs *old_regs; struct pt_regs *old_regs;
struct ext_int_info *p; struct ext_int_info *p;
int index; int index;
...@@ -248,6 +248,7 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, ...@@ -248,6 +248,7 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
clock_comparator_work(); clock_comparator_work();
} }
kstat_incr_irqs_this_cpu(EXTERNAL_INTERRUPT, NULL); kstat_incr_irqs_this_cpu(EXTERNAL_INTERRUPT, NULL);
ext_code = *(struct ext_code *) &regs->int_code;
if (ext_code.code != 0x1004) if (ext_code.code != 0x1004)
__get_cpu_var(s390_idle).nohz_delay = 1; __get_cpu_var(s390_idle).nohz_delay = 1;
...@@ -255,7 +256,8 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, ...@@ -255,7 +256,8 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(p, &ext_int_hash[index], entry) list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
if (likely(p->code == ext_code.code)) if (likely(p->code == ext_code.code))
p->handler(ext_code, param32, param64); p->handler(ext_code, regs->int_parm,
regs->int_parm_long);
rcu_read_unlock(); rcu_read_unlock();
irq_exit(); irq_exit();
set_irq_regs(old_regs); set_irq_regs(old_regs);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment