Skip to content

Commit

Permalink
s390/qdio: improve handling of CIWs
Browse files Browse the repository at this point in the history
Fetch the individual CIWs when we actually need them, rather than
fetching both of them in qdio_setup_irq() and then needing to cache
them inside the qdio_irq.

Also deal with the error when a CIW is not available, instead of
silently dropping this error condition in qdio_setup_irq()'s caller.

Signed-off-by: Julian Wiedmann <[email protected]>
Reviewed-by: Benjamin Block <[email protected]>
Signed-off-by: Heiko Carstens <[email protected]>
  • Loading branch information
julianwiedmann authored and hcahca committed Dec 6, 2021
1 parent 764fc31 commit bd3a025
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 26 deletions.
4 changes: 1 addition & 3 deletions drivers/s390/cio/qdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,6 @@ struct qdio_irq {
int nr_output_qs;

struct ccw1 ccw;
struct ciw equeue;
struct ciw aqueue;

struct qdio_ssqd_desc ssqd_desc;
void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *);
Expand Down Expand Up @@ -338,7 +336,7 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr);
int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr,
struct subchannel_id *schid,
struct qdio_ssqd_desc *data);
int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data);
void qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data);
void qdio_shutdown_irq(struct qdio_irq *irq);
void qdio_print_subchannel_info(struct qdio_irq *irq_ptr);
void qdio_free_queues(struct qdio_irq *irq_ptr);
Expand Down
22 changes: 18 additions & 4 deletions drivers/s390/cio/qdio_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,7 @@ int qdio_establish(struct ccw_device *cdev,
{
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
struct subchannel_id schid;
struct ciw *ciw;
long timeout;
int rc;

Expand All @@ -996,6 +997,12 @@ int qdio_establish(struct ccw_device *cdev,
if (!init_data->irq_poll)
return -EINVAL;

ciw = ccw_device_get_ciw(cdev, CIW_TYPE_EQUEUE);
if (!ciw) {
DBF_ERROR("%4x NO EQ", schid.sch_no);
return -EIO;
}

mutex_lock(&irq_ptr->setup_mutex);
qdio_trace_init_data(irq_ptr, init_data);
qdio_setup_irq(irq_ptr, init_data);
Expand All @@ -1005,9 +1012,9 @@ int qdio_establish(struct ccw_device *cdev,
goto err_thinint;

/* establish q */
irq_ptr->ccw.cmd_code = irq_ptr->equeue.cmd;
irq_ptr->ccw.cmd_code = ciw->cmd;
irq_ptr->ccw.flags = CCW_FLAG_SLI;
irq_ptr->ccw.count = irq_ptr->equeue.count;
irq_ptr->ccw.count = ciw->count;
irq_ptr->ccw.cda = (u32) virt_to_phys(irq_ptr->qdr);

spin_lock_irq(get_ccwdev_lock(cdev));
Expand Down Expand Up @@ -1065,6 +1072,7 @@ int qdio_activate(struct ccw_device *cdev)
{
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
struct subchannel_id schid;
struct ciw *ciw;
int rc;

ccw_device_get_schid(cdev, &schid);
Expand All @@ -1073,15 +1081,21 @@ int qdio_activate(struct ccw_device *cdev)
if (!irq_ptr)
return -ENODEV;

ciw = ccw_device_get_ciw(cdev, CIW_TYPE_AQUEUE);
if (!ciw) {
DBF_ERROR("%4x NO AQ", schid.sch_no);
return -EIO;
}

mutex_lock(&irq_ptr->setup_mutex);
if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) {
rc = -EBUSY;
goto out;
}

irq_ptr->ccw.cmd_code = irq_ptr->aqueue.cmd;
irq_ptr->ccw.cmd_code = ciw->cmd;
irq_ptr->ccw.flags = CCW_FLAG_SLI;
irq_ptr->ccw.count = irq_ptr->aqueue.count;
irq_ptr->ccw.count = ciw->count;
irq_ptr->ccw.cda = 0;

spin_lock_irq(get_ccwdev_lock(cdev));
Expand Down
20 changes: 1 addition & 19 deletions drivers/s390/cio/qdio_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,9 @@ static void setup_qib(struct qdio_irq *irq_ptr,
sizeof(irq_ptr->qib.parm));
}

int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data)
void qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data)
{
struct ccw_device *cdev = irq_ptr->cdev;
struct ciw *ciw;

irq_ptr->qdioac1 = 0;
memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw));
Expand Down Expand Up @@ -386,23 +385,6 @@ int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data)
irq_ptr->orig_handler = cdev->handler;
cdev->handler = qdio_int_handler;
spin_unlock_irq(get_ccwdev_lock(cdev));

/* get qdio commands */
ciw = ccw_device_get_ciw(cdev, CIW_TYPE_EQUEUE);
if (!ciw) {
DBF_ERROR("%4x NO EQ", irq_ptr->schid.sch_no);
return -EINVAL;
}
irq_ptr->equeue = *ciw;

ciw = ccw_device_get_ciw(cdev, CIW_TYPE_AQUEUE);
if (!ciw) {
DBF_ERROR("%4x NO AQ", irq_ptr->schid.sch_no);
return -EINVAL;
}
irq_ptr->aqueue = *ciw;

return 0;
}

void qdio_shutdown_irq(struct qdio_irq *irq)
Expand Down

0 comments on commit bd3a025

Please sign in to comment.