Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce322ccd authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

[S390] cio: obtain mdc value per channel path



Add support to accumulate the number of 64K-bytes blocks all paths
to a device at least support for a transport command.

Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 37e89521
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -204,6 +204,8 @@ int ccw_device_tm_start_timeout(struct ccw_device *, struct tcw *,
			    unsigned long, u8, int);
			    unsigned long, u8, int);
int ccw_device_tm_intrg(struct ccw_device *cdev);
int ccw_device_tm_intrg(struct ccw_device *cdev);


int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask);

extern int ccw_device_set_online(struct ccw_device *cdev);
extern int ccw_device_set_online(struct ccw_device *cdev);
extern int ccw_device_set_offline(struct ccw_device *cdev);
extern int ccw_device_set_offline(struct ccw_device *cdev);


+19 −0
Original line number Original line Diff line number Diff line
@@ -695,6 +695,25 @@ int chsc_determine_base_channel_path_desc(struct chp_id chpid,
	return ret;
	return ret;
}
}


int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
					  struct channel_path_desc_fmt1 *desc)
{
	struct chsc_response_struct *chsc_resp;
	struct chsc_scpd *scpd_area;
	int ret;

	spin_lock_irq(&chsc_page_lock);
	scpd_area = chsc_page;
	ret = chsc_determine_channel_path_desc(chpid, 0, 0, 1, 0, scpd_area);
	if (ret)
		goto out;
	chsc_resp = (void *)&scpd_area->response;
	memcpy(desc, &chsc_resp->data, sizeof(*desc));
out:
	spin_unlock_irq(&chsc_page_lock);
	return ret;
}

static void
static void
chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
			  struct cmg_chars *chars)
			  struct cmg_chars *chars)
+18 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,22 @@ struct channel_path_desc {
	u8 chpp;
	u8 chpp;
} __attribute__ ((packed));
} __attribute__ ((packed));


struct channel_path_desc_fmt1 {
	u8 flags;
	u8 lsn;
	u8 desc;
	u8 chpid;
	u32:24;
	u8 chpp;
	u32 unused[3];
	u16 mdc;
	u16:13;
	u8 r:1;
	u8 s:1;
	u8 f:1;
	u32 zeros[2];
} __attribute__ ((packed));

struct channel_path;
struct channel_path;


struct css_chsc_char {
struct css_chsc_char {
@@ -92,6 +108,8 @@ int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
				     int c, int m, void *page);
				     int c, int m, void *page);
int chsc_determine_base_channel_path_desc(struct chp_id chpid,
int chsc_determine_base_channel_path_desc(struct chp_id chpid,
					  struct channel_path_desc *desc);
					  struct channel_path_desc *desc);
int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
					  struct channel_path_desc_fmt1 *desc);
void chsc_chp_online(struct chp_id chpid);
void chsc_chp_online(struct chp_id chpid);
void chsc_chp_offline(struct chp_id chpid);
void chsc_chp_offline(struct chp_id chpid);
int chsc_get_channel_measurement_chars(struct channel_path *chp);
int chsc_get_channel_measurement_chars(struct channel_path *chp);
+40 −0
Original line number Original line Diff line number Diff line
@@ -686,6 +686,46 @@ int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw,
}
}
EXPORT_SYMBOL(ccw_device_tm_start_timeout);
EXPORT_SYMBOL(ccw_device_tm_start_timeout);


/**
 * ccw_device_get_mdc - accumulate max data count
 * @cdev: ccw device for which the max data count is accumulated
 * @mask: mask of paths to use
 *
 * Return the number of 64K-bytes blocks all paths at least support
 * for a transport command. Return values <= 0 indicate failures.
 */
int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)
{
	struct subchannel *sch = to_subchannel(cdev->dev.parent);
	struct channel_path_desc_fmt1 desc;
	struct chp_id chpid;
	int mdc = 0, ret, i;

	/* Adjust requested path mask to excluded varied off paths. */
	if (mask)
		mask &= sch->lpm;
	else
		mask = sch->lpm;

	chp_id_init(&chpid);
	for (i = 0; i < 8; i++) {
		if (!(mask & (0x80 >> i)))
			continue;
		chpid.id = sch->schib.pmcw.chpid[i];
		ret = chsc_determine_fmt1_channel_path_desc(chpid, &desc);
		if (ret)
			return ret;
		if (!desc.f)
			return 0;
		if (!desc.r)
			mdc = 1;
		mdc = mdc ? min(mdc, (int)desc.mdc) : desc.mdc;
	}

	return mdc;
}
EXPORT_SYMBOL(ccw_device_get_mdc);

/**
/**
 * ccw_device_tm_intrg - perform interrogate function
 * ccw_device_tm_intrg - perform interrogate function
 * @cdev: ccw device on which to perform the interrogate function
 * @cdev: ccw device on which to perform the interrogate function