additional s390 patches for 2.6.27
cover additional s390 patches for 2.6.27
Greetings,
in the last couple of weeks some more s390 patches have piled up for the 2.6.27 merge window:
Cornelia Huck (7):
[S390] cio: Get rid of css_characteristics_avail. [S390] cio: Introduce abstract isc definitions. [S390] cio: Allow adapter interrupt handlers per isc. [S390] cio: Use isc_{register,unregister}. [S390] cio: Repair chpid event handling. [S390] css: Use css_device_id for bus matching. [S390] cio: Add chsc subchannel driver.
Felix Beck (1):
[S390] ap: Use high-resolution timer for polling
Heiko Carstens (1):
[S390] idle: remove idle notifier chain.
Hendrik Brueckner (1):
[S390] Extra Kernel Parameters via VMPARM
Peter Oberparleiter (2):
[S390] cio: suppress chpid event in case of configure error [S390] sclp: simplify vt220 cleanup logic
Ralph Wuerthner (1):
[S390] zcrypt: Add additional card IDs to CEX2C and CEX2A
Sebastian Ott (1):
[S390] cio: introduce isc_(un)register functions.
I've added them to the other patches in the feature branch of the it390 tree. See
git://git390.osdl.marist.edu/pub/scm/linux-2.6.git feeatures
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 1/14 cio: Get rid of css_characteristics_avail.
From: Cornelia Huck <[email protected]>
Checking for the validity of the css_*_characteristics is superfluous since they stay 0 for non-successful scsc.
---
drivers/s390/cio/chp.c | 3 +-- drivers/s390/cio/chsc.h | 1 - drivers/s390/cio/cmf.c | 3 +-- drivers/s390/cio/css.c | 12 +++--------- drivers/s390/cio/qdio.c | 3 --- 5 files changed, 5 insertions(+), 17 deletions(-)
drivers/s390/cio/chp.c +1 -2
@@ -415,8 +415,7 @@ int chp_new(struct chp_id chpid) goto out_free; }/* Get channel-measurement characteristics. */ -if (css_characteristics_avail && css_chsc_characteristics.scmc - && css_chsc_characteristics.secm) { +if (css_chsc_characteristics.scmc && css_chsc_characteristics.secm) { ret =chsc_get_channel_measurement_chars (chp);if (ret) goto out_free;
drivers/s390/cio/chsc.h +0 -1
@@ -78,7 +78,6 @@ struct chsc_ssd_info {extern int chsc_get_ssd_info (struct subchannel_id schid,struct chsc_ssd_info *ssd);extern int chsc_determine_css_characteristics (void ); -extern int css_characteristics_avail;extern int chsc_alloc_sei_area (void );extern void chsc_free_sei_area (void );
drivers/s390/cio/cmf.c +1 -2
@@ -1344,8 +1344,7 @@ static int __init init_cmf(void)* to basic mode. */ if (format ==CMF_AUTODETECT ) { -if (!css_characteristics_avail || - !css_general_characteristics.ext_mb) { +if (!css_general_characteristics.ext_mb) { format =CMF_BASIC ; }else { format =CMF_EXTENDED ;
drivers/s390/cio/css.c +3 -9
@@ -30,8 +30,6 @@ static int max_ssid = 0;struct channel_subsystem *channel_subsystems[__MAX_CSSID +1 ]; -int css_characteristics_avail =0 ; -int for_each_subchannel (int (*fn)(struct subchannel_id ,void *),void *data) {
@@ -611,7 +609,7 @@ __init_channel_subsystem(struct subchannstatic void __init css_generate_pgid (struct channel_subsystem *css,u32 tod_high) { -if (css_characteristics_avail && css_general_characteristics.mcss) { +if (css_general_characteristics.mcss) { css->global_pgid.pgid_high.ext_cssid.version =0x80 ; css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid; }else {
@@ -748,8 +746,6 @@ init_channel_subsystem (void) ret =chsc_determine_css_characteristics ();if (ret == -ENOMEM ) goto out;/* No need to continue. */ -if (ret ==0 ) - css_characteristics_avail =1 ; ret =chsc_alloc_sei_area ();if (ret)
@@ -793,8 +789,7 @@ init_channel_subsystem (void) ret =device_register (&css->device);if (ret) goto out_free_all; -if (css_characteristics_avail && - css_chsc_characteristics.secm) { +if (css_chsc_characteristics.secm) { ret =device_create_file (&css->device, &dev_attr_cm_enable);if (ret)
@@ -832,7 +827,7 @@ out_unregister: i--; css = channel_subsystems[i];device_unregister (&css->pseudo_subchannel->dev); -if (css_characteristics_avail && css_chsc_characteristics.secm) +if (css_chsc_characteristics.secm)device_remove_file (&css->device, &dev_attr_cm_enable);device_unregister (&css->device);
@@ -956,4 +951,3 @@ subsys_initcall(init_channel_subsystem);MODULE_LICENSE ("GPL" );EXPORT_SYMBOL (css_bus_type); -EXPORT_SYMBOL_GPL (css_characteristics_avail);
drivers/s390/cio/qdio.c +0 -3
@@ -2354,9 +2354,6 @@ tiqdio_check_chsc_availability(void) {char dbf_text[15 ]; -if (!css_characteristics_avail) -return -EIO ; -/* Check for bit 41. */ if (!css_general_characteristics.aif) { QDIO_PRINT_WARN("Adapter interruption facility not " \
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 2/14 cio: Introduce abstract isc definitions.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Replace the numeric values for I/O interruption subclass usage with abstract definitions and collect them all in asm/isc.h. This gives us a better overview of which iscs are actually used and makes it possible to better spread out isc usage in the future.
---
drivers/s390/cio/cio.c | 13 +++++++------ drivers/s390/cio/css.c | 4 +++- drivers/s390/cio/device.c | 3 ++- drivers/s390/cio/qdio.h | 3 ++- include/asm-s390/isc.h | 18 ++++++++++++++++++ 5 files changed, 32 insertions(+), 9 deletions(-)
drivers/s390/cio/cio.c +7 -6
@@ -24,6 +24,7 @@#include <asm/ipl.h> #include <asm/chpid.h> #include <asm/airq.h> +#include <asm/isc.h> #include <asm/cpu.h> #include <asm/fcx.h> #include "cio.h"
@@ -699,9 +700,9 @@ void wait_cons_dev(void)if (!console_subchannel_in_use)return ; -/* disable all but isc 1 (console device) */ +/* disable all but the console isc */ __ctl_store (save_cr6,6 ,6 ); - cr6 =0x40000000 ; + cr6 =1UL << (31 -CONSOLE_ISC );__ctl_load (cr6,6 ,6 ); do {
@@ -783,10 +784,10 @@ cio_probe_console(void) }/* -* enable console I/O-interrupt subclass 1 +* enable console I/O-interrupt subclass */ -ctl_set_bit (6 ,30 ); - console_subchannel.schib.pmcw.isc =1 ; +ctl_set_bit (6 ,31 -CONSOLE_ISC ); + console_subchannel.schib.pmcw.isc =CONSOLE_ISC ; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel; ret =cio_modify (&console_subchannel);
@@ -802,7 +803,7 @@ cio_release_console(void) { console_subchannel.schib.pmcw.intparm =0 ;cio_modify (&console_subchannel); -ctl_clear_bit (6 ,30 ); +ctl_clear_bit (6 ,31 -CONSOLE_ISC ); console_subchannel_in_use =0 ; }
drivers/s390/cio/css.c +3 -1
@@ -13,6 +13,7 @@#include <linux/errno.h> #include <linux/list.h> #include <linux/reboot.h> +#include <asm/isc.h> #include "../s390mach.h" #include "css.h"
@@ -804,7 +805,8 @@ init_channel_subsystem (void) goto out_pseudo; css_init_done =1 ; -ctl_set_bit (6 ,28 ); +/* Enable default isc for I/O subchannels. */ +ctl_set_bit (6 ,31 -IO_SCH_ISC );for_each_subchannel (__init_channel_subsystem,NULL );return 0 ;
drivers/s390/cio/device.c +2 -1
@@ -22,6 +22,7 @@#include <asm/cio.h> #include <asm/param.h> /* HZ */ #include <asm/cmb.h> +#include <asm/isc.h> #include "chp.h" #include "cio.h"
@@ -1121,7 +1122,7 @@ static void io_subchannel_init_fields(stelse sch->opm =chp_get_sch_opm (sch); sch->lpm = sch->schib.pmcw.pam & sch->opm; - sch->isc =cio_is_console (sch->schid) ?1 :3 ; + sch->isc =cio_is_console (sch->schid) ?CONSOLE_ISC :IO_SCH_ISC ; CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X" " - PIM = %02X, PAM = %02X, POM = %02X\n",
drivers/s390/cio/qdio.h +2 -1
@@ -2,6 +2,7 @@#define _CIO_QDIO_H#include <asm/page.h> +#include <asm/isc.h> #include "schid.h"
@@ -26,7 +27,7 @@*/ #define IQDIO_FILL_LEVEL_TO_POLL 4 -#define TIQDIO_THININT_ISC 3 +#define TIQDIO_THININT_ISC QDIO_AIRQ_ISC#define TIQDIO_DELAY_TARGET 0#define QDIO_BUSY_BIT_PATIENCE 100/* in microsecs */ #define QDIO_BUSY_BIT_GIVE_UP 10000000/* 10 seconds */
include/asm-s390/isc.h new file +18 -0
@@ -0,0 +1,18 @@ +#ifndef _ASM_S390_ISC_H +#define _ASM_S390_ISC_H + +/* +* I/O interruption subclasses used by drivers. +* Please add all used iscs here so that it is possible to distribute +* isc usage between drivers. +* Reminder: 0 is highest priority, 7 lowest. +*/ +#define MAX_ISC 7 + +/* Regular I/O interrupts. */ +#define IO_SCH_ISC 3/* regular I/O subchannels */ +#define CONSOLE_ISC 1/* console I/O subchannel */ +/* Adapter interrupts. */ +#define QDIO_AIRQ_ISC IO_SCH_ISC/* I/O subchannel in qdio mode */ + +#endif /* _ASM_S390_ISC_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 3/14 cio: Allow adapter interrupt handlers per isc.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Enhance the adapter interruption API so that device drivers can register a handler for a specific interruption subclass. This will allow different device drivers to move to differently prioritized subclasses in order to avoid congestion.
---
drivers/s390/cio/airq.c | 45 +++++++++++++++++++++++++-------------------- drivers/s390/cio/cio.c | 2 +- drivers/s390/cio/cio.h | 2 +- drivers/s390/cio/qdio.c | 6 ++++-- include/asm-s390/airq.h | 4 ++-- 5 files changed, 33 insertions(+), 26 deletions(-)
drivers/s390/cio/airq.c +25 -20
@@ -15,6 +15,7 @@#include <linux/rcupdate.h> #include <asm/airq.h> +#include <asm/isc.h> #include "cio.h" #include "cio_debug.h"
@@ -33,15 +34,15 @@ struct airq_t {void *drv_data; }; -static union indicator_t indicators; -static struct airq_t *airqs[NR_AIRQS ]; +static union indicator_t indicators[MAX_ISC ]; +static struct airq_t *airqs[MAX_ISC ][NR_AIRQS ]; -static int register_airq (struct airq_t *airq) +static int register_airq (struct airq_t *airq,u8 isc) {int i;for (i =0 ; i <NR_AIRQS ; i++) -if (!cmpxchg (&airqs[i],NULL , airq)) +if (!cmpxchg (&airqs[isc][i],NULL , airq))return i;return -ENOMEM ; }
@@ -50,18 +51,21 @@ static int register_airq(struct airq_t ** s390_register_adapter_interrupt() - register adapter interrupt handler * @handler: adapter handler to be registered * @drv_data: driver data passed with each call to the handler +* @isc: isc for which the handler should be called * * Returns: * Pointer to the indicator to be used on success * ERR_PTR() if registration failed */ void *s390_register_adapter_interrupt (adapter_int_handler_t handler, -void *drv_data) +void *drv_data,u8 isc) {struct airq_t *airq;char dbf_txt[16 ];int ret; +if (isc >MAX_ISC ) +return ERR_PTR (-EINVAL ); airq =kmalloc (sizeof (struct airq_t ),GFP_KERNEL );if (!airq) { ret = -ENOMEM ;
@@ -69,34 +73,35 @@ void *s390_register_adapter_interrupt(ad } airq->handler = handler; airq->drv_data = drv_data; - ret =register_airq (airq); -if (ret <0 ) -kfree (airq); + + ret =register_airq (airq, isc); out:snprintf (dbf_txt,sizeof (dbf_txt),"rairq:%d" , ret);CIO_TRACE_EVENT (4 , dbf_txt); -if (ret <0 ) +if (ret <0 ) { +kfree (airq);return ERR_PTR (ret); -else -return &indicators.byte[ret]; + }else +return &indicators[isc].byte[ret]; }EXPORT_SYMBOL (s390_register_adapter_interrupt);/** * s390_unregister_adapter_interrupt - unregister adapter interrupt handler * @ind: indicator for which the handler is to be unregistered +* @isc: interruption subclass */ -void s390_unregister_adapter_interrupt (void *ind) +void s390_unregister_adapter_interrupt (void *ind,u8 isc) {struct airq_t *airq;char dbf_txt[16 ];int i; - i = (int ) ((addr_t ) ind) - ((addr_t) &indicators.byte[0 ]); + i = (int ) ((addr_t ) ind) - ((addr_t) &indicators[isc].byte[0 ]);snprintf (dbf_txt,sizeof (dbf_txt),"urairq:%d" , i);CIO_TRACE_EVENT (4 , dbf_txt); - indicators.byte[i] =0 ; - airq =xchg (&airqs[i],NULL ); + indicators[isc].byte[i] =0 ; + airq =xchg (&airqs[isc][i],NULL );/* * Allow interrupts to complete. This will ensure that the airq handle * is no longer referenced by any interrupt handler.
@@ -108,7 +113,7 @@ EXPORT_SYMBOL(s390_unregister_adapter_in#define INDICATOR_MASK (0xffUL << ((NR_AIRQS_PER_WORD - 1) * 8)) -void do_adapter_IO (void ) +void do_adapter_IO (u8 isc) {int w;int i;
@@ -120,22 +125,22 @@ void do_adapter_IO(void)* fetch operations. */ for (w =0 ; w <NR_AIRQ_WORDS ; w++) { - word = indicators.word[w]; + word = indicators[isc].word[w]; i = w *NR_AIRQS_PER_WORD ;/* * Check bytes within word for active indicators. */ while (word) {if (word &INDICATOR_MASK ) { - airq = airqs[i]; + airq = airqs[isc][i];if (likely (airq)) - airq->handler (&indicators.byte[i], + airq->handler (&indicators[isc].byte[i], airq->drv_data);else /* * Reset ill-behaved indicator. */ - indicators.byte[i] =0 ; + indicators[isc].byte[i] =0 ; } word <<=8 ; i++;
drivers/s390/cio/cio.c +1 -1
@@ -641,7 +641,7 @@ do_IRQ (struct pt_regs *regs)*/ if (tpi_info->adapter_IO ==1 && tpi_info->int_type ==IO_INTERRUPT_TYPE ) { -do_adapter_IO (); +do_adapter_IO (tpi_info->isc);continue ; } sch = (struct subchannel *)(unsigned long )tpi_info->intparm;
drivers/s390/cio/cio.h +1 -1
@@ -106,7 +106,7 @@ int cio_tm_start_key(struct subchannel *int cio_tm_intrg (struct subchannel *sch);int cio_create_sch_lock (struct subchannel *); -void do_adapter_IO (void ); +void do_adapter_IO (u8 isc);void do_IRQ (struct pt_regs *);/* Use with care. */
drivers/s390/cio/qdio.c +4 -2
@@ -3713,7 +3713,8 @@ tiqdio_register_thinints(void)char dbf_text[20 ]; tiqdio_ind = -s390_register_adapter_interrupt (&tiqdio_thinint_handler,NULL ); +s390_register_adapter_interrupt (&tiqdio_thinint_handler,NULL , +TIQDIO_THININT_ISC );if (IS_ERR (tiqdio_ind)) {sprintf (dbf_text,"regthn%lx" ,PTR_ERR (tiqdio_ind));QDIO_DBF_TEXT0 (0 ,setup,dbf_text);
@@ -3729,7 +3730,8 @@ static voidtiqdio_unregister_thinints (void) {if (tiqdio_ind) -s390_unregister_adapter_interrupt (tiqdio_ind); +s390_unregister_adapter_interrupt (tiqdio_ind, +TIQDIO_THININT_ISC ); } static int
include/asm-s390/airq.h +2 -2
@@ -13,7 +13,7 @@typedef void (*adapter_int_handler_t )(void *,void *); -void *s390_register_adapter_interrupt (adapter_int_handler_t ,void *); -void s390_unregister_adapter_interrupt (void *); +void *s390_register_adapter_interrupt (adapter_int_handler_t ,void *,u8 ); +void s390_unregister_adapter_interrupt (void *,u8 );#endif /* _ASM_S390_AIRQ_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 4/14 cio: introduce isc_(un)register functions.
In reply to Martin SchwidefskyFrom: Sebastian Ott <[email protected]>
This interface makes it easy for drivers to register usage of different I/O interruption subclasses without needing to worry about possible other users of the same isc.
---
drivers/s390/cio/Makefile | 4 +- drivers/s390/cio/isc.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ include/asm-s390/isc.h | 6 ++++ 3 files changed, 76 insertions(+), 2 deletions(-)
drivers/s390/cio/isc.c new file +68 -0
@@ -0,0 +1,68 @@ +/* +* Functions for registration of I/O interruption subclasses on s390. +* +* Copyright IBM Corp. 2008 +* Authors: Sebastian Ott <[email protected]> +*/ + +#include <linux/spinlock.h> +#include <linux/module.h> +#include <asm/isc.h> + +static unsigned int isc_refs[MAX_ISC +1 ]; +static DEFINE_SPINLOCK (isc_ref_lock); + + +/** +* isc_register - register an I/O interruption subclass. +* @isc: I/O interruption subclass to register +* +* The number of users for @isc is increased. If this is the first user to +* register @isc, the corresponding I/O interruption subclass mask is enabled. +* +* Context: +* This function must not be called in interrupt context. +*/ +void isc_register (unsigned int isc) +{ +if (isc >MAX_ISC ) { +WARN_ON (1 ); +return ; + } + +spin_lock (&isc_ref_lock); +if (isc_refs[isc] ==0 ) +ctl_set_bit (6 ,31 - isc); + isc_refs[isc]++; +spin_unlock (&isc_ref_lock); +} +EXPORT_SYMBOL_GPL (isc_register); + +/** +* isc_unregister - unregister an I/O interruption subclass. +* @isc: I/O interruption subclass to unregister +* +* The number of users for @isc is decreased. If this is the last user to +* unregister @isc, the corresponding I/O interruption subclass mask is +* disabled. +* Note: This function must not be called if isc_register() hasn't been called +* before by the driver for @isc. +* +* Context: +* This function must not be called in interrupt context. +*/ +void isc_unregister (unsigned int isc) +{ +spin_lock (&isc_ref_lock); +/* check for misuse */ +if (isc >MAX_ISC || isc_refs[isc] ==0 ) { +WARN_ON (1 ); + goto out_unlock; + } +if (isc_refs[isc] ==1 ) +ctl_clear_bit (6 ,31 - isc); + isc_refs[isc]--; +out_unlock: +spin_unlock (&isc_ref_lock); +} +EXPORT_SYMBOL_GPL (isc_unregister);
drivers/s390/cio/Makefile +2 -2
@@ -2,8 +2,8 @@ # Makefile for the S/390 common i/o drivers # -obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o fcx.o \ - itcw.o +obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \ + fcx.o itcw.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o
include/asm-s390/isc.h +6 -0
@@ -1,6 +1,8 @@#ifndef _ASM_S390_ISC_H#define _ASM_S390_ISC_H +#include <linux/types.h> +/* * I/O interruption subclasses used by drivers. * Please add all used iscs here so that it is possible to distribute
@@ -15,4 +17,8 @@/* Adapter interrupts. */ #define QDIO_AIRQ_ISC IO_SCH_ISC/* I/O subchannel in qdio mode */ +/* Functions for registration of I/O interruption subclasses */ +void isc_register (unsigned int isc); +void isc_unregister (unsigned int isc); +#endif /* _ASM_S390_ISC_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 5/14 cio: Use isc_{register,unregister}.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Use the new isc registration functions for all places that need an I/O interruption subclass.
---
drivers/s390/cio/cio.c | 5 +++-- drivers/s390/cio/css.c | 2 +- drivers/s390/cio/qdio.c | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-)
drivers/s390/cio/cio.c +3 -2
@@ -786,12 +786,13 @@ cio_probe_console(void)/* * enable console I/O-interrupt subclass */ -ctl_set_bit (6 ,31 -CONSOLE_ISC ); +isc_register (CONSOLE_ISC ); console_subchannel.schib.pmcw.isc =CONSOLE_ISC ; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel; ret =cio_modify (&console_subchannel);if (ret) { +isc_unregister (CONSOLE_ISC ); console_subchannel_in_use =0 ;return ERR_PTR (ret); }
@@ -803,7 +804,7 @@ cio_release_console(void) { console_subchannel.schib.pmcw.intparm =0 ;cio_modify (&console_subchannel); -ctl_clear_bit (6 ,31 -CONSOLE_ISC ); +isc_unregister (CONSOLE_ISC ); console_subchannel_in_use =0 ; }
drivers/s390/cio/css.c +1 -1
@@ -806,7 +806,7 @@ init_channel_subsystem (void) css_init_done =1 ;/* Enable default isc for I/O subchannels. */ -ctl_set_bit (6 ,31 -IO_SCH_ISC ); +isc_register (IO_SCH_ISC );for_each_subchannel (__init_channel_subsystem,NULL );return 0 ;
drivers/s390/cio/qdio.c +2 -0
@@ -3892,6 +3892,7 @@ init_QDIO(void) qdio_mempool_alloc, qdio_mempool_free, NULL); +isc_register (QDIO_AIRQ_ISC );if (tiqdio_check_chsc_availability ())QDIO_PRINT_ERR ("Not all CHSCs supported. Continuing.\n" );
@@ -3904,6 +3905,7 @@ static void __exitcleanup_QDIO (void) {tiqdio_unregister_thinints (); +isc_unregister (QDIO_AIRQ_ISC );qdio_remove_procfs_entry ();qdio_release_qdio_memory ();qdio_unregister_dbf_views ();
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 6/14 cio: Repair chpid event handling.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Passing the affected chpid in chp_event() worked only by chance since chpid is the first element in res_acc_data. Make it work properly by generalizing res_acc_data as chp_link and always passing around a properly filled out chp_link structure in chp_event().
---
drivers/s390/cio/chp.c | 6 ++--- drivers/s390/cio/chp.h | 4 +-- drivers/s390/cio/chsc.c | 55 +++++++++++++++++++++++++--------------------- drivers/s390/cio/css.h | 3 +- drivers/s390/cio/device.c | 11 ++++----- 5 files changed, 43 insertions(+), 36 deletions(-)
drivers/s390/cio/chp.c +3 -3
@@ -525,7 +525,7 @@ static void chp_process_crw(struct crw * } } -int chp_ssd_get_mask (struct chsc_ssd_info *ssd,struct res_acc_data *data) +int chp_ssd_get_mask (struct chsc_ssd_info *ssd,struct chp_link *link) {int i;int mask;
@@ -534,10 +534,10 @@ int chp_ssd_get_mask(struct chsc_ssd_inf mask =0x80 >> i;if (!(ssd->path_mask & mask))continue ; -if (!chp_id_is_equal (&ssd->chpid[i], &data->chpid)) +if (!chp_id_is_equal (&ssd->chpid[i], &link->chpid))continue ;if ((ssd->fla_valid_mask & mask) && - ((ssd->fla[i] & data->fla_mask) != data->fla)) + ((ssd->fla[i] & link->fla_mask) != link->fla))continue ;return mask; }
drivers/s390/cio/chp.h +2 -2
@@ -24,7 +24,7 @@#define CHP_VARY_ON 2#define CHP_VARY_OFF 3 -struct res_acc_data { +struct chp_link {struct chp_id chpid;u32 fla_mask;u16 fla;
@@ -60,5 +60,5 @@ int chp_new(struct chp_id chpid);void chp_cfg_schedule (struct chp_id chpid,int configure);void chp_cfg_cancel_deconfigure (struct chp_id chpid);int chp_info_get_status (struct chp_id chpid); -int chp_ssd_get_mask (struct chsc_ssd_info *,struct res_acc_data *); +int chp_ssd_get_mask (struct chsc_ssd_info *,struct chp_link *);#endif /* S390_CHP_H */
drivers/s390/cio/chsc.c +31 -24
140 lines not on this page · raw message
drivers/s390/cio/css.h +2 -1
@@ -59,6 +59,7 @@ struct pgid { } __attribute__ ((packed));struct subchannel ; +struct chp_link ;/** * struct css_driver - device driver for subchannels * @owner: owning module
@@ -77,7 +78,7 @@ struct css_driver {unsigned int subchannel_type;struct device_driver drv;void (*irq)(struct subchannel *); -int (*chp_event)(struct subchannel *,void *,int ); +int (*chp_event)(struct subchannel *,struct chp_link *,int );int (*sch_event)(struct subchannel *,int );int (*probe)(struct subchannel *);int (*remove)(struct subchannel *);
drivers/s390/cio/device.c +5 -6
@@ -128,7 +128,8 @@ static int io_subchannel_probe(struct sustatic int io_subchannel_remove (struct subchannel *);static void io_subchannel_shutdown (struct subchannel *);static int io_subchannel_sch_event (struct subchannel *,int ); -static int io_subchannel_chp_event (struct subchannel *,void *,int ); +static int io_subchannel_chp_event (struct subchannel *,struct chp_link *, +int );static struct css_driver io_subchannel_driver = { .owner =THIS_MODULE ,
@@ -1329,14 +1330,12 @@ static void io_subchannel_terminate_path } -static int io_subchannel_chp_event (struct subchannel *sch,void *data, -int event) +static int io_subchannel_chp_event (struct subchannel *sch, +struct chp_link *link,int event) {int mask; -struct res_acc_data *res_data; - res_data = data; - mask =chp_ssd_get_mask (&sch->ssd_info, res_data); + mask =chp_ssd_get_mask (&sch->ssd_info, link);if (!mask)return 0 ;switch (event) {
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 7/14 css: Use css_device_id for bus matching.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
css_device_id exists, so use it for determining the right driver (and add a match_flags which is always 1 for valid types).
---
drivers/s390/cio/css.c | 15 ++++++--------- drivers/s390/cio/css.h | 2 +- drivers/s390/cio/device.c | 8 +++++++- include/linux/mod_devicetable.h | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-)
drivers/s390/cio/css.c +6 -9
@@ -850,19 +850,16 @@ int sch_is_pseudo_sch(struct subchannelreturn sch ==to_css (sch->dev.parent)->pseudo_subchannel; } -/* -* find a driver for a subchannel. They identify by the subchannel -* type with the exception that the console subchannel driver has its own -* subchannel type although the device is an i/o subchannel -*/ -static int -css_bus_match (struct device *dev,struct device_driver *drv) +static int css_bus_match (struct device *dev,struct device_driver *drv) {struct subchannel *sch =to_subchannel (dev);struct css_driver *driver =to_cssdriver (drv); +struct css_device_id *id; -if (sch->st == driver->subchannel_type) -return 1 ; +for (id = driver->subchannel_type; id->match_flags; id++) { +if (sch->st == id->type) +return 1 ; + }return 0 ; }
drivers/s390/cio/css.h +1 -1
@@ -75,7 +75,7 @@ struct chp_link;*/ struct css_driver {struct module *owner; -unsigned int subchannel_type; +struct css_device_id *subchannel_type;struct device_driver drv;void (*irq)(struct subchannel *);int (*chp_event)(struct subchannel *,struct chp_link *,int );
drivers/s390/cio/device.c +7 -1
@@ -131,9 +131,15 @@ static int io_subchannel_sch_event(strucstatic int io_subchannel_chp_event (struct subchannel *,struct chp_link *,int ); +static struct css_device_id io_subchannel_ids[] = { + { .match_flags =0x1 , .type =SUBCHANNEL_TYPE_IO , }, + {/* end of list */ }, +}; +MODULE_DEVICE_TABLE (css, io_subchannel_ids); +static struct css_driver io_subchannel_driver = { .owner =THIS_MODULE , - .subchannel_type =SUBCHANNEL_TYPE_IO , + .subchannel_type = io_subchannel_ids, .name ="io_subchannel" , .irq = io_subchannel_irq, .sch_event = io_subchannel_sch_event,
include/linux/mod_devicetable.h +1 -1
@@ -161,8 +161,8 @@ struct ap_device_id {/* s390 css bus devices (subchannels) */ struct css_device_id { +__u8 match_flags;__u8 type;/* subchannel type */ -__u8 pad1;__u16 pad2;__u32 pad3;kernel_ulong_t driver_data;
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 8/14 cio: suppress chpid event in case of configure error
In reply to Martin SchwidefskyFrom: Peter Oberparleiter <[email protected]>
Do not send CHP_ONLINE/CHP_OFFLINE events to subchannel drivers when a channel-path configure request failed.
---
drivers/s390/cio/chp.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
drivers/s390/cio/chp.c +17 -6
@@ -624,6 +624,7 @@ static void cfg_func(struct work_struct {struct chp_id chpid;enum cfg_task_t t; +int rc;mutex_lock (&cfg_lock); t = cfg_none;
@@ -638,14 +639,24 @@ static void cfg_func(struct work_structswitch (t) {case cfg_configure: -sclp_chp_configure (chpid); -info_expire (); -chsc_chp_online (chpid); + rc =sclp_chp_configure (chpid); +if (rc) +CIO_MSG_EVENT (2 ,"chp: sclp_chp_configure(%x.%02x)=" +"%d\n" , chpid.cssid, chpid.id, rc); +else { +info_expire (); +chsc_chp_online (chpid); + }break ;case cfg_deconfigure: -sclp_chp_deconfigure (chpid); -info_expire (); -chsc_chp_offline (chpid); + rc =sclp_chp_deconfigure (chpid); +if (rc) +CIO_MSG_EVENT (2 ,"chp: sclp_chp_deconfigure(%x.%02x)=" +"%d\n" , chpid.cssid, chpid.id, rc); +else { +info_expire (); +chsc_chp_offline (chpid); + }break ;case cfg_none:/* Get updated information after last change. */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 9/14 cio: Add chsc subchannel driver.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
This patch adds a driver for subchannels of type chsc.
A device /dev/chsc is created which may be used to issue ioctls to:
- obtain information about the machine's I/O configuration
- dynamically change the machine's I/O configuration via asynchronous chsc commands
---
Documentation/ioctl-number.txt | 1 arch/s390/Kconfig | 16 drivers/s390/cio/Makefile | 1 drivers/s390/cio/chp.c | 2 drivers/s390/cio/chsc.c | 48 ++ drivers/s390/cio/chsc.h | 21 - drivers/s390/cio/chsc_sch.c | 820 +++++++++++++++++++++++++++++++++++++++++ drivers/s390/cio/chsc_sch.h | 13 drivers/s390/cio/cio.c | 9 drivers/s390/cio/cio.h | 2 drivers/s390/cio/css.h | 3 drivers/s390/cio/idset.h | 2 drivers/s390/cio/io_sch.h | 2 drivers/s390/cio/ioasm.h | 2 drivers/s390/cio/qdio.h | 3 drivers/s390/cio/schid.h | 26 - include/asm-s390/Kbuild | 3 include/asm-s390/chpid.h | 5 include/asm-s390/chsc.h | 127 ++++++ include/asm-s390/isc.h | 1 include/asm-s390/schid.h | 28 + 21 files changed, 1086 insertions(+), 49 deletions(-)
arch/s390/Kconfig +16 -0
@@ -345,6 +345,22 @@ config QDIO_DEBUG If unsure, say N. +config CHSC_SCH + tristate "Support for CHSC subchannels" + help + This driver allows usage of CHSC subchannels. A CHSC subchannel + is usually present on LPAR only. + The driver creates a device /dev/chsc, which may be used to + obtain I/O configuration information about the machine and + to issue asynchronous chsc commands (DANGEROUS). + You will usually only want to use this interface on a special + LPAR designated for system management. + + To compile this driver as a module, choose M here: the + module will be called chsc_sch. + + If unsure, say N. + comment "Misc" config IPL
Documentation/ioctl-number.txt +1 -0
@@ -117,6 +117,7 @@ Code Seq# Include File Comments <mailto:[email protected]> 'c' 00-7F linux/comstats.h conflict! 'c' 00-7F linux/coda.h conflict! +'c' 80-9F asm-s390/chsc.h 'd' 00-FF linux/char/drm/drm/h conflict! 'd' 00-DF linux/video_decoder.h conflict! 'd' F0-FF linux/digi1.h
drivers/s390/cio/chp.c +1 -1
@@ -407,7 +407,7 @@ int chp_new(struct chp_id chpid) chpid.id);/* Obtain channel path description and fill it in. */ - ret =chsc_determine_channel_path_description (chpid, &chp->desc); + ret =chsc_determine_base_channel_path_desc (chpid, &chp->desc);if (ret) goto out_free;if ((chp->desc.flags &0x80 ) ==0 ) {
drivers/s390/cio/chsc.c +41 -7
92 lines not on this page · raw message
drivers/s390/cio/chsc.h +15 -6
@@ -4,7 +4,8 @@#include <linux/types.h> #include <linux/device.h> #include <asm/chpid.h> -#include "schid.h" +#include <asm/chsc.h> +#include <asm/schid.h> #define CHSC_SDA_OC_MSS 0x2
@@ -37,11 +38,14 @@ struct channel_path_desc {struct channel_path ;struct css_general_char { - u64 : 41; + u64 : 12; +u32 dynio :1 ;/* bit 12 */ + u32 : 28;u32 aif :1 ;/* bit 41 */ u32 : 3;u32 mcss :1 ;/* bit 45 */ - u32 : 2; +u32 fcs :1 ;/* bit 46 */ + u32 : 1;u32 ext_mb :1 ;/* bit 48 */ u32 : 7;u32 aif_tdd :1 ;/* bit 56 */
@@ -49,7 +53,9 @@ struct css_general_char { u32 qebsm : 1; /* bit 58 */ u32 :8 ; u32 aif_osa : 1; /* bit 67 */ - u32 :20 ; + u32 :14 ; + u32 cib : 1; /* bit 82 */ + u32 :5 ; u32 fcx : 1; /* bit 88 */ u32 :7 ; }__attribute__((packed));
@@ -86,8 +92,11 @@ struct channel_subsystem;extern int chsc_secm (struct channel_subsystem *,int );int chsc_chp_vary (struct chp_id chpid,int on); -int chsc_determine_channel_path_description (struct chp_id chpid, -struct channel_path_desc *desc); +int chsc_determine_channel_path_desc (struct chp_id chpid,int fmt,int rfmt, +int c,int m, +struct chsc_response_struct *resp); +int chsc_determine_base_channel_path_desc (struct chp_id chpid, +struct channel_path_desc *desc);void chsc_chp_online (struct chp_id chpid);void chsc_chp_offline (struct chp_id chpid);int chsc_get_channel_measurement_chars (struct channel_path *chp);
drivers/s390/cio/chsc_sch.c new file +820 -0
820 lines not on this page · raw message
drivers/s390/cio/chsc_sch.h new file +13 -0
@@ -0,0 +1,13 @@ +#ifndef _CHSC_SCH_H +#define _CHSC_SCH_H + +struct chsc_request { +struct completion completion; +struct irb irb; +}; + +struct chsc_private { +struct chsc_request *request; +}; + +#endif
drivers/s390/cio/cio.c +9 -0
@@ -877,6 +877,12 @@ __clear_io_subchannel_easy(struct subchareturn -EBUSY ; } +static void __clear_chsc_subchannel_easy (void ) +{ +/* It seems we can only wait for a bit here :/ */ +udelay_reset (100 ); +} +static int pgm_check_occured;static void cio_reset_pgm_check_handler (void )
@@ -920,6 +926,9 @@ static int __shutdown_subchannel_easy(stif (__clear_io_subchannel_easy (schid)) goto out;/* give up... */ break ; +case SUBCHANNEL_TYPE_CHSC : +__clear_chsc_subchannel_easy (); +break ;default :/* No default clear strategy */ break ;
drivers/s390/cio/cio.h +1 -1
@@ -7,8 +7,8 @@#include <asm/chpid.h> #include <asm/cio.h> #include <asm/fcx.h> +#include <asm/schid.h> #include "chsc.h" -#include "schid.h" /* * path management control word
drivers/s390/cio/css.h +1 -2
@@ -9,8 +9,7 @@#include <asm/cio.h> #include <asm/chpid.h> - -#include "schid.h" +#include <asm/schid.h> /* * path grouping stuff
drivers/s390/cio/idset.h +1 -1
@@ -8,7 +8,7 @@#ifndef S390_IDSET_H #define S390_IDSET_H S390_IDSET_H -#include "schid.h" +#include <asm/schid.h> struct idset ;
drivers/s390/cio/ioasm.h +1 -1
@@ -2,7 +2,7 @@#define S390_CIO_IOASM_H #include <asm/chpid.h> -#include "schid.h" +#include <asm/schid.h> /* * TPI info structure
drivers/s390/cio/io_sch.h +1 -1
@@ -1,7 +1,7 @@#ifndef S390_IO_SCH_H #define S390_IO_SCH_H -#include "schid.h" +#include <asm/schid.h> /* * command-mode operation request block
drivers/s390/cio/Makefile +1 -0
@@ -7,5 +7,6 @@ obj-y += airq.o blacklist.o chsc.o cio.o ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o cmf.o +obj-$(CONFIG_CHSC_SCH) += chsc_sch.o obj-$(CONFIG_CCWGROUP) += ccwgroup.o obj-$(CONFIG_QDIO) += qdio.o
drivers/s390/cio/qdio.h +1 -2
@@ -3,8 +3,7 @@#include <asm/page.h> #include <asm/isc.h> - -#include "schid.h" +#include <asm/schid.h> #ifdef CONFIG_QDIO_DEBUG #define QDIO_VERBOSE_LEVEL 9
drivers/s390/cio/schid.h deleted +0 -26
@@ -1,26 +0,0 @@ -#ifndef S390_SCHID_H -#define S390_SCHID_H - -struct subchannel_id { -__u32 reserved:13 ; -__u32 ssid:2 ; -__u32 one:1 ; -__u32 sch_no:16 ; -} __attribute__ ((packed,aligned (4 ))); - - -/* Helper function for sane state of pre-allocated subchannel_id. */ -static inline void -init_subchannel_id (struct subchannel_id *schid) -{ -memset (schid,0 ,sizeof (struct subchannel_id )); - schid->one =1 ; -} - -static inline int -schid_equal (struct subchannel_id *schid1,struct subchannel_id *schid2) -{ -return !memcmp (schid1, schid2,sizeof (struct subchannel_id )); -} - -#endif /* S390_SCHID_H */
include/asm-s390/chpid.h +4 -1
@@ -10,7 +10,6 @@#include <linux/string.h> #include <asm/types.h> -#include <asm/cio.h> #define __MAX_CHPID 255
@@ -41,6 +40,9 @@ static inline void chp_id_next(struct ch } } +#ifdef __KERNEL__ +#include <asm/cio.h> +static inline int chp_id_is_valid (struct chp_id *chpid) {return (chpid->cssid <= __MAX_CSSID);
@@ -49,5 +51,6 @@ static inline int chp_id_is_valid(struct#define chp_id_for_each (c) \ for (chp_id_init(c); chp_id_is_valid(c); chp_id_next(c)) +#endif /* __KERNEL */ #endif /* _ASM_S390_CHPID_H */
include/asm-s390/chsc.h new file +127 -0
127 lines not on this page · raw message
include/asm-s390/isc.h +1 -0
@@ -14,6 +14,7 @@/* Regular I/O interrupts. */ #define IO_SCH_ISC 3/* regular I/O subchannels */ #define CONSOLE_ISC 1/* console I/O subchannel */ +#define CHSC_SCH_ISC 7/* CHSC subchannels */ /* Adapter interrupts. */ #define QDIO_AIRQ_ISC IO_SCH_ISC/* I/O subchannel in qdio mode */
include/asm-s390/Kbuild +3 -0
@@ -8,6 +8,9 @@ header-y += ucontext.h header-y += vtoc.h header-y += zcrypt.h header-y += kvm.h +header-y += schid.h +header-y += chsc.h unifdef-y += cmb.h unifdef-y += debug.h +unifdef-y += chpid.h
include/asm-s390/schid.h new file +28 -0
@@ -0,0 +1,28 @@ +#ifndef ASM_SCHID_H +#define ASM_SCHID_H + +struct subchannel_id { +__u32 cssid :8 ; + __u32 : 4; +__u32 m :1 ; +__u32 ssid :2 ; +__u32 one :1 ; +__u32 sch_no :16 ; +} __attribute__ ((packed,aligned (4 ))); + + +/* Helper function for sane state of pre-allocated subchannel_id. */ +static inline void +init_subchannel_id (struct subchannel_id *schid) +{ +memset (schid,0 ,sizeof (struct subchannel_id )); + schid->one =1 ; +} + +static inline int +schid_equal (struct subchannel_id *schid1,struct subchannel_id *schid2) +{ +return !memcmp (schid1, schid2,sizeof (struct subchannel_id )); +} + +#endif /* ASM_SCHID_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 10/14 idle: remove idle notifier chain.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
The idle notifier chain consists of at most one element. So there's no point in having a notifier chain. Remove it and directly call the function.
---
arch/s390/kernel/process.c | 32 ++------------------------------ arch/s390/kernel/vtime.c | 25 ++----------------------- include/asm-s390/processor.h | 10 ---------- include/asm-s390/timer.h | 12 ++++++++++++ 4 files changed, 16 insertions(+), 63 deletions(-)
arch/s390/kernel/process.c +2 -30
@@ -75,46 +75,19 @@ unsigned long thread_saved_pc(struct tasreturn sf->gprs[8 ]; } -/* -* Need to know about CPUs going idle? -*/ -static ATOMIC_NOTIFIER_HEAD (idle_chain); DEFINE_PER_CPU(struct s390_idle_data, s390_idle); -int register_idle_notifier (struct notifier_block *nb) -{ -return atomic_notifier_chain_register (&idle_chain, nb); -} -EXPORT_SYMBOL (register_idle_notifier); - -int unregister_idle_notifier (struct notifier_block *nb) -{ -return atomic_notifier_chain_unregister (&idle_chain, nb); -} -EXPORT_SYMBOL (unregister_idle_notifier); -static int s390_idle_enter (void ) {struct s390_idle_data *idle; -int nr_calls =0 ; -void *hcpu; -int rc; - hcpu = (void *)(long )smp_processor_id (); - rc =__atomic_notifier_call_chain (&idle_chain,S390_CPU_IDLE , hcpu,-1 , - &nr_calls); -if (rc ==NOTIFY_BAD ) { - nr_calls--; -__atomic_notifier_call_chain (&idle_chain,S390_CPU_NOT_IDLE , - hcpu, nr_calls,NULL ); -return rc; - } idle = &__get_cpu_var (s390_idle);spin_lock (&idle->lock); idle->idle_count++; idle->in_idle =1 ; idle->idle_enter =get_clock ();spin_unlock (&idle->lock); +vtime_stop_cpu_timer ();return NOTIFY_OK ; }
@@ -122,13 +95,12 @@ void s390_idle_leave(void) {struct s390_idle_data *idle; +vtime_start_cpu_timer (); idle = &__get_cpu_var (s390_idle);spin_lock (&idle->lock); idle->idle_time +=get_clock () - idle->idle_enter; idle->in_idle =0 ;spin_unlock (&idle->lock); -atomic_notifier_call_chain (&idle_chain,S390_CPU_NOT_IDLE , - (void *)(long )smp_processor_id ()); }extern void s390_handle_mcck (void );
arch/s390/kernel/vtime.c +2 -23
@@ -136,7 +136,7 @@ static inline void set_vtimer(__u64 expi }#endif -static void start_cpu_timer (void ) +void vtime_start_cpu_timer (void ) {struct vtimer_queue *vt_list;
@@ -150,7 +150,7 @@ static void start_cpu_timer(void)set_vtimer (vt_list->idle); } -static void stop_cpu_timer (void ) +void vtime_stop_cpu_timer (void ) {struct vtimer_queue *vt_list;
@@ -536,24 +536,6 @@ void init_cpu_vtimer(void) } -static int vtimer_idle_notify (struct notifier_block *self, -unsigned long action,void *hcpu) -{ -switch (action) { -case S390_CPU_IDLE : -stop_cpu_timer (); -break ; -case S390_CPU_NOT_IDLE : -start_cpu_timer (); -break ; - } -return NOTIFY_OK ; -} - -static struct notifier_block vtimer_idle_nb = { - .notifier_call = vtimer_idle_notify, -}; -void __init vtime_init (void ) {/* request the cpu timer external interrupt */
@@ -561,9 +543,6 @@ void __init vtime_init(void) &ext_int_info_timer) != 0)panic ("Couldn't request external interrupt 0x1005" ); -if (register_idle_notifier (&vtimer_idle_nb)) -panic ("Couldn't register idle notifier" ); -/* Enable cpu timer interrupts on the boot cpu. */ init_cpu_vtimer (); }
include/asm-s390/processor.h +0 -10
@@ -336,16 +336,6 @@ extern void (*s390_base_mcck_handler_fn)extern void (*s390_base_pgm_handler_fn)(void );extern void (*s390_base_ext_handler_fn)(void ); -/* -* CPU idle notifier chain. -*/ -#define S390_CPU_IDLE 0 -#define S390_CPU_NOT_IDLE 1 - -struct notifier_block ; -int register_idle_notifier (struct notifier_block *nb); -int unregister_idle_notifier (struct notifier_block *nb); -#define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL#endif
include/asm-s390/timer.h +12 -0
@@ -48,6 +48,18 @@ extern int del_virt_timer(struct vtimer_extern void init_cpu_vtimer (void );extern void vtime_init (void ); +#ifdef CONFIG_VIRT_TIMER + +extern void vtime_start_cpu_timer (void ); +extern void vtime_stop_cpu_timer (void ); + +#else + +static inline void vtime_start_cpu_timer (void ) { } +static inline void vtime_stop_cpu_timer (void ) { } + +#endif /* CONFIG_VIRT_TIMER */ +#endif /* __KERNEL__ */ #endif /* _ASM_S390_TIMER_H */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 11/14 sclp: simplify vt220 cleanup logic
In reply to Martin SchwidefskyFrom: Peter Oberparleiter <[email protected]>
Fix a number of sclp_vt220 cleanup problems:
* fix list_empty check after list_del()
* mark init-only flag as __initdata
* remove implicit dependency between slab_available() and num_pages
* straighten multiple init handling (use init count)
---
drivers/s390/char/sclp_vt220.c | 55 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 27 deletions(-)
drivers/s390/char/sclp_vt220.c +28 -27
@@ -82,8 +82,8 @@ static struct sclp_vt220_request *sclp_v/* Number of characters in current request buffer */ static int sclp_vt220_buffered_chars; -/* Flag indicating whether this driver has already been initialized */ -static int sclp_vt220_initialized =0 ; +/* Counter controlling core driver initialization. */ +static int __initdata sclp_vt220_init_count;/* Flag indicating that sclp_vt220_current_request should really * have been already queued but wasn't because the SCLP was processing
@@ -609,10 +609,8 @@ sclp_vt220_flush_buffer(struct tty_strucsclp_vt220_emit_current (); } -/* -* Initialize all relevant components and register driver with system. -*/ -static void __init __sclp_vt220_cleanup (void ) +/* Release allocated pages. */ +static void __init __sclp_vt220_free_pages (void ) {struct list_head *page, *p;
@@ -623,21 +621,30 @@ static void __init __sclp_vt220_cleanup(else free_bootmem ((unsigned long ) page,PAGE_SIZE ); } -if (!list_empty (&sclp_vt220_register.list)) -sclp_unregister (&sclp_vt220_register); - sclp_vt220_initialized =0 ; } -static int __init __sclp_vt220_init (void ) +/* Release memory and unregister from sclp core. Controlled by init counting - +* only the last invoker will actually perform these actions. */ +static void __init __sclp_vt220_cleanup (void ) +{ + sclp_vt220_init_count--; +if (sclp_vt220_init_count !=0 ) +return ; +sclp_unregister (&sclp_vt220_register); +__sclp_vt220_free_pages (); +} + +/* Allocate buffer pages and register with sclp core. Controlled by init +* counting - only the first invoker will actually perform these actions. */ +static int __init __sclp_vt220_init (int num_pages) {void *page;int i; -int num_pages;int rc; -if (sclp_vt220_initialized) + sclp_vt220_init_count++; +if (sclp_vt220_init_count !=1 )return 0 ; - sclp_vt220_initialized =1 ;spin_lock_init (&sclp_vt220_lock);INIT_LIST_HEAD (&sclp_vt220_empty);INIT_LIST_HEAD (&sclp_vt220_outqueue);
@@ -649,24 +656,22 @@ static int __init __sclp_vt220_init(void sclp_vt220_flush_later =0 ;/* Allocate pages for output buffering */ - num_pages =slab_is_available () ?MAX_KMEM_PAGES :MAX_CONSOLE_PAGES ;for (i =0 ; i < num_pages; i++) {if (slab_is_available ()) page = (void *)get_zeroed_page (GFP_KERNEL |GFP_DMA );else page =alloc_bootmem_low_pages (PAGE_SIZE );if (!page) { -__sclp_vt220_cleanup (); -return -ENOMEM ; + rc = -ENOMEM ; + goto out; }list_add_tail ((struct list_head *) page, &sclp_vt220_empty); } rc =sclp_register (&sclp_vt220_register); +out:if (rc) { - printk(KERN_ERR SCLP_VT220_PRINT_HEADER -"could not register vt220 - " - "sclp_register returned %d\n", rc); -__sclp_vt220_cleanup (); +__sclp_vt220_free_pages (); + sclp_vt220_init_count--; }return rc; }
@@ -689,15 +694,13 @@ static int __init sclp_vt220_tty_init(vo {struct tty_driver *driver;int rc; -int cleanup;/* Note: we're not testing for CONSOLE_IS_SCLP here to preserve * symmetry between VM and LPAR systems regarding ttyS1. */ driver =alloc_tty_driver (1 );if (!driver)return -ENOMEM ; - cleanup = !sclp_vt220_initialized; - rc =__sclp_vt220_init (); + rc =__sclp_vt220_init (MAX_KMEM_PAGES );if (rc) goto out_driver;
@@ -723,8 +726,7 @@ static int __init sclp_vt220_tty_init(voreturn 0 ; out_init: -if (cleanup) -__sclp_vt220_cleanup (); +__sclp_vt220_cleanup (); out_driver:put_tty_driver (driver);return rc;
@@ -773,10 +775,9 @@ sclp_vt220_con_init(void) {int rc; -INIT_LIST_HEAD (&sclp_vt220_register.list);if (!CONSOLE_IS_SCLP )return 0 ; - rc =__sclp_vt220_init (); + rc =__sclp_vt220_init (MAX_CONSOLE_PAGES );if (rc)return rc;/* Attach linux console */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 12/14 ap: Use high-resolution timer for polling
In reply to Martin SchwidefskyFrom: Felix Beck <[email protected]>
The ap poll mechanism is converted to use a high-resolution timer for polling. This allows more specific polling. With this a new sysfs attribute is introduced to specify the polling rate in nanoseconds.
---
drivers/s390/crypto/ap_bus.c | 63 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 10 deletions(-)
drivers/s390/crypto/ap_bus.c +53 -10
@@ -34,13 +34,15 @@#include <linux/mutex.h> #include <asm/s390_rdev.h> #include <asm/reset.h> +#include <linux/hrtimer.h> +#include <linux/ktime.h> #include "ap_bus.h" /* Some prototypes. */ static void ap_scan_bus (struct work_struct *);static void ap_poll_all (unsigned long ); -static void ap_poll_timeout (unsigned long ); +static enum hrtimer_restart ap_poll_timeout (struct hrtimer *);static int ap_poll_thread_start (void );static void ap_poll_thread_stop (void );static void ap_request_timeout (unsigned long );
@@ -80,12 +82,15 @@ static DECLARE_WORK(ap_config_work, ap_s/* * Tasklet & timer for AP request polling. */ -static struct timer_list ap_poll_timer =TIMER_INITIALIZER (ap_poll_timeout,0 ,0 ); static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);static atomic_t ap_poll_requests =ATOMIC_INIT (0 );static DECLARE_WAIT_QUEUE_HEAD (ap_poll_wait);static struct task_struct *ap_poll_kthread =NULL ;static DEFINE_MUTEX (ap_poll_thread_mutex); +static struct hrtimer ap_poll_timer; +/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds. +* If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/ +static unsigned long long poll_timeout =250000 ;/** * ap_intructions_available() - Test if AP instructions are available.
@@ -636,11 +641,39 @@ static ssize_t ap_poll_thread_store(stru static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store); +static ssize_t poll_timeout_show (struct bus_type *bus,char *buf) +{ +return snprintf (buf,PAGE_SIZE ,"%llu\n" , poll_timeout); +} + +static ssize_t poll_timeout_store (struct bus_type *bus,const char *buf, +size_t count) +{ +unsigned long long time; +ktime_t hr_time; + +/* 120 seconds = maximum poll interval */ +if (sscanf (buf,"%llu\n" , &time) !=1 || time <1 || time >120000000000 ) +return -EINVAL ; + poll_timeout = time; + hr_time =ktime_set (0 , poll_timeout); + +if (!hrtimer_is_queued (&ap_poll_timer) || + !hrtimer_forward (&ap_poll_timer, ap_poll_timer.expires, hr_time)) { + ap_poll_timer.expires = hr_time; +hrtimer_start (&ap_poll_timer, hr_time,HRTIMER_MODE_ABS ); + } +return count; +} + +static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store); +static struct bus_attribute *const ap_bus_attrs[] = { &bus_attr_ap_domain, &bus_attr_config_time, &bus_attr_poll_thread, -NULL + &bus_attr_poll_timeout, +NULL , };/**
@@ -895,9 +928,10 @@ ap_config_timeout(unsigned long ptr)*/ static inline void ap_schedule_poll_timer (void ) { -if (timer_pending (&ap_poll_timer)) +if (hrtimer_is_queued (&ap_poll_timer))return ; -mod_timer (&ap_poll_timer, jiffies +AP_POLL_TIME ); +hrtimer_start (&ap_poll_timer,ktime_set (0 , poll_timeout), +HRTIMER_MODE_ABS ); }/**
@@ -1115,13 +1149,14 @@ EXPORT_SYMBOL(ap_cancel_message);/** * ap_poll_timeout(): AP receive polling for finished AP requests. -* @unused: Unused variable. +* @unused: Unused pointer. * -* Schedules the AP tasklet. +* Schedules the AP tasklet using a high resolution timer. */ -static void ap_poll_timeout (unsigned long unused) +static enum hrtimer_restart ap_poll_timeout (struct hrtimer *unused) {tasklet_schedule (&ap_tasklet); +return HRTIMER_NORESTART ; }/**
@@ -1344,6 +1379,14 @@ int __init ap_module_init(void) ap_config_timer.expires = jiffies + ap_config_time *HZ ;add_timer (&ap_config_timer); +/* Setup the high resultion poll timer. +* If we are running under z/VM adjust polling to z/VM polling rate. +*/ +if (MACHINE_IS_VM ) + poll_timeout =1500000 ; +hrtimer_init (&ap_poll_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_ABS ); + ap_poll_timer.function = ap_poll_timeout; +/* Start the low priority AP bus poll thread. */ if (ap_thread_flag) { rc =ap_poll_thread_start ();
@@ -1355,7 +1398,7 @@ int __init ap_module_init(void) out_work:del_timer_sync (&ap_config_timer); -del_timer_sync (&ap_poll_timer); +hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue); out_root:s390_root_dev_unregister (ap_root_device);
@@ -1386,7 +1429,7 @@ void ap_module_exit(void)ap_reset_domain ();ap_poll_thread_stop ();del_timer_sync (&ap_config_timer); -del_timer_sync (&ap_poll_timer); +hrtimer_cancel (&ap_poll_timer);destroy_workqueue (ap_work_queue);tasklet_kill (&ap_tasklet);s390_root_dev_unregister (ap_root_device);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 13/14 Extra Kernel Parameters via VMPARM
In reply to Martin SchwidefskyFrom: Hendrik Brueckner <[email protected]>
Now it is possible to specify additional kernel parameters on the IPL command line using the IPL PARM option.
If the Linux system is already running, the new reipl sysfs attribute 'parm' can be used to change kernel parameters for the next reboot. Examples:
IPL C PARM dasd=1234 root=/dev/dasda1
IPL 1234 PARM savesys=mylnxnss
echo "init=/bin/bash" > /sys/firmware/reipl/ccw/parm
---
arch/s390/kernel/early.c | 82 +++++++- arch/s390/kernel/ipl.c | 444 ++++++++++++++++++++++++++++++++++++++++------- arch/s390/kernel/setup.c | 17 - include/asm-s390/ipl.h | 17 + include/asm-s390/setup.h | 4 5 files changed, 476 insertions(+), 88 deletions(-)
arch/s390/kernel/early.c +73 -9
@@ -14,6 +14,7 @@#include <linux/module.h> #include <linux/pfn.h> #include <linux/uaccess.h> +#include <asm/ebcdic.h> #include <asm/ipl.h> #include <asm/lowcore.h> #include <asm/processor.h>
@@ -26,12 +27,40 @@/* * Create a Kernel NSS if the SAVESYS= parameter is defined */ -#define DEFSYS_CMD_SIZE 96 +#define DEFSYS_CMD_SIZE 128#define SAVESYS_CMD_SIZE 32char kernel_nss_name[NSS_NAME_SIZE +1 ]; +static void __init setup_boot_command_line (void ); + +#ifdef CONFIG_SHARED_KERNEL +int __init savesys_ipl_nss (char *cmd,const int cmdlen); + +asm( + " .section .init.text,\"ax\",@progbits\n" + " .align 4\n" + " .type savesys_ipl_nss, @function\n" + "savesys_ipl_nss:\n" +#ifdef CONFIG_64BIT + " stmg 6,15,48(15)\n" + " lgr 14,3\n" + " sam31\n" + " diag 2,14,0x8\n" + " sam64\n" + " lgr 2,14\n" + " lmg 6,15,48(15)\n" +#else + " stm 6,15,24(15)\n" + " lr 14,3\n" + " diag 2,14,0x8\n" + " lr 2,14\n" + " lm 6,15,24(15)\n" +#endif +" br 14\n" +" .size savesys_ipl_nss, .-savesys_ipl_nss\n" ); + static noinline __init void create_kernel_nss(void) {unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size;
@@ -39,6 +68,7 @@ static noinline __init void create_kerneunsigned int sinitrd_pfn, einitrd_pfn;#endif int response; +size_t len;char *savesys_ptr;char upper_command_line[COMMAND_LINE_SIZE ];char defsys_cmd[DEFSYS_CMD_SIZE ];
@@ -49,8 +79,8 @@ static noinline __init void create_kernereturn ;/* Convert COMMAND_LINE to upper case */ -for (i =0 ; i <strlen (COMMAND_LINE ); i++) - upper_command_line[i] =toupper (COMMAND_LINE [i]); +for (i =0 ; i <strlen (boot_command_line); i++) + upper_command_line[i] =toupper (boot_command_line[i]); savesys_ptr =strstr (upper_command_line,"SAVESYS=" );
@@ -83,7 +113,8 @@ static noinline __init void create_kerne }#endif -sprintf (defsys_cmd,"%s EW MINSIZE=%.7iK" , defsys_cmd, min_size); +sprintf (defsys_cmd,"%s EW MINSIZE=%.7iK PARMREGS=0-13" , + defsys_cmd, min_size);sprintf (savesys_cmd,"SAVESYS %s \n IPL %s" , kernel_nss_name, kernel_nss_name);
@@ -94,13 +125,24 @@ static noinline __init void create_kernereturn ; } -__cpcmd (savesys_cmd,NULL ,0 , &response); - -if (response !=strlen (savesys_cmd)) { + len =strlen (savesys_cmd); +ASCEBC (savesys_cmd, len); + response =savesys_ipl_nss (savesys_cmd, len); + +/* On success: response is equal to the command size, +* max SAVESYS_CMD_SIZE +* On error: response contains the numeric portion of cp error message. +* for SAVESYS it will be >= 263 +*/ +if (response >SAVESYS_CMD_SIZE ) { kernel_nss_name[0 ] ='\0' ;return ; } +/* re-setup boot command line with new ipl vm parms */ +ipl_update_parameters (); +setup_boot_command_line (); + ipl_flags =IPL_NSS_VALID ; }
@@ -397,6 +439,26 @@ static __init void rescue_initrd(void)#endif } +/* Set up boot command line */ +static void __init setup_boot_command_line (void ) +{ +char *parm =NULL ; + +/* copy arch command line */ +strlcpy (boot_command_line,COMMAND_LINE ,ARCH_COMMAND_LINE_SIZE ); + boot_command_line[ARCH_COMMAND_LINE_SIZE -1 ] =0 ; + +/* append IPL PARM data to the boot command line */ +if (MACHINE_IS_VM ) { + parm = boot_command_line +strlen (boot_command_line); + *parm++ =' ' ; +get_ipl_vmparm (parm); +if (parm[0 ] =='=' ) +memmove (boot_command_line, parm +1 ,strlen (parm)); + } +} + +/* * Save ipl parameters, clear bss memory, initialize storage keys * and create a kernel NSS at startup if the SAVESYS= parm is defined
@@ -411,10 +473,12 @@ void __init startup_init(void)init_kernel_storage_key ();lockdep_init ();lockdep_off (); -detect_machine_type (); -create_kernel_nss ();sort_main_extable ();setup_lowcore_early (); +detect_machine_type (); +ipl_update_parameters (); +setup_boot_command_line (); +create_kernel_nss ();detect_mvpg ();detect_ieee ();detect_csp ();
arch/s390/kernel/ipl.c +379 -65
613 lines not on this page · raw message
arch/s390/kernel/setup.c +7 -10
@@ -221,18 +221,17 @@ static void __init conmode_default(void)#if defined(CONFIG_ZFCPDUMP ) || defined(CONFIG_ZFCPDUMP_MODULE )static void __init setup_zfcpdump (unsigned int console_devno) { -static char str[64 ]; +static char str[41 ];if (ipl_info.type !=IPL_TYPE_FCP_DUMP )return ;if (console_devno !=-1 ) -sprintf (str,"cio_ignore=all,!0.0.%04x,!0.0.%04x" , +sprintf (str," cio_ignore=all,!0.0.%04x,!0.0.%04x" , ipl_info.data.fcp.dev_id.devno, console_devno);else -sprintf (str,"cio_ignore=all,!0.0.%04x" , +sprintf (str," cio_ignore=all,!0.0.%04x" , ipl_info.data.fcp.dev_id.devno); -strcat (COMMAND_LINE ," " ); -strcat (COMMAND_LINE , str); +strcat (boot_command_line, str); console_loglevel =2 ; }#else
@@ -804,11 +803,9 @@ setup_arch(char **cmdline_p)printk ("We are running native (64 bit mode)\n" );#endif /* CONFIG_64BIT */ -/* Save unparsed command line copy for /proc/cmdline */ -strlcpy (boot_command_line,COMMAND_LINE ,COMMAND_LINE_SIZE ); - - *cmdline_p =COMMAND_LINE ; - *(*cmdline_p +COMMAND_LINE_SIZE -1 ) ='\0' ; +/* Have one command line that is parsed and saved in /proc/cmdline */ +/* boot_command_line has been already set up in early.c */ + *cmdline_p = boot_command_line;ROOT_DEV = Root_RAM0;
include/asm-s390/ipl.h +14 -3
@@ -56,15 +56,19 @@ struct ipl_block_fcp {u8 scp_data[]; } __attribute__((packed)); +#define DIAG308_VMPARM_SIZE 64 +struct ipl_block_ccw { -u8 load_param[8 ]; +u8 load_parm[8 ];u8 reserved1[84 ];u8 reserved2[2 ];u16 devno;u8 vm_flags;u8 reserved3[3 ];u32 vm_parm_len; -u8 reserved4[80 ]; +u8 nss_name[8 ]; +u8 vm_parm[DIAG308_VMPARM_SIZE ]; +u8 reserved4[8 ]; } __attribute__((packed));struct ipl_parameter_block {
@@ -73,7 +77,7 @@ struct ipl_parameter_block {struct ipl_block_fcp fcp;struct ipl_block_ccw ccw; } ipl_info; -} __attribute__((packed)); +} __attribute__((packed,aligned(4096)));/* * IPL validity flags
@@ -86,6 +90,8 @@ extern void do_reipl(void);extern void do_halt (void );extern void do_poff (void );extern void ipl_save_parameters (void ); +extern void ipl_update_parameters (void ); +extern void get_ipl_vmparm (char *);enum {IPL_DEVNO_VALID =1 ,
@@ -147,6 +153,11 @@ enum diag308_flags { DIAG308_FLAGS_LP_VALID = 0x80, }; +enum diag308_vm_flags { +DIAG308_VM_FLAGS_NSS_VALID =0x80 , +DIAG308_VM_FLAGS_VP_VALID =0x40 , +}; +enum diag308_rc {DIAG308_RC_OK =1 , };
include/asm-s390/setup.h +3 -1
@@ -8,7 +8,9 @@#ifndef _ASM_S390_SETUP_H#define _ASM_S390_SETUP_H -#define COMMAND_LINE_SIZE 896 +#define COMMAND_LINE_SIZE 1024 + +#define ARCH_COMMAND_LINE_SIZE 896#ifdef __KERNEL__
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 14/14 zcrypt: Add additional card IDs to CEX2C and CEX2A
In reply to Martin SchwidefskyFrom: Ralph Wuerthner <[email protected]>
Add support for new micro code load of CEX2C and CEX2A adapters, which uses different IDs. This patch just adds the IDs to the existing drivers.
---
drivers/s390/crypto/ap_bus.h | 2 ++ drivers/s390/crypto/zcrypt_cex2a.c | 1 + drivers/s390/crypto/zcrypt_pcixcc.c | 1 + include/asm-s390/zcrypt.h | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-)
drivers/s390/crypto/ap_bus.h +2 -0
@@ -92,6 +92,8 @@ struct ap_queue_status {#define AP_DEVICE_TYPE_PCIXCC 5#define AP_DEVICE_TYPE_CEX2A 6#define AP_DEVICE_TYPE_CEX2C 7 +#define AP_DEVICE_TYPE_CEX2A2 8 +#define AP_DEVICE_TYPE_CEX2C2 9/* * AP reset flag states
drivers/s390/crypto/zcrypt_cex2a.c +1 -0
@@ -49,6 +49,7 @@static struct ap_device_id zcrypt_cex2a_ids[] = { {AP_DEVICE (AP_DEVICE_TYPE_CEX2A ) }, + {AP_DEVICE (AP_DEVICE_TYPE_CEX2A2 ) }, {/* end of list */ }, };
drivers/s390/crypto/zcrypt_pcixcc.c +1 -0
@@ -72,6 +72,7 @@ struct response_type {static struct ap_device_id zcrypt_pcixcc_ids[] = { {AP_DEVICE (AP_DEVICE_TYPE_PCIXCC ) }, {AP_DEVICE (AP_DEVICE_TYPE_CEX2C ) }, + {AP_DEVICE (AP_DEVICE_TYPE_CEX2C2 ) }, {/* end of list */ }, };
include/asm-s390/zcrypt.h +1 -1
@@ -29,7 +29,7 @@#define ZCRYPT_VERSION 2#define ZCRYPT_RELEASE 1 -#define ZCRYPT_VARIANT 0 +#define ZCRYPT_VARIANT 1#include <linux/ioctl.h> #include <linux/compiler.h>
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.