Source
x
static int chsc_subchannel_match_next_free(struct device *dev, void *data)
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for s390 chsc subchannels
*
* Copyright IBM Corp. 2008, 2011
*
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
*
*/
static debug_info_t *chsc_debug_msg_id;
static debug_info_t *chsc_debug_log_id;
static struct chsc_request *on_close_request;
static struct chsc_async_area *on_close_chsc_area;
static DEFINE_MUTEX(on_close_mutex);
static void CHSC_LOG_HEX(int level, void *data, int length)
{
debug_event(chsc_debug_log_id, level, data, length);
}
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("driver for s390 chsc subchannels");
MODULE_LICENSE("GPL");
static void chsc_subchannel_irq(struct subchannel *sch)
{
struct chsc_private *private = dev_get_drvdata(&sch->dev);
struct chsc_request *request = private->request;
struct irb *irb = this_cpu_ptr(&cio_irb);
CHSC_LOG(4, "irb");
CHSC_LOG_HEX(4, irb, sizeof(*irb));
inc_irq_stat(IRQIO_CSC);
/* Copy irb to provided request and set done. */
if (!request) {
CHSC_MSG(0, "Interrupt on sch 0.%x.%04x with no request\n",
sch->schid.ssid, sch->schid.sch_no);
return;
}
private->request = NULL;
memcpy(&request->irb, irb, sizeof(*irb));
cio_update_schib(sch);
complete(&request->completion);
put_device(&sch->dev);
}
static int chsc_subchannel_probe(struct subchannel *sch)
{
struct chsc_private *private;
int ret;
CHSC_MSG(6, "Detected chsc subchannel 0.%x.%04x\n",
sch->schid.ssid, sch->schid.sch_no);
sch->isc = CHSC_SCH_ISC;
private = kzalloc(sizeof(*private), GFP_KERNEL);
if (!private)
return -ENOMEM;
dev_set_drvdata(&sch->dev, private);
ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
if (ret) {
CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n",
sch->schid.ssid, sch->schid.sch_no, ret);
dev_set_drvdata(&sch->dev, NULL);