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

[PATCH] s390 update (23/27): channel paths.

Check if defined chpids are available. Some code simplification.
parent 09212816
/* /*
* 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.9 $ * $Revision: 1.12 $
* *
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -52,6 +52,49 @@ chsc_chpid_logical (int irq, int chp) ...@@ -52,6 +52,49 @@ chsc_chpid_logical (int irq, int chp)
return test_bit (ioinfo[irq]->schib.pmcw.chpid[chp], &chpids_logical); return test_bit (ioinfo[irq]->schib.pmcw.chpid[chp], &chpids_logical);
} }
static inline void
chsc_clear_chpid(int irq, int chp)
{
clear_bit(ioinfo[irq]->schib.pmcw.chpid[chp], &chpids);
}
void
chsc_validate_chpids(int irq)
{
int mask, chp;
if (ioinfo[irq]->opm) {
for (chp=0;chp<=7;chp++) {
mask = 0x80 >> chp;
if (ioinfo[irq]->opm & mask) {
if (!chsc_chpid_logical(irq,chp))
/* disable using this path */
ioinfo[irq]->opm &= ~mask;
} else {
/* This chpid is not
* available to us */
chsc_clear_chpid(irq,chp);
}
}
}
}
void
switch_off_chpids(int irq, __u8 mask)
{
int i;
pmcw_t *pmcw = &ioinfo[irq]->schib.pmcw;
for (i=0;i<8;i++)
if ((0x80>>i) & mask
& pmcw->pim
& pmcw->pam
& pmcw->pom)
clear_bit(pmcw->chpid[i], &chpids);
}
/* FIXME: this is _always_ called for every subchannel. shouldn't we /* FIXME: this is _always_ called for every subchannel. shouldn't we
* process more than one at a time?*/ * process more than one at a time?*/
static int static int
...@@ -213,11 +256,9 @@ s390_do_chpid_processing( __u8 chpid) ...@@ -213,11 +256,9 @@ s390_do_chpid_processing( __u8 chpid)
{ {
int irq; int irq;
int j; int j;
int mask;
char dbf_txt[15]; char dbf_txt[15];
int ccode; int ccode;
int was_oper; int was_oper;
int chp = 0;
int mask2; int mask2;
sprintf(dbf_txt, "chpr%x", chpid); sprintf(dbf_txt, "chpr%x", chpid);
...@@ -266,21 +307,7 @@ s390_do_chpid_processing( __u8 chpid) ...@@ -266,21 +307,7 @@ s390_do_chpid_processing( __u8 chpid)
ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pam &
ioinfo[irq]->schib.pmcw.pom; ioinfo[irq]->schib.pmcw.pom;
if (ioinfo[irq]->opm) { chsc_validate_chpids(irq);
for (chp=0;chp<=7;chp++) {
mask2 = 0x80 >> chp;
if (ioinfo[irq]->opm & mask2) {
if (!test_bit
(ioinfo[irq]->
schib.pmcw.chpid[chp],
&chpids_logical)) {
/* disable using this path */
ioinfo[irq]->opm
&= ~mask2;
}
}
}
}
if (!ioinfo[irq]->opm) { if (!ioinfo[irq]->opm) {
/* /*
...@@ -307,20 +334,7 @@ s390_do_chpid_processing( __u8 chpid) ...@@ -307,20 +334,7 @@ s390_do_chpid_processing( __u8 chpid)
nopfunc(irq, DEVSTAT_DEVICE_GONE); nopfunc(irq, DEVSTAT_DEVICE_GONE);
} }
} else if (ioinfo[irq]->ui.flags.ready) { }
/*
* Re-do path verification for the chpid in question
* FIXME: is this neccessary?
*/
mask = 0x80 >> j;
if (!s390_DevicePathVerification(irq,mask)) {
CHSC_DEBUG (KERN_DEBUG, CRW, 2,
"DevicePathVerification "
"successful for Subchannel %x, "
"chpid %x\n", irq, chpid);
}
}
s390irq_spin_unlock(irq); s390irq_spin_unlock(irq);
break; break;
...@@ -432,18 +446,7 @@ s390_process_res_acc_chpid (u8 chpid) ...@@ -432,18 +446,7 @@ s390_process_res_acc_chpid (u8 chpid)
ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pam &
ioinfo[irq]->schib.pmcw.pom; ioinfo[irq]->schib.pmcw.pom;
if (ioinfo[irq]->opm) { chsc_validate_chpids(irq);
for (chp=0;chp<=7;chp++) {
mask = 0x80 >> chp;
if ((ioinfo[irq]->opm & mask) &&
!test_bit (ioinfo[irq]->schib.pmcw.chpid[chp],
&chpids_logical)) {
/* disable using this path */
ioinfo[irq]->opm &= ~mask;
}
}
}
if ((ioinfo[irq]->ui.flags.ready) && (chpid & ioinfo[irq]->opm)) if ((ioinfo[irq]->ui.flags.ready) && (chpid & ioinfo[irq]->opm))
s390_DevicePathVerification(irq, chpid); s390_DevicePathVerification(irq, chpid);
...@@ -456,8 +459,7 @@ s390_process_res_acc_linkaddr ( __u8 chpid, __u16 fla, u32 fla_mask) ...@@ -456,8 +459,7 @@ s390_process_res_acc_linkaddr ( __u8 chpid, __u16 fla, u32 fla_mask)
char dbf_txt[15]; char dbf_txt[15];
int irq = 0; int irq = 0;
int ccode; int ccode;
int chp; int mask2;
int mask, mask2;
int ret; int ret;
int j; int j;
...@@ -517,18 +519,7 @@ s390_process_res_acc_linkaddr ( __u8 chpid, __u16 fla, u32 fla_mask) ...@@ -517,18 +519,7 @@ s390_process_res_acc_linkaddr ( __u8 chpid, __u16 fla, u32 fla_mask)
ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pam &
ioinfo[irq]->schib.pmcw.pom; ioinfo[irq]->schib.pmcw.pom;
if (ioinfo[irq]->opm) { chsc_validate_chpids(irq);
for (chp=0;chp<=7;chp++) {
mask = 0x80 >> chp;
if ((ioinfo[irq]->opm & mask)
&& (!test_bit (ioinfo[irq]->
schib.pmcw.chpid[chp],
&chpids_logical))) {
/* disable using this path */
ioinfo[irq]->opm &= ~mask;
}
}
}
if (ioinfo[irq]->ui.flags.ready) if (ioinfo[irq]->ui.flags.ready)
s390_DevicePathVerification(irq, chpid); s390_DevicePathVerification(irq, chpid);
...@@ -782,11 +773,20 @@ cio_chpids_read (char *page, char **start, off_t off, ...@@ -782,11 +773,20 @@ cio_chpids_read (char *page, char **start, off_t off,
} }
while (chp < NR_CHPIDS && len + entry_size < count) { while (chp < NR_CHPIDS && len + entry_size < count) {
if ((test_bit( chp, &chpids)) && test_bit(chp, &chpids_logical)) if (test_bit(chp, &chpids_known)) {
len += sprintf(page+len, "0x%02X online\n", chp);
else if (test_bit(chp, &chpids_known)) if (!test_bit(chp, &chpids))
len += sprintf(page+len, "0x%02X logically offline\n", len += sprintf(page+len,
chp); "0x%02X n/a\n", chp);
else if (test_bit(chp, &chpids_logical))
len += sprintf(page+len,
"0x%02X online\n", chp);
else
len += sprintf(page+len,
"0x%02X logically offline\n",
chp);
}
chp++; chp++;
} }
......
...@@ -3,4 +3,6 @@ ...@@ -3,4 +3,6 @@
extern void s390_process_css( void ); extern void s390_process_css( void );
extern int chsc_chpid_logical (int irq, int chp); extern int chsc_chpid_logical (int irq, int chp);
extern void chsc_validate_chpids(int irq);
extern void switch_off_chpids(int irq, __u8 mask);
#endif #endif
/* /*
* 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.25 $ * $Revision: 1.26 $
* *
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation * IBM Corporation
...@@ -342,6 +342,7 @@ s390_start_IO_handle_notoper(int irq, ...@@ -342,6 +342,7 @@ s390_start_IO_handle_notoper(int irq,
if (valid_lpm) { if (valid_lpm) {
ioinfo[irq]->opm &= ~lpm; ioinfo[irq]->opm &= ~lpm;
switch_off_chpids(irq, lpm);
} else { } else {
ioinfo[irq]->opm = 0; ioinfo[irq]->opm = 0;
...@@ -1386,7 +1387,7 @@ s390_process_IRQ_notoper(unsigned int irq) ...@@ -1386,7 +1387,7 @@ s390_process_IRQ_notoper(unsigned int irq)
ioinfo[irq]->devstat.intparm = 0; ioinfo[irq]->devstat.intparm = 0;
if (!ioinfo[irq]->ui.flags.s_pend) if (!(ioinfo[irq]->ui.flags.s_pend || ioinfo[irq]->ui.flags.repnone))
ioinfo[irq]->irq_desc.handler (irq, udp, NULL); ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
return 1; return 1;
......
...@@ -991,9 +991,6 @@ s390_validate_subchannel (int irq, int enable) ...@@ -991,9 +991,6 @@ s390_validate_subchannel (int irq, int enable)
int ccode2; /* condition code for other I/O routines */ int ccode2; /* condition code for other I/O routines */
schib_t *p_schib; schib_t *p_schib;
int ret; int ret;
int chp = 0;
int mask;
char dbf_txt[15]; char dbf_txt[15];
sprintf (dbf_txt, "valsch%x", irq); sprintf (dbf_txt, "valsch%x", irq);
...@@ -1115,17 +1112,7 @@ s390_validate_subchannel (int irq, int enable) ...@@ -1115,17 +1112,7 @@ s390_validate_subchannel (int irq, int enable)
ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
& ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom; & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom;
if (ioinfo[irq]->opm) { chsc_validate_chpids(irq);
for (chp=0;chp<=7;chp++) {
mask = 0x80 >> chp;
if (ioinfo[irq]->opm & mask) {
if (!chsc_chpid_logical (irq, chp)) {
/* disable using this path */
ioinfo[irq]->opm &= ~mask;
}
}
}
}
CIO_DEBUG_IFMSG(KERN_INFO, 0, CIO_DEBUG_IFMSG(KERN_INFO, 0,
"Detected device %04X " "Detected device %04X "
...@@ -1690,8 +1677,6 @@ s390_DevicePathVerification (int irq, __u8 usermask) ...@@ -1690,8 +1677,6 @@ s390_DevicePathVerification (int irq, __u8 usermask)
int ccode; int ccode;
__u8 pathmask; __u8 pathmask;
__u8 domask; __u8 domask;
int chp;
int mask;
int old_opm = 0; int old_opm = 0;
int ret = 0; int ret = 0;
...@@ -1772,18 +1757,8 @@ s390_DevicePathVerification (int irq, __u8 usermask) ...@@ -1772,18 +1757,8 @@ s390_DevicePathVerification (int irq, __u8 usermask)
ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
& ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom; & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom;
if (ioinfo[irq]->opm) { chsc_validate_chpids(irq);
for (chp=0;chp<=7;chp++) {
mask = 0x80 >> chp;
if (ioinfo[irq]->opm & mask) {
if (!chsc_chpid_logical (irq, chp)) {
/* disable using this path */
ioinfo[irq]->opm &= ~mask;
}
}
}
}
if ((ioinfo[irq]->opm == 0) && (old_opm)) { if ((ioinfo[irq]->opm == 0) && (old_opm)) {
not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc; not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc;
int was_oper = ioinfo[irq]->ui.flags.ready; int was_oper = ioinfo[irq]->ui.flags.ready;
...@@ -1815,7 +1790,7 @@ s390_DevicePathVerification (int irq, __u8 usermask) ...@@ -1815,7 +1790,7 @@ s390_DevicePathVerification (int irq, __u8 usermask)
} }
if ( ioinfo[irq]->ui.flags.pgid_supp == 0 ) if ( ioinfo[irq]->ui.flags.pgid_supp == 0 )
return( 0); /* just exit ... */ return 0; /* just exit ... */
if (usermask) { if (usermask) {
dev_path = usermask; dev_path = usermask;
...@@ -2229,8 +2204,8 @@ s390_SensePGID (int irq, __u8 lpm, pgid_t * pgid) ...@@ -2229,8 +2204,8 @@ s390_SensePGID (int irq, __u8 lpm, pgid_t * pgid)
* Sense Path Group ID command * Sense Path Group ID command
* further retries wouldn't help ... * further retries wouldn't help ...
*/ */
if (pdevstat->ii.sense. if (pdevstat->ii.sense.data[0] &
data[0] & SNS0_CMD_REJECT) { (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) {
retry = 0; retry = 0;
irq_ret = -EOPNOTSUPP; irq_ret = -EOPNOTSUPP;
} else { } else {
......
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