From 68dd13d6d58c145bbf6d295b8c430b4d38c943d9 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 27 Nov 2015 11:15:36 +0100 Subject: s390/sclp: move pci related commands to separate file sclp commands only used by the PCI code shouldn't be build for !CONFIG_PCI. Instead of adding more ifdefs to sclp_cmd.c just move them to a new file. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/char/Makefile | 2 ++ drivers/s390/char/sclp_cmd.c | 61 ----------------------------------- drivers/s390/char/sclp_pci.c | 76 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 61 deletions(-) create mode 100644 drivers/s390/char/sclp_pci.c (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index dd2f7c832e5e..41e28b23b26a 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -18,6 +18,8 @@ obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o +obj-$(CONFIG_PCI) += sclp_pci.o + obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o obj-$(CONFIG_VMCP) += vmcp.o diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index d3947ea3e351..e3fc7539116b 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -575,67 +575,6 @@ __initcall(sclp_detect_standby_memory); #endif /* CONFIG_MEMORY_HOTPLUG */ -/* - * PCI I/O adapter configuration related functions. - */ -#define SCLP_CMDW_CONFIGURE_PCI 0x001a0001 -#define SCLP_CMDW_DECONFIGURE_PCI 0x001b0001 - -#define SCLP_RECONFIG_PCI_ATPYE 2 - -struct pci_cfg_sccb { - struct sccb_header header; - u8 atype; /* adapter type */ - u8 reserved1; - u16 reserved2; - u32 aid; /* adapter identifier */ -} __packed; - -static int do_pci_configure(sclp_cmdw_t cmd, u32 fid) -{ - struct pci_cfg_sccb *sccb; - int rc; - - if (!SCLP_HAS_PCI_RECONFIG) - return -EOPNOTSUPP; - - sccb = (struct pci_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!sccb) - return -ENOMEM; - - sccb->header.length = PAGE_SIZE; - sccb->atype = SCLP_RECONFIG_PCI_ATPYE; - sccb->aid = fid; - rc = sclp_sync_request(cmd, sccb); - if (rc) - goto out; - switch (sccb->header.response_code) { - case 0x0020: - case 0x0120: - break; - default: - pr_warn("configure PCI I/O adapter failed: cmd=0x%08x response=0x%04x\n", - cmd, sccb->header.response_code); - rc = -EIO; - break; - } -out: - free_page((unsigned long) sccb); - return rc; -} - -int sclp_pci_configure(u32 fid) -{ - return do_pci_configure(SCLP_CMDW_CONFIGURE_PCI, fid); -} -EXPORT_SYMBOL(sclp_pci_configure); - -int sclp_pci_deconfigure(u32 fid) -{ - return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI, fid); -} -EXPORT_SYMBOL(sclp_pci_deconfigure); - /* * Channel path configuration related functions. */ diff --git a/drivers/s390/char/sclp_pci.c b/drivers/s390/char/sclp_pci.c new file mode 100644 index 000000000000..943e92539e65 --- /dev/null +++ b/drivers/s390/char/sclp_pci.c @@ -0,0 +1,76 @@ +/* + * PCI I/O adapter configuration related functions. + * + * Copyright IBM Corp. 2016 + */ +#define KMSG_COMPONENT "sclp_cmd" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include + +#include + +#include "sclp.h" + +#define SCLP_CMDW_CONFIGURE_PCI 0x001a0001 +#define SCLP_CMDW_DECONFIGURE_PCI 0x001b0001 + +#define SCLP_RECONFIG_PCI_ATPYE 2 + +struct pci_cfg_sccb { + struct sccb_header header; + u8 atype; /* adapter type */ + u8 reserved1; + u16 reserved2; + u32 aid; /* adapter identifier */ +} __packed; + +static int do_pci_configure(sclp_cmdw_t cmd, u32 fid) +{ + struct pci_cfg_sccb *sccb; + int rc; + + if (!SCLP_HAS_PCI_RECONFIG) + return -EOPNOTSUPP; + + sccb = (struct pci_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sccb) + return -ENOMEM; + + sccb->header.length = PAGE_SIZE; + sccb->atype = SCLP_RECONFIG_PCI_ATPYE; + sccb->aid = fid; + rc = sclp_sync_request(cmd, sccb); + if (rc) + goto out; + switch (sccb->header.response_code) { + case 0x0020: + case 0x0120: + break; + default: + pr_warn("configure PCI I/O adapter failed: cmd=0x%08x response=0x%04x\n", + cmd, sccb->header.response_code); + rc = -EIO; + break; + } +out: + free_page((unsigned long) sccb); + return rc; +} + +int sclp_pci_configure(u32 fid) +{ + return do_pci_configure(SCLP_CMDW_CONFIGURE_PCI, fid); +} +EXPORT_SYMBOL(sclp_pci_configure); + +int sclp_pci_deconfigure(u32 fid) +{ + return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI, fid); +} +EXPORT_SYMBOL(sclp_pci_deconfigure); -- cgit 1.4.1 From 12283a4035691697977083a5ac1e00ad5cfa6a3d Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 27 Nov 2015 11:18:02 +0100 Subject: s390/sclp: add error notification command Add SCLP event 24 "Adapter-error notification". Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sclp.h | 13 +++++ drivers/s390/char/sclp.h | 2 + drivers/s390/char/sclp_pci.c | 120 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 133 insertions(+), 2 deletions(-) (limited to 'drivers/s390/char') diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index bab456be9a4f..bd7893d274fa 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -72,6 +72,18 @@ struct sclp_info { }; extern struct sclp_info sclp; +struct zpci_report_error_header { + u8 version; /* Interface version byte */ + u8 action; /* Action qualifier byte + * 1: Deconfigure and repair action requested + * (OpenCrypto Problem Call Home) + * 2: Informational Report + * (OpenCrypto Successful Diagnostics Execution) + */ + u16 length; /* Length of Subsequent Data (up to 4K – SCLP header */ + u8 data[0]; /* Subsequent Data passed verbatim to SCLP ET 24 */ +} __packed; + int sclp_get_core_info(struct sclp_core_info *info); int sclp_core_configure(u8 core); int sclp_core_deconfigure(u8 core); @@ -83,6 +95,7 @@ int sclp_chp_read_info(struct sclp_chp_info *info); void sclp_get_ipl_info(struct sclp_ipl_info *info); int sclp_pci_configure(u32 fid); int sclp_pci_deconfigure(u32 fid); +int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid); int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count); int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count); void sclp_early_detect(void); diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index 026e38990952..6079efa95eaa 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -22,6 +22,7 @@ #define EVTYP_DIAG_TEST 0x07 #define EVTYP_STATECHANGE 0x08 #define EVTYP_PMSGCMD 0x09 +#define EVTYP_ERRNOTIFY 0x18 #define EVTYP_CNTLPROGOPCMD 0x20 #define EVTYP_CNTLPROGIDENT 0x0B #define EVTYP_SIGQUIESCE 0x1D @@ -36,6 +37,7 @@ #define EVTYP_DIAG_TEST_MASK 0x02000000 #define EVTYP_STATECHANGE_MASK 0x01000000 #define EVTYP_PMSGCMD_MASK 0x00800000 +#define EVTYP_ERRNOTIFY_MASK 0x00000100 #define EVTYP_CTLPROGOPCMD_MASK 0x00000001 #define EVTYP_CTLPROGIDENT_MASK 0x00200000 #define EVTYP_SIGQUIESCE_MASK 0x00000008 diff --git a/drivers/s390/char/sclp_pci.c b/drivers/s390/char/sclp_pci.c index 943e92539e65..0c8973c45b48 100644 --- a/drivers/s390/char/sclp_pci.c +++ b/drivers/s390/char/sclp_pci.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -20,7 +21,29 @@ #define SCLP_CMDW_CONFIGURE_PCI 0x001a0001 #define SCLP_CMDW_DECONFIGURE_PCI 0x001b0001 -#define SCLP_RECONFIG_PCI_ATPYE 2 +#define SCLP_ATYPE_PCI 2 + +#define SCLP_ERRNOTIFY_AQ_REPAIR 1 +#define SCLP_ERRNOTIFY_AQ_INFO_LOG 2 + +static DEFINE_MUTEX(sclp_pci_mutex); +static struct sclp_register sclp_pci_event = { + .send_mask = EVTYP_ERRNOTIFY_MASK, +}; + +struct err_notify_evbuf { + struct evbuf_header header; + u8 action; + u8 atype; + u32 fh; + u32 fid; + u8 data[0]; +} __packed; + +struct err_notify_sccb { + struct sccb_header header; + struct err_notify_evbuf evbuf; +} __packed; struct pci_cfg_sccb { struct sccb_header header; @@ -43,7 +66,7 @@ static int do_pci_configure(sclp_cmdw_t cmd, u32 fid) return -ENOMEM; sccb->header.length = PAGE_SIZE; - sccb->atype = SCLP_RECONFIG_PCI_ATPYE; + sccb->atype = SCLP_ATYPE_PCI; sccb->aid = fid; rc = sclp_sync_request(cmd, sccb); if (rc) @@ -74,3 +97,96 @@ int sclp_pci_deconfigure(u32 fid) return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI, fid); } EXPORT_SYMBOL(sclp_pci_deconfigure); + +static void sclp_pci_callback(struct sclp_req *req, void *data) +{ + struct completion *completion = data; + + complete(completion); +} + +static int sclp_pci_check_report(struct zpci_report_error_header *report) +{ + if (report->version != 1) + return -EINVAL; + + if (report->action != SCLP_ERRNOTIFY_AQ_REPAIR && + report->action != SCLP_ERRNOTIFY_AQ_INFO_LOG) + return -EINVAL; + + if (report->length > (PAGE_SIZE - sizeof(struct err_notify_sccb))) + return -EINVAL; + + return 0; +} + +int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid) +{ + DECLARE_COMPLETION_ONSTACK(completion); + struct err_notify_sccb *sccb; + struct sclp_req req = {0}; + int ret; + + ret = sclp_pci_check_report(report); + if (ret) + return ret; + + mutex_lock(&sclp_pci_mutex); + ret = sclp_register(&sclp_pci_event); + if (ret) + goto out_unlock; + + if (!(sclp_pci_event.sclp_receive_mask & EVTYP_ERRNOTIFY_MASK)) { + ret = -EOPNOTSUPP; + goto out_unregister; + } + + sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sccb) { + ret = -ENOMEM; + goto out_unregister; + } + + req.callback_data = &completion; + req.callback = sclp_pci_callback; + req.command = SCLP_CMDW_WRITE_EVENT_DATA; + req.status = SCLP_REQ_FILLED; + req.sccb = sccb; + + sccb->evbuf.header.length = sizeof(sccb->evbuf) + report->length; + sccb->evbuf.header.type = EVTYP_ERRNOTIFY; + sccb->header.length = sizeof(sccb->header) + sccb->evbuf.header.length; + + sccb->evbuf.action = report->action; + sccb->evbuf.atype = SCLP_ATYPE_PCI; + sccb->evbuf.fh = fh; + sccb->evbuf.fid = fid; + + memcpy(sccb->evbuf.data, report->data, report->length); + + ret = sclp_add_request(&req); + if (ret) + goto out_free_req; + + wait_for_completion(&completion); + if (req.status != SCLP_REQ_DONE) { + pr_warn("request failed (status=0x%02x)\n", + req.status); + ret = -EIO; + goto out_free_req; + } + + if (sccb->header.response_code != 0x0020) { + pr_warn("request failed with response code 0x%x\n", + sccb->header.response_code); + ret = -EIO; + } + +out_free_req: + free_page((unsigned long) sccb); +out_unregister: + sclp_unregister(&sclp_pci_event); +out_unlock: + mutex_unlock(&sclp_pci_mutex); + return ret; +} -- cgit 1.4.1 From 3fa7ee8844c31cb9c78992bb82cfaeb13375345d Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 27 Nov 2015 12:33:18 +0100 Subject: s390/sclp: event type macro cleanup Sort the sclp event type defines and use a macro to create the corresponding event type masks. In addition to that one unused type/mask pair is removed and another previously unused define is used now (it was probably unused/unknown because it didn't follow the EVTYP_X EVTYP_X_MASK convention). Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp.h | 38 +++++++++++++++++++------------------- drivers/s390/char/sclp_cpi_sys.c | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index 6079efa95eaa..7a10c56334bb 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -17,35 +17,35 @@ #define MAX_KMEM_PAGES (sizeof(unsigned long) << 3) #define SCLP_CONSOLE_PAGES 6 +#define SCLP_EVTYP_MASK(T) (1U << (32 - (T))) + #define EVTYP_OPCMD 0x01 #define EVTYP_MSG 0x02 +#define EVTYP_CONFMGMDATA 0x04 #define EVTYP_DIAG_TEST 0x07 #define EVTYP_STATECHANGE 0x08 #define EVTYP_PMSGCMD 0x09 +#define EVTYP_ASYNC 0x0A +#define EVTYP_CTLPROGIDENT 0x0B #define EVTYP_ERRNOTIFY 0x18 -#define EVTYP_CNTLPROGOPCMD 0x20 -#define EVTYP_CNTLPROGIDENT 0x0B -#define EVTYP_SIGQUIESCE 0x1D #define EVTYP_VT220MSG 0x1A -#define EVTYP_CONFMGMDATA 0x04 #define EVTYP_SDIAS 0x1C -#define EVTYP_ASYNC 0x0A +#define EVTYP_SIGQUIESCE 0x1D #define EVTYP_OCF 0x1E -#define EVTYP_OPCMD_MASK 0x80000000 -#define EVTYP_MSG_MASK 0x40000000 -#define EVTYP_DIAG_TEST_MASK 0x02000000 -#define EVTYP_STATECHANGE_MASK 0x01000000 -#define EVTYP_PMSGCMD_MASK 0x00800000 -#define EVTYP_ERRNOTIFY_MASK 0x00000100 -#define EVTYP_CTLPROGOPCMD_MASK 0x00000001 -#define EVTYP_CTLPROGIDENT_MASK 0x00200000 -#define EVTYP_SIGQUIESCE_MASK 0x00000008 -#define EVTYP_VT220MSG_MASK 0x00000040 -#define EVTYP_CONFMGMDATA_MASK 0x10000000 -#define EVTYP_SDIAS_MASK 0x00000010 -#define EVTYP_ASYNC_MASK 0x00400000 -#define EVTYP_OCF_MASK 0x00000004 +#define EVTYP_OPCMD_MASK SCLP_EVTYP_MASK(EVTYP_OPCMD) +#define EVTYP_MSG_MASK SCLP_EVTYP_MASK(EVTYP_MSG) +#define EVTYP_CONFMGMDATA_MASK SCLP_EVTYP_MASK(EVTYP_CONFMGMDATA) +#define EVTYP_DIAG_TEST_MASK SCLP_EVTYP_MASK(EVTYP_DIAG_TEST) +#define EVTYP_STATECHANGE_MASK SCLP_EVTYP_MASK(EVTYP_STATECHANGE) +#define EVTYP_PMSGCMD_MASK SCLP_EVTYP_MASK(EVTYP_PMSGCMD) +#define EVTYP_ASYNC_MASK SCLP_EVTYP_MASK(EVTYP_ASYNC) +#define EVTYP_CTLPROGIDENT_MASK SCLP_EVTYP_MASK(EVTYP_CTLPROGIDENT) +#define EVTYP_ERRNOTIFY_MASK SCLP_EVTYP_MASK(EVTYP_ERRNOTIFY) +#define EVTYP_VT220MSG_MASK SCLP_EVTYP_MASK(EVTYP_VT220MSG) +#define EVTYP_SDIAS_MASK SCLP_EVTYP_MASK(EVTYP_SDIAS) +#define EVTYP_SIGQUIESCE_MASK SCLP_EVTYP_MASK(EVTYP_SIGQUIESCE) +#define EVTYP_OCF_MASK SCLP_EVTYP_MASK(EVTYP_OCF) #define GNRLMSGFLGS_DOM 0x8000 #define GNRLMSGFLGS_SNDALRM 0x4000 diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index f344e5bd2d9f..90d92fbe7b9b 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -93,7 +93,7 @@ static struct sclp_req *cpi_prepare_req(void) /* setup SCCB for Control-Program Identification */ sccb->header.length = sizeof(struct cpi_sccb); sccb->cpi_evbuf.header.length = sizeof(struct cpi_evbuf); - sccb->cpi_evbuf.header.type = 0x0b; + sccb->cpi_evbuf.header.type = EVTYP_CTLPROGIDENT; evb = &sccb->cpi_evbuf; /* set system type */ -- cgit 1.4.1 From 99d00a2bd3c4f24ef90960a563f6f190e81e4ed3 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 18 Apr 2016 09:52:05 +0200 Subject: s390/sclp: avoid compile warning in sclp_pci_report Fix the initialization of a local variable to remove this warning: All warnings (new ones prefixed by >>): drivers/s390/char/sclp_pci.c: In function 'sclp_pci_report': >> drivers/s390/char/sclp_pci.c:127:9: warning: missing braces around initializer [-Wmissing-braces] struct sclp_req req = {0}; ^ drivers/s390/char/sclp_pci.c:127:9: warning: (near initialization for 'req.list') [-Wmissing-braces] Fixes: 12283a4035691697 "s390/sclp: add error notification command" Reported-by: kbuild test robot Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/sclp_pci.c b/drivers/s390/char/sclp_pci.c index 0c8973c45b48..4dbb3dfd4bc7 100644 --- a/drivers/s390/char/sclp_pci.c +++ b/drivers/s390/char/sclp_pci.c @@ -124,7 +124,7 @@ int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid) { DECLARE_COMPLETION_ONSTACK(completion); struct err_notify_sccb *sccb; - struct sclp_req req = {0}; + struct sclp_req req; int ret; ret = sclp_pci_check_report(report); @@ -147,6 +147,7 @@ int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid) goto out_unregister; } + memset(&req, 0, sizeof(req)); req.callback_data = &completion; req.callback = sclp_pci_callback; req.command = SCLP_CMDW_WRITE_EVENT_DATA; -- cgit 1.4.1 From 18900ca65a8553edc608b6c9d518eb31e6c09ba1 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 9 Apr 2016 17:06:48 -0700 Subject: tty: Replace TTY_IO_ERROR bit tests with tty_io_error() Abstract TTY_IO_ERROR status test treewide with tty_io_error(). NB: tty->flags uses atomic bit ops; replace non-atomic bit test with test_bit(). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- arch/ia64/hp/sim/simserial.c | 2 +- drivers/char/pcmcia/synclink_cs.c | 2 +- drivers/isdn/i4l/isdn_tty.c | 6 +++--- drivers/s390/char/tty3270.c | 4 ++-- drivers/staging/dgnc/dgnc_tty.c | 2 +- drivers/tty/amiserial.c | 6 +++--- drivers/tty/mxser.c | 7 +++---- drivers/tty/pty.c | 2 +- drivers/tty/serial/crisv10.c | 5 ++--- drivers/tty/serial/serial_core.c | 8 ++++---- drivers/tty/synclink.c | 4 ++-- drivers/tty/synclink_gt.c | 4 ++-- drivers/tty/synclinkmp.c | 4 ++-- drivers/tty/tty_io.c | 5 ++--- drivers/tty/tty_port.c | 2 +- include/linux/tty.h | 5 +++++ net/irda/ircomm/ircomm_tty.c | 2 +- net/irda/ircomm/ircomm_tty_ioctl.c | 6 +++--- 18 files changed, 39 insertions(+), 37 deletions(-) (limited to 'drivers/s390/char') diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index e70cadec7ce6..21fd50def270 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -300,7 +300,7 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 22c27652e46a..825db423b7a8 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -2246,7 +2246,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 947d5c978b8f..f1edc0814120 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1351,7 +1351,7 @@ isdn_tty_tiocmget(struct tty_struct *tty) if (isdn_tty_paranoia_check(info, tty->name, __func__)) return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; mutex_lock(&modem_info_mutex); @@ -1378,7 +1378,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, if (isdn_tty_paranoia_check(info, tty->name, __func__)) return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; #ifdef ISDN_DEBUG_MODEM_IOCTL @@ -1419,7 +1419,7 @@ isdn_tty_ioctl(struct tty_struct *tty, uint cmd, ulong arg) if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_ioctl")) return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index e96fc7fd9498..080a9872c68f 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1804,7 +1804,7 @@ static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd, tp = tty->driver_data; if (!tp) return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; return kbd_ioctl(tp->kbd, cmd, arg); } @@ -1818,7 +1818,7 @@ static long tty3270_compat_ioctl(struct tty_struct *tty, tp = tty->driver_data; if (!tp) return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg)); } diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index bcd2bdfb9c8f..5c221593a0c6 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -1255,7 +1255,7 @@ static int dgnc_block_til_ready(struct tty_struct *tty, if (file->f_flags & O_NONBLOCK) break; - if (tty->flags & (1 << TTY_IO_ERROR)) { + if (tty_io_error(tty)) { retval = -EIO; break; } diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index eacf4c9f3b29..183e98e84d09 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1143,7 +1143,7 @@ static int rs_tiocmget(struct tty_struct *tty) if (serial_paranoia_check(info, tty->name, "rs_ioctl")) return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; control = info->MCR; @@ -1165,7 +1165,7 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set, if (serial_paranoia_check(info, tty->name, "rs_ioctl")) return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; local_irq_save(flags); @@ -1250,7 +1250,7 @@ static int rs_ioctl(struct tty_struct *tty, if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 2f12bb9f4336..f23c2a101688 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1334,7 +1334,7 @@ static int mxser_tiocmget(struct tty_struct *tty) if (tty->index == MXSER_PORTS) return -ENOIOCTLCMD; - if (test_bit(TTY_IO_ERROR, &tty->flags)) + if (tty_io_error(tty)) return -EIO; control = info->MCR; @@ -1361,7 +1361,7 @@ static int mxser_tiocmset(struct tty_struct *tty, if (tty->index == MXSER_PORTS) return -ENOIOCTLCMD; - if (test_bit(TTY_IO_ERROR, &tty->flags)) + if (tty_io_error(tty)) return -EIO; spin_lock_irqsave(&info->slock, flags); @@ -1715,8 +1715,7 @@ static int mxser_ioctl(struct tty_struct *tty, return 0; } - if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && - test_bit(TTY_IO_ERROR, &tty->flags)) + if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && tty_io_error(tty)) return -EIO; switch (cmd) { diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 0058d9fbf931..a8a292fd564f 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -44,7 +44,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) if (tty->driver->subtype == PTY_TYPE_MASTER) WARN_ON(tty->count > 1); else { - if (test_bit(TTY_IO_ERROR, &tty->flags)) + if (tty_io_error(tty)) return; if (tty->count > 2) return; diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index c0172bf54a9b..546990334815 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3445,7 +3445,7 @@ rs_ioctl(struct tty_struct *tty, if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } @@ -3755,8 +3755,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, * If non-blocking mode is set, or the port is not enabled, * then make the check up front and then exit. */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { + if ((filp->f_flags & O_NONBLOCK) || tty_io_error(tty)) { info->port.flags |= ASYNC_NORMAL_ACTIVE; return 0; } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a126a603b083..67b395031347 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -969,7 +969,7 @@ static int uart_tiocmget(struct tty_struct *tty) int result = -EIO; mutex_lock(&port->mutex); - if (!(tty->flags & (1 << TTY_IO_ERROR))) { + if (!tty_io_error(tty)) { result = uport->mctrl; spin_lock_irq(&uport->lock); result |= uport->ops->get_mctrl(uport); @@ -989,7 +989,7 @@ uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) int ret = -EIO; mutex_lock(&port->mutex); - if (!(tty->flags & (1 << TTY_IO_ERROR))) { + if (!tty_io_error(tty)) { uart_update_mctrl(uport, set, clear); ret = 0; } @@ -1238,7 +1238,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, if (ret != -ENOIOCTLCMD) goto out; - if (tty->flags & (1 << TTY_IO_ERROR)) { + if (tty_io_error(tty)) { ret = -EIO; goto out; } @@ -1257,7 +1257,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, mutex_lock(&port->mutex); - if (tty->flags & (1 << TTY_IO_ERROR)) { + if (tty_io_error(tty)) { ret = -EIO; goto out_up; } diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index f5476e270734..8b2277223ee7 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -2972,7 +2972,7 @@ static int mgsl_ioctl(struct tty_struct *tty, if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } @@ -3270,7 +3270,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, printk("%s(%d):block_til_ready on %s\n", __FILE__,__LINE__, tty->driver->name ); - if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ + if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { /* nonblock mode is set or port is not enabled */ port->flags |= ASYNC_NORMAL_ACTIVE; return 0; diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index c0a2f5a1b1c2..1f7d6d9437e6 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -1032,7 +1032,7 @@ static int ioctl(struct tty_struct *tty, if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } @@ -3269,7 +3269,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, DBGINFO(("%s block_til_ready\n", tty->driver->name)); - if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ + if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { /* nonblock mode is set or port is not enabled */ port->flags |= ASYNC_NORMAL_ACTIVE; return 0; diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 90da0c712262..e93879944905 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -1261,7 +1261,7 @@ static int ioctl(struct tty_struct *tty, if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } @@ -3285,7 +3285,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, printk("%s(%d):%s block_til_ready()\n", __FILE__,__LINE__, tty->driver->name ); - if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ + if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { /* nonblock mode is set or port is not enabled */ /* just verify that callout device is not active */ port->flags |= ASYNC_NORMAL_ACTIVE; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 9b04d72e752e..320dc4da7162 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1070,7 +1070,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, if (tty_paranoia_check(tty, inode, "tty_read")) return -EIO; - if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) + if (!tty || tty_io_error(tty)) return -EIO; /* We want to wait for the line discipline to sort out in this @@ -1245,8 +1245,7 @@ static ssize_t tty_write(struct file *file, const char __user *buf, if (tty_paranoia_check(tty, file_inode(file), "tty_write")) return -EIO; - if (!tty || !tty->ops->write || - (test_bit(TTY_IO_ERROR, &tty->flags))) + if (!tty || !tty->ops->write || tty_io_error(tty)) return -EIO; /* Short term debug to catch buggy drivers */ if (tty->ops->write_room == NULL) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index dbcca30a54b1..9127c54b803e 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -364,7 +364,7 @@ int tty_port_block_til_ready(struct tty_port *port, /* if non-blocking mode is set we can pass directly to open unless the port has just hung up or is in another error state */ - if (tty->flags & (1 << TTY_IO_ERROR)) { + if (tty_io_error(tty)) { port->flags |= ASYNC_NORMAL_ACTIVE; return 0; } diff --git a/include/linux/tty.h b/include/linux/tty.h index 3b09f235db66..68d829bf93b8 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -360,6 +360,11 @@ static inline void tty_set_flow_change(struct tty_struct *tty, int val) smp_mb(); } +static inline bool tty_io_error(struct tty_struct *tty) +{ + return test_bit(TTY_IO_ERROR, &tty->flags); +} + #ifdef CONFIG_TTY extern void console_init(void); extern void tty_kref_put(struct tty_struct *tty); diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index da126ee6d218..840b82f760ba 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -280,7 +280,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, * If non-blocking mode is set, or the port is not enabled, * then make the check up front and then exit. */ - if (test_bit(TTY_IO_ERROR, &tty->flags)) { + if (tty_io_error(tty)) { port->flags |= ASYNC_NORMAL_ACTIVE; return 0; } diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index d3687aaa23de..9beb011441fa 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c @@ -190,7 +190,7 @@ int ircomm_tty_tiocmget(struct tty_struct *tty) struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; unsigned int result; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; result = ((self->settings.dte & IRCOMM_RTS) ? TIOCM_RTS : 0) @@ -213,7 +213,7 @@ int ircomm_tty_tiocmset(struct tty_struct *tty, { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; IRDA_ASSERT(self != NULL, return -1;); @@ -362,7 +362,7 @@ int ircomm_tty_ioctl(struct tty_struct *tty, if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) + if (tty_io_error(tty)) return -EIO; } -- cgit 1.4.1 From 80f02d5424301bf4df195d09b1a664f394435851 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 9 Apr 2016 17:53:24 -0700 Subject: tty: Replace ASYNC_SUSPENDED bit and update atomically Replace ASYNC_SUSPENDED bit in the tty_port::flags field with TTY_PORT_SUSPENDED bit in the tty_port::iflags field. Introduce helpers tty_port_set_suspended() and tty_port_suspended() to abstract atomic bit ops. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/con3215.c | 12 ++++++------ drivers/tty/serial/serial_core.c | 8 ++++---- include/linux/tty.h | 13 +++++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index e7e078b3c7e6..114fe2845270 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -289,7 +289,7 @@ static void raw3215_timeout(unsigned long __data) spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); raw->flags &= ~RAW3215_TIMER_RUNS; - if (!(raw->port.flags & ASYNC_SUSPENDED)) { + if (!tty_port_suspended(&raw->port)) { raw3215_mk_write_req(raw); raw3215_start_io(raw); if ((raw->queued_read || raw->queued_write) && @@ -312,7 +312,7 @@ static void raw3215_timeout(unsigned long __data) static inline void raw3215_try_io(struct raw3215_info *raw) { if (!(raw->port.flags & ASYNC_INITIALIZED) || - (raw->port.flags & ASYNC_SUSPENDED)) + tty_port_suspended(&raw->port)) return; if (raw->queued_read != NULL) raw3215_start_io(raw); @@ -494,7 +494,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length) /* While console is frozen for suspend we have no other * choice but to drop message from the buffer to make * room for even more messages. */ - if (raw->port.flags & ASYNC_SUSPENDED) { + if (tty_port_suspended(&raw->port)) { raw3215_drop_line(raw); continue; } @@ -773,7 +773,7 @@ static int raw3215_pm_stop(struct ccw_device *cdev) raw = dev_get_drvdata(&cdev->dev); spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); raw3215_make_room(raw, RAW3215_BUFFER_SIZE); - raw->port.flags |= ASYNC_SUSPENDED; + tty_port_set_suspended(&raw->port, 1); spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); return 0; } @@ -786,7 +786,7 @@ static int raw3215_pm_start(struct ccw_device *cdev) /* Allow I/O again and flush output buffer. */ raw = dev_get_drvdata(&cdev->dev); spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); - raw->port.flags &= ~ASYNC_SUSPENDED; + tty_port_set_suspended(&raw->port, 0); raw->flags |= RAW3215_FLUSHING; raw3215_try_io(raw); raw->flags &= ~RAW3215_FLUSHING; @@ -859,7 +859,7 @@ static void con3215_flush(void) unsigned long flags; raw = raw3215[0]; /* console 3215 is the first one */ - if (raw->port.flags & ASYNC_SUSPENDED) + if (tty_port_suspended(&raw->port)) /* The console is still frozen for suspend. */ if (ccw_device_force_console(raw->cdev)) /* Forcing didn't work, no panic message .. */ diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2471380fb92e..933606777f45 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -249,7 +249,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) * a DCD drop (hangup) at just the right time. Clear suspended bit so * we don't try to resume a port that has been shutdown. */ - clear_bit(ASYNCB_SUSPENDED, &port->flags); + tty_port_set_suspended(port, 0); /* * Free the transmit buffer page. @@ -2007,7 +2007,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) const struct uart_ops *ops = uport->ops; int tries; - set_bit(ASYNCB_SUSPENDED, &port->flags); + tty_port_set_suspended(port, 1); clear_bit(ASYNCB_INITIALIZED, &port->flags); spin_lock_irq(&uport->lock); @@ -2088,7 +2088,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) console_start(uport->cons); } - if (port->flags & ASYNC_SUSPENDED) { + if (tty_port_suspended(port)) { const struct uart_ops *ops = uport->ops; int ret; @@ -2118,7 +2118,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) } } - clear_bit(ASYNCB_SUSPENDED, &port->flags); + tty_port_set_suspended(port, 0); } mutex_unlock(&port->mutex); diff --git a/include/linux/tty.h b/include/linux/tty.h index 4254dfb12fb1..7ac5add66c00 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -597,6 +597,19 @@ static inline void tty_port_set_check_carrier(struct tty_port *port, bool val) clear_bit(TTY_PORT_CHECK_CD, &port->iflags); } +static inline bool tty_port_suspended(struct tty_port *port) +{ + return test_bit(TTY_PORT_SUSPENDED, &port->iflags); +} + +static inline void tty_port_set_suspended(struct tty_port *port, bool val) +{ + if (val) + set_bit(TTY_PORT_SUSPENDED, &port->iflags); + else + clear_bit(TTY_PORT_SUSPENDED, &port->iflags); +} + extern struct tty_struct *tty_port_tty_get(struct tty_port *port); extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); extern int tty_port_carrier_raised(struct tty_port *port); -- cgit 1.4.1 From d41861ca19c9e96f12a4f1ebbc8255d00909a232 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 9 Apr 2016 17:53:25 -0700 Subject: tty: Replace ASYNC_INITIALIZED bit and update atomically Replace ASYNC_INITIALIZED bit in the tty_port::flags field with TTY_PORT_INITIALIZED bit in the tty_port::iflags field. Introduce helpers tty_port_set_initialized() and tty_port_initialized() to abstract atomic bit ops. Note: the transforms for test_and_set_bit() and test_and_clear_bit() are unnecessary as the state transitions are already mutually exclusive; the tty lock prevents concurrent open/close/hangup. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- drivers/char/pcmcia/synclink_cs.c | 12 +++++----- drivers/ipack/devices/ipoctal.c | 5 ++--- drivers/isdn/i4l/isdn_tty.c | 10 ++++----- drivers/s390/char/con3215.c | 12 +++++----- drivers/tty/amiserial.c | 14 ++++++------ drivers/tty/cyclades.c | 14 ++++++------ drivers/tty/isicom.c | 6 ++--- drivers/tty/moxa.c | 10 ++++----- drivers/tty/mxser.c | 14 +++++------- drivers/tty/n_gsm.c | 8 +++---- drivers/tty/rocket.c | 10 ++++----- drivers/tty/serial/crisv10.c | 17 +++++++------- drivers/tty/serial/serial_core.c | 24 +++++++++++--------- drivers/tty/synclink.c | 46 ++++++++++++++++++-------------------- drivers/tty/synclink_gt.c | 16 ++++++------- drivers/tty/synclinkmp.c | 16 ++++++------- drivers/tty/tty_port.c | 13 ++++++----- drivers/usb/class/cdc-acm.c | 4 ++-- drivers/usb/serial/console.c | 4 ++-- drivers/usb/serial/generic.c | 6 ++--- drivers/usb/serial/mxuport.c | 6 ++--- drivers/usb/serial/sierra.c | 4 ++-- drivers/usb/serial/usb-serial.c | 2 +- drivers/usb/serial/usb_wwan.c | 4 ++-- include/linux/tty.h | 13 +++++++++++ net/irda/ircomm/ircomm_tty.c | 15 +++++++------ net/irda/ircomm/ircomm_tty_ioctl.c | 2 +- 27 files changed, 157 insertions(+), 150 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index bf54f4e23b6f..345ca7c7ea74 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -1272,7 +1272,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty) if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):startup(%s)\n", __FILE__, __LINE__, info->device_name); - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) return 0; if (!info->tx_buf) { @@ -1311,7 +1311,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty) if (tty) clear_bit(TTY_IO_ERROR, &tty->flags); - info->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 1); return 0; } @@ -1322,7 +1322,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) { unsigned long flags; - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) return; if (debug_level >= DEBUG_LEVEL_INFO) @@ -1361,7 +1361,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) if (tty) set_bit(TTY_IO_ERROR, &tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 0); } static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty) @@ -2338,7 +2338,7 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp) if (tty_port_close_start(port, tty, filp) == 0) goto cleanup; - if (port->flags & ASYNC_INITIALIZED) + if (tty_port_initialized(port)) mgslpc_wait_until_sent(tty, info->timeout); mgslpc_flush_buffer(tty); @@ -2371,7 +2371,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_wait_until_sent")) return; - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) goto exit; orig_jiffies = jiffies; diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 035d5449227e..75dd15d66df6 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -629,8 +629,7 @@ static void ipoctal_hangup(struct tty_struct *tty) tty_port_hangup(&channel->tty_port); ipoctal_reset_channel(channel); - - clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); + tty_port_set_initialized(&channel->tty_port, 0); wake_up_interruptible(&channel->tty_port.open_wait); } @@ -642,7 +641,7 @@ static void ipoctal_shutdown(struct tty_struct *tty) return; ipoctal_reset_channel(channel); - clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); + tty_port_set_initialized(&channel->tty_port, 0); } static void ipoctal_cleanup(struct tty_struct *tty) diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 023a350a8cd8..63eaa0a9f8a1 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1049,7 +1049,7 @@ isdn_tty_change_speed(modem_info *info) static int isdn_tty_startup(modem_info *info) { - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) return 0; isdn_lock_drivers(); #ifdef ISDN_DEBUG_MODEM_OPEN @@ -1066,7 +1066,7 @@ isdn_tty_startup(modem_info *info) */ isdn_tty_change_speed(info); - info->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 1); info->msr |= (UART_MSR_DSR | UART_MSR_CTS); info->send_outstanding = 0; return 0; @@ -1079,7 +1079,7 @@ isdn_tty_startup(modem_info *info) static void isdn_tty_shutdown(modem_info *info) { - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) return; #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line); @@ -1099,7 +1099,7 @@ isdn_tty_shutdown(modem_info *info) if (info->port.tty) set_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 0); } /* isdn_tty_write() is the main send-routine. It is called from the upper @@ -1577,7 +1577,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) * interrupt driver to stop checking the data ready bit in the * line status register. */ - if (port->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(port)) { tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ /* * Before we drop DTR, make sure the UART transmitter diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 114fe2845270..931d10e86837 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -311,8 +311,7 @@ static void raw3215_timeout(unsigned long __data) */ static inline void raw3215_try_io(struct raw3215_info *raw) { - if (!(raw->port.flags & ASYNC_INITIALIZED) || - tty_port_suspended(&raw->port)) + if (!tty_port_initialized(&raw->port) || tty_port_suspended(&raw->port)) return; if (raw->queued_read != NULL) raw3215_start_io(raw); @@ -616,10 +615,10 @@ static int raw3215_startup(struct raw3215_info *raw) { unsigned long flags; - if (raw->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&raw->port)) return 0; raw->line_pos = 0; - raw->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&raw->port, 1); spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); raw3215_try_io(raw); spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); @@ -635,8 +634,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) DECLARE_WAITQUEUE(wait, current); unsigned long flags; - if (!(raw->port.flags & ASYNC_INITIALIZED) || - (raw->flags & RAW3215_FIXED)) + if (!tty_port_initialized(&raw->port) || (raw->flags & RAW3215_FIXED)) return; /* Wait for outstanding requests, then free irq */ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); @@ -650,7 +648,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); remove_wait_queue(&raw->empty_wait, &wait); set_current_state(TASK_RUNNING); - raw->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&raw->port, 1); } spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); } diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index b4ab97d56351..208f573495dc 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -525,7 +525,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info) local_irq_save(flags); - if (port->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(port)) { free_page(page); goto errout; } @@ -586,7 +586,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info) */ change_speed(tty, info, NULL); - port->flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(port, 1); local_irq_restore(flags); return 0; @@ -604,7 +604,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) unsigned long flags; struct serial_state *state; - if (!(info->tport.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->tport)) return; state = info; @@ -645,7 +645,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) set_bit(TTY_IO_ERROR, &tty->flags); - info->tport.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->tport, 0); local_irq_restore(flags); } @@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; check_and_exit: - if (port->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(port)) { if (change_spd) { if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) tty->alt_speed = 57600; @@ -1390,7 +1390,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) * line status register. */ state->read_status_mask &= ~UART_LSR_DR; - if (port->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(port)) { /* disable receive interrupts */ custom.intena = IF_RBF; mb(); @@ -1538,7 +1538,7 @@ static inline void line_info(struct seq_file *m, int line, local_irq_save(flags); status = ciab.pra; - control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status; + control = tty_port_initialized(&state->tport) ? state->MCR : status; local_irq_restore(flags); stat_buf[0] = 0; diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 9d1e19ba25cb..3840d6b421c4 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -1279,7 +1279,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) spin_lock_irqsave(&card->card_lock, flags); - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) goto errout; if (!info->type) { @@ -1364,7 +1364,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) /* enable send, recv, modem !!! */ } - info->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 1); clear_bit(TTY_IO_ERROR, &tty->flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; @@ -1424,7 +1424,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) struct cyclades_card *card; unsigned long flags; - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) return; card = info->card; @@ -1448,7 +1448,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) some later date (after testing)!!! */ set_bit(TTY_IO_ERROR, &tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 0); spin_unlock_irqrestore(&card->card_lock, flags); } else { #ifdef CY_DEBUG_OPEN @@ -1473,7 +1473,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) tty_port_lower_dtr_rts(&info->port); set_bit(TTY_IO_ERROR, &tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 0); spin_unlock_irqrestore(&card->card_lock, flags); } @@ -1711,7 +1711,7 @@ static void cy_do_close(struct tty_port *port) /* Stop accepting input */ cyy_writeb(info, CyCAR, channel & 0x03); cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData); - if (info->port.flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(&info->port)) { /* Waiting for on-board buffers to be empty before closing the port */ spin_unlock_irqrestore(&card->card_lock, flags); @@ -2334,7 +2334,7 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, info->port.closing_wait = new_serial.closing_wait * HZ / 100; check_and_exit: - if (info->port.flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(&info->port)) { cy_set_line_char(info, tty); ret = 0; } else { diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 0b2bae1b2d55..b70187b46d9d 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -438,8 +438,8 @@ static void isicom_tx(unsigned long _data) for (; count > 0; count--, port++) { /* port not active or tx disabled to force flow control */ - if (!(port->port.flags & ASYNC_INITIALIZED) || - !(port->status & ISI_TXOK)) + if (!tty_port_initialized(&port->port) || + !(port->status & ISI_TXOK)) continue; txcount = min_t(short, TX_SIZE, port->xmit_cnt); @@ -553,7 +553,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } port = card->ports + channel; - if (!(port->port.flags & ASYNC_INITIALIZED)) { + if (!tty_port_initialized(&port->port)) { outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); return IRQ_HANDLED; diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index ce521d3f58cb..60d37b225589 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -912,7 +912,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) /* pci hot-un-plug support */ for (a = 0; a < brd->numPorts; a++) - if (brd->ports[a].port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&brd->ports[a].port)) tty_port_tty_hangup(&brd->ports[a].port, false); for (a = 0; a < MAX_PORTS_PER_BOARD; a++) @@ -921,7 +921,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) while (1) { opened = 0; for (a = 0; a < brd->numPorts; a++) - if (brd->ports[a].port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&brd->ports[a].port)) opened++; mutex_unlock(&moxa_openlock); if (!opened) @@ -1192,13 +1192,13 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) tty->driver_data = ch; tty_port_tty_set(&ch->port, tty); mutex_lock(&ch->port.mutex); - if (!(ch->port.flags & ASYNC_INITIALIZED)) { + if (!tty_port_initialized(&ch->port)) { ch->statusflags = 0; moxa_set_tty_param(tty, &tty->termios); MoxaPortLineCtrl(ch, 1, 1); MoxaPortEnable(ch); MoxaSetFifo(ch, ch->type == PORT_16550A); - ch->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&ch->port, 1); } mutex_unlock(&ch->port.mutex); mutex_unlock(&moxa_openlock); @@ -1379,7 +1379,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, { struct tty_struct *tty = tty_port_tty_get(&p->port); void __iomem *ofsAddr; - unsigned int inited = p->port.flags & ASYNC_INITIALIZED; + unsigned int inited = tty_port_initialized(&p->port); u16 intr; if (tty) { diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index ab618ef3d171..7e8c27bf1ac8 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1081,12 +1081,10 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) mutex_lock(&port->mutex); mxser_close_port(port); mxser_flush_buffer(tty); - if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { - if (C_HUPCL(tty)) - tty_port_lower_dtr_rts(port); - } + if (tty_port_initialized(port) && C_HUPCL(tty)) + tty_port_lower_dtr_rts(port); mxser_shutdown_port(port); - clear_bit(ASYNCB_INITIALIZED, &port->flags); + tty_port_set_initialized(port, 0); mutex_unlock(&port->mutex); info->closing = 0; /* Right now the tty_port set is done outside of the close_end helper @@ -1282,7 +1280,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, process_txrx_fifo(info); - if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (tty_port_initialized(port)) { if (flags != (port->flags & ASYNC_SPD_MASK)) { spin_lock_irqsave(&info->slock, sl_flags); mxser_change_speed(tty, NULL); @@ -1291,7 +1289,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, } else { retval = mxser_activate(port, tty); if (retval == 0) - set_bit(ASYNCB_INITIALIZED, &port->flags); + tty_port_set_initialized(port, 1); } return retval; } @@ -2251,7 +2249,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) iir &= MOXA_MUST_IIR_MASK; tty = tty_port_tty_get(&port->port); if (!tty || port->closing || - !(port->port.flags & ASYNC_INITIALIZED)) { + !tty_port_initialized(&port->port)) { status = inb(port->ioaddr + UART_LSR); outb(0x27, port->ioaddr + UART_FCR); inb(port->ioaddr + UART_MSR); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 365dfd8bc42b..9f7a7bbff57d 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2949,7 +2949,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) dlci->modem_rx = 0; /* We could in theory open and close before we wait - eg if we get a DM straight back. This is ok as that will have caused a hangup */ - set_bit(ASYNCB_INITIALIZED, &port->flags); + tty_port_set_initialized(port, 1); /* Start sending off SABM messages */ gsm_dlci_begin_open(dlci); /* And wait for virtual carrier */ @@ -2972,10 +2972,8 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) if (tty_port_close_start(&dlci->port, tty, filp) == 0) return; gsm_dlci_begin_close(dlci); - if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) { - if (C_HUPCL(tty)) - tty_port_lower_dtr_rts(&dlci->port); - } + if (tty_port_initialized(&dlci->port) && C_HUPCL(tty)) + tty_port_lower_dtr_rts(&dlci->port); tty_port_close_end(&dlci->port, tty); tty_port_tty_set(&dlci->port, NULL); return; diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index eb8311b20782..7f3b1db88061 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -495,7 +495,7 @@ static void rp_handle_port(struct r_port *info) if (!info) return; - if ((info->port.flags & ASYNC_INITIALIZED) == 0) { + if (!tty_port_initialized(&info->port)) { printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " "info->flags & NOT_INIT\n"); return; @@ -920,7 +920,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) /* * Info->count is now 1; so it's safe to sleep now. */ - if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (!tty_port_initialized(port)) { cp = &info->channel; sSetRxTrigger(cp, TRIG_1); if (sGetChanStatus(cp) & CD_ACT) @@ -944,7 +944,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) sEnRxFIFO(cp); sEnTransmit(cp); - set_bit(ASYNCB_INITIALIZED, &info->port.flags); + tty_port_set_initialized(&info->port, 1); /* * Set up the tty->alt_speed kludge @@ -1042,9 +1042,9 @@ static void rp_close(struct tty_struct *tty, struct file *filp) } } spin_lock_irq(&port->lock); - port->flags &= ~ASYNC_INITIALIZED; tty->closing = 0; spin_unlock_irq(&port->lock); + tty_port_set_initialized(port, 0); tty_port_set_active(port, 0); mutex_unlock(&port->mutex); tty_port_tty_set(port, NULL); @@ -1513,7 +1513,7 @@ static void rp_hangup(struct tty_struct *tty) sDisCTSFlowCtl(cp); sDisTxSoftFlowCtl(cp); sClrTxXOFF(cp); - clear_bit(ASYNCB_INITIALIZED, &info->port.flags); + tty_port_set_initialized(&info->port, 0); wake_up_interruptible(&info->port.open_wait); } diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 92c8c628e00e..315c84979b18 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -2599,7 +2599,7 @@ startup(struct e100_serial * info) /* if it was already initialized, skip this */ - if (info->port.flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(&info->port)) { local_irq_restore(flags); free_page(xmit_page); return 0; @@ -2703,7 +2703,7 @@ startup(struct e100_serial * info) e100_rts(info, 1); e100_dtr(info, 1); - info->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 1); local_irq_restore(flags); return 0; @@ -2745,7 +2745,7 @@ shutdown(struct e100_serial * info) info->tr_running = 0; } - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) return; #ifdef SERIAL_DEBUG_OPEN @@ -2776,7 +2776,7 @@ shutdown(struct e100_serial * info) if (info->port.tty) set_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 0); local_irq_restore(flags); } @@ -3273,9 +3273,9 @@ set_serial_info(struct e100_serial *info, info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; check_and_exit: - if (info->port.flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(&info->port)) change_speed(info); - } else + else retval = startup(info); return retval; } @@ -3628,7 +3628,7 @@ rs_close(struct tty_struct *tty, struct file * filp) e100_disable_rx(info); e100_disable_rx_irq(info); - if (info->port.flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(&info->port)) { /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially @@ -3787,8 +3787,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, e100_dtr(info, 1); local_irq_restore(flags); set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->port.flags & ASYNC_INITIALIZED)) { + if (tty_hung_up_p(filp) || !tty_port_initialized(&info->port)) { #ifdef SERIAL_DO_RESTART if (info->port.flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 933606777f45..0c48051db172 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -196,7 +196,7 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, struct tty_port *port = &state->port; int retval; - if (port->flags & ASYNC_INITIALIZED) + if (tty_port_initialized(port)) return 0; /* @@ -207,7 +207,7 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, retval = uart_port_startup(tty, state, init_hw); if (!retval) { - set_bit(ASYNCB_INITIALIZED, &port->flags); + tty_port_set_initialized(port, 1); clear_bit(TTY_IO_ERROR, &tty->flags); } else if (retval > 0) retval = 0; @@ -231,7 +231,9 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) if (tty) set_bit(TTY_IO_ERROR, &tty->flags); - if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (tty_port_initialized(port)) { + tty_port_set_initialized(port, 0); + /* * Turn off DTR and RTS early. */ @@ -886,7 +888,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, retval = 0; if (uport->type == PORT_UNKNOWN) goto exit; - if (port->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(port)) { if (((old_flags ^ uport->flags) & UPF_SPD_MASK) || old_custom_divisor != uport->custom_divisor) { /* @@ -1390,7 +1392,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) * At this point, we stop accepting input. To do this, we * disable the receive line status interrupts. */ - if (port->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(port)) { spin_lock_irq(&uport->lock); uport->ops->stop_rx(uport); spin_unlock_irq(&uport->lock); @@ -2003,12 +2005,12 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) uport->suspended = 1; - if (port->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(port)) { const struct uart_ops *ops = uport->ops; int tries; tty_port_set_suspended(port, 1); - clear_bit(ASYNCB_INITIALIZED, &port->flags); + tty_port_set_initialized(port, 0); spin_lock_irq(&uport->lock); ops->stop_tx(uport); @@ -2107,7 +2109,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) ops->set_mctrl(uport, uport->mctrl); ops->start_tx(uport); spin_unlock_irq(&uport->lock); - set_bit(ASYNCB_INITIALIZED, &port->flags); + tty_port_set_initialized(port, 1); } else { /* * Failed to resume - maybe hardware went away? @@ -2248,10 +2250,10 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) ret = 0; mutex_lock(&tport->mutex); /* - * We don't set ASYNCB_INITIALIZED as we only initialized the - * hw, e.g. state->xmit is still uninitialized. + * We don't set initialized as we only initialized the hw, + * e.g. state->xmit is still uninitialized. */ - if (!test_bit(ASYNCB_INITIALIZED, &tport->flags)) + if (!tty_port_initialized(tport)) ret = port->ops->poll_init(port); mutex_unlock(&tport->mutex); if (ret) diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index b67b54a800bb..bc4bc1ff775e 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -1749,13 +1749,13 @@ static irqreturn_t mgsl_interrupt(int dummy, void *dev_id) static int startup(struct mgsl_struct * info) { int retval = 0; - + if ( debug_level >= DEBUG_LEVEL_INFO ) printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name); - - if (info->port.flags & ASYNC_INITIALIZED) + + if (tty_port_initialized(&info->port)) return 0; - + if (!info->xmit_buf) { /* allocate a page of memory for a transmit buffer */ info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); @@ -1788,14 +1788,13 @@ static int startup(struct mgsl_struct * info) /* program hardware for current parameters */ mgsl_change_params(info); - + if (info->port.tty) clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags |= ASYNC_INITIALIZED; - + tty_port_set_initialized(&info->port, 1); + return 0; - } /* end of startup() */ /* shutdown() @@ -1808,8 +1807,8 @@ static int startup(struct mgsl_struct * info) static void shutdown(struct mgsl_struct * info) { unsigned long flags; - - if (!(info->port.flags & ASYNC_INITIALIZED)) + + if (!tty_port_initialized(&info->port)) return; if (debug_level >= DEBUG_LEVEL_INFO) @@ -1853,13 +1852,12 @@ static void shutdown(struct mgsl_struct * info) spin_unlock_irqrestore(&info->irq_spinlock,flags); - mgsl_release_resources(info); - + mgsl_release_resources(info); + if (info->port.tty) set_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; - + tty_port_set_initialized(&info->port, 0); } /* end of shutdown() */ static void mgsl_program_hw(struct mgsl_struct *info) @@ -3084,7 +3082,7 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp) goto cleanup; mutex_lock(&info->port.mutex); - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) mgsl_wait_until_sent(tty, info->timeout); mgsl_flush_buffer(tty); tty_ldisc_flush(tty); @@ -3122,15 +3120,15 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgsl_wait_until_sent(%s) entry\n", __FILE__,__LINE__, info->device_name ); - + if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent")) return; - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) goto exit; - + orig_jiffies = jiffies; - + /* Set check interval to 1/5 of estimated time to * send a character, and make it at least 1. The check * interval should also be less than the timeout. @@ -3290,14 +3288,14 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, port->count--; spin_unlock_irqrestore(&info->irq_spinlock, flags); port->blocked_open++; - + while (1) { - if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) + if (C_BAUD(tty) && tty_port_initialized(port)) tty_port_raise_dtr_rts(port); - + set_current_state(TASK_INTERRUPTIBLE); - - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ + + if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { retval = (port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS; break; diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 333652a8896a..82c98b820335 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -726,7 +726,7 @@ static void close(struct tty_struct *tty, struct file *filp) goto cleanup; mutex_lock(&info->port.mutex); - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) wait_until_sent(tty, info->timeout); flush_buffer(tty); tty_ldisc_flush(tty); @@ -893,7 +893,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) if (sanity_check(info, tty->name, "wait_until_sent")) return; DBGINFO(("%s wait_until_sent entry\n", info->device_name)); - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) goto exit; orig_jiffies = jiffies; @@ -2421,7 +2421,7 @@ static int startup(struct slgt_info *info) { DBGINFO(("%s startup\n", info->device_name)); - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) return 0; if (!info->tx_buf) { @@ -2442,7 +2442,7 @@ static int startup(struct slgt_info *info) if (info->port.tty) clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 1); return 0; } @@ -2454,7 +2454,7 @@ static void shutdown(struct slgt_info *info) { unsigned long flags; - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) return; DBGINFO(("%s shutdown\n", info->device_name)); @@ -2489,7 +2489,7 @@ static void shutdown(struct slgt_info *info) if (info->port.tty) set_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 0); } static void program_hw(struct slgt_info *info) @@ -3287,12 +3287,12 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, port->blocked_open++; while (1) { - if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) + if (C_BAUD(tty) && tty_port_initialized(port)) tty_port_raise_dtr_rts(port); set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ + if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { retval = (port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS; break; diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 17bab5f5b858..6dcfc2089373 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -812,7 +812,7 @@ static void close(struct tty_struct *tty, struct file *filp) goto cleanup; mutex_lock(&info->port.mutex); - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) wait_until_sent(tty, info->timeout); flush_buffer(tty); @@ -1061,7 +1061,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) if (sanity_check(info, tty->name, "wait_until_sent")) return; - if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags)) + if (!tty_port_initialized(&info->port)) goto exit; orig_jiffies = jiffies; @@ -2636,7 +2636,7 @@ static int startup(SLMP_INFO * info) if ( debug_level >= DEBUG_LEVEL_INFO ) printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name); - if (info->port.flags & ASYNC_INITIALIZED) + if (tty_port_initialized(&info->port)) return 0; if (!info->tx_buf) { @@ -2662,7 +2662,7 @@ static int startup(SLMP_INFO * info) if (info->port.tty) clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags |= ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 1); return 0; } @@ -2673,7 +2673,7 @@ static void shutdown(SLMP_INFO * info) { unsigned long flags; - if (!(info->port.flags & ASYNC_INITIALIZED)) + if (!tty_port_initialized(&info->port)) return; if (debug_level >= DEBUG_LEVEL_INFO) @@ -2705,7 +2705,7 @@ static void shutdown(SLMP_INFO * info) if (info->port.tty) set_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; + tty_port_set_initialized(&info->port, 0); } static void program_hw(SLMP_INFO *info) @@ -3308,12 +3308,12 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, port->blocked_open++; while (1) { - if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) + if (C_BAUD(tty) && tty_port_initialized(port)) tty_port_raise_dtr_rts(port); set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ + if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { retval = (port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS; break; diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 130c8cf520cb..c3f9d93ba227 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -204,7 +204,8 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty) if (port->console) goto out; - if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (tty_port_initialized(port)) { + tty_port_set_initialized(port, 0); /* * Drop DTR/RTS if HUPCL is set. This causes any attached * modem to hang up the line. @@ -393,13 +394,13 @@ int tty_port_block_til_ready(struct tty_port *port, while (1) { /* Indicate we are open */ - if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) + if (C_BAUD(tty) && tty_port_initialized(port)) tty_port_raise_dtr_rts(port); prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); /* Check for a hangup or uninitialised port. Return accordingly */ - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { + if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { if (port->flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; else @@ -480,7 +481,7 @@ int tty_port_close_start(struct tty_port *port, tty->closing = 1; - if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (tty_port_initialized(port)) { /* Don't block on a stalled port, just pull the chain */ if (tty->flow_stopped) tty_driver_flush_buffer(tty); @@ -578,7 +579,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, mutex_lock(&port->mutex); - if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (!tty_port_initialized(port)) { clear_bit(TTY_IO_ERROR, &tty->flags); if (port->ops->activate) { int retval = port->ops->activate(port, tty); @@ -587,7 +588,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, return retval; } } - set_bit(ASYNCB_INITIALIZED, &port->flags); + tty_port_set_initialized(port, 1); } mutex_unlock(&port->mutex); return tty_port_block_til_ready(port, tty, filp); diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index a6c4a1b895bd..94a14f5dc4d4 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1680,7 +1680,7 @@ static int acm_resume(struct usb_interface *intf) if (--acm->susp_count) goto out; - if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) { + if (tty_port_initialized(&acm->port)) { rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC); for (;;) { @@ -1710,7 +1710,7 @@ static int acm_reset_resume(struct usb_interface *intf) { struct acm *acm = usb_get_intfdata(intf); - if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) + if (tty_port_initialized(&acm->port)) tty_port_tty_hangup(&acm->port, false); return acm_resume(intf); diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index a66b01bb1fa1..8967715fe6fc 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -127,7 +127,7 @@ static int usb_console_setup(struct console *co, char *options) info->port = port; ++port->port.count; - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) { + if (!tty_port_initialized(&port->port)) { if (serial->type->set_termios) { /* * allocate a fake tty so the driver can initialize @@ -168,7 +168,7 @@ static int usb_console_setup(struct console *co, char *options) tty_port_tty_set(&port->port, NULL); tty_kref_put(tty); } - set_bit(ASYNCB_INITIALIZED, &port->port.flags); + tty_port_set_initialized(&port->port, 1); } /* Now that any required fake tty operations are completed restore * the tty port count */ diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 54e170dd3dad..ae8c0365abd6 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -473,7 +473,7 @@ static bool usb_serial_generic_msr_changed(struct tty_struct *tty, * Use tty-port initialised flag to detect all hangups including the * one generated at USB-device disconnect. */ - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) + if (!tty_port_initialized(&port->port)) return true; spin_lock_irqsave(&port->lock, flags); @@ -503,7 +503,7 @@ int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg) ret = wait_event_interruptible(port->port.delta_msr_wait, usb_serial_generic_msr_changed(tty, arg, &cnow)); - if (!ret && !test_bit(ASYNCB_INITIALIZED, &port->port.flags)) + if (!ret && !tty_port_initialized(&port->port)) ret = -EIO; return ret; @@ -606,7 +606,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) + if (!tty_port_initialized(&port->port)) continue; if (port->bulk_in_size) { diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c index 31a8b47f1ac6..3722d6c1ba77 100644 --- a/drivers/usb/serial/mxuport.c +++ b/drivers/usb/serial/mxuport.c @@ -503,7 +503,7 @@ static void mxuport_process_read_urb_demux_data(struct urb *urb) return; } - if (test_bit(ASYNCB_INITIALIZED, &demux_port->port.flags)) { + if (tty_port_initialized(&demux_port->port)) { ch = data + HEADER_SIZE; mxuport_process_read_urb_data(demux_port, ch, rcv_len); } else { @@ -544,7 +544,7 @@ static void mxuport_process_read_urb_demux_event(struct urb *urb) } demux_port = serial->port[rcv_port]; - if (test_bit(ASYNCB_INITIALIZED, &demux_port->port.flags)) { + if (tty_port_initialized(&demux_port->port)) { ch = data + HEADER_SIZE; rcv_event = get_unaligned_be16(data + 2); mxuport_process_read_urb_event(demux_port, ch, @@ -1339,7 +1339,7 @@ static int mxuport_resume(struct usb_serial *serial) for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) + if (!tty_port_initialized(&port->port)) continue; r = usb_serial_generic_write_start(port, GFP_NOIO); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 07d1ecd564f7..e1994e264cc0 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -776,7 +776,7 @@ static void sierra_close(struct usb_serial_port *port) /* * Need to take susp_lock to make sure port is not already being - * resumed, but no need to hold it due to ASYNC_INITIALIZED. + * resumed, but no need to hold it due to initialized */ spin_lock_irq(&intfdata->susp_lock); if (--intfdata->open_ports == 0) @@ -1039,7 +1039,7 @@ static int sierra_resume(struct usb_serial *serial) for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) + if (!tty_port_initialized(&port->port)) continue; err = sierra_submit_delayed_urbs(port); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 46f1f13b41f1..3f253aec0c16 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -254,7 +254,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp) * * Shut down a USB serial port. Serialized against activate by the * tport mutex and kept to matching open/close pairs - * of calls by the ASYNCB_INITIALIZED flag. + * of calls by the initialized flag. * * Not called if tty is console. */ diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index be9cb61b4d19..3dfdfc81254b 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -464,7 +464,7 @@ void usb_wwan_close(struct usb_serial_port *port) /* * Need to take susp_lock to make sure port is not already being - * resumed, but no need to hold it due to ASYNC_INITIALIZED. + * resumed, but no need to hold it due to initialized */ spin_lock_irq(&intfdata->susp_lock); if (--intfdata->open_ports == 0) @@ -682,7 +682,7 @@ int usb_wwan_resume(struct usb_serial *serial) for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; - if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) + if (!tty_port_initialized(&port->port)) continue; portdata = usb_get_serial_port_data(port); diff --git a/include/linux/tty.h b/include/linux/tty.h index 7ac5add66c00..bf1bcdb01df0 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -610,6 +610,19 @@ static inline void tty_port_set_suspended(struct tty_port *port, bool val) clear_bit(TTY_PORT_SUSPENDED, &port->iflags); } +static inline bool tty_port_initialized(struct tty_port *port) +{ + return test_bit(TTY_PORT_INITIALIZED, &port->iflags); +} + +static inline void tty_port_set_initialized(struct tty_port *port, bool val) +{ + if (val) + set_bit(TTY_PORT_INITIALIZED, &port->iflags); + else + clear_bit(TTY_PORT_INITIALIZED, &port->iflags); +} + extern struct tty_struct *tty_port_tty_get(struct tty_port *port); extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); extern int tty_port_carrier_raised(struct tty_port *port); diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 5b7ce599c709..873c4b707d6a 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -220,10 +220,11 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); /* Check if already open */ - if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) { + if (tty_port_initialized(&self->port)) { pr_debug("%s(), already open so break out!\n", __func__); return 0; } + tty_port_set_initialized(&self->port, 1); /* Register with IrCOMM */ irda_notify_init(¬ify); @@ -257,7 +258,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) return 0; err: - clear_bit(ASYNCB_INITIALIZED, &self->port.flags); + tty_port_set_initialized(&self->port, 0); return ret; } @@ -318,13 +319,12 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, spin_unlock_irqrestore(&port->lock, flags); while (1) { - if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags)) + if (C_BAUD(tty) && tty_port_initialized(port)) tty_port_raise_dtr_rts(port); set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (tty_hung_up_p(filp) || !tty_port_initialized(port)) { retval = (port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS; break; @@ -876,8 +876,9 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); - if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags)) + if (!tty_port_initialized(&self->port)) return; + tty_port_set_initialized(&self->port, 0); ircomm_tty_detach_cable(self); @@ -1259,7 +1260,7 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) seq_printf(m, "%cASYNC_CHECK_CD", sep); sep = '|'; } - if (self->port.flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(&self->port)) { seq_printf(m, "%cASYNC_INITIALIZED", sep); sep = '|'; } diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index e24724db36a2..d4fdf8f7b471 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c @@ -324,7 +324,7 @@ static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *self, check_and_exit: - if (self->flags & ASYNC_INITIALIZED) { + if (tty_port_initialized(self)) { if (((old_state.flags & ASYNC_SPD_MASK) != (self->flags & ASYNC_SPD_MASK)) || (old_driver.custom_divisor != driver->custom_divisor)) { -- cgit 1.4.1 From 5ff04fe5659f78c0450cc6858b12bba9e4049578 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 27 Apr 2016 14:32:06 +0200 Subject: s390/3270: add missing tty_kref_put The tty3270_resize_work functions acquires a reference to the tty to call tty_do_resize but fails to release the reference again. Add the missing tty_kref_put. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tty3270.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index e96fc7fd9498..345f392b50b2 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -838,6 +838,7 @@ static void tty3270_resize_work(struct work_struct *work) ws.ws_row = tp->view.rows - 2; ws.ws_col = tp->view.cols; tty_do_resize(tty, &ws); + tty_kref_put(tty); } static void -- cgit 1.4.1 From b512353c15fe7665893e92e0c989c088505a37b8 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 2 May 2016 13:49:28 +0200 Subject: s390/3270: fix view reference counting The tty3270_close function set tty->driver_data to NULL after the open count dropped to zero but tty3270_cleanup still needs the pointer to the tty3270 view to drop the reference count. Move the clearing of tty->driver_data to tty3270_cleanup and drop the unnecessary tty_port_tty_set calls in tty3270_install. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tty3270.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 345f392b50b2..e8afa07f082e 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -924,10 +924,8 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) tty->winsize.ws_row = tp->view.rows - 2; tty->winsize.ws_col = tp->view.cols; tp->port.low_latency = 0; - /* why to reassign? */ - tty_port_tty_set(&tp->port, tty); tp->inattr = TF_INPUT; - return tty_port_install(&tp->port, driver, tty); + goto port_install; } if (tty3270_max_index < tty->index + 1) tty3270_max_index = tty->index + 1; @@ -953,7 +951,6 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) return rc; } - tty_port_tty_set(&tp->port, tty); tp->port.low_latency = 0; tty->winsize.ws_row = tp->view.rows - 2; tty->winsize.ws_col = tp->view.cols; @@ -975,6 +972,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) raw3270_activate_view(&tp->view); +port_install: rc = tty_port_install(&tp->port, driver, tty); if (rc) { raw3270_put_view(&tp->view); @@ -1011,18 +1009,18 @@ tty3270_close(struct tty_struct *tty, struct file * filp) if (tty->count > 1) return; - if (tp) { - tty->driver_data = NULL; + if (tp) tty_port_tty_set(&tp->port, NULL); - } } static void tty3270_cleanup(struct tty_struct *tty) { struct tty3270 *tp = tty->driver_data; - if (tp) + if (tp) { + tty->driver_data = NULL; raw3270_put_view(&tp->view); + } } /* -- cgit 1.4.1 From 2e63a3a66655d5fe5d85c090b009979870436c00 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 28 Apr 2016 16:32:13 +0200 Subject: s390/3270: fix garbled output on 3270 tty view The tty3270_update function tries to optimize the output stream by skipping the TO_SBA command to position the output offset if the TO_RA command of the previous line ended at the same offset. But some lines do not have the TO_RA at the end, namely those with a length equal to the number of columns. Make sure there is a TO_RA at the end of the previous line to avoid funny looking output. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tty3270.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index e8afa07f082e..54ea5a01e30d 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -405,7 +405,10 @@ tty3270_update(struct tty3270 *tp) if (raw3270_request_add_data(wrq, str, len) != 0) break; list_del_init(&s->update); - sba = s->string + s->len - 3; + if (s->string[s->len - 4] == TO_RA) + sba = s->string + s->len - 3; + else + sba = invalid_sba; } if (list_empty(&tp->update)) updated |= TTY_UPDATE_LIST; -- cgit 1.4.1 From 8340ab60b3624386eaa24fa21bdb4e6775066ccf Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 2 May 2016 14:53:29 +0200 Subject: s390/3270: avoid endless I/O loop with disconnected 3270 terminals If a 3270 terminal is disconnected while the tty view is active the 3270 driver goes into an endless loop of failed I/O requests until the terminal is connected again. Add code to the raw3270 interrupt handler to check for unit checks due to failed I/O requests and put the device to sleep with the RAW3270_FLAGS_BUSY flag until a unsolicited device end interrupt indicates that the device can be used again. while we are at it simplify the 3270 irq handling and remove unnecessary code. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/con3270.c | 3 +- drivers/s390/char/fs3270.c | 3 +- drivers/s390/char/raw3270.c | 101 +++++++++----------------------------------- drivers/s390/char/raw3270.h | 8 +--- drivers/s390/char/tty3270.c | 3 +- 5 files changed, 23 insertions(+), 95 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 4d7a9badfede..6b1577c73fe7 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -400,7 +400,7 @@ con3270_deactivate(struct raw3270_view *view) del_timer(&cp->timer); } -static int +static void con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb) { /* Handle ATTN. Schedule tasklet to read aid. */ @@ -418,7 +418,6 @@ con3270_irq(struct con3270 *cp, struct raw3270_request *rq, struct irb *irb) cp->update_flags = CON_UPDATE_ALL; con3270_set_timer(cp, 1); } - return RAW3270_IO_DONE; } /* Console view to a 3270 device. */ diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 71e974738014..85eca1cef063 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -217,7 +217,7 @@ fs3270_deactivate(struct raw3270_view *view) fp->init->callback(fp->init, NULL); } -static int +static void fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb) { /* Handle ATTN. Set indication and wake waiters for attention. */ @@ -233,7 +233,6 @@ fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb) /* Normal end. Copy residual count. */ rq->rescnt = irb->scsw.cmd.count; } - return RAW3270_IO_DONE; } /* diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 220acb4cbee5..0743f13101ee 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -228,29 +228,6 @@ raw3270_request_set_idal(struct raw3270_request *rq, struct idal_buffer *ib) rq->ccw.flags |= CCW_FLAG_IDA; } -/* - * Stop running ccw. - */ -static int -__raw3270_halt_io(struct raw3270 *rp, struct raw3270_request *rq) -{ - int retries; - int rc; - - if (raw3270_request_final(rq)) - return 0; - /* Check if interrupt has already been processed */ - for (retries = 0; retries < 5; retries++) { - if (retries < 2) - rc = ccw_device_halt(rp->cdev, (long) rq); - else - rc = ccw_device_clear(rp->cdev, (long) rq); - if (rc == 0) - break; /* termination successful */ - } - return rc; -} - /* * Add the request to the request queue, try to start it if the * 3270 device is idle. Return without waiting for end of i/o. @@ -342,7 +319,6 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) struct raw3270 *rp; struct raw3270_view *view; struct raw3270_request *rq; - int rc; rp = dev_get_drvdata(&cdev->dev); if (!rp) @@ -350,55 +326,27 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) rq = (struct raw3270_request *) intparm; view = rq ? rq->view : rp->view; - if (IS_ERR(irb)) - rc = RAW3270_IO_RETRY; - else if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) { - rq->rc = -EIO; - rc = RAW3270_IO_DONE; - } else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END | - DEV_STAT_UNIT_EXCEP)) { + if (!IS_ERR(irb)) { /* Handle CE-DE-UE and subsequent UDE */ - set_bit(RAW3270_FLAGS_BUSY, &rp->flags); - rc = RAW3270_IO_BUSY; - } else if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) { - /* Wait for UDE if busy flag is set. */ - if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { + if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) clear_bit(RAW3270_FLAGS_BUSY, &rp->flags); - /* Got it, now retry. */ - rc = RAW3270_IO_RETRY; - } else - rc = RAW3270_IO_BUSY; - } else if (view) - rc = view->fn->intv(view, rq, irb); - else - rc = RAW3270_IO_DONE; + if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | + DEV_STAT_DEV_END | + DEV_STAT_UNIT_EXCEP)) + set_bit(RAW3270_FLAGS_BUSY, &rp->flags); + /* Handle disconnected devices */ + if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && + (irb->ecw[0] & SNS0_INTERVENTION_REQ)) + set_bit(RAW3270_FLAGS_BUSY, &rp->flags); + /* Call interrupt handler of the view */ + if (view) + view->fn->intv(view, rq, irb); + } - switch (rc) { - case RAW3270_IO_DONE: - break; - case RAW3270_IO_BUSY: - /* - * Intervention required by the operator. We have to wait - * for unsolicited device end. - */ + if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) + /* Device busy, do not start I/O */ return; - case RAW3270_IO_RETRY: - if (!rq) - break; - rq->rc = ccw_device_start(rp->cdev, &rq->ccw, - (unsigned long) rq, 0, 0); - if (rq->rc == 0) - return; /* Successfully restarted. */ - break; - case RAW3270_IO_STOP: - if (!rq) - break; - __raw3270_halt_io(rp, rq); - rq->rc = -EIO; - break; - default: - BUG(); - } + if (rq) { BUG_ON(list_empty(&rq->list)); /* The request completed, remove from queue and do callback. */ @@ -408,6 +356,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* Do put_device for get_device in raw3270_start. */ raw3270_put_view(view); } + /* * Try to start each request on request queue until one is * started successful. @@ -685,23 +634,12 @@ raw3270_reset(struct raw3270_view *view) return rc; } -static int +static void raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, struct irb *irb) { struct raw3270 *rp; - /* - * Unit-Check Processing: - * Expect Command Reject or Intervention Required. - */ - if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { - /* Request finished abnormally. */ - if (irb->ecw[0] & SNS0_INTERVENTION_REQ) { - set_bit(RAW3270_FLAGS_BUSY, &view->dev->flags); - return RAW3270_IO_BUSY; - } - } if (rq) { if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { if (irb->ecw[0] & SNS0_CMD_REJECT) @@ -715,7 +653,6 @@ raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, rp = view->dev; raw3270_read_modified(rp); } - return RAW3270_IO_DONE; } static struct raw3270_fn raw3270_init_fn = { diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h index e1e41c2861fb..56519cbb165c 100644 --- a/drivers/s390/char/raw3270.h +++ b/drivers/s390/char/raw3270.h @@ -125,19 +125,13 @@ raw3270_request_final(struct raw3270_request *rq) void raw3270_buffer_address(struct raw3270 *, char *, unsigned short); -/* Return value of *intv (see raw3270_fn below) can be one of the following: */ -#define RAW3270_IO_DONE 0 /* request finished */ -#define RAW3270_IO_BUSY 1 /* request still active */ -#define RAW3270_IO_RETRY 2 /* retry current request */ -#define RAW3270_IO_STOP 3 /* kill current request */ - /* * Functions of a 3270 view. */ struct raw3270_fn { int (*activate)(struct raw3270_view *); void (*deactivate)(struct raw3270_view *); - int (*intv)(struct raw3270_view *, + void (*intv)(struct raw3270_view *, struct raw3270_request *, struct irb *); void (*release)(struct raw3270_view *); void (*free)(struct raw3270_view *); diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 54ea5a01e30d..d6da18612ba8 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -645,7 +645,7 @@ tty3270_deactivate(struct raw3270_view *view) del_timer(&tp->timer); } -static int +static void tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb) { /* Handle ATTN. Schedule tasklet to read aid. */ @@ -667,7 +667,6 @@ tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb) tp->update_flags = TTY_UPDATE_ALL; tty3270_set_timer(tp, 1); } - return RAW3270_IO_DONE; } /* -- cgit 1.4.1 From 154fa27e6ba37931ca585598acf17c4dcd44c81a Mon Sep 17 00:00:00 2001 From: Alexander Yarygin Date: Fri, 1 Apr 2016 15:36:51 +0300 Subject: s390/sclp: Add hmfai field Let's add hypervisor-managed facility-apportionment indications field to SCLP structs. KVM will use it to reduce maintenance cost of Non-Hypervisor-Managed facility bits. Signed-off-by: Alexander Yarygin Reviewed-by: David Hildenbrand Reviewed-by: Eric Farman Signed-off-by: Christian Borntraeger --- arch/s390/include/asm/sclp.h | 1 + drivers/s390/char/sclp_early.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/s390/char') diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index bab456be9a4f..994a66c09e8f 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -69,6 +69,7 @@ struct sclp_info { unsigned int max_cores; unsigned long hsa_size; unsigned long facilities; + unsigned int hmfai; }; extern struct sclp_info sclp; diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 6804354c42bd..0ac520dd1b21 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -49,7 +49,9 @@ struct read_info_sccb { u8 _pad_117[119 - 117]; /* 117-118 */ u8 fac119; /* 119 */ u16 hcpua; /* 120-121 */ - u8 _pad_122[4096 - 122]; /* 122-4095 */ + u8 _pad_122[124 - 122]; /* 122-123 */ + u32 hmfai; /* 124-127 */ + u8 _pad_128[4096 - 128]; /* 128-4095 */ } __packed __aligned(PAGE_SIZE); static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; @@ -155,6 +157,8 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) sclp.mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0; sclp.mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0; sclp.mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0; + + sclp.hmfai = sccb->hmfai; } /* -- cgit 1.4.1 From 7e36eff1eece29eaa37501806ded0e0fb88e61ee Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 2 May 2016 15:07:00 +0200 Subject: s390/3270: handle reconnect of a tty with a different size If an existing 3270 terminal disconnects and reconnects with a different size, the 3270 driver still works with the old size. If the new dimensions are larger the output merely looks funny, if the new dimensions are smaller the terminal is unusable. To fix this restart the size detection after a unit check has been received. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/raw3270.c | 32 +++++++++++++++++++++++++++++--- drivers/s390/char/tty3270.c | 25 ++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 0743f13101ee..a2da898ce90f 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -90,6 +90,8 @@ module_param(tubxcorrect, bool, 0); */ DECLARE_WAIT_QUEUE_HEAD(raw3270_wait_queue); +static void __raw3270_disconnect(struct raw3270 *rp); + /* * Encode array for 12 bit 3270 addresses. */ @@ -336,8 +338,11 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) set_bit(RAW3270_FLAGS_BUSY, &rp->flags); /* Handle disconnected devices */ if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && - (irb->ecw[0] & SNS0_INTERVENTION_REQ)) + (irb->ecw[0] & SNS0_INTERVENTION_REQ)) { set_bit(RAW3270_FLAGS_BUSY, &rp->flags); + if (rp->state > RAW3270_STATE_RESET) + __raw3270_disconnect(rp); + } /* Call interrupt handler of the view */ if (view) view->fn->intv(view, rq, irb); @@ -347,8 +352,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* Device busy, do not start I/O */ return; - if (rq) { - BUG_ON(list_empty(&rq->list)); + if (rq && !list_empty(&rq->list)) { /* The request completed, remove from queue and do callback. */ list_del_init(&rq->list); if (rq->callback) @@ -634,6 +638,28 @@ raw3270_reset(struct raw3270_view *view) return rc; } +static void +__raw3270_disconnect(struct raw3270 *rp) +{ + struct raw3270_request *rq; + struct raw3270_view *view; + + rp->state = RAW3270_STATE_INIT; + rp->view = &rp->init_view; + /* Cancel all queued requests */ + while (!list_empty(&rp->req_queue)) { + rq = list_entry(rp->req_queue.next,struct raw3270_request,list); + view = rq->view; + rq->rc = -EACCES; + list_del_init(&rq->list); + if (rq->callback) + rq->callback(rq, rq->callback_data); + raw3270_put_view(view); + } + /* Start from scratch */ + __raw3270_reset_device(rp); +} + static void raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, struct irb *irb) diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index d6da18612ba8..402eff3c1634 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -318,6 +318,27 @@ tty3270_blank_line(struct tty3270 *tp) tp->nr_up++; } +/* + * Create a blank screen and remove all lines from the history. + */ +static void +tty3270_blank_screen(struct tty3270 *tp) +{ + struct string *s, *n; + int i; + + for (i = 0; i < tp->view.rows - 2; i++) + tp->screen[i].len = 0; + tp->nr_up = 0; + list_for_each_entry_safe(s, n, &tp->lines, list) { + list_del(&s->list); + if (!list_empty(&s->update)) + list_del(&s->update); + tp->nr_lines--; + free_string(&tp->freemem, s); + } +} + /* * Write request completion callback. */ @@ -816,6 +837,7 @@ static void tty3270_resize_work(struct work_struct *work) return; /* Switch to new output size */ spin_lock_bh(&tp->view.lock); + tty3270_blank_screen(tp); oscreen = tp->screen; orows = tp->view.rows; tp->view.model = tp->n_model; @@ -826,7 +848,6 @@ static void tty3270_resize_work(struct work_struct *work) free_string(&tp->freemem, tp->status); tty3270_create_prompt(tp); tty3270_create_status(tp); - tp->nr_up = 0; while (tp->nr_lines < tp->view.rows - 2) tty3270_blank_line(tp); tp->update_flags = TTY_UPDATE_ALL; @@ -848,6 +869,8 @@ tty3270_resize(struct raw3270_view *view, int model, int rows, int cols) { struct tty3270 *tp = container_of(view, struct tty3270, view); + if (tp->n_model == model && tp->n_rows == rows && tp->n_cols == cols) + return; tp->n_model = model; tp->n_rows = rows; tp->n_cols = cols; -- cgit 1.4.1 From 0c756914920fc13061222d12fbbe85990df64928 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 2 May 2016 15:09:01 +0200 Subject: s390/3270: hangup the 3270 tty after a disconnect The disconnect and later reconnect of a 3270 terminal does not do a tty hangup. The current session is resumed which is a security issue. Do a tty hangup after a unit check has been received. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tty3270.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'drivers/s390/char') diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 402eff3c1634..0a9f219fdc7c 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -92,6 +92,7 @@ struct tty3270 { unsigned char inattr; /* Visible/invisible input. */ int throttle, attn; /* tty throttle/unthrottle. */ struct tasklet_struct readlet; /* Tasklet to issue read request. */ + struct tasklet_struct hanglet; /* Tasklet to hang up the tty. */ struct kbd_data *kbd; /* key_maps stuff. */ /* Escape sequence parsing. */ @@ -645,6 +646,16 @@ tty3270_issue_read(struct tty3270 *tp, int lock) } } +/* + * Hang up the tty + */ +static void +tty3270_hangup_tasklet(struct tty3270 *tp) +{ + tty_port_tty_hangup(&tp->port, true); + raw3270_put_view(&tp->view); +} + /* * Switch to the tty view. */ @@ -678,11 +689,14 @@ tty3270_irq(struct tty3270 *tp, struct raw3270_request *rq, struct irb *irb) } if (rq) { - if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) + if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) { rq->rc = -EIO; - else + raw3270_get_view(&tp->view); + tasklet_schedule(&tp->hanglet); + } else { /* Normal end. Copy residual count. */ rq->rescnt = irb->scsw.cmd.count; + } } else if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) { /* Interrupt without an outstanding request -> update all */ tp->update_flags = TTY_UPDATE_ALL; @@ -739,6 +753,9 @@ tty3270_alloc_view(void) tasklet_init(&tp->readlet, (void (*)(unsigned long)) tty3270_read_tasklet, (unsigned long) tp->read); + tasklet_init(&tp->hanglet, + (void (*)(unsigned long)) tty3270_hangup_tasklet, + (unsigned long) tp); INIT_WORK(&tp->resize_work, tty3270_resize_work); return tp; @@ -1812,7 +1829,22 @@ tty3270_unthrottle(struct tty_struct * tty) static void tty3270_hangup(struct tty_struct *tty) { - // FIXME: implement + struct tty3270 *tp; + + tp = tty->driver_data; + if (!tp) + return; + spin_lock_bh(&tp->view.lock); + tp->cx = tp->saved_cx = 0; + tp->cy = tp->saved_cy = 0; + tp->highlight = tp->saved_highlight = TAX_RESET; + tp->f_color = tp->saved_f_color = TAC_RESET; + tty3270_blank_screen(tp); + while (tp->nr_lines < tp->view.rows - 2) + tty3270_blank_line(tp); + tp->update_flags = TTY_UPDATE_ALL; + spin_unlock_bh(&tp->view.lock); + tty3270_set_timer(tp, 1); } static void -- cgit 1.4.1