Commit 2f7b411b authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: common i/o layer.

- Make ccwgroup online attribute consistent with ccw online attribute.
- Add link incident record handling to channel subsystem code.
- Do path grouping only if the device driver explicitly requests it.
- Fix multicast or broadcast flood ping hand on HiperSockets.
parent 87880da1
...@@ -80,7 +80,13 @@ static struct ccw_driver dasd_eckd_driver; /* see below */ ...@@ -80,7 +80,13 @@ static struct ccw_driver dasd_eckd_driver; /* see below */
static int static int
dasd_eckd_probe (struct ccw_device *cdev) dasd_eckd_probe (struct ccw_device *cdev)
{ {
return dasd_generic_probe (cdev, &dasd_eckd_discipline); int ret;
ret = dasd_generic_probe (cdev, &dasd_eckd_discipline);
if (ret)
return ret;
ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
return 0;
} }
static int static int
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Bugreports.to..: <Linux390@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
* *
* $Revision: 1.29 $ * $Revision: 1.30 $
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -57,7 +57,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */ ...@@ -57,7 +57,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */
static int static int
dasd_fba_probe(struct ccw_device *cdev) dasd_fba_probe(struct ccw_device *cdev)
{ {
return dasd_generic_probe (cdev, &dasd_fba_discipline); int ret;
ret = dasd_generic_probe (cdev, &dasd_fba_discipline);
if (ret)
return ret;
ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
return 0;
} }
static int static int
......
...@@ -372,6 +372,8 @@ tape_generic_probe(struct ccw_device *cdev) ...@@ -372,6 +372,8 @@ tape_generic_probe(struct ccw_device *cdev)
device->cdev = cdev; device->cdev = cdev;
cdev->handler = tape_do_irq; cdev->handler = tape_do_irq;
ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
return 0; return 0;
} }
...@@ -903,7 +905,7 @@ tape_init (void) ...@@ -903,7 +905,7 @@ tape_init (void)
{ {
tape_dbf_area = debug_register ( "tape", 1, 2, 3*sizeof(long)); tape_dbf_area = debug_register ( "tape", 1, 2, 3*sizeof(long));
debug_register_view(tape_dbf_area, &debug_sprintf_view); debug_register_view(tape_dbf_area, &debug_sprintf_view);
DBF_EVENT(3, "tape init: ($Revision: 1.25 $)\n"); DBF_EVENT(3, "tape init: ($Revision: 1.26 $)\n");
tape_proc_init(); tape_proc_init();
tapechar_init (); tapechar_init ();
tapeblock_init (); tapeblock_init ();
...@@ -928,7 +930,7 @@ tape_exit(void) ...@@ -928,7 +930,7 @@ tape_exit(void)
MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and " MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
"Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)"); "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
MODULE_DESCRIPTION("Linux on zSeries channel attached " MODULE_DESCRIPTION("Linux on zSeries channel attached "
"tape device driver ($Revision: 1.25 $)"); "tape device driver ($Revision: 1.26 $)");
module_init(tape_init); module_init(tape_init);
module_exit(tape_exit); module_exit(tape_exit);
......
/* /*
* drivers/s390/cio/ccwgroup.c * drivers/s390/cio/ccwgroup.c
* bus driver for ccwgroup * bus driver for ccwgroup
* $Revision: 1.6 $ * $Revision: 1.7 $
* *
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -196,10 +196,12 @@ ccwgroup_online_store (struct device *dev, const char *buf, size_t count) ...@@ -196,10 +196,12 @@ ccwgroup_online_store (struct device *dev, const char *buf, size_t count)
value = simple_strtoul(buf, 0, 0); value = simple_strtoul(buf, 0, 0);
if (value) if (value == 1)
ccwgroup_set_online(gdev); ccwgroup_set_online(gdev);
else else if (value == 0)
ccwgroup_set_offline(gdev); ccwgroup_set_offline(gdev);
else
return -EINVAL;
return count; return count;
} }
...@@ -211,7 +213,7 @@ ccwgroup_online_show (struct device *dev, char *buf) ...@@ -211,7 +213,7 @@ ccwgroup_online_show (struct device *dev, char *buf)
online = (to_ccwgroupdev(dev)->state == CCWGROUP_ONLINE); online = (to_ccwgroupdev(dev)->state == CCWGROUP_ONLINE);
return sprintf(buf, online ? "1\n" : "0\n"); return sprintf(buf, online ? "yes\n" : "no\n");
} }
static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store); static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);
......
/* /*
* drivers/s390/cio/chsc.c * drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call * S/390 common I/O routines -- channel subsystem call
* $Revision: 1.69 $ * $Revision: 1.73 $
* *
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -322,10 +322,6 @@ s390_set_chpid_offline( __u8 chpid) ...@@ -322,10 +322,6 @@ s390_set_chpid_offline( __u8 chpid)
sprintf(dbf_txt, "chpr%x", chpid); sprintf(dbf_txt, "chpr%x", chpid);
CIO_TRACE_EVENT(2, dbf_txt); CIO_TRACE_EVENT(2, dbf_txt);
/*
* TODO: the chpid may be not the chpid with the link incident,
* but the chpid the report came in through. How to handle???
*/
clear_bit(chpid, chpids); clear_bit(chpid, chpids);
if (!test_and_clear_bit(chpid, chpids_known)) if (!test_and_clear_bit(chpid, chpids_known))
return; /* we didn't know the chpid anyway */ return; /* we didn't know the chpid anyway */
...@@ -469,9 +465,40 @@ s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask) ...@@ -469,9 +465,40 @@ s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
free_page((unsigned long)page); free_page((unsigned long)page);
} }
static int
__get_chpid_from_lir(void *data)
{
struct lir {
u8 iq;
u8 ic;
u16 sci;
/* incident-node descriptor */
u32 indesc[28];
/* attached-node descriptor */
u32 andesc[28];
/* incident-specific information */
u32 isinfo[28];
} *lir;
lir = (struct lir*) data;
if (!(lir->iq&0x80))
/* NULL link incident record */
return -EINVAL;
if (!(lir->indesc[0]&0xc0000000))
/* node descriptor not valid */
return -EINVAL;
if (!(lir->indesc[0]&0x10000000))
/* don't handle device-type nodes - FIXME */
return -EINVAL;
/* Byte 3 contains the chpid. Could also be CTCA, but we don't care */
return (u16) (lir->indesc[0]&0x000000ff);
}
static void static void
do_process_crw(void *ignore) do_process_crw(void *ignore)
{ {
int chpid;
struct { struct {
struct chsc_header request; struct chsc_header request;
u32 reserved1; u32 reserved1;
...@@ -487,10 +514,8 @@ do_process_crw(void *ignore) ...@@ -487,10 +514,8 @@ do_process_crw(void *ignore)
u16 rsid; /* reporting source id */ u16 rsid; /* reporting source id */
u32 reserved5; u32 reserved5;
u32 reserved6; u32 reserved6;
u32 ccdf; /* content-code dependent field */ u32 ccdf[96]; /* content-code dependent field */
u32 reserved7; /* ccdf has to be big enough for a link-incident record */
u32 reserved8;
u32 reserved9;
} *sei_area; } *sei_area;
/* /*
...@@ -560,9 +585,14 @@ do_process_crw(void *ignore) ...@@ -560,9 +585,14 @@ do_process_crw(void *ignore)
case 1: /* link incident*/ case 1: /* link incident*/
CIO_CRW_EVENT(4, "chsc_process_crw: " CIO_CRW_EVENT(4, "chsc_process_crw: "
"channel subsystem reports link incident," "channel subsystem reports link incident,"
" source is chpid %x\n", sei_area->rsid); " reporting source is chpid %x\n",
sei_area->rsid);
s390_set_chpid_offline(sei_area->rsid); chpid = __get_chpid_from_lir(sei_area->ccdf);
if (chpid < 0)
CIO_CRW_EVENT(4, "%s: Invalid LIR, skipping\n",
__FUNCTION__);
else
s390_set_chpid_offline(chpid);
break; break;
case 2: /* i/o resource accessibiliy */ case 2: /* i/o resource accessibiliy */
......
...@@ -72,9 +72,9 @@ struct ccw_device_private { ...@@ -72,9 +72,9 @@ struct ccw_device_private {
struct { struct {
unsigned int fast:1; /* post with "channel end" */ unsigned int fast:1; /* post with "channel end" */
unsigned int repall:1; /* report every interrupt status */ unsigned int repall:1; /* report every interrupt status */
unsigned int pgroup:1; /* do path grouping */
} __attribute__ ((packed)) options; } __attribute__ ((packed)) options;
struct { struct {
unsigned int pgid_supp:1; /* "path group ID" supported */
unsigned int pgid_single:1; /* use single path for Set PGID */ unsigned int pgid_single:1; /* use single path for Set PGID */
unsigned int esid:1; /* Ext. SenseID supported by HW */ unsigned int esid:1; /* Ext. SenseID supported by HW */
unsigned int dosense:1; /* delayed SENSE required */ unsigned int dosense:1; /* delayed SENSE required */
......
/* /*
* drivers/s390/cio/device.c * drivers/s390/cio/device.c
* bus driver for ccw devices * bus driver for ccw devices
* $Revision: 1.54 $ * $Revision: 1.57 $
* *
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -298,20 +298,19 @@ static ssize_t ...@@ -298,20 +298,19 @@ static ssize_t
online_store (struct device *dev, const char *buf, size_t count) online_store (struct device *dev, const char *buf, size_t count)
{ {
struct ccw_device *cdev = to_ccwdev(dev); struct ccw_device *cdev = to_ccwdev(dev);
unsigned int value; int i;
char *tmp;
if (!cdev->drv) if (!cdev->drv)
return count; return count;
sscanf(buf, "%u", &value); i = simple_strtoul(buf, &tmp, 16);
if (i == 0 && cdev->drv->set_online)
if (value) { ccw_device_set_online(cdev);
if (cdev->drv->set_online) else if (i == 1 && cdev->drv->set_offline)
ccw_device_set_online(cdev); ccw_device_set_offline(cdev);
} else { else
if (cdev->drv->set_offline) return -EINVAL;
ccw_device_set_offline(cdev);
}
return count; return count;
} }
...@@ -405,11 +404,14 @@ device_add_files (struct device *dev) ...@@ -405,11 +404,14 @@ device_add_files (struct device *dev)
* This allows to trigger an unconditional reserve ccw to eckd dasds * This allows to trigger an unconditional reserve ccw to eckd dasds
* (if the device is something else, there should be no problems more than * (if the device is something else, there should be no problems more than
* a command reject; we don't have any means of finding out the device's * a command reject; we don't have any means of finding out the device's
* type if it was boxed at ipl/attach). * type if it was boxed at ipl/attach for older devices and under VM).
*/ */
void void
ccw_device_add_stlck(struct ccw_device *cdev) ccw_device_add_stlck(void *data)
{ {
struct ccw_device *cdev;
cdev = (struct ccw_device *)data;
device_create_file(&cdev->dev, &dev_attr_steal_lock); device_create_file(&cdev->dev, &dev_attr_steal_lock);
} }
...@@ -470,6 +472,8 @@ io_subchannel_register(void *data) ...@@ -470,6 +472,8 @@ io_subchannel_register(void *data)
if (ret) if (ret)
printk(KERN_WARNING "%s: could not add attributes to %04x\n", printk(KERN_WARNING "%s: could not add attributes to %04x\n",
__func__, sch->irq); __func__, sch->irq);
if (cdev->private->state == DEV_STATE_BOXED)
device_create_file(&cdev->dev, &dev_attr_steal_lock);
out: out:
put_device(&sch->dev); put_device(&sch->dev);
} }
...@@ -493,6 +497,8 @@ io_subchannel_recog_done(struct ccw_device *cdev) ...@@ -493,6 +497,8 @@ io_subchannel_recog_done(struct ccw_device *cdev)
if (cdev->dev.release) if (cdev->dev.release)
cdev->dev.release(&cdev->dev); cdev->dev.release(&cdev->dev);
break; break;
case DEV_STATE_BOXED:
/* Device did not respond in time. */
case DEV_STATE_OFFLINE: case DEV_STATE_OFFLINE:
/* /*
* We can't register the device in interrupt context so * We can't register the device in interrupt context so
...@@ -502,9 +508,6 @@ io_subchannel_recog_done(struct ccw_device *cdev) ...@@ -502,9 +508,6 @@ io_subchannel_recog_done(struct ccw_device *cdev)
io_subchannel_register, (void *) cdev); io_subchannel_register, (void *) cdev);
queue_work(ccw_device_work, &cdev->private->kick_work); queue_work(ccw_device_work, &cdev->private->kick_work);
break; break;
case DEV_STATE_BOXED:
/* Device did not respond in time. */
break;
} }
if (atomic_dec_and_test(&ccw_device_init_count)) if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq); wake_up(&ccw_device_init_wq);
......
...@@ -95,7 +95,7 @@ void ccw_device_disband_done(struct ccw_device *, int); ...@@ -95,7 +95,7 @@ void ccw_device_disband_done(struct ccw_device *, int);
void ccw_device_call_handler(struct ccw_device *); void ccw_device_call_handler(struct ccw_device *);
void ccw_device_add_stlck(struct ccw_device *); void ccw_device_add_stlck(void *);
int ccw_device_stlck(struct ccw_device *); int ccw_device_stlck(struct ccw_device *);
/* qdio needs this. */ /* qdio needs this. */
......
...@@ -132,11 +132,11 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) ...@@ -132,11 +132,11 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
CIO_DEBUG(KERN_WARNING, 2, CIO_DEBUG(KERN_WARNING, 2,
"SenseID : boxed device %04X on subchannel %04X\n", "SenseID : boxed device %04X on subchannel %04X\n",
sch->schib.pmcw.dev, sch->irq); sch->schib.pmcw.dev, sch->irq);
ccw_device_add_stlck(cdev);
break; break;
} }
io_subchannel_recog_done(cdev); io_subchannel_recog_done(cdev);
wake_up(&cdev->private->wait_q); if (state != DEV_STATE_NOT_OPER)
wake_up(&cdev->private->wait_q);
} }
/* /*
...@@ -158,23 +158,66 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err) ...@@ -158,23 +158,66 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err)
} }
} }
/*
* Finished with online/offline processing.
*/
static void
ccw_device_done(struct ccw_device *cdev, int state)
{
struct subchannel *sch;
sch = to_subchannel(cdev->dev.parent);
if (state != DEV_STATE_ONLINE)
cio_disable_subchannel(sch);
/* Reset device status. */
memset(&cdev->private->irb, 0, sizeof(struct irb));
cdev->private->state = state;
if (state == DEV_STATE_BOXED) {
CIO_DEBUG(KERN_WARNING, 2,
"Boxed device %04X on subchannel %04X\n",
sch->schib.pmcw.dev, sch->irq);
INIT_WORK(&cdev->private->kick_work,
ccw_device_add_stlck, (void *) cdev);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
wake_up(&cdev->private->wait_q);
if (state != DEV_STATE_ONLINE)
put_device (&cdev->dev);
}
/* /*
* Function called from device_pgid.c after sense path ground has completed. * Function called from device_pgid.c after sense path ground has completed.
*/ */
void void
ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
{ {
struct subchannel *sch;
sch = to_subchannel(cdev->dev.parent);
switch (err) { switch (err) {
case 0: case 0:
cdev->private->state = DEV_STATE_SENSE_ID; /* Start Path Group verification. */
ccw_device_sense_id_start(cdev); sch->vpm = 0; /* Start with no path groups set. */
cdev->private->state = DEV_STATE_VERIFY;
ccw_device_verify_start(cdev);
break; break;
case -ETIME: /* Sense path group id stopped by timeout. */ case -ETIME: /* Sense path group id stopped by timeout. */
case -EUSERS: /* device is reserved for someone else. */ case -EUSERS: /* device is reserved for someone else. */
ccw_device_recog_done(cdev, DEV_STATE_BOXED); ccw_device_done(cdev, DEV_STATE_BOXED);
break;
case -EOPNOTSUPP: /* path grouping not supported, just set online. */
cdev->private->options.pgroup = 0;
ccw_device_done(cdev, DEV_STATE_ONLINE);
break; break;
default: default:
ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER); ccw_device_done(cdev, DEV_STATE_NOT_OPER);
break; break;
} }
} }
...@@ -198,11 +241,15 @@ ccw_device_recognition(struct ccw_device *cdev) ...@@ -198,11 +241,15 @@ ccw_device_recognition(struct ccw_device *cdev)
ccw_device_set_timeout(cdev, 60*HZ); ccw_device_set_timeout(cdev, 60*HZ);
/* /*
* First thing we should do is a sensePGID in order to find out how * We used to start here with a sense pgid to find out whether a device
* we can proceed with the recognition process. * is locked by someone else. Unfortunately, the sense pgid command
* code has other meanings on devices predating the path grouping
* algorithm, so we start with sense id and box the device after an
* timeout (or if sense pgid during path verification detects the device
* is locked, as may happen on newer devices).
*/ */
cdev->private->state = DEV_STATE_SENSE_PGID; cdev->private->state = DEV_STATE_SENSE_ID;
ccw_device_sense_pgid_start(cdev); ccw_device_sense_id_start(cdev);
return 0; return 0;
} }
...@@ -218,29 +265,6 @@ ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event) ...@@ -218,29 +265,6 @@ ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event)
ccw_device_set_timeout(cdev, 3*HZ); ccw_device_set_timeout(cdev, 3*HZ);
} }
/*
* Finished with online/offline processing.
*/
static void
ccw_device_done(struct ccw_device *cdev, int state)
{
struct subchannel *sch;
sch = to_subchannel(cdev->dev.parent);
if (state != DEV_STATE_ONLINE)
cio_disable_subchannel(sch);
/* Reset device status. */
memset(&cdev->private->irb, 0, sizeof(struct irb));
cdev->private->state = state;
wake_up(&cdev->private->wait_q);
if (state != DEV_STATE_ONLINE)
put_device (&cdev->dev);
}
void void
ccw_device_verify_done(struct ccw_device *cdev, int err) ccw_device_verify_done(struct ccw_device *cdev, int err)
...@@ -276,16 +300,15 @@ ccw_device_online(struct ccw_device *cdev) ...@@ -276,16 +300,15 @@ ccw_device_online(struct ccw_device *cdev)
dev_fsm_event(cdev, DEV_EVENT_NOTOPER); dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
return -ENODEV; return -ENODEV;
} }
/* Is Set Path Group supported? */ /* Do we want to do path grouping? */
if (!cdev->private->flags.pgid_supp) { if (!cdev->private->options.pgroup) {
/* No, set state online immediately. */ /* No, set state online immediately. */
ccw_device_done(cdev, DEV_STATE_ONLINE); ccw_device_done(cdev, DEV_STATE_ONLINE);
return 0; return 0;
} }
/* Start Path Group verification. */ /* Do a SensePGID first. */
sch->vpm = 0; /* Start with no path groups set. */ cdev->private->state = DEV_STATE_SENSE_PGID;
cdev->private->state = DEV_STATE_VERIFY; ccw_device_sense_pgid_start(cdev);
ccw_device_verify_start(cdev);
return 0; return 0;
} }
...@@ -321,8 +344,8 @@ ccw_device_offline(struct ccw_device *cdev) ...@@ -321,8 +344,8 @@ ccw_device_offline(struct ccw_device *cdev)
} }
if (sch->schib.scsw.actl != 0) if (sch->schib.scsw.actl != 0)
return -EBUSY; return -EBUSY;
/* Is Set Path Group supported? */ /* Are we doing path grouping? */
if (!cdev->private->flags.pgid_supp) { if (!cdev->private->options.pgroup) {
/* No, set state offline immediately. */ /* No, set state offline immediately. */
ccw_device_done(cdev, DEV_STATE_OFFLINE); ccw_device_done(cdev, DEV_STATE_OFFLINE);
return 0; return 0;
...@@ -643,9 +666,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { ...@@ -643,9 +666,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
[DEV_EVENT_VERIFY] ccw_device_nop, [DEV_EVENT_VERIFY] ccw_device_nop,
}, },
[DEV_STATE_SENSE_PGID] { [DEV_STATE_SENSE_PGID] {
[DEV_EVENT_NOTOPER] ccw_device_recog_notoper, [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
[DEV_EVENT_INTERRUPT] ccw_device_sense_pgid_irq, [DEV_EVENT_INTERRUPT] ccw_device_sense_pgid_irq,
[DEV_EVENT_TIMEOUT] ccw_device_recog_timeout, [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout,
[DEV_EVENT_VERIFY] ccw_device_nop, [DEV_EVENT_VERIFY] ccw_device_nop,
}, },
[DEV_STATE_SENSE_ID] { [DEV_STATE_SENSE_ID] {
......
...@@ -37,6 +37,7 @@ ccw_device_set_options(struct ccw_device *cdev, unsigned long flags) ...@@ -37,6 +37,7 @@ ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
return -EINVAL; return -EINVAL;
cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0; cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0; cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
return 0; return 0;
} }
......
...@@ -84,7 +84,6 @@ ccw_device_sense_pgid_start(struct ccw_device *cdev) ...@@ -84,7 +84,6 @@ ccw_device_sense_pgid_start(struct ccw_device *cdev)
cdev->private->state = DEV_STATE_SENSE_PGID; cdev->private->state = DEV_STATE_SENSE_PGID;
cdev->private->imask = 0x80; cdev->private->imask = 0x80;
cdev->private->iretry = 5; cdev->private->iretry = 5;
cdev->private->flags.pgid_supp = 0;
memset (&cdev->private->pgid, 0, sizeof (struct pgid)); memset (&cdev->private->pgid, 0, sizeof (struct pgid));
ret = __ccw_device_sense_pgid_start(cdev); ret = __ccw_device_sense_pgid_start(cdev);
if (ret) if (ret)
...@@ -165,14 +164,13 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) ...@@ -165,14 +164,13 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
switch (__ccw_device_check_sense_pgid(cdev)) { switch (__ccw_device_check_sense_pgid(cdev)) {
/* 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;
opm = sch->schib.pmcw.pim & opm = sch->schib.pmcw.pim &
sch->schib.pmcw.pam & sch->schib.pmcw.pam &
sch->schib.pmcw.pom; sch->schib.pmcw.pom;
for (i=0;i<8;i++) { for (i=0;i<8;i++) {
if (opm == (0x80 << i)) { if (opm == (0x80 << i)) {
/* Don't group single path devices. */ /* Don't group single path devices. */
cdev->private->flags.pgid_supp = 0; cdev->private->options.pgroup = 0;
break; break;
} }
} }
...@@ -181,7 +179,7 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) ...@@ -181,7 +179,7 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
sizeof(struct pgid)); sizeof(struct pgid));
/* fall through. */ /* fall through. */
case -EOPNOTSUPP: /* Sense Path Group ID not supported */ case -EOPNOTSUPP: /* Sense Path Group ID not supported */
ccw_device_sense_pgid_done(cdev, 0); ccw_device_sense_pgid_done(cdev, -EOPNOTSUPP);
break; break;
case -ETIME: /* Sense path group id stopped by timeout. */ case -ETIME: /* Sense path group id stopped by timeout. */
ccw_device_sense_pgid_done(cdev, -ETIME); ccw_device_sense_pgid_done(cdev, -ETIME);
......
#ifndef _CIO_QDIO_H #ifndef _CIO_QDIO_H
#define _CIO_QDIO_H #define _CIO_QDIO_H
#define VERSION_CIO_QDIO_H "$Revision: 1.16 $" #define VERSION_CIO_QDIO_H "$Revision: 1.17 $"
//#define QDIO_DBF_LIKE_HELL //#define QDIO_DBF_LIKE_HELL
...@@ -21,7 +21,15 @@ ...@@ -21,7 +21,15 @@
#define QDIO_TIMER_POLL_VALUE 1 #define QDIO_TIMER_POLL_VALUE 1
#define IQDIO_TIMER_POLL_VALUE 1 #define IQDIO_TIMER_POLL_VALUE 1
#define IQDIO_FILL_LEVEL_TO_POLL (QDIO_MAX_BUFFERS_PER_Q*4/3) /*
* unfortunately this can't be (QDIO_MAX_BUFFERS_PER_Q*4/3) or so -- as
* we never know, whether we'll get initiative again, e.g. to give the
* transmit skb's back to the stack, however the stack may be waiting for
* them... therefore we define 4 as threshold to start polling (which
* will stop as soon as the asynchronous queue catches up)
* btw, this only applies to the asynchronous HiperSockets queue
*/
#define IQDIO_FILL_LEVEL_TO_POLL 4
#define IQDIO_THININT_ISC 3 #define IQDIO_THININT_ISC 3
#define IQDIO_DELAY_TARGET 0 #define IQDIO_DELAY_TARGET 0
......
...@@ -115,6 +115,8 @@ extern int ccw_device_set_options(struct ccw_device *, unsigned long); ...@@ -115,6 +115,8 @@ extern int ccw_device_set_options(struct ccw_device *, unsigned long);
#define CCWDEV_EARLY_NOTIFICATION 0x0001 #define CCWDEV_EARLY_NOTIFICATION 0x0001
/* Report all interrupt conditions. */ /* Report all interrupt conditions. */
#define CCWDEV_REPORT_ALL 0x0002 #define CCWDEV_REPORT_ALL 0x0002
/* Try to perform path grouping. */
#define CCWDEV_DO_PATHGROUP 0x0004
/* /*
* ccw_device_start() * ccw_device_start()
......
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