Skip to content

Commit

Permalink
s390/css: move subchannel lock allocation
Browse files Browse the repository at this point in the history
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: Peter Oberparleiter <[email protected]>
Signed-off-by: Sebastian Ott <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
  • Loading branch information
Sebastian Ott authored and Martin Schwidefsky committed Apr 17, 2013
1 parent 0ad8f71 commit e5dcf00
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 34 deletions.
29 changes: 4 additions & 25 deletions drivers/s390/cio/cio.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 +471,6 @@ int cio_disable_subchannel(struct subchannel *sch)
}
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)
{
if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) {
Expand Down Expand Up @@ -536,28 +527,19 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
sprintf(dbf_txt, "valsch%x", schid.sch_no);
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)
* indicates that there aren't any more devices available.
* indicates that there aren't any more devices available.
* If stsch gets an exception, it means the current subchannel set
* is not valid.
* is not valid.
*/
ccode = stsch_err (schid, &sch->schib);
ccode = stsch_err(schid, &sch->schib);
if (ccode) {
err = (ccode == 3) ? -ENXIO : ccode;
goto out;
}
/* Copy subchannel type from path management control word. */
sch->st = sch->schib.pmcw.st;
sch->schid = schid;

switch (sch->st) {
case SUBCHANNEL_TYPE_IO:
Expand All @@ -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",
sch->schid.ssid, sch->schid.sch_no, sch->st);
return 0;
out:
kfree(sch->lock);
sch->lock = NULL;
return err;
}

Expand Down
1 change: 0 additions & 1 deletion drivers/s390/cio/cio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_intrg(struct subchannel *sch);

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

Expand Down
36 changes: 28 additions & 8 deletions drivers/s390/cio/css.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,18 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),

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)
{
struct subchannel *sch = to_subchannel(dev);
Expand All @@ -152,18 +164,26 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid)
struct subchannel *sch;
int ret;

sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
if (sch == NULL)
sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA);
if (!sch)
return ERR_PTR(-ENOMEM);
ret = cio_validate_subchannel (sch, schid);
if (ret < 0) {
kfree(sch);
return ERR_PTR(ret);
}

ret = cio_validate_subchannel(sch, schid);
if (ret < 0)
goto err;

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

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

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

static int css_sch_device_register(struct subchannel *sch)
Expand Down Expand Up @@ -756,7 +776,7 @@ static int __init setup_css(int nr)
css->pseudo_subchannel->dev.release = css_subchannel_release;
dev_set_name(&css->pseudo_subchannel->dev, "defunct");
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) {
kfree(css->pseudo_subchannel);
return ret;
Expand Down

0 comments on commit e5dcf00

Please sign in to comment.