Commit 01613ea0 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: common i/o layer.

updates for the channel subsystem and qdio driver

This adds the missing support for chp machine checks, i.e.
enabling or disabling a set of devices from the service element.
Some minor bugs in the driver are fixed as well.
parent cbc67add
/* /*
* drivers/s390/cio/ccwgroup.c * drivers/s390/cio/ccwgroup.c
* bus driver for ccwgroup * bus driver for ccwgroup
* $Revision: 1.5 $ * $Revision: 1.6 $
* *
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
......
This diff is collapsed.
...@@ -95,7 +95,7 @@ struct ssd_area { ...@@ -95,7 +95,7 @@ struct ssd_area {
struct channel_path { struct channel_path {
int id; int id;
int state; int state;
struct sys_device sdev; struct device dev;
}; };
extern struct channel_path *chps[]; extern struct channel_path *chps[];
......
/* /*
* drivers/s390/cio/cio.c * drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls * S/390 common I/O routines -- low level i/o calls
* $Revision: 1.90 $ * $Revision: 1.91 $
* *
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -197,8 +197,7 @@ cio_start (struct subchannel *sch, /* subchannel structure */ ...@@ -197,8 +197,7 @@ cio_start (struct subchannel *sch, /* subchannel structure */
sch->orb.pfch = sch->options.prefetch == 0; sch->orb.pfch = sch->options.prefetch == 0;
sch->orb.spnd = sch->options.suspend; sch->orb.spnd = sch->options.suspend;
sch->orb.ssic = sch->options.suspend && sch->options.inter; sch->orb.ssic = sch->options.suspend && sch->options.inter;
sch->orb.lpm = (lpm != 0) ? (lpm & sch->lpm) : sch->lpm; sch->orb.lpm = (lpm != 0) ? lpm : sch->lpm;
#ifdef CONFIG_ARCH_S390X #ifdef CONFIG_ARCH_S390X
/* /*
* for 64 bit we always support 64 bit IDAWs with 4k page size only * for 64 bit we always support 64 bit IDAWs with 4k page size only
......
/* /*
* drivers/s390/cio/device.c * drivers/s390/cio/device.c
* bus driver for ccw devices * bus driver for ccw devices
* $Revision: 1.45 $ * $Revision: 1.50 $
* *
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -215,6 +215,8 @@ online_show (struct device *dev, char *buf) ...@@ -215,6 +215,8 @@ online_show (struct device *dev, char *buf)
void void
ccw_device_set_offline(struct ccw_device *cdev) ccw_device_set_offline(struct ccw_device *cdev)
{ {
int ret;
if (!cdev) if (!cdev)
return; return;
if (!cdev->online || !cdev->drv) if (!cdev->online || !cdev->drv)
...@@ -226,23 +228,36 @@ ccw_device_set_offline(struct ccw_device *cdev) ...@@ -226,23 +228,36 @@ ccw_device_set_offline(struct ccw_device *cdev)
cdev->online = 0; cdev->online = 0;
spin_lock_irq(cdev->ccwlock); spin_lock_irq(cdev->ccwlock);
ccw_device_offline(cdev); ret = ccw_device_offline(cdev);
spin_unlock_irq(cdev->ccwlock); spin_unlock_irq(cdev->ccwlock);
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); if (ret == 0)
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
else
//FIXME: we can't fail!
pr_debug("ccw_device_offline returned %d, device %s\n",
ret, cdev->dev.bus_id);
} }
void void
ccw_device_set_online(struct ccw_device *cdev) ccw_device_set_online(struct ccw_device *cdev)
{ {
if (!cdev || !cdev->handler) int ret;
if (!cdev)
return; return;
if (cdev->online || !cdev->drv) if (cdev->online || !cdev->drv)
return; return;
spin_lock_irq(cdev->ccwlock); spin_lock_irq(cdev->ccwlock);
ccw_device_online(cdev); ret = ccw_device_online(cdev);
spin_unlock_irq(cdev->ccwlock); spin_unlock_irq(cdev->ccwlock);
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); if (ret == 0)
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
else {
pr_debug("ccw_device_online returned %d, device %s\n",
ret, cdev->dev.bus_id);
return;
}
if (cdev->private->state != DEV_STATE_ONLINE) if (cdev->private->state != DEV_STATE_ONLINE)
return; return;
if (!cdev->drv->set_online || cdev->drv->set_online(cdev) == 0) { if (!cdev->drv->set_online || cdev->drv->set_online(cdev) == 0) {
...@@ -250,9 +265,13 @@ ccw_device_set_online(struct ccw_device *cdev) ...@@ -250,9 +265,13 @@ ccw_device_set_online(struct ccw_device *cdev)
return; return;
} }
spin_lock_irq(cdev->ccwlock); spin_lock_irq(cdev->ccwlock);
ccw_device_offline(cdev); ret = ccw_device_offline(cdev);
spin_unlock_irq(cdev->ccwlock); spin_unlock_irq(cdev->ccwlock);
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); if (ret == 0)
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
else
pr_debug("ccw_device_offline returned %d, device %s\n",
ret, cdev->dev.bus_id);
} }
static ssize_t static ssize_t
...@@ -574,7 +593,7 @@ ccw_device_remove (struct device *dev) ...@@ -574,7 +593,7 @@ ccw_device_remove (struct device *dev)
* doubled code. * doubled code.
* This is safe because of the checks in ccw_device_set_offline. * This is safe because of the checks in ccw_device_set_offline.
*/ */
pr_debug(KERN_INFO "removing device %s, sch %d, devno %x\n", pr_debug("removing device %s, sch %d, devno %x\n",
cdev->dev.name, cdev->dev.name,
cdev->private->irq, cdev->private->irq,
cdev->private->devno); cdev->private->devno);
......
...@@ -136,7 +136,7 @@ VM_virtual_device_info (__u16 devno, struct senseid *ps) ...@@ -136,7 +136,7 @@ VM_virtual_device_info (__u16 devno, struct senseid *ps)
ccode = diag210 (&diag_data); ccode = diag210 (&diag_data);
ps->reserved = 0xff; ps->reserved = 0xff;
/* Special case for bloddy osa devices. */ /* Special case for bloody osa devices. */
if (diag_data.vrdcvcla == 0x02 && if (diag_data.vrdcvcla == 0x02 &&
diag_data.vrdcvtyp == 0x20) { diag_data.vrdcvtyp == 0x20) {
ps->cu_type = 0x3088; ps->cu_type = 0x3088;
......
...@@ -48,7 +48,8 @@ ccw_device_clear(struct ccw_device *cdev, unsigned long intparm) ...@@ -48,7 +48,8 @@ ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
if (!cdev) if (!cdev)
return -ENODEV; return -ENODEV;
if (cdev->private->state != DEV_STATE_ONLINE && if (cdev->private->state != DEV_STATE_ONLINE &&
cdev->private->state != DEV_STATE_W4SENSE) cdev->private->state != DEV_STATE_W4SENSE &&
cdev->private->state != DEV_STATE_QDIO_ACTIVE)
return -EINVAL; return -EINVAL;
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
if (!sch) if (!sch)
...@@ -122,6 +123,15 @@ ccw_device_call_handler(struct ccw_device *cdev) ...@@ -122,6 +123,15 @@ ccw_device_call_handler(struct ccw_device *cdev)
{ {
struct subchannel *sch; struct subchannel *sch;
unsigned int stctl; unsigned int stctl;
void (*handler)(struct ccw_device *, unsigned long, struct irb *);
if (cdev->private->state == DEV_STATE_QDIO_ACTIVE) {
if (cdev->private->qdio_data)
handler = cdev->private->qdio_data->handler;
else
handler = NULL;
} else
handler = cdev->handler;
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
...@@ -144,13 +154,9 @@ ccw_device_call_handler(struct ccw_device *cdev) ...@@ -144,13 +154,9 @@ ccw_device_call_handler(struct ccw_device *cdev)
/* /*
* Now we are ready to call the device driver interrupt handler. * Now we are ready to call the device driver interrupt handler.
*/ */
if (cdev->private->state == DEV_STATE_QDIO_ACTIVE) { if (handler)
if (cdev->private->qdio_data && handler(cdev, sch->u_intparm, &cdev->private->irb);
cdev->private->qdio_data->handler)
cdev->private->qdio_data->handler(cdev, sch->u_intparm,
&cdev->private->irb);
} else
cdev->handler (cdev, sch->u_intparm, &cdev->private->irb);
/* /*
* Clear the old and now useless interrupt response block. * Clear the old and now useless interrupt response block.
*/ */
...@@ -245,6 +251,8 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length) ...@@ -245,6 +251,8 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
wait_event(cdev->private->wait_q, wait_event(cdev->private->wait_q,
sch->schib.scsw.actl == 0); sch->schib.scsw.actl == 0);
spin_lock_irqsave(&sch->lock, flags); spin_lock_irqsave(&sch->lock, flags);
/* FIXME: Check if we got sensible stuff. */
break;
} }
} }
/* Restore interrupt handler. */ /* Restore interrupt handler. */
...@@ -317,6 +325,8 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length) ...@@ -317,6 +325,8 @@ read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
spin_unlock_irqrestore(&sch->lock, flags); spin_unlock_irqrestore(&sch->lock, flags);
wait_event(cdev->private->wait_q, sch->schib.scsw.actl == 0); wait_event(cdev->private->wait_q, sch->schib.scsw.actl == 0);
spin_lock_irqsave(&sch->lock, flags); spin_lock_irqsave(&sch->lock, flags);
/* FIXME: Check if we got sensible stuff. */
break;
} }
/* Restore interrupt handler. */ /* Restore interrupt handler. */
cdev->handler = handler; cdev->handler = handler;
......
...@@ -141,6 +141,8 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) ...@@ -141,6 +141,8 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
struct subchannel *sch; struct subchannel *sch;
struct irb *irb; struct irb *irb;
int ret; int ret;
int opm;
int i;
irb = (struct irb *) __LC_IRB; irb = (struct irb *) __LC_IRB;
/* Ignore unsolicited interrupts. */ /* Ignore unsolicited interrupts. */
...@@ -154,6 +156,16 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) ...@@ -154,6 +156,16 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */ /* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */
case 0: /* Sense Path Group ID successful. */ case 0: /* Sense Path Group ID successful. */
cdev->private->flags.pgid_supp = 1; cdev->private->flags.pgid_supp = 1;
opm = sch->schib.pmcw.pim &
sch->schib.pmcw.pam &
sch->schib.pmcw.pom;
for (i=0;i<8;i++) {
if (opm == (0x80 << i)) {
/* Don't group single path devices. */
cdev->private->flags.pgid_supp = 0;
break;
}
}
if (cdev->private->pgid.inf.ps.state1 == SNID_STATE1_RESET) if (cdev->private->pgid.inf.ps.state1 == SNID_STATE1_RESET)
memcpy(&cdev->private->pgid, &global_pgid, memcpy(&cdev->private->pgid, &global_pgid,
sizeof(struct pgid)); sizeof(struct pgid));
......
...@@ -62,8 +62,9 @@ ccw_device_path_notoper(struct ccw_device *cdev) ...@@ -62,8 +62,9 @@ ccw_device_path_notoper(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
stsch (sch->irq, &sch->schib); stsch (sch->irq, &sch->schib);
CIO_MSG_EVENT(0, "cio_process_irq(%04X) - path(s) %02x are " CIO_MSG_EVENT(0, "%s(%04X) - path(s) %02x are "
"not operational ", sch->irq, sch->schib.pmcw.pnom); "not operational \n", __FUNCTION__, sch->irq,
sch->schib.pmcw.pnom);
sch->lpm &= ~sch->schib.pmcw.pnom; sch->lpm &= ~sch->schib.pmcw.pnom;
dev_fsm_event(cdev, DEV_EVENT_VERIFY); dev_fsm_event(cdev, DEV_EVENT_VERIFY);
...@@ -289,7 +290,7 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb) ...@@ -289,7 +290,7 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
/* A sense is required, can we do it now ? */ /* A sense is required, can we do it now ? */
if (irb->scsw.actl != 0) if ((irb->scsw.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0)
/* /*
* we received an Unit Check but we have no final * we received an Unit Check but we have no final
* status yet, therefore we must delay the SENSE * status yet, therefore we must delay the SENSE
...@@ -348,7 +349,7 @@ int ...@@ -348,7 +349,7 @@ int
ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb) ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb)
{ {
ccw_device_accumulate_irb(cdev, irb); ccw_device_accumulate_irb(cdev, irb);
if (irb->scsw.actl != 0) if ((irb->scsw.actl & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0)
return -EBUSY; return -EBUSY;
/* Check for basic sense. */ /* Check for basic sense. */
if (cdev->private->flags.dosense && if (cdev->private->flags.dosense &&
......
#ifndef S390_CIO_IOASM_H #ifndef S390_CIO_IOASM_H
#define S390_CIO_IOASM_H #define S390_CIO_IOASM_H
/*
* area for channel subsystem call
*/
struct chsc_area {
struct {
/* word 0 */
__u16 command_code1;
__u16 command_code2;
union {
struct {
/* word 1 */
__u32 reserved1;
/* word 2 */
__u32 reserved2;
} __attribute__ ((packed,aligned(8))) sei_req;
struct {
/* word 1 */
__u16 reserved1;
__u16 f_sch; /* first subchannel */
/* word 2 */
__u16 reserved2;
__u16 l_sch; /* last subchannel */
} __attribute__ ((packed,aligned(8))) ssd_req;
} request_block_data;
/* word 3 */
__u32 reserved3;
} __attribute__ ((packed,aligned(8))) request_block;
struct {
/* word 0 */
__u16 length;
__u16 response_code;
/* word 1 */
__u32 reserved1;
union {
struct {
/* word 2 */
__u8 flags;
__u8 vf; /* validity flags */
__u8 rs; /* reporting source */
__u8 cc; /* content code */
/* word 3 */
__u16 fla; /* full link address */
__u16 rsid; /* reporting source id */
/* word 4 */
__u32 reserved2;
/* word 5 */
__u32 reserved3;
/* word 6 */
__u32 ccdf; /* content-code dependent field */
/* word 7 */
__u32 reserved4;
/* word 8 */
__u32 reserved5;
/* word 9 */
__u32 reserved6;
} __attribute__ ((packed,aligned(8))) sei_res;
struct {
/* word 2 */
__u8 sch_valid : 1;
__u8 dev_valid : 1;
__u8 st : 3; /* subchannel type */
__u8 zeroes : 3;
__u8 unit_addr; /* unit address */
__u16 devno; /* device number */
/* word 3 */
__u8 path_mask;
__u8 fla_valid_mask;
__u16 sch; /* subchannel */
/* words 4-5 */
__u8 chpid[8]; /* chpids 0-7 */
/* words 6-9 */
__u16 fla[8]; /* full link addresses 0-7 */
} __attribute__ ((packed,aligned(8))) ssd_res;
} response_block_data;
} __attribute__ ((packed,aligned(8))) response_block;
} __attribute__ ((packed,aligned(PAGE_SIZE)));
/* /*
* TPI info structure * TPI info structure
*/ */
......
This diff is collapsed.
#ifndef _CIO_QDIO_H #ifndef _CIO_QDIO_H
#define _CIO_QDIO_H #define _CIO_QDIO_H
#define VERSION_CIO_QDIO_H "$Revision: 1.8 $" #define VERSION_CIO_QDIO_H "$Revision: 1.11 $"
//#define QDIO_DBF_LIKE_HELL //#define QDIO_DBF_LIKE_HELL
...@@ -48,6 +48,10 @@ ...@@ -48,6 +48,10 @@
#define QDIO_STATS_CLASSES 2 #define QDIO_STATS_CLASSES 2
#define QDIO_STATS_COUNT_NEEDED 2*/ #define QDIO_STATS_COUNT_NEEDED 2*/
#define QDIO_ACTIVATE_DELAY 5 /* according to brenton belmar and paul
gioquindo it can take up to 5ms before
queues are really active */
#define QDIO_NO_USE_COUNT_TIME 10 #define QDIO_NO_USE_COUNT_TIME 10
#define QDIO_NO_USE_COUNT_TIMEOUT 1000 /* wait for 1 sec on each q before #define QDIO_NO_USE_COUNT_TIMEOUT 1000 /* wait for 1 sec on each q before
exiting without having use_count exiting without having use_count
...@@ -579,6 +583,7 @@ struct qdio_q { ...@@ -579,6 +583,7 @@ struct qdio_q {
int is_input_q; int is_input_q;
int irq; int irq;
struct ccw_device *cdev;
unsigned int is_iqdio_q; unsigned int is_iqdio_q;
...@@ -670,7 +675,7 @@ struct qdio_irq { ...@@ -670,7 +675,7 @@ struct qdio_irq {
unsigned int sync_done_on_outb_pcis; unsigned int sync_done_on_outb_pcis;
unsigned int state; unsigned int state;
spinlock_t setting_up_lock; struct semaphore setting_up_sema;
unsigned int no_input_qs; unsigned int no_input_qs;
unsigned int no_output_qs; unsigned int no_output_qs;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
extern void css_process_crw(int); extern void css_process_crw(int);
extern void chsc_process_crw(void); extern void chsc_process_crw(void);
extern void chp_process_crw(int);
static void static void
s390_handle_damage(char *msg) s390_handle_damage(char *msg)
...@@ -53,29 +54,25 @@ s390_collect_crw_info(void) ...@@ -53,29 +54,25 @@ s390_collect_crw_info(void)
crw.erc, crw.rsid); crw.erc, crw.rsid);
switch (crw.rsc) { switch (crw.rsc) {
case CRW_RSC_SCH: case CRW_RSC_SCH:
pr_debug(KERN_NOTICE, "source is subchannel %04X\n", pr_debug("source is subchannel %04X\n", crw.rsid);
crw.rsid);
css_process_crw (crw.rsid); css_process_crw (crw.rsid);
break; break;
case CRW_RSC_MONITOR: case CRW_RSC_MONITOR:
pr_debug(KERN_NOTICE, pr_debug("source is monitoring facility\n");
"source is monitoring facility\n");
break; break;
case CRW_RSC_CPATH: case CRW_RSC_CPATH:
pr_debug(KERN_NOTICE, pr_debug("source is channel path %02X\n", crw.rsid);
"source is channel path %02X\n", chp_process_crw(crw.rsid);
pcrwe->crw.rsid);
break; break;
case CRW_RSC_CONFIG: case CRW_RSC_CONFIG:
pr_debug(KERN_NOTICE, pr_debug("source is configuration-alert facility\n");
"source is configuration-alert facility\n");
break; break;
case CRW_RSC_CSS: case CRW_RSC_CSS:
pr_debug(KERN_NOTICE, "source is channel subsystem\n"); pr_debug("source is channel subsystem\n");
chsc_process_crw(); chsc_process_crw();
break; break;
default: default:
pr_debug(KERN_NOTICE, "unknown source\n"); pr_debug("unknown source\n");
break; break;
} }
} while (crw.chn); } while (crw.chn);
......
...@@ -50,11 +50,11 @@ struct qdio_buffer{ ...@@ -50,11 +50,11 @@ struct qdio_buffer{
} __attribute__ ((packed,aligned(256))); } __attribute__ ((packed,aligned(256)));
/* params are: irq, status, qdio_error, siga_error, /* params are: ccw_device, status, qdio_error, siga_error,
queue_number, first element processed, number of elements processed, queue_number, first element processed, number of elements processed,
int_parm */ int_parm */
typedef void qdio_handler_t(int,unsigned int,unsigned int,unsigned int, typedef void qdio_handler_t(struct ccw_device *,unsigned int,unsigned int,
unsigned int,int,int,unsigned long); unsigned int,unsigned int,int,int,unsigned long);
#define QDIO_STATUS_INBOUND_INT 0x01 #define QDIO_STATUS_INBOUND_INT 0x01
...@@ -100,6 +100,8 @@ struct qdio_initialize{ ...@@ -100,6 +100,8 @@ struct qdio_initialize{
void **output_sbal_addr_array; /* addr of n*128 void ptrs */ void **output_sbal_addr_array; /* addr of n*128 void ptrs */
}; };
extern int qdio_initialize(struct qdio_initialize *init_data); extern int qdio_initialize(struct qdio_initialize *init_data);
extern int qdio_allocate(struct qdio_initialize *init_data);
extern int qdio_establish(struct ccw_device *);
extern int qdio_activate(struct ccw_device *,int flags); extern int qdio_activate(struct ccw_device *,int flags);
...@@ -127,6 +129,8 @@ extern int qdio_synchronize(struct ccw_device*, unsigned int flags, ...@@ -127,6 +129,8 @@ extern int qdio_synchronize(struct ccw_device*, unsigned int flags,
unsigned int queue_number); unsigned int queue_number);
extern int qdio_cleanup(struct ccw_device*, int how); extern int qdio_cleanup(struct ccw_device*, int how);
extern int qdio_shutdown(struct ccw_device*, int how);
extern int qdio_free(struct ccw_device*);
unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag, unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag,
unsigned int queue_number, unsigned int queue_number,
......
...@@ -50,11 +50,11 @@ struct qdio_buffer{ ...@@ -50,11 +50,11 @@ struct qdio_buffer{
} __attribute__ ((packed,aligned(256))); } __attribute__ ((packed,aligned(256)));
/* params are: irq, status, qdio_error, siga_error, /* params are: ccw_device, status, qdio_error, siga_error,
queue_number, first element processed, number of elements processed, queue_number, first element processed, number of elements processed,
int_parm */ int_parm */
typedef void qdio_handler_t(int,unsigned int,unsigned int,unsigned int, typedef void qdio_handler_t(struct ccw_device *,unsigned int,unsigned int,
unsigned int,int,int,unsigned long); unsigned int,unsigned int,int,int,unsigned long);
#define QDIO_STATUS_INBOUND_INT 0x01 #define QDIO_STATUS_INBOUND_INT 0x01
...@@ -100,6 +100,8 @@ struct qdio_initialize{ ...@@ -100,6 +100,8 @@ struct qdio_initialize{
void **output_sbal_addr_array; /* addr of n*128 void ptrs */ void **output_sbal_addr_array; /* addr of n*128 void ptrs */
}; };
extern int qdio_initialize(struct qdio_initialize *init_data); extern int qdio_initialize(struct qdio_initialize *init_data);
extern int qdio_allocate(struct qdio_initialize *init_data);
extern int qdio_establish(struct ccw_device *);
extern int qdio_activate(struct ccw_device *,int flags); extern int qdio_activate(struct ccw_device *,int flags);
...@@ -127,6 +129,8 @@ extern int qdio_synchronize(struct ccw_device*, unsigned int flags, ...@@ -127,6 +129,8 @@ extern int qdio_synchronize(struct ccw_device*, unsigned int flags,
unsigned int queue_number); unsigned int queue_number);
extern int qdio_cleanup(struct ccw_device*, int how); extern int qdio_cleanup(struct ccw_device*, int how);
extern int qdio_shutdown(struct ccw_device*, int how);
extern int qdio_free(struct ccw_device*);
unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag, unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag,
unsigned int queue_number, unsigned int queue_number,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment