win-pvdrivers

changeset 416:dd729c3bd53e

Update to the way IRQ's are handled. Now they all just tack onto the same IRQ as xenpci.
author James Harper <james.harper@bendigoit.com.au>
date Mon Aug 18 21:14:13 2008 +1000 (2008-08-18)
parents 62dc0a1661e3
children ef5345ea9984
files common/include/xen_public.h xennet/xennet.c xenpci/evtchn.c xenpci/xenpci.h xenpci/xenpci_pdo.c xenvbd/scsiport.c
line diff
     1.1 --- a/common/include/xen_public.h	Mon Aug 18 13:21:02 2008 +1000
     1.2 +++ b/common/include/xen_public.h	Mon Aug 18 21:14:13 2008 +1000
     1.3 @@ -52,6 +52,9 @@ typedef NTSTATUS
     1.4  typedef evtchn_port_t
     1.5  (*PXEN_EVTCHN_ALLOCUNBOUND)(PVOID Context, domid_t Domain);
     1.6  
     1.7 +typedef BOOLEAN
     1.8 +(*PXEN_EVTCHN_ACK_EVENT)(PVOID context, evtchn_port_t port);
     1.9 +
    1.10  typedef grant_ref_t
    1.11  (*PXEN_GNTTBL_GRANTACCESS)(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref);
    1.12  
    1.13 @@ -111,6 +114,8 @@ typedef struct {
    1.14    PXEN_EVTCHN_MASK EvtChn_Mask;
    1.15    PXEN_EVTCHN_UNMASK EvtChn_Unmask;
    1.16    PXEN_EVTCHN_NOTIFY EvtChn_Notify;
    1.17 +  PXEN_EVTCHN_ACK_EVENT EvtChn_AckEvent;
    1.18 +
    1.19    PXEN_GNTTBL_GETREF GntTbl_GetRef;
    1.20    PXEN_GNTTBL_PUTREF GntTbl_PutRef;
    1.21    PXEN_GNTTBL_GRANTACCESS GntTbl_GrantAccess;
     2.1 --- a/xennet/xennet.c	Mon Aug 18 13:21:02 2008 +1000
     2.2 +++ b/xennet/xennet.c	Mon Aug 18 21:14:13 2008 +1000
     2.3 @@ -128,9 +128,17 @@ XenNet_InterruptIsr(
     2.4    struct xennet_info *xi = MiniportAdapterContext;
     2.5    
     2.6    //FUNCTION_ENTER();
     2.7 -
     2.8 -  *QueueMiniportHandleInterrupt = (BOOLEAN)!!xi->connected;
     2.9 -  *InterruptRecognized = TRUE;
    2.10 +  if (!xi->vectors.EvtChn_AckEvent(xi->vectors.context, xi->event_channel))
    2.11 +  {
    2.12 +    /* interrupt was not for us */
    2.13 +    *InterruptRecognized = FALSE;
    2.14 +    *QueueMiniportHandleInterrupt = FALSE;
    2.15 +  }
    2.16 +  else
    2.17 +  {
    2.18 +    *QueueMiniportHandleInterrupt = (BOOLEAN)!!xi->connected;
    2.19 +    *InterruptRecognized = TRUE;
    2.20 +  }
    2.21  
    2.22    //FUNCTION_EXIT();
    2.23  }
    2.24 @@ -581,7 +589,7 @@ XenNet_Init(
    2.25    KeMemoryBarrier(); // packets could be received anytime after we set Frontent to Connected
    2.26  
    2.27    status = NdisMRegisterInterrupt(&xi->interrupt, MiniportAdapterHandle, irq_vector, irq_level,
    2.28 -    TRUE, FALSE, NdisInterruptLatched);
    2.29 +    TRUE, TRUE, NdisInterruptLevelSensitive);
    2.30    if (!NT_SUCCESS(status))
    2.31    {
    2.32      KdPrint(("NdisMRegisterInterrupt failed with 0x%x\n", status));
     3.1 --- a/xenpci/evtchn.c	Mon Aug 18 13:21:02 2008 +1000
     3.2 +++ b/xenpci/evtchn.c	Mon Aug 18 21:14:13 2008 +1000
     3.3 @@ -47,8 +47,20 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
     3.4  
     3.5    if (action->type == EVT_ACTION_TYPE_IRQ)
     3.6    {
     3.7 +    LARGE_INTEGER tstart = {0}, tend = {0};
     3.8      //KdPrint((__DRIVER_NAME "     Calling interrupt vector %02x\n", action->vector));
     3.9 +    if ((action->count & 0xFF) == 0)
    3.10 +    {
    3.11 +      tstart = KeQueryPerformanceCounter(NULL);
    3.12 +    }
    3.13      sw_interrupt((UCHAR)action->vector);
    3.14 +    if ((action->count & 0xFF) == 0)
    3.15 +    {
    3.16 +      LARGE_INTEGER tdiff;
    3.17 +      tend = KeQueryPerformanceCounter(NULL);
    3.18 +      tdiff.QuadPart = tend.QuadPart - tstart.QuadPart;
    3.19 +      KdPrint((__DRIVER_NAME "     EvtChn %s tdiff = %d\n", action->description, tdiff.LowPart));
    3.20 +    }
    3.21    }
    3.22    else
    3.23    {
    3.24 @@ -59,6 +71,25 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
    3.25  
    3.26  BOOLEAN no_more_interrupts;
    3.27  
    3.28 +/* Called at DIRQL */
    3.29 +BOOLEAN
    3.30 +EvtChn_AckEvent(PVOID context, evtchn_port_t port)
    3.31 +{
    3.32 +  PXENPCI_DEVICE_DATA xpdd = context;
    3.33 +  ULONG evt_word;
    3.34 +  ULONG evt_bit;
    3.35 +  xen_ulong_t val;
    3.36 +
    3.37 +  evt_bit = port & ((sizeof(xen_ulong_t) * 8) - 1);
    3.38 +  evt_word = port >> (5 + (sizeof(xen_ulong_t) >> 3));
    3.39 +
    3.40 +  val = synch_clear_bit(evt_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[evt_word]);
    3.41 +  
    3.42 +  //KdPrint((__DRIVER_NAME "     port %d = %d\n", port, !!val));
    3.43 +
    3.44 +  return (BOOLEAN)!!val;
    3.45 +}
    3.46 +
    3.47  static DDKAPI BOOLEAN
    3.48  EvtChn_Interrupt(PKINTERRUPT Interrupt, PVOID Context)
    3.49  {
    3.50 @@ -72,6 +103,7 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    3.51    unsigned int port;
    3.52    ev_action_t *ev_action;
    3.53    BOOLEAN handled = FALSE;
    3.54 +  BOOLEAN deferred = FALSE;
    3.55  
    3.56    //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
    3.57  
    3.58 @@ -83,6 +115,8 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    3.59      
    3.60    //ASSERT(!no_more_interrupts);
    3.61    
    3.62 +  /* we should check the evtchn_pending_pvt here and report if != 0 */
    3.63 +  
    3.64    UNREFERENCED_PARAMETER(Interrupt);
    3.65  
    3.66    vcpu_info = &shared_info_area->vcpu_info[cpu];
    3.67 @@ -107,11 +141,13 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    3.68          ev_action->ServiceRoutine(NULL, ev_action->ServiceContext);
    3.69          break;
    3.70        case EVT_ACTION_TYPE_IRQ:
    3.71 -/*
    3.72          synch_clear_bit(evt_bit, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
    3.73 -        sw_interrupt((UCHAR)ev_action->vector);
    3.74 +        synch_set_bit(evt_bit, (volatile xen_long_t *)&xpdd->evtchn_pending_pvt[evt_word]);
    3.75 +        //KdPrint((__DRIVER_NAME "     deferred %d\n", port));
    3.76 +        /* this is now handled by one of the next Isr's */
    3.77 +        //sw_interrupt((UCHAR)ev_action->vector);
    3.78 +        deferred = TRUE;
    3.79          break;
    3.80 -*/
    3.81        case EVT_ACTION_TYPE_DPC:
    3.82          synch_clear_bit(evt_bit, (volatile xen_long_t *)&shared_info_area->evtchn_pending[evt_word]);
    3.83          KeInsertQueueDpc(&ev_action->Dpc, NULL, NULL);
    3.84 @@ -126,7 +162,7 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    3.85  
    3.86    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    3.87  
    3.88 -  return handled;
    3.89 +  return handled && !deferred;
    3.90  }
    3.91  
    3.92  NTSTATUS
    3.93 @@ -185,7 +221,7 @@ EvtChn_BindDpc(PVOID Context, evtchn_por
    3.94  }
    3.95  
    3.96  NTSTATUS
    3.97 -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector)
    3.98 +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description)
    3.99  {
   3.100    PXENPCI_DEVICE_DATA xpdd = Context;
   3.101  
   3.102 @@ -203,6 +239,7 @@ EvtChn_BindIrq(PVOID Context, evtchn_por
   3.103    xpdd->ev_actions[Port].xpdd = xpdd;
   3.104    KeMemoryBarrier();
   3.105    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_IRQ;
   3.106 +  strncpy(xpdd->ev_actions[Port].description, description, 128);
   3.107  
   3.108    EvtChn_Unmask(Context, Port);
   3.109  
     4.1 --- a/xenpci/xenpci.h	Mon Aug 18 13:21:02 2008 +1000
     4.2 +++ b/xenpci/xenpci.h	Mon Aug 18 21:14:13 2008 +1000
     4.3 @@ -70,6 +70,7 @@ DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC82
     4.4  typedef struct _ev_action_t {
     4.5    PKSERVICE_ROUTINE ServiceRoutine;
     4.6    PVOID ServiceContext;
     4.7 +  CHAR description[128];
     4.8    ULONG type; /* EVT_ACTION_TYPE_* */
     4.9    KDPC Dpc;
    4.10    ULONG vector;
    4.11 @@ -176,6 +177,7 @@ typedef struct {
    4.12  
    4.13    PHYSICAL_ADDRESS shared_info_area_unmapped;
    4.14    shared_info_t *shared_info_area;
    4.15 +  xen_ulong_t evtchn_pending_pvt[sizeof(xen_ulong_t) * 8];
    4.16    BOOLEAN interrupts_masked;
    4.17  
    4.18    PHYSICAL_ADDRESS platform_mmio_addr;
    4.19 @@ -436,7 +438,7 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
    4.20  NTSTATUS
    4.21  EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
    4.22  NTSTATUS
    4.23 -EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector);
    4.24 +EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector, PCHAR description);
    4.25  NTSTATUS
    4.26  EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
    4.27  NTSTATUS
    4.28 @@ -445,6 +447,8 @@ VOID
    4.29  EvtChn_Close(PVOID Context, evtchn_port_t Port);
    4.30  evtchn_port_t
    4.31  EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
    4.32 +BOOLEAN
    4.33 +EvtChn_AckEvent(PVOID context, evtchn_port_t port);
    4.34  
    4.35  VOID
    4.36  GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
     5.1 --- a/xenpci/xenpci_pdo.c	Mon Aug 18 13:21:02 2008 +1000
     5.2 +++ b/xenpci/xenpci_pdo.c	Mon Aug 18 21:14:13 2008 +1000
     5.3 @@ -348,6 +348,15 @@ XenPci_EvtChn_Notify(PVOID Context, evtc
     5.4    return EvtChn_Notify(xpdd, Port);
     5.5  }
     5.6  
     5.7 +static BOOLEAN
     5.8 +XenPci_EvtChn_AckEvent(PVOID context, evtchn_port_t port)
     5.9 +{
    5.10 +  PXENPCI_PDO_DEVICE_DATA xppdd = context;
    5.11 +  PXENPCI_DEVICE_DATA xpdd = xppdd->bus_fdo->DeviceExtension;
    5.12 +  
    5.13 +  return EvtChn_AckEvent(xpdd, port);
    5.14 +}
    5.15 +
    5.16  static grant_ref_t
    5.17  XenPci_GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t frame, int readonly, grant_ref_t ref)
    5.18  {
    5.19 @@ -483,6 +492,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
    5.20    vectors.EvtChn_Mask = XenPci_EvtChn_Mask;
    5.21    vectors.EvtChn_Unmask = XenPci_EvtChn_Unmask;
    5.22    vectors.EvtChn_Notify = XenPci_EvtChn_Notify;
    5.23 +  vectors.EvtChn_AckEvent = XenPci_EvtChn_AckEvent;
    5.24    vectors.GntTbl_GetRef = XenPci_GntTbl_GetRef;
    5.25    vectors.GntTbl_PutRef = XenPci_GntTbl_PutRef;
    5.26    vectors.GntTbl_GrantAccess = XenPci_GntTbl_GrantAccess;
    5.27 @@ -559,7 +569,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
    5.28          ADD_XEN_INIT_RSP(&out_ptr, type, setting, UlongToPtr(event_channel));
    5.29          ADD_XEN_INIT_RSP(&xppdd->assigned_resources_ptr, type, setting, UlongToPtr(event_channel));
    5.30          if (type == XEN_INIT_TYPE_EVENT_CHANNEL_IRQ)
    5.31 -          EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector);
    5.32 +          EvtChn_BindIrq(xpdd, event_channel, xppdd->irq_vector, path);
    5.33        }
    5.34        else
    5.35        {
    5.36 @@ -948,24 +958,12 @@ XenPci_QueryResourceRequirements(PDEVICE
    5.37    PIO_RESOURCE_REQUIREMENTS_LIST irrl;
    5.38    PIO_RESOURCE_DESCRIPTOR ird;
    5.39    ULONG length;
    5.40 -  //ULONG available_interrupts[] = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; //{3, 4, 5, 10, 11, 14};
    5.41 -  ULONG available_interrupts[] = {
    5.42 -    //62, 61, 60, 59, 58, 57, 56,
    5.43 -    //55, 54, 53, 52, 51, 50, 49, 48,
    5.44 -    47, 46, 45, 44, 43, 42, 41, 40,
    5.45 -    39, 38, 37, 36, 35, 34, 33, 32,
    5.46 -    31, 30, 29, 28, 27, 26, 25, 24,
    5.47 -    23, 22, 21, 20, 19, 18, 17, 16,
    5.48 -    //15, 14, 13, 12, 11, 10, 8,
    5.49 -    //7, 6, 5, 4, 3, 1
    5.50 -  };
    5.51 -  int i;
    5.52  
    5.53    UNREFERENCED_PARAMETER(device_object);
    5.54  
    5.55    length = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
    5.56      FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) +
    5.57 -    sizeof(IO_RESOURCE_DESCRIPTOR) * ARRAY_SIZE(available_interrupts);
    5.58 +    sizeof(IO_RESOURCE_DESCRIPTOR) * 1;
    5.59    irrl = ExAllocatePoolWithTag(NonPagedPool,
    5.60      length,
    5.61      XENPCI_POOL_TAG);
    5.62 @@ -979,24 +977,13 @@ XenPci_QueryResourceRequirements(PDEVICE
    5.63    irrl->List[0].Revision = 1;
    5.64    irrl->List[0].Count = 0;
    5.65  
    5.66 -  for (i = 0; i < ARRAY_SIZE(available_interrupts); i++)
    5.67 -  {
    5.68 -    if (i == (int)xpdd->irq_number)
    5.69 -      continue;
    5.70 -    ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
    5.71 -    ird->Option = i?IO_RESOURCE_ALTERNATIVE:0;
    5.72 -    ird->Type = CmResourceTypeInterrupt;
    5.73 -    if (available_interrupts[i] >= 16)
    5.74 -    {
    5.75 -      ird->Option |= IO_RESOURCE_PREFERRED;
    5.76 -      ird->ShareDisposition = CmResourceShareDeviceExclusive;
    5.77 -    }
    5.78 -    else
    5.79 -      ird->ShareDisposition = CmResourceShareShared;
    5.80 -    ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
    5.81 -    ird->u.Interrupt.MinimumVector = available_interrupts[i];
    5.82 -    ird->u.Interrupt.MaximumVector = available_interrupts[i];
    5.83 -  }
    5.84 +  ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
    5.85 +  ird->Option = 0;
    5.86 +  ird->Type = CmResourceTypeInterrupt;
    5.87 +  ird->ShareDisposition = CmResourceShareShared;
    5.88 +  ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
    5.89 +  ird->u.Interrupt.MinimumVector = xpdd->irq_number;
    5.90 +  ird->u.Interrupt.MaximumVector = xpdd->irq_number;
    5.91    
    5.92    irp->IoStatus.Information = (ULONG_PTR)irrl;
    5.93    return STATUS_SUCCESS;
     6.1 --- a/xenvbd/scsiport.c	Mon Aug 18 13:21:02 2008 +1000
     6.2 +++ b/xenvbd/scsiport.c	Mon Aug 18 21:14:13 2008 +1000
     6.3 @@ -217,10 +217,6 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
     6.4        xvdd->grant_entries = (USHORT)PtrToUlong(setting);
     6.5        memcpy(&xvdd->grant_free_list, value, sizeof(grant_ref_t) * xvdd->grant_entries);
     6.6        xvdd->grant_free = xvdd->grant_entries;
     6.7 -      for (i = 0; i < xvdd->grant_entries; i++)
     6.8 -      {
     6.9 -        KdPrint((__DRIVER_NAME "     grant_entry = %d\n", xvdd->grant_free_list[i]));
    6.10 -      }
    6.11        break;
    6.12      case XEN_INIT_TYPE_STATE_PTR:
    6.13        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
    6.14 @@ -685,12 +681,15 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
    6.15    int more_to_do = TRUE;
    6.16    blkif_shadow_t *shadow;
    6.17    ULONG offset;
    6.18 +  LARGE_INTEGER tstart = {0}, tend = {0};
    6.19  
    6.20    //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.21  
    6.22 -  if (counter & 0xFF == 0)
    6.23 +  if (!xvdd->vectors.EvtChn_AckEvent(xvdd->vectors.context, xvdd->event_channel))
    6.24 +    return FALSE; /* interrupt was not for us */
    6.25 +  if ((counter & 0xFFF) == 0)
    6.26    {
    6.27 -    KdPrint((__DRIVER_NAME "     SCSI ISR IRQL = %d\n", KeGetCurrentIrql()));
    6.28 +    tstart = KeQueryPerformanceCounter(NULL);
    6.29    }
    6.30    if (xvdd->device_state->resume_state != RESUME_STATE_RUNNING)
    6.31    {
    6.32 @@ -796,6 +795,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
    6.33            else
    6.34              ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
    6.35          }
    6.36 +        break;
    6.37        }
    6.38      }
    6.39  
    6.40 @@ -817,6 +817,15 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
    6.41    //KdPrint((__DRIVER_NAME "     ring.req_prod_pvt = %d\n", xvdd->ring.req_prod_pvt));
    6.42  
    6.43    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    6.44 +
    6.45 +  if ((counter & 0xFFF) == 0)
    6.46 +  {
    6.47 +    LARGE_INTEGER tdiff;
    6.48 +    tend = KeQueryPerformanceCounter(NULL);
    6.49 +    tdiff.QuadPart = tend.QuadPart - tstart.QuadPart;
    6.50 +    KdPrint((__DRIVER_NAME "     SCSI ISR IRQL = %d, tdiff = %d\n", KeGetCurrentIrql(), tdiff.LowPart));
    6.51 +  }
    6.52 +  counter++;
    6.53    
    6.54    return FALSE; /* we just don't know... */
    6.55  }