Commit 17db3da8 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: comon i/o layer

From: Utz Bacher <utz.bacher@de.ibm.com>
From: Cornelia Huck <cohuck@de.ibm.com>

Common i/o layer changes:
 - Consolidate store channel subsystem characteristics from its three
   users (css, cmf and qdio) to a single location.
 - Always use new stipd format and move creation of global path group
   to channel subsystem init function. Add dummy init_IRQ to setup.c
   and remove requestirq.c.
 - Remove bogus CHPID_LONGS define.
 - Add more magic to catch chpids coming online again without generating
   machine checks.
 - Fix check for unsolicited interrupts. Deferred cc=1 indicates a
   solicited interrupt.
 - Fix progress indication in qdio summary bytes to avoid loosing interrupts.
 - Rename console_device to console_devno to avoid naming conflict.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3fb67b11
......@@ -613,10 +613,6 @@ startup:basr %r13,0 # get base
bne .Lnop390-.LPG1(%r13)
oi 3(%r12),4 # set P/390 flag
.Lnop390:
chi %r0,0x2084 # new stidp format?
bne .Loldfmt-.LPG1(%r13)
oi 3(%r12),64 # set new stidp flag
.Loldfmt:
#
# find out if we have an IEEE fpu
......
......@@ -623,10 +623,6 @@ startup:basr %r13,0 # get base
bne 1f-.LPG1(%r13)
oi 7(%r12),4 # set P/390 flag
1:
chi %r0,0x2084 # new stidp format?
bne 2f-.LPG1(%r13)
oi 7(%r12),64 # set new stidp flag
2:
#
# find out if we have the MVPG instruction
......
......@@ -72,7 +72,8 @@ EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(csum_fold);
EXPORT_SYMBOL(console_mode);
EXPORT_SYMBOL(console_device);
EXPORT_SYMBOL(console_devno);
EXPORT_SYMBOL(console_irq);
EXPORT_SYMBOL_NOVERS(do_call_softirq);
EXPORT_SYMBOL(sys_wait4);
EXPORT_SYMBOL(cpcmd);
......@@ -49,7 +49,7 @@
* Machine setup..
*/
unsigned int console_mode = 0;
unsigned int console_device = -1;
unsigned int console_devno = -1;
unsigned int console_irq = -1;
unsigned long memory_size = 0;
unsigned long machine_flags = 0;
......@@ -160,7 +160,7 @@ static int __init condev_setup(char *str)
vdev = simple_strtoul(str, &str, 0);
if (vdev >= 0 && vdev < 65536) {
console_device = vdev;
console_devno = vdev;
console_irq = -1;
}
return 1;
......@@ -194,7 +194,7 @@ static void __init conmode_default(void)
if (MACHINE_IS_VM) {
cpcmd("QUERY CONSOLE", query_buffer, 1024);
console_device = simple_strtoul(query_buffer + 5, NULL, 16);
console_devno = simple_strtoul(query_buffer + 5, NULL, 16);
ptr = strstr(query_buffer, "SUBCHANNEL =");
console_irq = simple_strtoul(ptr + 13, NULL, 16);
cpcmd("QUERY TERM", query_buffer, 1024);
......@@ -649,3 +649,13 @@ int show_interrupts(struct seq_file *p, void *v)
return 0;
}
/*
* For compatibilty only. S/390 specific setup of interrupts et al. is done
* much later in init_channel_subsystem().
*/
void __init
init_IRQ(void)
{
/* nothing... */
}
......@@ -2,7 +2,7 @@
# Makefile for the S/390 common i/o drivers
#
obj-y += airq.o blacklist.o chsc.o cio.o css.o requestirq.o
obj-y += airq.o blacklist.o chsc.o cio.o css.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
......
/*
* drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call
* $Revision: 1.112 $
* $Revision: 1.114 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
......@@ -942,3 +942,59 @@ chsc_alloc_sei_area(void)
}
subsys_initcall(chsc_alloc_sei_area);
struct css_general_char css_general_characteristics;
struct css_chsc_char css_chsc_characteristics;
int __init
chsc_determine_css_characteristics(void)
{
int result;
struct {
struct chsc_header request;
u32 reserved1;
u32 reserved2;
u32 reserved3;
struct chsc_header response;
u32 reserved4;
u32 general_char[510];
u32 chsc_char[518];
} *scsc_area;
scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scsc_area) {
printk(KERN_WARNING"cio: Was not able to determine available" \
"CHSCs due to no memory.\n");
return -ENOMEM;
}
scsc_area->request = (struct chsc_header) {
.length = 0x0010,
.code = 0x0010,
};
result = chsc(scsc_area);
if (result) {
printk(KERN_WARNING"cio: Was not able to determine " \
"available CHSCs, cc=%i.\n", result);
result = -EIO;
goto exit;
}
if (scsc_area->response.code != 1) {
printk(KERN_WARNING"cio: Was not able to determine " \
"available CHSCs.\n");
result = -EIO;
goto exit;
}
memcpy(&css_general_characteristics, scsc_area->general_char,
sizeof(css_general_characteristics));
memcpy(&css_chsc_characteristics, scsc_area->chsc_char,
sizeof(css_chsc_characteristics));
exit:
free_page ((unsigned long) scsc_area);
return result;
}
EXPORT_SYMBOL_GPL(css_general_characteristics);
EXPORT_SYMBOL_GPL(css_chsc_characteristics);
......@@ -23,4 +23,32 @@ extern struct channel_path *chps[];
extern void s390_process_css( void );
extern void chsc_validate_chpids(struct subchannel *);
extern void chpid_is_actually_online(int);
struct css_general_char {
u64 : 41;
u32 aif : 1; /* bit 41 */
u32 : 3;
u32 mcss : 1; /* bit 45 */
u32 : 2;
u32 ext_mb : 1; /* bit 48 */
u32 : 7;
u32 aif_tdd : 1; /* bit 56 */
u32 : 10;
u32 aif_osa : 1; /* bit 67 */
u32 : 28;
}__attribute__((packed));
struct css_chsc_char {
u64 res;
u64 : 43;
u32 scssc : 1; /* bit 107 */
u32 scsscf : 1; /* bit 108 */
u32 : 19;
}__attribute__((packed));
extern struct css_general_char css_general_characteristics;
extern struct css_chsc_char css_chsc_characteristics;
extern int chsc_determine_css_characteristics(void);
extern int css_characteristics_avail;
#endif
......@@ -688,15 +688,15 @@ cio_console_irq(void)
if (stsch(console_irq, &console_subchannel.schib) != 0 ||
!console_subchannel.schib.pmcw.dnv)
return -1;
console_device = console_subchannel.schib.pmcw.dev;
} else if (console_device != -1) {
console_devno = console_subchannel.schib.pmcw.dev;
} else if (console_devno != -1) {
/* At least the console device number is known. */
for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
if (stsch(irq, &console_subchannel.schib) != 0)
break;
if (console_subchannel.schib.pmcw.dnv &&
console_subchannel.schib.pmcw.dev ==
console_device) {
console_devno) {
console_irq = irq;
break;
}
......
/*
* linux/drivers/s390/cio/cmf.c ($Revision: 1.13 $)
* linux/drivers/s390/cio/cmf.c ($Revision: 1.15 $)
*
* Linux on zSeries Channel Measurement Facility support
*
......@@ -39,6 +39,7 @@
#include "css.h"
#include "device.h"
#include "ioasm.h"
#include "chsc.h"
/* parameter to enable cmf during boot, possible uses are:
* "s390cmf" -- enable cmf and allocate 2 MB of ram so measuring can be
......@@ -996,7 +997,8 @@ init_cmf(void)
see if we are running on z990 or up, otherwise fall back to basic mode. */
if (format == CMF_AUTODETECT) {
if (!MACHINE_NEW_STIDP) {
if (!css_characteristics_avail ||
!css_general_characteristics.ext_mb) {
format = CMF_BASIC;
} else {
format = CMF_EXTENDED;
......
/*
* drivers/s390/cio/css.c
* driver for channel subsystem
* $Revision: 1.77 $
* $Revision: 1.80 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
......@@ -19,11 +19,15 @@
#include "cio.h"
#include "cio_debug.h"
#include "ioasm.h"
#include "chsc.h"
unsigned int highest_subchannel;
int need_rescan = 0;
int css_init_done = 0;
struct pgid global_pgid;
int css_characteristics_avail = 0;
struct device css_bus_device = {
.bus_id = "css0",
};
......@@ -201,6 +205,20 @@ css_evaluate_subchannel(int irq, int slow)
ret = 0;
break;
}
if (disc && (event == CIO_NO_PATH)) {
/*
* Uargh, hack again. Because we don't get a machine
* check on configure on, our path bookkeeping can
* be out of date here (it's fine while we only do
* logical varying or get chsc machine checks). We
* need to force reprobing or we might miss devices
* coming operational again. It won't do harm in real
* no path situations.
*/
device_trigger_reprobe(sch);
ret = 0;
break;
}
if (sch->driver && sch->driver->notify &&
sch->driver->notify(&sch->dev, event)) {
cio_disable_subchannel(sch);
......@@ -352,9 +370,26 @@ css_process_crw(int irq)
return ret;
}
static void __init
css_generate_pgid(void)
{
/* Let's build our path group ID here. */
if (css_characteristics_avail && css_general_characteristics.mcss)
global_pgid.cpu_addr = 0x8000;
else {
#ifdef CONFIG_SMP
global_pgid.cpu_addr = hard_smp_processor_id();
#else
global_pgid.cpu_addr = 0;
#endif
}
global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
global_pgid.tod_high = (__u32) (get_clock() >> 32);
}
/*
* some of the initialization has already been done from init_IRQ(),
* here we do the rest now that the driver core is running.
* Now that the driver core is running, we can setup our channel subsystem.
* The struct subchannel's are created during probing (except for the
* static console subchannel).
*/
......@@ -363,6 +398,11 @@ init_channel_subsystem (void)
{
int ret, irq;
if (chsc_determine_css_characteristics() == 0)
css_characteristics_avail = 1;
css_generate_pgid();
if ((ret = bus_register(&css_bus_type)))
goto out;
if ((ret = device_register (&css_bus_device)))
......@@ -517,3 +557,4 @@ MODULE_LICENSE("GPL");
EXPORT_SYMBOL(css_bus_type);
EXPORT_SYMBOL(s390_root_dev_register);
EXPORT_SYMBOL(s390_root_dev_unregister);
EXPORT_SYMBOL_GPL(css_characteristics_avail);
......@@ -672,8 +672,20 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
irb = (struct irb *) __LC_IRB;
/* Check for unsolicited interrupt. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if ((irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
&& (!irb->scsw.cc)) {
if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
!irb->esw.esw0.erw.cons) {
/* Unit check but no sense data. Need basic sense. */
if (ccw_device_do_sense(cdev, irb) != 0)
goto call_handler_unsol;
memcpy(irb, &cdev->private->irb, sizeof(struct irb));
cdev->private->state = DEV_STATE_W4SENSE;
cdev->private->intparm = 0;
return;
}
call_handler_unsol:
if (cdev->handler)
cdev->handler (cdev, 0, irb);
return;
......@@ -735,11 +747,15 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
/* Check for unsolicited interrupt. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if (cdev->handler)
cdev->handler (cdev, 0, irb);
if (irb->scsw.cc == 1)
/* Basic sense hasn't started. Try again. */
ccw_device_do_sense(cdev, irb);
else {
printk("Huh? %s(%s): unsolicited interrupt...\n",
__FUNCTION__, cdev->dev.bus_id);
if (cdev->handler)
cdev->handler (cdev, 0, irb);
}
return;
}
/* Add basic sense info to irb. */
......@@ -762,13 +778,6 @@ ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event)
struct irb *irb;
irb = (struct irb *) __LC_IRB;
/* Check for unsolicited interrupt. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if (cdev->handler)
cdev->handler (cdev, 0, irb);
return;
}
/* Accumulate status. We don't do basic sense. */
ccw_device_accumulate_irb(cdev, irb);
/* Try to start delayed device verification. */
......@@ -834,15 +843,6 @@ ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event)
struct subchannel *sch;
irb = (struct irb *) __LC_IRB;
/* Check for unsolicited interrupt. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if (cdev->handler)
cdev->handler (cdev, 0, irb);
if (irb->scsw.cc == 1)
goto call_handler;
return;
}
/*
* Accumulate status and find out if a basic sense is needed.
* This is fine since we have already adapted the lpm.
......@@ -854,7 +854,7 @@ ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event)
}
return;
}
call_handler:
/* Iff device is idle, reset timeout. */
sch = to_subchannel(cdev->dev.parent);
if (!stsch(sch->irq, &sch->schib))
......@@ -923,8 +923,9 @@ ccw_device_stlck_done(struct ccw_device *cdev, enum dev_event dev_event)
case DEV_EVENT_INTERRUPT:
irb = (struct irb *) __LC_IRB;
/* Check for unsolicited interrupt. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
if ((irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
(!irb->scsw.cc))
/* FIXME: we should restart stlck here, but this
* is extremely unlikely ... */
goto out_wakeup;
......
......@@ -303,15 +303,14 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
sch = to_subchannel(cdev->dev.parent);
irb = (struct irb *) __LC_IRB;
/*
* Unsolicited interrupts may pertain to an earlier status pending or
* busy condition on the subchannel. Retry sense id.
*/
/* Retry sense id for cc=1. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
ret = __ccw_device_sense_id_start(cdev);
if (ret && ret != -EBUSY)
ccw_device_sense_id_done(cdev, ret);
if (irb->scsw.cc == 1) {
ret = __ccw_device_sense_id_start(cdev);
if (ret && ret != -EBUSY)
ccw_device_sense_id_done(cdev, ret);
}
return;
}
if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
......
/*
* drivers/s390/cio/device_ops.c
*
* $Revision: 1.34 $
* $Revision: 1.47 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
......
......@@ -143,15 +143,14 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;
irb = (struct irb *) __LC_IRB;
/*
* Unsolicited interrupts may pertain to an earlier status pending or
* busy condition on the subchannel. Retry sense pgid.
*/
/* Retry sense pgid for cc=1. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
ret = __ccw_device_sense_pgid_start(cdev);
if (ret && ret != -EBUSY)
ccw_device_sense_pgid_done(cdev, ret);
if (irb->scsw.cc == 1) {
ret = __ccw_device_sense_pgid_start(cdev);
if (ret && ret != -EBUSY)
ccw_device_sense_pgid_done(cdev, ret);
}
return;
}
if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
......@@ -310,13 +309,11 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
struct irb *irb;
irb = (struct irb *) __LC_IRB;
/*
* Unsolicited interrupts may pertain to an earlier status pending or
* busy condition on the subchannel. Restart path verification.
*/
/* Retry set pgid for cc=1. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
__ccw_device_verify_start(cdev);
if (irb->scsw.cc == 1)
__ccw_device_verify_start(cdev);
return;
}
if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
......@@ -397,10 +394,13 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;
irb = (struct irb *) __LC_IRB;
/* Ignore unsolicited interrupts. */
/* Retry set pgid for cc=1. */
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
if (irb->scsw.cc == 1)
__ccw_device_disband_start(cdev);
return;
}
if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
return;
sch = to_subchannel(cdev->dev.parent);
......
......@@ -35,7 +35,7 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
return;
CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check "
"received\n"
"received"
" ... device %04X on subchannel %04X, dev_stat "
": %02X sch_stat : %02X\n",
cdev->private->devno, cdev->private->irq,
......@@ -216,8 +216,9 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
/*
* Don't accumulate unsolicited interrupts.
*/
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
if ((irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
(!irb->scsw.cc))
return;
cdev_irb = &cdev->private->irb;
......
......@@ -56,7 +56,7 @@
#include "ioasm.h"
#include "chsc.h"
#define VERSION_QDIO_C "$Revision: 1.80 $"
#define VERSION_QDIO_C "$Revision: 1.83 $"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
......@@ -354,7 +354,8 @@ qdio_stop_polling(struct qdio_q *q)
SLSB_P_INPUT_NOT_INIT);
/*
* we don't issue this SYNC_MEMORY, as we trust Rick T and
* moreover will not use the PROCESSING state, so q->polling was 0
* moreover will not use the PROCESSING state under VM, so
* q->polling was 0 anyway
*/
/*SYNC_MEMORY;*/
if (q->slsb.acc.val[gsf]!=SLSB_P_INPUT_PRIMED)
......@@ -732,6 +733,9 @@ qdio_get_inbound_buffer_frontier(struct qdio_q *q)
volatile char *slsb;
int first_not_to_check;
char dbf_text[15];
#ifdef QDIO_USE_PROCESSING_STATE
int last_position=-1;
#endif /* QDIO_USE_PROCESSING_STATE */
QDIO_DBF_TEXT4(0,trace,"getibfro");
QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
......@@ -774,8 +778,14 @@ qdio_get_inbound_buffer_frontier(struct qdio_q *q)
if (q->siga_sync) {
set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
} else {
set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_PROCESSING);
/* set the previous buffer to NOT_INIT. The current
* buffer will be set to PROCESSING at the end of
* this function to avoid further interrupts. */
if (last_position>=0)
set_slsb(&slsb[last_position],
SLSB_P_INPUT_NOT_INIT);
atomic_set(&q->polling,1);
last_position=f_mod_no;
}
#else /* QDIO_USE_PROCESSING_STATE */
set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
......@@ -814,6 +824,10 @@ qdio_get_inbound_buffer_frontier(struct qdio_q *q)
f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
atomic_dec(&q->number_of_buffers_used);
#ifdef QDIO_USE_PROCESSING_STATE
last_position=-1;
#endif /* QDIO_USE_PROCESSING_STATE */
break;
/* everything else means frontier not changed (HALTED or so) */
......@@ -823,6 +837,11 @@ qdio_get_inbound_buffer_frontier(struct qdio_q *q)
out:
q->first_to_check=f_mod_no;
#ifdef QDIO_USE_PROCESSING_STATE
if (last_position>=0)
set_slsb(&slsb[last_position],SLSB_P_INPUT_PROCESSING);
#endif /* QDIO_USE_PROCESSING_STATE */
QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
return q->first_to_check;
......@@ -1160,7 +1179,7 @@ qdio_inbound_processing(struct qdio_q *q)
#ifdef QDIO_USE_PROCESSING_STATE
static inline int
tiqdio_do_inbound_checks(struct qdio_q *q, int q_laps)
tiqdio_reset_processing_state(struct qdio_q *q, int q_laps)
{
if (!q) {
tiqdio_sched_tl();
......@@ -1247,7 +1266,7 @@ tiqdio_inbound_checks(void)
do {
int ret;
ret = tiqdio_do_inbound_checks(q, q_laps);
ret = tiqdio_reset_processing_state(q, q_laps);
switch (ret) {
case 0:
return;
......@@ -1971,77 +1990,36 @@ qdio_check_siga_needs(int sch)
static unsigned int
tiqdio_check_chsc_availability(void)
{
int result;
char dbf_text[15];
struct {
struct chsc_header request;
u32 reserved1;
u32 reserved2;
u32 reserved3;
struct chsc_header response;
u32 reserved4;
u32 general_char[510];
u32 chsc_char[518];
} *scsc_area;
scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scsc_area) {
QDIO_PRINT_WARN("Was not able to determine available" \
"CHSCs due to no memory.\n");
return -ENOMEM;
}
scsc_area->request = (struct chsc_header) {
.length = 0x0010,
.code = 0x0010,
};
result=chsc(scsc_area);
if (result) {
QDIO_PRINT_WARN("Was not able to determine " \
"available CHSCs, cc=%i.\n",
result);
result=-EIO;
goto exit;
}
if (!css_characteristics_avail)
return -EIO;
if (scsc_area->response.code != 1) {
QDIO_PRINT_WARN("Was not able to determine " \
"available CHSCs.\n");
result=-EIO;
goto exit;
}
/* Check for bit 41. */
if ((scsc_area->general_char[1] & 0x00400000) != 0x00400000) {
if (!css_general_characteristics.aif) {
QDIO_PRINT_WARN("Adapter interruption facility not " \
"installed.\n");
result=-ENOENT;
goto exit;
return -ENOENT;
}
/* Check for bits 107 and 108. */
if ((scsc_area->chsc_char[3] & 0x00180000) != 0x00180000) {
if (!css_chsc_characteristics.scssc ||
!css_chsc_characteristics.scsscf) {
QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \
"not available.\n");
result=-ENOENT;
goto exit;
return -ENOENT;
}
/* Check for OSA/FCP thin interrupts (bit 67). */
hydra_thinints = ((scsc_area->general_char[2] & 0x10000000)
== 0x10000000);
hydra_thinints = css_general_characteristics.aif_osa;
sprintf(dbf_text,"hydrati%1x", hydra_thinints);
QDIO_DBF_TEXT0(0,setup,dbf_text);
/* Check for aif time delay disablement fac (bit 56). If installed,
* omit svs even under lpar (good point by rick again) */
omit_svs = ((scsc_area->general_char[1] & 0x00000080)
== 0x00000080);
omit_svs = css_general_characteristics.aif_tdd;
sprintf(dbf_text,"omitsvs%1x", omit_svs);
QDIO_DBF_TEXT0(0,setup,dbf_text);
exit:
free_page ((unsigned long) scsc_area);
return result;
return 0;
}
......
#ifndef _CIO_QDIO_H
#define _CIO_QDIO_H
#define VERSION_CIO_QDIO_H "$Revision: 1.23 $"
#define VERSION_CIO_QDIO_H "$Revision: 1.24 $"
//#define QDIO_DBF_LIKE_HELL
......@@ -518,6 +518,8 @@ struct qdio_perf_stats {
struct qdio_q {
volatile struct slsb slsb;
char unused[QDIO_MAX_BUFFERS_PER_Q];
__u32 * volatile dev_st_chg_ind;
int is_input_q;
......
/*
* drivers/s390/cio/requestirq.c
* S/390 common I/O routines -- enabling and disabling of devices
* $Revision: 1.46 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
* Author(s): Ingo Adlung (adlung@de.ibm.com)
* Cornelia Huck (cohuck@de.ibm.com)
* Arnd Bergmann (arndb@de.ibm.com)
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/device.h>
#include <linux/init.h>
#include <asm/lowcore.h>
#include "css.h"
struct pgid global_pgid;
EXPORT_SYMBOL_GPL(global_pgid);
/*
* init_IRQ is now only used to set the pgid as early as possible
*/
void __init
init_IRQ(void)
{
/*
* Let's build our path group ID here.
*/
if (MACHINE_NEW_STIDP)
global_pgid.cpu_addr = 0x8000;
else {
#ifdef CONFIG_SMP
global_pgid.cpu_addr = hard_smp_processor_id();
#else
global_pgid.cpu_addr = 0;
#endif
}
global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
global_pgid.tod_high = (__u32) (get_clock() >> 32);
}
......@@ -36,7 +36,6 @@ extern unsigned long machine_flags;
#define MACHINE_IS_P390 (machine_flags & 4)
#define MACHINE_HAS_MVPG (machine_flags & 16)
#define MACHINE_HAS_DIAG44 (machine_flags & 32)
#define MACHINE_NEW_STIDP (machine_flags & 64)
#define MACHINE_HAS_IDTE (machine_flags & 128)
#ifndef __s390x__
......@@ -54,7 +53,7 @@ extern unsigned long machine_flags;
* Console mode. Override with conmode=
*/
extern unsigned int console_mode;
extern unsigned int console_device;
extern unsigned int console_devno;
extern unsigned int console_irq;
#define CONSOLE_IS_UNDEFINED (console_mode == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment