From 62733e5a5a480a893e56fa6133ae90904d857bc4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:28:15 +0200 Subject: [S390] cio: move scsw helper functions to header file All scsw helper functions are very short and usage of them shouldn't result in function calls. Therefore we move them to a separate header file. Also saves a lot of EXPORT_SYMBOLs. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/chsc.h | 28 ++ arch/s390/include/asm/cio.h | 223 +--------- arch/s390/include/asm/scsw.h | 956 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 985 insertions(+), 222 deletions(-) create mode 100644 arch/s390/include/asm/scsw.h (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h index 807997f..4943654 100644 --- a/arch/s390/include/asm/chsc.h +++ b/arch/s390/include/asm/chsc.h @@ -125,4 +125,32 @@ 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) +#ifdef __KERNEL__ + +struct css_general_char { + u64 : 12; + u32 dynio : 1; /* bit 12 */ + u32 : 28; + u32 aif : 1; /* bit 41 */ + u32 : 3; + u32 mcss : 1; /* bit 45 */ + u32 fcs : 1; /* bit 46 */ + u32 : 1; + u32 ext_mb : 1; /* bit 48 */ + u32 : 7; + u32 aif_tdd : 1; /* bit 56 */ + u32 : 1; + u32 qebsm : 1; /* bit 58 */ + u32 : 8; + u32 aif_osa : 1; /* bit 67 */ + u32 : 14; + u32 cib : 1; /* bit 82 */ + u32 : 5; + u32 fcx : 1; /* bit 88 */ + u32 : 7; +}__attribute__((packed)); + +extern struct css_general_char css_general_characteristics; + +#endif /* __KERNEL__ */ #endif diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 619bf94..e85679a 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -15,228 +15,7 @@ #define LPM_ANYPATH 0xff #define __MAX_CSSID 0 -/** - * struct cmd_scsw - command-mode subchannel status word - * @key: subchannel key - * @sctl: suspend control - * @eswf: esw format - * @cc: deferred condition code - * @fmt: format - * @pfch: prefetch - * @isic: initial-status interruption control - * @alcc: address-limit checking control - * @ssi: suppress-suspended interruption - * @zcc: zero condition code - * @ectl: extended control - * @pno: path not operational - * @res: reserved - * @fctl: function control - * @actl: activity control - * @stctl: status control - * @cpa: channel program address - * @dstat: device status - * @cstat: subchannel status - * @count: residual count - */ -struct cmd_scsw { - __u32 key : 4; - __u32 sctl : 1; - __u32 eswf : 1; - __u32 cc : 2; - __u32 fmt : 1; - __u32 pfch : 1; - __u32 isic : 1; - __u32 alcc : 1; - __u32 ssi : 1; - __u32 zcc : 1; - __u32 ectl : 1; - __u32 pno : 1; - __u32 res : 1; - __u32 fctl : 3; - __u32 actl : 7; - __u32 stctl : 5; - __u32 cpa; - __u32 dstat : 8; - __u32 cstat : 8; - __u32 count : 16; -} __attribute__ ((packed)); - -/** - * struct tm_scsw - transport-mode subchannel status word - * @key: subchannel key - * @eswf: esw format - * @cc: deferred condition code - * @fmt: format - * @x: IRB-format control - * @q: interrogate-complete - * @ectl: extended control - * @pno: path not operational - * @fctl: function control - * @actl: activity control - * @stctl: status control - * @tcw: TCW address - * @dstat: device status - * @cstat: subchannel status - * @fcxs: FCX status - * @schxs: subchannel-extended status - */ -struct tm_scsw { - u32 key:4; - u32 :1; - u32 eswf:1; - u32 cc:2; - u32 fmt:3; - u32 x:1; - u32 q:1; - u32 :1; - u32 ectl:1; - u32 pno:1; - u32 :1; - u32 fctl:3; - u32 actl:7; - u32 stctl:5; - u32 tcw; - u32 dstat:8; - u32 cstat:8; - u32 fcxs:8; - u32 schxs:8; -} __attribute__ ((packed)); - -/** - * union scsw - subchannel status word - * @cmd: command-mode SCSW - * @tm: transport-mode SCSW - */ -union scsw { - struct cmd_scsw cmd; - struct tm_scsw tm; -} __attribute__ ((packed)); - -int scsw_is_tm(union scsw *scsw); -u32 scsw_key(union scsw *scsw); -u32 scsw_eswf(union scsw *scsw); -u32 scsw_cc(union scsw *scsw); -u32 scsw_ectl(union scsw *scsw); -u32 scsw_pno(union scsw *scsw); -u32 scsw_fctl(union scsw *scsw); -u32 scsw_actl(union scsw *scsw); -u32 scsw_stctl(union scsw *scsw); -u32 scsw_dstat(union scsw *scsw); -u32 scsw_cstat(union scsw *scsw); -int scsw_is_solicited(union scsw *scsw); -int scsw_is_valid_key(union scsw *scsw); -int scsw_is_valid_eswf(union scsw *scsw); -int scsw_is_valid_cc(union scsw *scsw); -int scsw_is_valid_ectl(union scsw *scsw); -int scsw_is_valid_pno(union scsw *scsw); -int scsw_is_valid_fctl(union scsw *scsw); -int scsw_is_valid_actl(union scsw *scsw); -int scsw_is_valid_stctl(union scsw *scsw); -int scsw_is_valid_dstat(union scsw *scsw); -int scsw_is_valid_cstat(union scsw *scsw); -int scsw_cmd_is_valid_key(union scsw *scsw); -int scsw_cmd_is_valid_sctl(union scsw *scsw); -int scsw_cmd_is_valid_eswf(union scsw *scsw); -int scsw_cmd_is_valid_cc(union scsw *scsw); -int scsw_cmd_is_valid_fmt(union scsw *scsw); -int scsw_cmd_is_valid_pfch(union scsw *scsw); -int scsw_cmd_is_valid_isic(union scsw *scsw); -int scsw_cmd_is_valid_alcc(union scsw *scsw); -int scsw_cmd_is_valid_ssi(union scsw *scsw); -int scsw_cmd_is_valid_zcc(union scsw *scsw); -int scsw_cmd_is_valid_ectl(union scsw *scsw); -int scsw_cmd_is_valid_pno(union scsw *scsw); -int scsw_cmd_is_valid_fctl(union scsw *scsw); -int scsw_cmd_is_valid_actl(union scsw *scsw); -int scsw_cmd_is_valid_stctl(union scsw *scsw); -int scsw_cmd_is_valid_dstat(union scsw *scsw); -int scsw_cmd_is_valid_cstat(union scsw *scsw); -int scsw_cmd_is_solicited(union scsw *scsw); -int scsw_tm_is_valid_key(union scsw *scsw); -int scsw_tm_is_valid_eswf(union scsw *scsw); -int scsw_tm_is_valid_cc(union scsw *scsw); -int scsw_tm_is_valid_fmt(union scsw *scsw); -int scsw_tm_is_valid_x(union scsw *scsw); -int scsw_tm_is_valid_q(union scsw *scsw); -int scsw_tm_is_valid_ectl(union scsw *scsw); -int scsw_tm_is_valid_pno(union scsw *scsw); -int scsw_tm_is_valid_fctl(union scsw *scsw); -int scsw_tm_is_valid_actl(union scsw *scsw); -int scsw_tm_is_valid_stctl(union scsw *scsw); -int scsw_tm_is_valid_dstat(union scsw *scsw); -int scsw_tm_is_valid_cstat(union scsw *scsw); -int scsw_tm_is_valid_fcxs(union scsw *scsw); -int scsw_tm_is_valid_schxs(union scsw *scsw); -int scsw_tm_is_solicited(union scsw *scsw); - -#define SCSW_FCTL_CLEAR_FUNC 0x1 -#define SCSW_FCTL_HALT_FUNC 0x2 -#define SCSW_FCTL_START_FUNC 0x4 - -#define SCSW_ACTL_SUSPENDED 0x1 -#define SCSW_ACTL_DEVACT 0x2 -#define SCSW_ACTL_SCHACT 0x4 -#define SCSW_ACTL_CLEAR_PEND 0x8 -#define SCSW_ACTL_HALT_PEND 0x10 -#define SCSW_ACTL_START_PEND 0x20 -#define SCSW_ACTL_RESUME_PEND 0x40 - -#define SCSW_STCTL_STATUS_PEND 0x1 -#define SCSW_STCTL_SEC_STATUS 0x2 -#define SCSW_STCTL_PRIM_STATUS 0x4 -#define SCSW_STCTL_INTER_STATUS 0x8 -#define SCSW_STCTL_ALERT_STATUS 0x10 - -#define DEV_STAT_ATTENTION 0x80 -#define DEV_STAT_STAT_MOD 0x40 -#define DEV_STAT_CU_END 0x20 -#define DEV_STAT_BUSY 0x10 -#define DEV_STAT_CHN_END 0x08 -#define DEV_STAT_DEV_END 0x04 -#define DEV_STAT_UNIT_CHECK 0x02 -#define DEV_STAT_UNIT_EXCEP 0x01 - -#define SCHN_STAT_PCI 0x80 -#define SCHN_STAT_INCORR_LEN 0x40 -#define SCHN_STAT_PROG_CHECK 0x20 -#define SCHN_STAT_PROT_CHECK 0x10 -#define SCHN_STAT_CHN_DATA_CHK 0x08 -#define SCHN_STAT_CHN_CTRL_CHK 0x04 -#define SCHN_STAT_INTF_CTRL_CHK 0x02 -#define SCHN_STAT_CHAIN_CHECK 0x01 - -/* - * architectured values for first sense byte - */ -#define SNS0_CMD_REJECT 0x80 -#define SNS_CMD_REJECT SNS0_CMD_REJEC -#define SNS0_INTERVENTION_REQ 0x40 -#define SNS0_BUS_OUT_CHECK 0x20 -#define SNS0_EQUIPMENT_CHECK 0x10 -#define SNS0_DATA_CHECK 0x08 -#define SNS0_OVERRUN 0x04 -#define SNS0_INCOMPL_DOMAIN 0x01 - -/* - * architectured values for second sense byte - */ -#define SNS1_PERM_ERR 0x80 -#define SNS1_INV_TRACK_FORMAT 0x40 -#define SNS1_EOC 0x20 -#define SNS1_MESSAGE_TO_OPER 0x10 -#define SNS1_NO_REC_FOUND 0x08 -#define SNS1_FILE_PROTECTED 0x04 -#define SNS1_WRITE_INHIBITED 0x02 -#define SNS1_INPRECISE_END 0x01 - -/* - * architectured values for third sense byte - */ -#define SNS2_REQ_INH_WRITE 0x80 -#define SNS2_CORRECTABLE 0x40 -#define SNS2_FIRST_LOG_ERR 0x20 -#define SNS2_ENV_DATA_PRESENT 0x10 -#define SNS2_INPRECISE_END 0x04 +#include /** * struct ccw1 - channel command word diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h new file mode 100644 index 0000000..de389cb --- /dev/null +++ b/arch/s390/include/asm/scsw.h @@ -0,0 +1,956 @@ +/* + * Helper functions for scsw access. + * + * Copyright IBM Corp. 2008,2009 + * Author(s): Peter Oberparleiter + */ + +#ifndef _ASM_S390_SCSW_H_ +#define _ASM_S390_SCSW_H_ + +#include +#include +#include + +/** + * struct cmd_scsw - command-mode subchannel status word + * @key: subchannel key + * @sctl: suspend control + * @eswf: esw format + * @cc: deferred condition code + * @fmt: format + * @pfch: prefetch + * @isic: initial-status interruption control + * @alcc: address-limit checking control + * @ssi: suppress-suspended interruption + * @zcc: zero condition code + * @ectl: extended control + * @pno: path not operational + * @res: reserved + * @fctl: function control + * @actl: activity control + * @stctl: status control + * @cpa: channel program address + * @dstat: device status + * @cstat: subchannel status + * @count: residual count + */ +struct cmd_scsw { + __u32 key : 4; + __u32 sctl : 1; + __u32 eswf : 1; + __u32 cc : 2; + __u32 fmt : 1; + __u32 pfch : 1; + __u32 isic : 1; + __u32 alcc : 1; + __u32 ssi : 1; + __u32 zcc : 1; + __u32 ectl : 1; + __u32 pno : 1; + __u32 res : 1; + __u32 fctl : 3; + __u32 actl : 7; + __u32 stctl : 5; + __u32 cpa; + __u32 dstat : 8; + __u32 cstat : 8; + __u32 count : 16; +} __attribute__ ((packed)); + +/** + * struct tm_scsw - transport-mode subchannel status word + * @key: subchannel key + * @eswf: esw format + * @cc: deferred condition code + * @fmt: format + * @x: IRB-format control + * @q: interrogate-complete + * @ectl: extended control + * @pno: path not operational + * @fctl: function control + * @actl: activity control + * @stctl: status control + * @tcw: TCW address + * @dstat: device status + * @cstat: subchannel status + * @fcxs: FCX status + * @schxs: subchannel-extended status + */ +struct tm_scsw { + u32 key:4; + u32 :1; + u32 eswf:1; + u32 cc:2; + u32 fmt:3; + u32 x:1; + u32 q:1; + u32 :1; + u32 ectl:1; + u32 pno:1; + u32 :1; + u32 fctl:3; + u32 actl:7; + u32 stctl:5; + u32 tcw; + u32 dstat:8; + u32 cstat:8; + u32 fcxs:8; + u32 schxs:8; +} __attribute__ ((packed)); + +/** + * union scsw - subchannel status word + * @cmd: command-mode SCSW + * @tm: transport-mode SCSW + */ +union scsw { + struct cmd_scsw cmd; + struct tm_scsw tm; +} __attribute__ ((packed)); + +#define SCSW_FCTL_CLEAR_FUNC 0x1 +#define SCSW_FCTL_HALT_FUNC 0x2 +#define SCSW_FCTL_START_FUNC 0x4 + +#define SCSW_ACTL_SUSPENDED 0x1 +#define SCSW_ACTL_DEVACT 0x2 +#define SCSW_ACTL_SCHACT 0x4 +#define SCSW_ACTL_CLEAR_PEND 0x8 +#define SCSW_ACTL_HALT_PEND 0x10 +#define SCSW_ACTL_START_PEND 0x20 +#define SCSW_ACTL_RESUME_PEND 0x40 + +#define SCSW_STCTL_STATUS_PEND 0x1 +#define SCSW_STCTL_SEC_STATUS 0x2 +#define SCSW_STCTL_PRIM_STATUS 0x4 +#define SCSW_STCTL_INTER_STATUS 0x8 +#define SCSW_STCTL_ALERT_STATUS 0x10 + +#define DEV_STAT_ATTENTION 0x80 +#define DEV_STAT_STAT_MOD 0x40 +#define DEV_STAT_CU_END 0x20 +#define DEV_STAT_BUSY 0x10 +#define DEV_STAT_CHN_END 0x08 +#define DEV_STAT_DEV_END 0x04 +#define DEV_STAT_UNIT_CHECK 0x02 +#define DEV_STAT_UNIT_EXCEP 0x01 + +#define SCHN_STAT_PCI 0x80 +#define SCHN_STAT_INCORR_LEN 0x40 +#define SCHN_STAT_PROG_CHECK 0x20 +#define SCHN_STAT_PROT_CHECK 0x10 +#define SCHN_STAT_CHN_DATA_CHK 0x08 +#define SCHN_STAT_CHN_CTRL_CHK 0x04 +#define SCHN_STAT_INTF_CTRL_CHK 0x02 +#define SCHN_STAT_CHAIN_CHECK 0x01 + +/* + * architectured values for first sense byte + */ +#define SNS0_CMD_REJECT 0x80 +#define SNS_CMD_REJECT SNS0_CMD_REJEC +#define SNS0_INTERVENTION_REQ 0x40 +#define SNS0_BUS_OUT_CHECK 0x20 +#define SNS0_EQUIPMENT_CHECK 0x10 +#define SNS0_DATA_CHECK 0x08 +#define SNS0_OVERRUN 0x04 +#define SNS0_INCOMPL_DOMAIN 0x01 + +/* + * architectured values for second sense byte + */ +#define SNS1_PERM_ERR 0x80 +#define SNS1_INV_TRACK_FORMAT 0x40 +#define SNS1_EOC 0x20 +#define SNS1_MESSAGE_TO_OPER 0x10 +#define SNS1_NO_REC_FOUND 0x08 +#define SNS1_FILE_PROTECTED 0x04 +#define SNS1_WRITE_INHIBITED 0x02 +#define SNS1_INPRECISE_END 0x01 + +/* + * architectured values for third sense byte + */ +#define SNS2_REQ_INH_WRITE 0x80 +#define SNS2_CORRECTABLE 0x40 +#define SNS2_FIRST_LOG_ERR 0x20 +#define SNS2_ENV_DATA_PRESENT 0x10 +#define SNS2_INPRECISE_END 0x04 + +/** + * scsw_is_tm - check for transport mode scsw + * @scsw: pointer to scsw + * + * Return non-zero if the specified scsw is a transport mode scsw, zero + * otherwise. + */ +static inline int scsw_is_tm(union scsw *scsw) +{ + return css_general_characteristics.fcx && (scsw->tm.x == 1); +} + +/** + * scsw_key - return scsw key field + * @scsw: pointer to scsw + * + * Return the value of the key field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_key(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.key; + else + return scsw->cmd.key; +} + +/** + * scsw_eswf - return scsw eswf field + * @scsw: pointer to scsw + * + * Return the value of the eswf field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_eswf(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.eswf; + else + return scsw->cmd.eswf; +} + +/** + * scsw_cc - return scsw cc field + * @scsw: pointer to scsw + * + * Return the value of the cc field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_cc(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.cc; + else + return scsw->cmd.cc; +} + +/** + * scsw_ectl - return scsw ectl field + * @scsw: pointer to scsw + * + * Return the value of the ectl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_ectl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.ectl; + else + return scsw->cmd.ectl; +} + +/** + * scsw_pno - return scsw pno field + * @scsw: pointer to scsw + * + * Return the value of the pno field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_pno(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.pno; + else + return scsw->cmd.pno; +} + +/** + * scsw_fctl - return scsw fctl field + * @scsw: pointer to scsw + * + * Return the value of the fctl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_fctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.fctl; + else + return scsw->cmd.fctl; +} + +/** + * scsw_actl - return scsw actl field + * @scsw: pointer to scsw + * + * Return the value of the actl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_actl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.actl; + else + return scsw->cmd.actl; +} + +/** + * scsw_stctl - return scsw stctl field + * @scsw: pointer to scsw + * + * Return the value of the stctl field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_stctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.stctl; + else + return scsw->cmd.stctl; +} + +/** + * scsw_dstat - return scsw dstat field + * @scsw: pointer to scsw + * + * Return the value of the dstat field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_dstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.dstat; + else + return scsw->cmd.dstat; +} + +/** + * scsw_cstat - return scsw cstat field + * @scsw: pointer to scsw + * + * Return the value of the cstat field of the specified scsw, regardless of + * whether it is a transport mode or command mode scsw. + */ +static inline u32 scsw_cstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw->tm.cstat; + else + return scsw->cmd.cstat; +} + +/** + * scsw_cmd_is_valid_key - check key field validity + * @scsw: pointer to scsw + * + * Return non-zero if the key field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_key(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_cmd_is_valid_sctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_sctl(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_cmd_is_valid_eswf - check eswf field validity + * @scsw: pointer to scsw + * + * Return non-zero if the eswf field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_eswf(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); +} + +/** + * scsw_cmd_is_valid_cc - check cc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cc field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_cc(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && + (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); +} + +/** + * scsw_cmd_is_valid_fmt - check fmt field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fmt field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_fmt(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_cmd_is_valid_pfch - check pfch field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pfch field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_pfch(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_cmd_is_valid_isic - check isic field validity + * @scsw: pointer to scsw + * + * Return non-zero if the isic field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_isic(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_cmd_is_valid_alcc - check alcc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the alcc field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_alcc(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_cmd_is_valid_ssi - check ssi field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ssi field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_ssi(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_cmd_is_valid_zcc - check zcc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the zcc field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_zcc(union scsw *scsw) +{ + return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && + (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS); +} + +/** + * scsw_cmd_is_valid_ectl - check ectl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ectl field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_ectl(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + !(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS); +} + +/** + * scsw_cmd_is_valid_pno - check pno field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pno field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_pno(union scsw *scsw) +{ + return (scsw->cmd.fctl != 0) && + (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) || + ((scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->cmd.actl & SCSW_ACTL_SUSPENDED))); +} + +/** + * scsw_cmd_is_valid_fctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_fctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} + +/** + * scsw_cmd_is_valid_actl - check actl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the actl field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_actl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} + +/** + * scsw_cmd_is_valid_stctl - check stctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the stctl field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_stctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} + +/** + * scsw_cmd_is_valid_dstat - check dstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the dstat field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_dstat(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->cmd.cc != 3); +} + +/** + * scsw_cmd_is_valid_cstat - check cstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cstat field of the specified command mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_cmd_is_valid_cstat(union scsw *scsw) +{ + return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->cmd.cc != 3); +} + +/** + * scsw_tm_is_valid_key - check key field validity + * @scsw: pointer to scsw + * + * Return non-zero if the key field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_key(union scsw *scsw) +{ + return (scsw->tm.fctl & SCSW_FCTL_START_FUNC); +} + +/** + * scsw_tm_is_valid_eswf - check eswf field validity + * @scsw: pointer to scsw + * + * Return non-zero if the eswf field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_eswf(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); +} + +/** + * scsw_tm_is_valid_cc - check cc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cc field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_cc(union scsw *scsw) +{ + return (scsw->tm.fctl & SCSW_FCTL_START_FUNC) && + (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); +} + +/** + * scsw_tm_is_valid_fmt - check fmt field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fmt field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_fmt(union scsw *scsw) +{ + return 1; +} + +/** + * scsw_tm_is_valid_x - check x field validity + * @scsw: pointer to scsw + * + * Return non-zero if the x field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_x(union scsw *scsw) +{ + return 1; +} + +/** + * scsw_tm_is_valid_q - check q field validity + * @scsw: pointer to scsw + * + * Return non-zero if the q field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_q(union scsw *scsw) +{ + return 1; +} + +/** + * scsw_tm_is_valid_ectl - check ectl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ectl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_ectl(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + !(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS); +} + +/** + * scsw_tm_is_valid_pno - check pno field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pno field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_pno(union scsw *scsw) +{ + return (scsw->tm.fctl != 0) && + (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) || + ((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && + (scsw->tm.actl & SCSW_ACTL_SUSPENDED))); +} + +/** + * scsw_tm_is_valid_fctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_fctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} + +/** + * scsw_tm_is_valid_actl - check actl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the actl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_actl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} + +/** + * scsw_tm_is_valid_stctl - check stctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the stctl field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_stctl(union scsw *scsw) +{ + /* Only valid if pmcw.dnv == 1*/ + return 1; +} + +/** + * scsw_tm_is_valid_dstat - check dstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the dstat field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_dstat(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->tm.cc != 3); +} + +/** + * scsw_tm_is_valid_cstat - check cstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cstat field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_cstat(union scsw *scsw) +{ + return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && + (scsw->tm.cc != 3); +} + +/** + * scsw_tm_is_valid_fcxs - check fcxs field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fcxs field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_fcxs(union scsw *scsw) +{ + return 1; +} + +/** + * scsw_tm_is_valid_schxs - check schxs field validity + * @scsw: pointer to scsw + * + * Return non-zero if the schxs field of the specified transport mode scsw is + * valid, zero otherwise. + */ +static inline int scsw_tm_is_valid_schxs(union scsw *scsw) +{ + return (scsw->tm.cstat & (SCHN_STAT_PROG_CHECK | + SCHN_STAT_INTF_CTRL_CHK | + SCHN_STAT_PROT_CHECK | + SCHN_STAT_CHN_DATA_CHK)); +} + +/** + * scsw_is_valid_actl - check actl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the actl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_actl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_actl(scsw); + else + return scsw_cmd_is_valid_actl(scsw); +} + +/** + * scsw_is_valid_cc - check cc field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cc field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_cc(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_cc(scsw); + else + return scsw_cmd_is_valid_cc(scsw); +} + +/** + * scsw_is_valid_cstat - check cstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the cstat field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_cstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_cstat(scsw); + else + return scsw_cmd_is_valid_cstat(scsw); +} + +/** + * scsw_is_valid_dstat - check dstat field validity + * @scsw: pointer to scsw + * + * Return non-zero if the dstat field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_dstat(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_dstat(scsw); + else + return scsw_cmd_is_valid_dstat(scsw); +} + +/** + * scsw_is_valid_ectl - check ectl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the ectl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_ectl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_ectl(scsw); + else + return scsw_cmd_is_valid_ectl(scsw); +} + +/** + * scsw_is_valid_eswf - check eswf field validity + * @scsw: pointer to scsw + * + * Return non-zero if the eswf field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_eswf(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_eswf(scsw); + else + return scsw_cmd_is_valid_eswf(scsw); +} + +/** + * scsw_is_valid_fctl - check fctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the fctl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_fctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_fctl(scsw); + else + return scsw_cmd_is_valid_fctl(scsw); +} + +/** + * scsw_is_valid_key - check key field validity + * @scsw: pointer to scsw + * + * Return non-zero if the key field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_key(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_key(scsw); + else + return scsw_cmd_is_valid_key(scsw); +} + +/** + * scsw_is_valid_pno - check pno field validity + * @scsw: pointer to scsw + * + * Return non-zero if the pno field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_pno(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_pno(scsw); + else + return scsw_cmd_is_valid_pno(scsw); +} + +/** + * scsw_is_valid_stctl - check stctl field validity + * @scsw: pointer to scsw + * + * Return non-zero if the stctl field of the specified scsw is valid, + * regardless of whether it is a transport mode or command mode scsw. + * Return zero if the field does not contain a valid value. + */ +static inline int scsw_is_valid_stctl(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_valid_stctl(scsw); + else + return scsw_cmd_is_valid_stctl(scsw); +} + +/** + * scsw_cmd_is_solicited - check for solicited scsw + * @scsw: pointer to scsw + * + * Return non-zero if the command mode scsw indicates that the associated + * status condition is solicited, zero if it is unsolicited. + */ +static inline int scsw_cmd_is_solicited(union scsw *scsw) +{ + return (scsw->cmd.cc != 0) || (scsw->cmd.stctl != + (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); +} + +/** + * scsw_tm_is_solicited - check for solicited scsw + * @scsw: pointer to scsw + * + * Return non-zero if the transport mode scsw indicates that the associated + * status condition is solicited, zero if it is unsolicited. + */ +static inline int scsw_tm_is_solicited(union scsw *scsw) +{ + return (scsw->tm.cc != 0) || (scsw->tm.stctl != + (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); +} + +/** + * scsw_is_solicited - check for solicited scsw + * @scsw: pointer to scsw + * + * Return non-zero if the transport or command mode scsw indicates that the + * associated status condition is solicited, zero if it is unsolicited. + */ +static inline int scsw_is_solicited(union scsw *scsw) +{ + if (scsw_is_tm(scsw)) + return scsw_tm_is_solicited(scsw); + else + return scsw_cmd_is_solicited(scsw); +} + +#endif /* _ASM_S390_SCSW_H_ */ -- cgit v1.1 From 05e7ff7da78bad3edc1290ed86b4a37da72ced62 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:28:31 +0200 Subject: [S390] introduce get_clock_monotonic Introduce get_clock_monotonic() function which can be used to get a (fast) timestamp. Resolution is the same as for get_clock(). The only difference is that the timestamps are monotonic and don't jump backward or forward. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/timex.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index cc21e3e..24aa1cd 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -90,4 +90,18 @@ unsigned long long monotonic_clock(void); extern u64 sched_clock_base_cc; +/** + * get_clock_monotonic - returns current time in clock rate units + * + * The caller must ensure that preemption is disabled. + * The clock and sched_clock_base get changed via stop_machine. + * Therefore preemption must be disabled when calling this + * function, otherwise the returned value is not guaranteed to + * be monotonic. + */ +static inline unsigned long long get_clock_monotonic(void) +{ + return get_clock_xt() - sched_clock_base_cc; +} + #endif -- cgit v1.1 From 04efc3be767cfed0d348fd598eba8fe5f5bf5fe6 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:28:32 +0200 Subject: [S390] convert/optimize csum_fold() to C In the meantime gcc generates better code than the old inline assemblies do. Original inline assembly results in: lr %r1,%r2 sr %r3,%r3 lr %r2,%r1 srdl %r2,16 alr %r2,%r3 alr %r1,%r2 srl %r1,16 xilf %r1,65535 llghr %r2,%r1 br %r14 Out of the C code gcc generates this: rll %r1,%r2,16 ar %r1,%r2 srl %r1,16 xilf %r1,65535 llghr %r2,%r1 br %r14 In addition we don't have any static register allocations anymore and gcc is free to shuffle instructions around for better pipeline usage. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/checksum.h | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index d5a8e7c..6c00f68 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h @@ -78,28 +78,11 @@ csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) */ static inline __sum16 csum_fold(__wsum sum) { -#ifndef __s390x__ - register_pair rp; + u32 csum = (__force u32) sum; - asm volatile( - " slr %N1,%N1\n" /* %0 = H L */ - " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ - " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ - " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ - " alr %0,%1\n" /* %0 = H+L+C L+H */ - " srl %0,16\n" /* %0 = H+L+C */ - : "+&d" (sum), "=d" (rp) : : "cc"); -#else /* __s390x__ */ - asm volatile( - " sr 3,3\n" /* %0 = H*65536 + L */ - " lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */ - " srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */ - " alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */ - " alr %0,2\n" /* %0 = H+L+C L+H */ - " srl %0,16\n" /* %0 = H+L+C */ - : "+&d" (sum) : : "cc", "2", "3"); -#endif /* __s390x__ */ - return (__force __sum16) ~sum; + csum += (csum >> 16) + (csum << 16); + csum >>= 16; + return (__force __sum16) ~csum; } /* -- cgit v1.1 From 12751058515860ed43c8f874ebcb2097b323736a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:28:34 +0200 Subject: [S390] atomic ops: add effecient atomic64 support for 31 bit Use compare double and swap to implement efficient atomic64 ops for 31 bit. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/atomic.h | 164 +++++++++++++++++++++++++++++++---------- 1 file changed, 127 insertions(+), 37 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index c7d0abf..b491d5e 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -1,28 +1,20 @@ #ifndef __ARCH_S390_ATOMIC__ #define __ARCH_S390_ATOMIC__ -#include -#include - /* - * include/asm-s390/atomic.h + * Copyright 1999,2009 IBM Corp. + * Author(s): Martin Schwidefsky , + * Denis Joseph Barrow, + * Arnd Bergmann , * - * S390 version - * Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * Denis Joseph Barrow, - * Arnd Bergmann (arndb@de.ibm.com) - * - * Derived from "include/asm-i386/bitops.h" - * Copyright (C) 1992, Linus Torvalds + * Atomic operations that C can't guarantee us. + * Useful for resource counting etc. + * s390 uses 'Compare And Swap' for atomicity in SMP enviroment. * */ -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. - * S390 uses 'Compare And Swap' for atomicity in SMP enviroment - */ +#include +#include #define ATOMIC_INIT(i) { (i) } @@ -146,9 +138,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) #undef __CS_LOOP -#ifdef __s390x__ #define ATOMIC64_INIT(i) { (i) } +#ifdef CONFIG_64BIT + #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) #define __CSG_LOOP(ptr, op_val, op_string) ({ \ @@ -202,21 +195,11 @@ static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) { return __CSG_LOOP(v, i, "agr"); } -#define atomic64_add(_i, _v) atomic64_add_return(_i, _v) -#define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) -#define atomic64_inc(_v) atomic64_add_return(1, _v) -#define atomic64_inc_return(_v) atomic64_add_return(1, _v) -#define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v) { return __CSG_LOOP(v, i, "sgr"); } -#define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) -#define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) -#define atomic64_dec(_v) atomic64_sub_return(1, _v) -#define atomic64_dec_return(_v) atomic64_sub_return(1, _v) -#define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) { @@ -249,6 +232,111 @@ static __inline__ long long atomic64_cmpxchg(atomic64_t *v, return old; } +#undef __CSG_LOOP + +#else /* CONFIG_64BIT */ + +typedef struct { + long long counter; +} atomic64_t; + +static inline long long atomic64_read(const atomic64_t *v) +{ + register_pair rp; + + asm volatile( + " lm %0,%N0,0(%1)" + : "=&d" (rp) + : "a" (&v->counter), "m" (v->counter) + ); + return rp.pair; +} + +static inline void atomic64_set(atomic64_t *v, long long i) +{ + register_pair rp = {.pair = i}; + + asm volatile( + " stm %1,%N1,0(%2)" + : "=m" (v->counter) + : "d" (rp), "a" (&v->counter) + ); +} + +static inline long long atomic64_xchg(atomic64_t *v, long long new) +{ + register_pair rp_new = {.pair = new}; + register_pair rp_old; + + asm volatile( + " lm %0,%N0,0(%2)\n" + "0: cds %0,%3,0(%2)\n" + " jl 0b\n" + : "=&d" (rp_old), "+m" (v->counter) + : "a" (&v->counter), "d" (rp_new) + : "cc"); + return rp_old.pair; +} + +static inline long long atomic64_cmpxchg(atomic64_t *v, + long long old, long long new) +{ + register_pair rp_old = {.pair = old}; + register_pair rp_new = {.pair = new}; + + asm volatile( + " cds %0,%3,0(%2)" + : "+&d" (rp_old), "+m" (v->counter) + : "a" (&v->counter), "d" (rp_new) + : "cc"); + return rp_old.pair; +} + + +static inline long long atomic64_add_return(long long i, atomic64_t *v) +{ + long long old, new; + + do { + old = atomic64_read(v); + new = old + i; + } while (atomic64_cmpxchg(v, old, new) != old); + return new; +} + +static inline long long atomic64_sub_return(long long i, atomic64_t *v) +{ + long long old, new; + + do { + old = atomic64_read(v); + new = old - i; + } while (atomic64_cmpxchg(v, old, new) != old); + return new; +} + +static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v) +{ + long long old, new; + + do { + old = atomic64_read(v); + new = old | mask; + } while (atomic64_cmpxchg(v, old, new) != old); +} + +static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v) +{ + long long old, new; + + do { + old = atomic64_read(v); + new = old & mask; + } while (atomic64_cmpxchg(v, old, new) != old); +} + +#endif /* CONFIG_64BIT */ + static __inline__ int atomic64_add_unless(atomic64_t *v, long long a, long long u) { @@ -265,15 +353,17 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, return c != u; } -#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) - -#undef __CSG_LOOP - -#else /* __s390x__ */ - -#include - -#endif /* __s390x__ */ +#define atomic64_add(_i, _v) atomic64_add_return(_i, _v) +#define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) +#define atomic64_inc(_v) atomic64_add_return(1, _v) +#define atomic64_inc_return(_v) atomic64_add_return(1, _v) +#define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) +#define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) +#define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) +#define atomic64_dec(_v) atomic64_sub_return(1, _v) +#define atomic64_dec_return(_v) atomic64_sub_return(1, _v) +#define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) +#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) #define smp_mb__before_atomic_dec() smp_mb() #define smp_mb__after_atomic_dec() smp_mb() -- cgit v1.1 From bfe3349b516df011dcf6462b0fd748a6f5c2e8af Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:28:35 +0200 Subject: [S390] atomic ops: small cleanups Couple of coding style fixes, replace __inline__ with inline and remove #ifdef __KERNEL_- since the header file isn't exported. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/atomic.h | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index b491d5e..ae7c8f9 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -18,8 +18,6 @@ #define ATOMIC_INIT(i) { (i) } -#ifdef __KERNEL__ - #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) #define __CS_LOOP(ptr, op_val, op_string) ({ \ @@ -69,7 +67,7 @@ static inline void atomic_set(atomic_t *v, int i) barrier(); } -static __inline__ int atomic_add_return(int i, atomic_t * v) +static inline int atomic_add_return(int i, atomic_t *v) { return __CS_LOOP(v, i, "ar"); } @@ -79,7 +77,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) #define atomic_inc_return(_v) atomic_add_return(1, _v) #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) -static __inline__ int atomic_sub_return(int i, atomic_t * v) +static inline int atomic_sub_return(int i, atomic_t *v) { return __CS_LOOP(v, i, "sr"); } @@ -89,19 +87,19 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) #define atomic_dec_return(_v) atomic_sub_return(1, _v) #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) -static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v) +static inline void atomic_clear_mask(unsigned long mask, atomic_t *v) { - __CS_LOOP(v, ~mask, "nr"); + __CS_LOOP(v, ~mask, "nr"); } -static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) +static inline void atomic_set_mask(unsigned long mask, atomic_t *v) { - __CS_LOOP(v, mask, "or"); + __CS_LOOP(v, mask, "or"); } #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) +static inline int atomic_cmpxchg(atomic_t *v, int old, int new) { #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) asm volatile( @@ -119,7 +117,7 @@ static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) return old; } -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static inline int atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -155,7 +153,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) : "=&d" (old_val), "=&d" (new_val), \ "=Q" (((atomic_t *)(ptr))->counter) \ : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ - : "cc", "memory" ); \ + : "cc", "memory"); \ new_val; \ }) @@ -173,7 +171,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) "=m" (((atomic_t *)(ptr))->counter) \ : "a" (ptr), "d" (op_val), \ "m" (((atomic_t *)(ptr))->counter) \ - : "cc", "memory" ); \ + : "cc", "memory"); \ new_val; \ }) @@ -191,29 +189,29 @@ static inline void atomic64_set(atomic64_t *v, long long i) barrier(); } -static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) +static inline long long atomic64_add_return(long long i, atomic64_t *v) { return __CSG_LOOP(v, i, "agr"); } -static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v) +static inline long long atomic64_sub_return(long long i, atomic64_t *v) { return __CSG_LOOP(v, i, "sgr"); } -static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) +static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v) { - __CSG_LOOP(v, ~mask, "ngr"); + __CSG_LOOP(v, ~mask, "ngr"); } -static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) +static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v) { - __CSG_LOOP(v, mask, "ogr"); + __CSG_LOOP(v, mask, "ogr"); } #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -static __inline__ long long atomic64_cmpxchg(atomic64_t *v, +static inline long long atomic64_cmpxchg(atomic64_t *v, long long old, long long new) { #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) @@ -337,8 +335,7 @@ static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v) #endif /* CONFIG_64BIT */ -static __inline__ int atomic64_add_unless(atomic64_t *v, - long long a, long long u) +static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) { long long c, old; c = atomic64_read(v); @@ -371,5 +368,5 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, #define smp_mb__after_atomic_inc() smp_mb() #include -#endif /* __KERNEL__ */ + #endif /* __ARCH_S390_ATOMIC__ */ -- cgit v1.1 From 684d2fd48e718e70dad21ef7c528649578147e48 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Fri, 11 Sep 2009 10:28:40 +0200 Subject: [S390] kernel: Append scpdata to kernel boot command line Append scpdata to the kernel boot command line. If scpdata starts with the equal sign (=), the kernel boot command line is replaced. (For consistency with zIPL and IPL PARM parameters.) To use scpdata for the kernel boot command line, scpdata must consist of ascii characters only. If scpdata contains other characters, scpdata is not appended to the kernel boot command line. In addition, re-IPL is extended for setting scpdata for the next Linux reboot. Signed-off-by: Hendrik Brueckner Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ipl.h | 5 ++++- arch/s390/include/asm/setup.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 1171e6d..5e95d95 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -57,6 +57,8 @@ struct ipl_block_fcp { } __attribute__((packed)); #define DIAG308_VMPARM_SIZE 64 +#define DIAG308_SCPDATA_SIZE (PAGE_SIZE - (sizeof(struct ipl_list_hdr) + \ + offsetof(struct ipl_block_fcp, scp_data))) struct ipl_block_ccw { u8 load_parm[8]; @@ -91,7 +93,8 @@ extern void do_halt(void); extern void do_poff(void); extern void ipl_save_parameters(void); extern void ipl_update_parameters(void); -extern void get_ipl_vmparm(char *); +extern size_t append_ipl_vmparm(char *, size_t); +extern size_t append_ipl_scpdata(char *, size_t); enum { IPL_DEVNO_VALID = 1, diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 38b0fc2..e37478e 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -8,7 +8,7 @@ #ifndef _ASM_S390_SETUP_H #define _ASM_S390_SETUP_H -#define COMMAND_LINE_SIZE 1024 +#define COMMAND_LINE_SIZE 4096 #define ARCH_COMMAND_LINE_SIZE 896 -- cgit v1.1 From 275c340941991a925969c03ec6b900fd135d09dd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 11 Sep 2009 10:28:46 +0200 Subject: [S390] remove unused irq_cpustat_t defintion No need to defined a irq_cpustat_t type if __ARCH_IRQ_STAT is defined. Signed-off-by: Christoph Hellwig Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/hardirq.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index 89ec705..498bc38 100644 --- a/arch/s390/include/asm/hardirq.h +++ b/arch/s390/include/asm/hardirq.h @@ -18,13 +18,6 @@ #include #include -/* irq_cpustat_t is unused currently, but could be converted - * into a percpu variable instead of storing softirq_pending - * on the lowcore */ -typedef struct { - unsigned int __softirq_pending; -} irq_cpustat_t; - #define local_softirq_pending() (S390_lowcore.softirq_pending) #define __ARCH_IRQ_STAT -- cgit v1.1 From c4de0c1a18237c2727dde8ad392e333539b0af3c Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Fri, 11 Sep 2009 10:28:56 +0200 Subject: [S390] kvm: use console_initcall() to initialize s390 virtio console Use a console_initcall() to initialize the s390 virtio console and clean up s390 console initialization in setup.c. Signed-off-by: Hendrik Brueckner Tested-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/kvm_virtio.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h index 0503936..acdfdff 100644 --- a/arch/s390/include/asm/kvm_virtio.h +++ b/arch/s390/include/asm/kvm_virtio.h @@ -54,14 +54,4 @@ struct kvm_vqconfig { * This is pagesize for historical reasons. */ #define KVM_S390_VIRTIO_RING_ALIGN 4096 -#ifdef __KERNEL__ -/* early virtio console setup */ -#ifdef CONFIG_S390_GUEST -extern void s390_virtio_console_init(void); -#else -static inline void s390_virtio_console_init(void) -{ -} -#endif /* CONFIG_VIRTIO_CONSOLE */ -#endif /* __KERNEL__ */ #endif -- cgit v1.1 From 50aa98bad056a17655864a4d71ebc32d95c629a7 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 11 Sep 2009 10:28:57 +0200 Subject: [S390] fix recursive locking on page_table_lock Suzuki Poulose reported the following recursive locking bug on s390: Here is the stack trace : (see Appendix I for more info) [<0000000000406ed6>] _spin_lock+0x52/0x94 [<0000000000103bde>] crst_table_free+0x14e/0x1a4 [<00000000001ba684>] __pmd_alloc+0x114/0x1ec [<00000000001be8d0>] handle_mm_fault+0x2cc/0xb80 [<0000000000407d62>] do_dat_exception+0x2b6/0x3a0 [<0000000000114f8c>] sysc_return+0x0/0x8 [<00000200001642b2>] 0x200001642b2 The page_table_lock is already acquired in __pmd_alloc (mm/memory.c) and it tries to populate the pud/pgd with a new pmd allocated. If another thread populates it before we get a chance, we free the pmd using pmd_free(). On s390x, pmd_free(even pud_free ) is #defined to crst_table_free(), which acquires the page_table_lock to protect the crst_table index updates. Hence this ends up in a recursive locking of the page_table_lock. The solution suggested by Dave Hansen is to use a new spin lock in the mmu context to protect the access to the crst_list and the pgtable_list. Reported-by: Suzuki Poulose Cc: Dave Hansen Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/mmu.h | 1 + arch/s390/include/asm/pgalloc.h | 1 + 2 files changed, 2 insertions(+) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 3b59216..03be999 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h @@ -2,6 +2,7 @@ #define __MMU_H typedef struct { + spinlock_t list_lock; struct list_head crst_list; struct list_head pgtable_list; unsigned long asce_bits; diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index b2658b9..ddad590 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -140,6 +140,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) static inline pgd_t *pgd_alloc(struct mm_struct *mm) { + spin_lock_init(&mm->context.list_lock); INIT_LIST_HEAD(&mm->context.crst_list); INIT_LIST_HEAD(&mm->context.pgtable_list); return (pgd_t *) crst_table_alloc(mm, s390_noexec); -- cgit v1.1 From f64d04c042193183c6dad98944ae2861b998e8b7 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 11 Sep 2009 10:28:59 +0200 Subject: [S390] s390dbf: Add description for usage of "%s" in sprintf events Using "%s" in sprintf event functions is dangerous. This patch adds a short description for this issue to the s390 debug feature documentation. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/debug.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index 31ed568..18124b7 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h @@ -167,6 +167,10 @@ debug_text_event(debug_info_t* id, int level, const char* txt) return debug_event_common(id,level,txt,strlen(txt)); } +/* + * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are + * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! + */ extern debug_entry_t * debug_sprintf_event(debug_info_t* id,int level,char *string,...) __attribute__ ((format(printf, 3, 4))); @@ -206,7 +210,10 @@ debug_text_exception(debug_info_t* id, int level, const char* txt) return debug_exception_common(id,level,txt,strlen(txt)); } - +/* + * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are + * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! + */ extern debug_entry_t * debug_sprintf_exception(debug_info_t* id,int level,char *string,...) __attribute__ ((format(printf, 3, 4))); -- cgit v1.1 From 5dd1d2ece0250125fec2dcccbfb8ab9bb2ac020c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:29:00 +0200 Subject: [S390] use generic scatterlist.h Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/scatterlist.h | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h index 29ec8e2..35d786f 100644 --- a/arch/s390/include/asm/scatterlist.h +++ b/arch/s390/include/asm/scatterlist.h @@ -1,19 +1 @@ -#ifndef _ASMS390_SCATTERLIST_H -#define _ASMS390_SCATTERLIST_H - -struct scatterlist { -#ifdef CONFIG_DEBUG_SG - unsigned long sg_magic; -#endif - unsigned long page_link; - unsigned int offset; - unsigned int length; -}; - -#ifdef __s390x__ -#define ISA_DMA_THRESHOLD (0xffffffffffffffffUL) -#else -#define ISA_DMA_THRESHOLD (0xffffffffUL) -#endif - -#endif /* _ASMS390X_SCATTERLIST_H */ +#include -- cgit v1.1 From 2ddddf3e0a55a7fcd6f240a7416cfcb12dd38b7e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:29:01 +0200 Subject: [S390] Enable guest page hinting by default. Get rid of the PAGE_STATES config option and enable guest page hinting by default. It can be disabled by specifying "cmma=off" at the command line. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/page.h | 4 ---- arch/s390/include/asm/system.h | 4 ---- 2 files changed, 8 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 3e3594d..5e9daf5 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -125,8 +125,6 @@ page_get_storage_key(unsigned long addr) return skey; } -#ifdef CONFIG_PAGE_STATES - struct page; void arch_free_page(struct page *page, int order); void arch_alloc_page(struct page *page, int order); @@ -134,8 +132,6 @@ void arch_alloc_page(struct page *page, int order); #define HAVE_ARCH_FREE_PAGE #define HAVE_ARCH_ALLOC_PAGE -#endif - #endif /* !__ASSEMBLY__ */ #define __PAGE_OFFSET 0x0UL diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 4fb83c1..379661d 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h @@ -109,11 +109,7 @@ extern void pfault_fini(void); #define pfault_fini() do { } while (0) #endif /* CONFIG_PFAULT */ -#ifdef CONFIG_PAGE_STATES extern void cmma_init(void); -#else -static inline void cmma_init(void) { } -#endif #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ -- cgit v1.1 From 4bb5e07b68565d7983108993aa23eccf5f1b35fe Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:29:03 +0200 Subject: [S390] Limit cpu detection to 256 physical cpus. Saves us more than 65k pointless IPIs. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cpu.h | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 arch/s390/include/asm/cpu.h (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h new file mode 100644 index 0000000..702ad46 --- /dev/null +++ b/arch/s390/include/asm/cpu.h @@ -0,0 +1,6 @@ +#ifndef _ASM_S390_CPU_H +#define _ASM_S390_CPU_H + +#define MAX_CPU_ADDRESS 255 + +#endif /* _ASM_S390_CPU_H */ -- cgit v1.1 From e86a6ed63f46fe8fb555fda531084bca3ef62fd7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:29:04 +0200 Subject: [S390] Get rid of cpuid.h header file. Merge cpuid.h header file into cpu.h. While at it convert from typedef to struct declaration and also convert cio code to use proper lowcore structure instead of casts. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cpu.h | 20 ++++++++++++++++++++ arch/s390/include/asm/cpuid.h | 25 ------------------------- arch/s390/include/asm/kvm_host.h | 6 +++--- arch/s390/include/asm/lowcore.h | 6 +++--- arch/s390/include/asm/processor.h | 4 ++-- 5 files changed, 28 insertions(+), 33 deletions(-) delete mode 100644 arch/s390/include/asm/cpuid.h (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h index 702ad46..471234b 100644 --- a/arch/s390/include/asm/cpu.h +++ b/arch/s390/include/asm/cpu.h @@ -1,6 +1,26 @@ +/* + * Copyright IBM Corp. 2000,2009 + * Author(s): Hartmut Penner , + * Martin Schwidefsky , + * Christian Ehrhardt , + */ + #ifndef _ASM_S390_CPU_H #define _ASM_S390_CPU_H #define MAX_CPU_ADDRESS 255 +#ifndef __ASSEMBLY__ + +#include + +struct cpuid +{ + unsigned int version : 8; + unsigned int ident : 24; + unsigned int machine : 16; + unsigned int unused : 16; +} __packed; + +#endif /* __ASSEMBLY__ */ #endif /* _ASM_S390_CPU_H */ diff --git a/arch/s390/include/asm/cpuid.h b/arch/s390/include/asm/cpuid.h deleted file mode 100644 index 07836a2..0000000 --- a/arch/s390/include/asm/cpuid.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright IBM Corp. 2000,2009 - * Author(s): Hartmut Penner , - * Martin Schwidefsky - * Christian Ehrhardt - */ - -#ifndef _ASM_S390_CPUID_H_ -#define _ASM_S390_CPUID_H_ - -/* - * CPU type and hardware bug flags. Kept separately for each CPU. - * Members of this structure are referenced in head.S, so think twice - * before touching them. [mj] - */ - -typedef struct -{ - unsigned int version : 8; - unsigned int ident : 24; - unsigned int machine : 16; - unsigned int unused : 16; -} __attribute__ ((packed)) cpuid_t; - -#endif /* _ASM_S390_CPUID_H_ */ diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 1cd02f6..698988f 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #define KVM_MAX_VCPUS 64 #define KVM_MEMORY_SLOTS 32 @@ -217,8 +217,8 @@ struct kvm_vcpu_arch { struct hrtimer ckc_timer; struct tasklet_struct tasklet; union { - cpuid_t cpu_id; - u64 stidp_data; + struct cpuid cpu_id; + u64 stidp_data; }; }; diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 5046ad6..6bc9426 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -132,7 +132,7 @@ #ifndef __ASSEMBLY__ -#include +#include #include #include @@ -275,7 +275,7 @@ struct _lowcore __u32 user_exec_asce; /* 0x02ac */ /* SMP info area */ - cpuid_t cpu_id; /* 0x02b0 */ + struct cpuid cpu_id; /* 0x02b0 */ __u32 cpu_nr; /* 0x02b8 */ __u32 softirq_pending; /* 0x02bc */ __u32 percpu_offset; /* 0x02c0 */ @@ -380,7 +380,7 @@ struct _lowcore __u64 user_exec_asce; /* 0x0318 */ /* SMP info area */ - cpuid_t cpu_id; /* 0x0320 */ + struct cpuid cpu_id; /* 0x0320 */ __u32 cpu_nr; /* 0x0328 */ __u32 softirq_pending; /* 0x032c */ __u64 percpu_offset; /* 0x0330 */ diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index c139fa7..cf8eed3 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -14,7 +14,7 @@ #define __ASM_S390_PROCESSOR_H #include -#include +#include #include #include #include @@ -26,7 +26,7 @@ */ #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) -static inline void get_cpu_id(cpuid_t *ptr) +static inline void get_cpu_id(struct cpuid *ptr) { asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); } -- cgit v1.1 From 5c0b912e755caaad555eb6feefdb1124462d8f37 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 11 Sep 2009 10:29:05 +0200 Subject: [S390] Remove smp_cpu_not_running. smp_cpu_not_running() and cpu_stopped() are doing the same. Remove one and also get rid of the last hard_smp_processor_id() leftover. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/smp.h | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) (limited to 'arch/s390/include/asm') diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 72137bc..c991fe6 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -51,32 +51,7 @@ extern void machine_power_off_smp(void); #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ #define raw_smp_processor_id() (S390_lowcore.cpu_nr) - -/* - * returns 1 if cpu is in stopped/check stopped state or not operational - * returns 0 otherwise - */ -static inline int -smp_cpu_not_running(int cpu) -{ - __u32 status; - - switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { - case sigp_order_code_accepted: - case sigp_status_stored: - /* Check for stopped and check stop state */ - if (status & 0x50) - return 1; - break; - case sigp_not_operational: - return 1; - default: - break; - } - return 0; -} - -#define cpu_logical_map(cpu) (cpu) +#define cpu_logical_map(cpu) (cpu) extern int __cpu_disable (void); extern void __cpu_die (unsigned int cpu); @@ -91,11 +66,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask); #endif -#ifndef CONFIG_SMP -#define hard_smp_processor_id() 0 -#define smp_cpu_not_running(cpu) 1 -#endif - #ifdef CONFIG_HOTPLUG_CPU extern int smp_rescan_cpus(void); #else -- cgit v1.1