Skip to content

Commit c39016e

Browse files
committed
Fix QETH shutdown handling
1 parent c11206b commit c39016e

File tree

2 files changed

+62
-22
lines changed

2 files changed

+62
-22
lines changed

qdio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef struct _QDIO_DEV {
1818
int idxstate; /* IDX state */
1919
#define MPC_IDX_STATE_INACTIVE 0x00 // ZZ THIS FIELD NEEDS TO MOVE
2020
#define MPC_IDX_STATE_ACTIVE 0x01
21+
#define MPC_IDX_STATE_HALTING 0x02
2122

2223
int thinint; /* Thin Interrupts on PCI */
2324

qeth.c

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,37 +2277,62 @@ int found_buff = 0; /* Found primed o/p buffer */
22772277
/*-------------------------------------------------------------------*/
22782278
/* Halt device related functions... */
22792279
/*-------------------------------------------------------------------*/
2280-
static void qeth_signal_halt (OSA_GRP *grp)
2280+
static void qeth_halt_read_device (DEVBLK *dev, OSA_GRP *grp)
2281+
{
2282+
if (dev->qdio.idxstate == MPC_IDX_STATE_ACTIVE)
2283+
{
2284+
DBGTRC( dev, "Halting read device\n" );
2285+
2286+
/* Ask, then wait for, the READ CCW loop to exit */
2287+
obtain_lock( &grp->qlock );
2288+
PTT_QETH_TRACE( "b4 halt read", 0,0,0 );
2289+
dev->qdio.idxstate = MPC_IDX_STATE_HALTING;
2290+
signal_condition( &grp->qcond );
2291+
wait_condition( &grp->qcond, &grp->qlock );
2292+
PTT_QETH_TRACE( "af halt read", 0,0,0 );
2293+
release_lock( &grp->qlock );
2294+
2295+
DBGTRC( dev, "Read device halted\n" );
2296+
}
2297+
}
2298+
2299+
static void qeth_halt_data_device (DEVBLK *dev, OSA_GRP *grp)
22812300
{
22822301
fd_set readset;
22832302
BYTE sig = QDSIG_HALT;
22842303

2285-
/* Send signal */
2286-
qeth_write_pipe( grp->ppfd[1], &sig );
2304+
UNREFERENCED(dev); /* (unreferenced for non-DEBUG builds) */
22872305

2288-
/* Wait for reply */
2289-
FD_ZERO( &readset );
2290-
FD_SET( grp->ppfd[0], &readset );
2291-
qeth_select( grp->ppfd[0]+1, &readset, NULL );
2292-
qeth_read_pipe( grp->ppfd[0], &sig );
2306+
if (dev->scsw.flag2 & SCSW2_Q)
2307+
{
2308+
DBGTRC( dev, "Halting data device\n" );
2309+
2310+
/* Indicate QDIO no longer active, write halt request to
2311+
signalling pipe, then wait for and read the halt reply. */
2312+
dev->scsw.flag2 &= ~SCSW2_Q;
2313+
qeth_write_pipe( grp->ppfd[1], &sig );
2314+
FD_ZERO( &readset );
2315+
FD_SET( grp->ppfd[0], &readset );
2316+
qeth_select( grp->ppfd[0]+1, &readset, NULL );
2317+
qeth_read_pipe( grp->ppfd[0], &sig );
2318+
2319+
DBGTRC( dev, "Data device halted\n" );
2320+
}
22932321
}
22942322

22952323
static void qeth_halt_device (DEVBLK *dev)
22962324
{
22972325
OSA_GRP *grp = (OSA_GRP*)dev->group->grp_data;
22982326

2299-
/* Signal ACTIVATE QUEUES loop to exit if QDIO is active */
2300-
if(dev->scsw.flag2 & SCSW2_Q)
2301-
{
2302-
dev->scsw.flag2 &= ~SCSW2_Q;
2303-
qeth_signal_halt(grp);
2304-
}
2327+
if (dev == dev->group->memdev[2])
2328+
qeth_halt_data_device( dev, grp );
23052329
else
2306-
if(dev->group->acount == OSA_GROUP_SIZE)
2330+
if (dev == dev->group->memdev[0])
2331+
qeth_halt_read_device( dev, grp );
2332+
else
23072333
{
2308-
/* Tell READ loop to not wait for IDX response */
2309-
dev->qdio.idxstate = MPC_IDX_STATE_INACTIVE;
2310-
signal_condition(&grp->qcond);
2334+
DBGTRC( dev, "qeth_halt_device: noop!\n" );
2335+
PTT_QETH_TRACE( "*halt noop", dev->devnum, 0,0 );
23112336
}
23122337
}
23132338

@@ -2591,6 +2616,11 @@ int i;
25912616
}
25922617
}
25932618

2619+
2620+
// warn if ttnetmask/ttpfxlen discrepency
2621+
// build default ttnetmask/ttpfxlen if undefined
2622+
2623+
25942624
#if defined(ENABLE_IPV6)
25952625
/* Check the grp->ttipaddr6 and grp->ttpfxlen6 values */
25962626
if (grp->ttipaddr6)
@@ -2748,19 +2778,19 @@ static int qeth_close_device ( DEVBLK *dev )
27482778
{
27492779
OSA_GRP *grp = (OSA_GRP*)dev->group->grp_data;
27502780

2751-
if(!dev->member && dev->group->grp_data)
2781+
if (!dev->member && dev->group->grp_data)
27522782
{
27532783
int ttfd = grp->ttfd;
27542784

27552785
PTT_QETH_TRACE( "b4 clos halt", 0,0,0 );
2756-
qeth_halt_device(dev);
2786+
qeth_halt_read_device( dev->group->memdev[0], grp );
2787+
qeth_halt_data_device( dev->group->memdev[2], grp );
27572788
PTT_QETH_TRACE( "af clos halt", 0,0,0 );
27582789

27592790
PTT_QETH_TRACE( "b4 clos ttfd", 0,0,0 );
27602791
grp->ttfd = -1;
27612792
dev->fd = -1;
2762-
2763-
if(ttfd)
2793+
if(ttfd > 0)
27642794
TUNTAP_Close(ttfd);
27652795
PTT_QETH_TRACE( "af clos ttfd", 0,0,0 );
27662796

@@ -3141,6 +3171,15 @@ int num; /* Number of bytes to move */
31413171

31423172
} /* end while (dev->qdio.idxstate == MPC_IDX_STATE_ACTIVE) */
31433173

3174+
if (dev->qdio.idxstate == MPC_IDX_STATE_HALTING)
3175+
{
3176+
obtain_lock( &grp->qlock );
3177+
PTT_QETH_TRACE( "read hlt ack", 0,0,0 );
3178+
dev->qdio.idxstate = MPC_IDX_STATE_INACTIVE;
3179+
signal_condition( &grp->qcond );
3180+
release_lock( &grp->qlock );
3181+
}
3182+
31443183
PTT_QETH_TRACE( "read exit", 0,0,0 );
31453184

31463185
break; /*switch*/

0 commit comments

Comments
 (0)