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

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

s390/css: move subchannel lock allocation



cio_validate_subchannel is used to do some basic checks to find out
if it's worth to further investigate a subchannel. Move the allocation
and initialization of the subchannels locks to css_alloc_subchannel.

Clean up the functions involved while at it.

Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 0ad8f714
Loading
Loading
Loading
Loading
+4 −25
Original line number Original line Diff line number Diff line
@@ -471,15 +471,6 @@ int cio_disable_subchannel(struct subchannel *sch)
}
}
EXPORT_SYMBOL_GPL(cio_disable_subchannel);
EXPORT_SYMBOL_GPL(cio_disable_subchannel);


int cio_create_sch_lock(struct subchannel *sch)
{
	sch->lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
	if (!sch->lock)
		return -ENOMEM;
	spin_lock_init(sch->lock);
	return 0;
}

static int cio_check_devno_blacklisted(struct subchannel *sch)
static int cio_check_devno_blacklisted(struct subchannel *sch)
{
{
	if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) {
	if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) {
@@ -536,15 +527,6 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
	sprintf(dbf_txt, "valsch%x", schid.sch_no);
	sprintf(dbf_txt, "valsch%x", schid.sch_no);
	CIO_TRACE_EVENT(4, dbf_txt);
	CIO_TRACE_EVENT(4, dbf_txt);


	/* Nuke all fields. */
	memset(sch, 0, sizeof(struct subchannel));

	sch->schid = schid;
	err = cio_create_sch_lock(sch);
	if (err)
		goto out;
	mutex_init(&sch->reg_mutex);

	/*
	/*
	 * The first subchannel that is not-operational (ccode==3)
	 * The first subchannel that is not-operational (ccode==3)
	 * indicates that there aren't any more devices available.
	 * indicates that there aren't any more devices available.
@@ -556,8 +538,8 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
		err = (ccode == 3) ? -ENXIO : ccode;
		err = (ccode == 3) ? -ENXIO : ccode;
		goto out;
		goto out;
	}
	}
	/* Copy subchannel type from path management control word. */
	sch->st = sch->schib.pmcw.st;
	sch->st = sch->schib.pmcw.st;
	sch->schid = schid;


	switch (sch->st) {
	switch (sch->st) {
	case SUBCHANNEL_TYPE_IO:
	case SUBCHANNEL_TYPE_IO:
@@ -574,10 +556,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)


	CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n",
	CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n",
		      sch->schid.ssid, sch->schid.sch_no, sch->st);
		      sch->schid.ssid, sch->schid.sch_no, sch->st);
	return 0;
out:
out:
	kfree(sch->lock);
	sch->lock = NULL;
	return err;
	return err;
}
}


+0 −1
Original line number Original line Diff line number Diff line
@@ -121,7 +121,6 @@ extern int cio_commit_config(struct subchannel *sch);
int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key);
int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key);
int cio_tm_intrg(struct subchannel *sch);
int cio_tm_intrg(struct subchannel *sch);


int cio_create_sch_lock(struct subchannel *);
void do_adapter_IO(u8 isc);
void do_adapter_IO(u8 isc);
void do_IRQ(struct pt_regs *);
void do_IRQ(struct pt_regs *);


+28 −8
Original line number Original line Diff line number Diff line
@@ -137,6 +137,18 @@ out:


static void css_sch_todo(struct work_struct *work);
static void css_sch_todo(struct work_struct *work);


static int css_sch_create_locks(struct subchannel *sch)
{
	sch->lock = kmalloc(sizeof(*sch->lock), GFP_KERNEL);
	if (!sch->lock)
		return -ENOMEM;

	spin_lock_init(sch->lock);
	mutex_init(&sch->reg_mutex);

	return 0;
}

static void css_subchannel_release(struct device *dev)
static void css_subchannel_release(struct device *dev)
{
{
	struct subchannel *sch = to_subchannel(dev);
	struct subchannel *sch = to_subchannel(dev);
@@ -152,18 +164,26 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid)
	struct subchannel *sch;
	struct subchannel *sch;
	int ret;
	int ret;


	sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
	sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA);
	if (sch == NULL)
	if (!sch)
		return ERR_PTR(-ENOMEM);
		return ERR_PTR(-ENOMEM);

	ret = cio_validate_subchannel(sch, schid);
	ret = cio_validate_subchannel(sch, schid);
	if (ret < 0) {
	if (ret < 0)
		kfree(sch);
		goto err;
		return ERR_PTR(ret);

	}
	ret = css_sch_create_locks(sch);
	if (ret)
		goto err;

	INIT_WORK(&sch->todo_work, css_sch_todo);
	INIT_WORK(&sch->todo_work, css_sch_todo);
	sch->dev.release = &css_subchannel_release;
	sch->dev.release = &css_subchannel_release;
	device_initialize(&sch->dev);
	device_initialize(&sch->dev);
	return sch;
	return sch;

err:
	kfree(sch);
	return ERR_PTR(ret);
}
}


static int css_sch_device_register(struct subchannel *sch)
static int css_sch_device_register(struct subchannel *sch)
@@ -756,7 +776,7 @@ static int __init setup_css(int nr)
	css->pseudo_subchannel->dev.release = css_subchannel_release;
	css->pseudo_subchannel->dev.release = css_subchannel_release;
	dev_set_name(&css->pseudo_subchannel->dev, "defunct");
	dev_set_name(&css->pseudo_subchannel->dev, "defunct");
	mutex_init(&css->pseudo_subchannel->reg_mutex);
	mutex_init(&css->pseudo_subchannel->reg_mutex);
	ret = cio_create_sch_lock(css->pseudo_subchannel);
	ret = css_sch_create_locks(css->pseudo_subchannel);
	if (ret) {
	if (ret) {
		kfree(css->pseudo_subchannel);
		kfree(css->pseudo_subchannel);
		return ret;
		return ret;