win-pvdrivers

changeset 577:17e6a7e1d3df 0.10.0.80

If a device sharing the same IRQ triggered an interrupt, xenvbd could crash. Fixed.
author James Harper <james.harper@bendigoit.com.au>
date Thu May 21 00:05:11 2009 +1000 (2009-05-21)
parents dc0a293c870c
children e155447178e4
files xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/xenvbd/xenvbd.c	Thu May 21 00:04:46 2009 +1000
     1.2 +++ b/xenvbd/xenvbd.c	Thu May 21 00:05:11 2009 +1000
     1.3 @@ -533,7 +533,8 @@ XenVbd_StartRingDetection(PXENVBD_DEVICE
     1.4    int i;
     1.5    int notify;
     1.6  
     1.7 -  xvdd->ring_detect_state = 0;
     1.8 +  xvdd->ring_detect_state = RING_DETECT_STATE_DETECT1;
     1.9 +  
    1.10    req = RING_GET_REQUEST(&xvdd->ring, xvdd->ring.req_prod_pvt);
    1.11    req->operation = 0xff;
    1.12    req->nr_segments = 0;
    1.13 @@ -583,7 +584,7 @@ XenVbd_HwScsiInitialize(PVOID DeviceExte
    1.14          xvdd->ring.nr_ents = BLK_OTHER_RING_SIZE;
    1.15          xvdd->use_other = TRUE;
    1.16        }
    1.17 -      xvdd->ring_detect_state = 2;
    1.18 +      xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
    1.19      }
    1.20    }
    1.21    FUNCTION_EXIT();
    1.22 @@ -816,11 +817,14 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
    1.23  */
    1.24        switch (xvdd->ring_detect_state)
    1.25        {
    1.26 -      case 0:
    1.27 +      case RING_DETECT_STATE_NOT_STARTED:
    1.28 +        KdPrint((__DRIVER_NAME "     premature IRQ\n"));
    1.29 +        break;
    1.30 +      case RING_DETECT_STATE_DETECT1:
    1.31          KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
    1.32 -        xvdd->ring_detect_state = 1;
    1.33 +        xvdd->ring_detect_state = RING_DETECT_STATE_DETECT2;
    1.34          break;
    1.35 -      case 1:
    1.36 +      case RING_DETECT_STATE_DETECT2:
    1.37          KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", xvdd->ring_detect_state, rep->operation, rep->id, rep->status));
    1.38          *xvdd->event_channel_ptr |= 0x80000000;
    1.39          if (rep->operation != 0xff)
    1.40 @@ -829,10 +833,10 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
    1.41            xvdd->use_other = TRUE;
    1.42            *xvdd->event_channel_ptr |= 0x40000000;
    1.43          }
    1.44 -        xvdd->ring_detect_state = 2;
    1.45 +        xvdd->ring_detect_state = RING_DETECT_STATE_COMPLETE;
    1.46          ScsiPortNotification(NextRequest, DeviceExtension);
    1.47          break;
    1.48 -      case 2:
    1.49 +      case RING_DETECT_STATE_COMPLETE:
    1.50          shadow = &xvdd->shadows[rep->id];
    1.51          srb = shadow->srb;
    1.52          ASSERT(srb != NULL);
    1.53 @@ -918,7 +922,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
    1.54    }
    1.55    
    1.56    // If we haven't enumerated all the devices yet then just defer the request
    1.57 -  if (xvdd->ring_detect_state < 2)
    1.58 +  if (xvdd->ring_detect_state < RING_DETECT_STATE_COMPLETE)
    1.59    {
    1.60      Srb->SrbStatus = SRB_STATUS_BUSY;
    1.61      ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
    1.62 @@ -1282,7 +1286,7 @@ XenVbd_HwScsiResetBus(PVOID DeviceExtens
    1.63    FUNCTION_ENTER();
    1.64  
    1.65    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
    1.66 -  if (xvdd->ring_detect_state == 2 && xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
    1.67 +  if (xvdd->ring_detect_state == RING_DETECT_STATE_COMPLETE && xvdd->device_state->suspend_resume_state_pdo == SR_STATE_RUNNING)
    1.68    {
    1.69      ScsiPortNotification(NextRequest, DeviceExtension);
    1.70    }
     2.1 --- a/xenvbd/xenvbd.h	Thu May 21 00:04:46 2009 +1000
     2.2 +++ b/xenvbd/xenvbd.h	Thu May 21 00:05:11 2009 +1000
     2.3 @@ -101,6 +101,11 @@ typedef enum {
     2.4    XENVBD_DEVICEMODE_WRITE
     2.5  } XENVBD_DEVICEMODE;
     2.6  
     2.7 +#define RING_DETECT_STATE_NOT_STARTED  0
     2.8 +#define RING_DETECT_STATE_DETECT1      1
     2.9 +#define RING_DETECT_STATE_DETECT2      2
    2.10 +#define RING_DETECT_STATE_COMPLETE     3
    2.11 +
    2.12  struct
    2.13  {
    2.14    BOOLEAN inactive;