Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 98973
b: refs/heads/master
c: 9d92a7e
h: refs/heads/master
i:
  98971: 4e696cc
v: v3
  • Loading branch information
Cornelia Huck authored and Heiko Carstens committed Jul 14, 2008
1 parent 7faebdf commit 5a80aa6
Show file tree
Hide file tree
Showing 21 changed files with 1,069 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 683c5418e6ac9f40f925dab6f547a5b0a4ad43c6
refs/heads/master: 9d92a7e1b0d095c8be96ce5e592c6c5541684631
1 change: 1 addition & 0 deletions trunk/Documentation/ioctl-number.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ Code Seq# Include File Comments
<mailto:natalia@nikhefk.nikhef.nl>
'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
Expand Down
16 changes: 16 additions & 0 deletions trunk/arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/s390/cio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.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
2 changes: 1 addition & 1 deletion trunk/drivers/s390/cio/chp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
48 changes: 41 additions & 7 deletions trunk/drivers/s390/cio/chsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <asm/cio.h>
#include <asm/chpid.h>
#include <asm/chsc.h>

#include "../s390mach.h"
#include "css.h"
Expand Down Expand Up @@ -627,32 +628,47 @@ chsc_secm(struct channel_subsystem *css, int enable)
return ret;
}

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 ccode, ret;

struct {
struct chsc_header request;
u32 : 24;
u32 : 2;
u32 m : 1;
u32 c : 1;
u32 fmt : 4;
u32 cssid : 8;
u32 : 4;
u32 rfmt : 4;
u32 first_chpid : 8;
u32 : 24;
u32 last_chpid : 8;
u32 zeroes1;
struct chsc_header response;
u32 zeroes2;
struct channel_path_desc desc;
u8 data[PAGE_SIZE - 20];
} __attribute__ ((packed)) *scpd_area;

if ((rfmt == 1) && !css_general_characteristics.fcs)
return -EINVAL;
if ((rfmt == 2) && !css_general_characteristics.cib)
return -EINVAL;
scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!scpd_area)
return -ENOMEM;

scpd_area->request.length = 0x0010;
scpd_area->request.code = 0x0002;

scpd_area->cssid = chpid.cssid;
scpd_area->first_chpid = chpid.id;
scpd_area->last_chpid = chpid.id;
scpd_area->m = m;
scpd_area->c = c;
scpd_area->fmt = fmt;
scpd_area->rfmt = rfmt;

ccode = chsc(scpd_area);
if (ccode > 0) {
Expand All @@ -663,15 +679,33 @@ int chsc_determine_channel_path_description(struct chp_id chpid,
ret = chsc_error_from_response(scpd_area->response.code);
if (ret == 0)
/* Success. */
memcpy(desc, &scpd_area->desc,
sizeof(struct channel_path_desc));
memcpy(resp, &scpd_area->response, scpd_area->response.length);
else
CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n",
scpd_area->response.code);
out:
free_page((unsigned long)scpd_area);
return ret;
}
EXPORT_SYMBOL_GPL(chsc_determine_channel_path_desc);

int chsc_determine_base_channel_path_desc(struct chp_id chpid,
struct channel_path_desc *desc)
{
struct chsc_response_struct *chsc_resp;
int ret;

chsc_resp = kzalloc(sizeof(*chsc_resp), GFP_KERNEL);
if (!chsc_resp)
return -ENOMEM;
ret = chsc_determine_channel_path_desc(chpid, 0, 0, 0, 0, chsc_resp);
if (ret)
goto out_free;
memcpy(desc, &chsc_resp->data, chsc_resp->length);
out_free:
kfree(chsc_resp);
return ret;
}

static void
chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
Expand Down
21 changes: 15 additions & 6 deletions trunk/drivers/s390/cio/chsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -37,19 +38,24 @@ 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 */
u32 : 1;
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));
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 5a80aa6

Please sign in to comment.