コード例 #1
0
ファイル: ntmgr.c プロジェクト: BillTheBest/WinNT4
DEVICE_PTR
APIFindDev (const ADAPTER_PTR HA, const unsigned TID, const unsigned LUN)
{

  return ScsiPortGetLogicalUnit(HA, 0, (char)TID, (char)LUN);

}
コード例 #2
0
ファイル: ntmgr.c プロジェクト: BillTheBest/WinNT4
BOOLEAN
StartIO (IN PVOID HAObject, IN PSCSI_REQUEST_BLOCK Req)
{
  ADAPTER_PTR HA = HAObject;
  DEVICE_PTR DevP;
  int i;

  TRACE(2, ("StartIO(): Req @%x, Function = 0x%x, Req->SrbExtension @%x\n", Req, Req->Function, Req->SrbExtension));

  switch (Req->Function) {

  case SRB_FUNCTION_EXECUTE_SCSI:


    ReqNext(Req) = (IO_REQ_PTR)NILL;
    ReqAdapterPtr(Req) = HA;
    for (i=0; i < sizeof(ReqState(Req)); i++)
      ((U8 *)&ReqState(Req))[i] = 0;

    ReqState(Req).ReqType = RTNormalReq;

    if ( (DevP = ScsiPortGetLogicalUnit(HA, Req->PathId, ReqTargetID(Req), ReqTargetLUN(Req))) == NILL) {

      TRACE(3, ("ExecuteReq(): Unable to get device info\n"));
      Req->SrbStatus = SRB_STATUS_NO_DEVICE;
      return FALSE;

    }

    ReqDevP(Req) = DevP;
    if (!DevP->Flags.Initialized)
      QueueInternalRequest(HA, Req, RTGetInfoReq);
    else
      IExecuteReq(HA, DevP, Req, NORMAL_REQ);
    break;


  case SRB_FUNCTION_RESET_BUS:

    TRACE(3, ("StartIO(): RESET_BUS command\n"));
    ResetBus(HAObject, Req->PathId);
    break;


  case SRB_FUNCTION_RESET_DEVICE:
  case SRB_FUNCTION_TERMINATE_IO:
  case SRB_FUNCTION_FLUSH:
  case SRB_FUNCTION_SHUTDOWN:

    Req->SrbStatus = SRB_STATUS_SUCCESS;
    ScsiPortNotification(RequestComplete, HA, Req);
    break;


  case SRB_FUNCTION_ABORT_COMMAND:

    TRACE(0, ("StartIO(): Request at %x to abort request %x\n", Req, Req->NextSrb));
    if ((DevP = ScsiPortGetLogicalUnit(HA, Req->PathId, ReqTargetID(Req), ReqTargetLUN(Req))) == NILL
    || (DevP->Flags.Initialized == 0)
    || !AbortRequest(HA, DevP, Req->NextSrb) ) {

      TRACE(0, ("StartIO(): Abort operation failed\n"));
      Req->SrbStatus = SRB_STATUS_ABORT_FAILED;

    } else {


      TRACE(0, ("StartIO(): Abort operation success\n"));
      Req->SrbStatus = SRB_STATUS_SUCCESS;

    }
    ScsiPortNotification(RequestComplete, HA, Req);
    break;


  case SRB_FUNCTION_RELEASE_RECOVERY:
  case SRB_FUNCTION_RECEIVE_EVENT:
  case SRB_FUNCTION_IO_CONTROL:
  default:

    TRACE(0, ("StartIO(): Unsupported command: 0x%x\n", Req->Function));
    APISetStatus(Req, S_REQ_OPCODE, Terminal, NotSenseable);
    return FALSE;
    break;


  }

  ScsiPortNotification(NextLuRequest, HA, Req->PathId, Req->TargetId, Req->Lun);
  return TRUE;

}
コード例 #3
0
ファイル: xenscsi.c プロジェクト: B-Rich/smart
static BOOLEAN
XenScsi_HwScsiStartIo(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb)
{
  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
  scsi_dev_t *dev;

  //FUNCTION_ENTER();
  
  XenScsi_CheckNewDevice(DeviceExtension);

  if (xsdd->scsiport_paused)
  {
    KdPrint((__DRIVER_NAME "     Busy\n"));
    Srb->SrbStatus = SRB_STATUS_BUSY;
    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
    //FUNCTION_EXIT();
    return TRUE;
  }

  for (dev = (scsi_dev_t *)xsdd->dev_list_head.Flink;
    dev != (scsi_dev_t *)&xsdd->dev_list_head;
    dev = (scsi_dev_t * )dev->entry.Flink)
  {
    if (dev->channel == Srb->PathId && dev->id == Srb->TargetId && dev->lun == Srb->Lun)
      break;
  }
  if (dev == (scsi_dev_t *)&xsdd->dev_list_head)
  {
    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
    //KdPrint((__DRIVER_NAME "     Out of bounds\n"));
    ScsiPortNotification(NextRequest, DeviceExtension);
    //FUNCTION_EXIT();
    return TRUE;
  }

  switch (Srb->Function)
  {
  case SRB_FUNCTION_EXECUTE_SCSI:
    switch (Srb->Cdb[0])
    {
    case 0x03: { /* REQUEST_SENSE*/
      /* but what about when we allow multiple requests per lu? */
      PXENSCSI_LU_DATA lud = ScsiPortGetLogicalUnit(DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
      if (lud != NULL && lud->sense_len)
      {
        int i;
        KdPrint((__DRIVER_NAME "     Emulating REQUEST_SENSE (lu data = %p)\n", lud));
        memcpy(Srb->DataBuffer, lud->sense_buffer, min(lud->sense_len, Srb->DataTransferLength));
        if (lud->sense_len > Srb->DataTransferLength)
        {
          KdPrint((__DRIVER_NAME "     Sense overrun Srb->DataTransferLength = %d, lud->sense_len = %d\n", Srb->DataTransferLength, lud->sense_len));
          Srb->DataTransferLength = lud->sense_len;
          Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
        }
        else
        {
          Srb->SrbStatus = SRB_STATUS_SUCCESS;
        }
        for (i = 0; i < min(lud->sense_len, 8); i++)
          KdPrint((__DRIVER_NAME "     sense %02x: %02x\n", i, (ULONG)((PUCHAR)lud->sense_buffer)[i]));
        lud->sense_len = 0;
        ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
        ScsiPortNotification(NextRequest, DeviceExtension);
        break;
      }
      else
      {
        KdPrint((__DRIVER_NAME "     Issuing REQUEST_SENSE (lud = %p)\n", lud));
      }
      // fall through
    }
    default:
      XenScsi_PutSrbOnRing(xsdd, Srb);
      Srb->SrbStatus = SRB_STATUS_PENDING;
      break;
    }
    break;
  case SRB_FUNCTION_IO_CONTROL:
    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_IO_CONTROL\n"));
    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
    ScsiPortNotification(NextRequest, DeviceExtension);
    break;
  case SRB_FUNCTION_FLUSH:
    KdPrint((__DRIVER_NAME "     SRB_FUNCTION_FLUSH\n"));
    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
    ScsiPortNotification(NextRequest, DeviceExtension);
    break;
  default:
    KdPrint((__DRIVER_NAME "     Unhandled Srb->Function = %08X\n", Srb->Function));
    Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
    ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
    ScsiPortNotification(NextRequest, DeviceExtension);
    break;
  }

  //FUNCTION_EXIT();
  return TRUE;
}
コード例 #4
0
ファイル: xenscsi.c プロジェクト: B-Rich/smart
static BOOLEAN
XenScsi_HwScsiInterrupt(PVOID DeviceExtension)
{
  PXENSCSI_DEVICE_DATA xsdd = DeviceExtension;
  PSCSI_REQUEST_BLOCK Srb;
  RING_IDX i, rp;
  int j;
  vscsiif_response_t *rep;
  int more_to_do = TRUE;
  vscsiif_shadow_t *shadow;
  BOOLEAN last_interrupt = FALSE;

  XenScsi_CheckNewDevice(DeviceExtension);

  if (!dump_mode && !xsdd->vectors.EvtChn_AckEvent(xsdd->vectors.context, xsdd->event_channel, &last_interrupt))
  {
    return FALSE;
  }

  //FUNCTION_ENTER();
  
  while (more_to_do)
  {
    rp = xsdd->ring.sring->rsp_prod;
    KeMemoryBarrier();
    for (i = xsdd->ring.rsp_cons; i != rp; i++)
    {
      rep = RING_GET_RESPONSE(&xsdd->ring, i);
      shadow = &xsdd->shadows[rep->rqid];
      Srb = shadow->Srb;
      Srb->ScsiStatus = (UCHAR)rep->rslt;
      memset(Srb->SenseInfoBuffer, 0, Srb->SenseInfoBufferLength);
      if (rep->sense_len > 0 && Srb->SenseInfoBuffer != NULL)
      {
        memcpy(Srb->SenseInfoBuffer, rep->sense_buffer, min(Srb->SenseInfoBufferLength, rep->sense_len));
      }
      switch(rep->rslt)
      {
      case 0:
        //KdPrint((__DRIVER_NAME "     Xen Operation complete - result = 0x%08x, sense_len = %d, residual = %d\n", rep->rslt, rep->sense_len, rep->residual_len));
        Srb->SrbStatus = SRB_STATUS_SUCCESS;
        if (Srb->Cdb[0] == 0x03)
        {
          KdPrint((__DRIVER_NAME "     REQUEST_SENSE DataTransferLength = %d, residual = %d\n", Srb->DataTransferLength, rep->residual_len));
          //for (j = 0; j < Srb->DataTransferLength - rep->residual_len; j++)
          //  KdPrint((__DRIVER_NAME "     sense %02x: %02x\n", j, (ULONG)((PUCHAR)Srb->DataBuffer)[j]));
        }
        break;
      case 0x00010000: /* Device does not exist */
        KdPrint((__DRIVER_NAME "     Xen Operation error - cdb[0] = %02x, result = 0x%08x, sense_len = %d, residual = %d\n", (ULONG)Srb->Cdb[0], rep->rslt, rep->sense_len, rep->residual_len));
        Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
        break;
      default:
        KdPrint((__DRIVER_NAME "     Xen Operation error - cdb[0] = %02x, result = 0x%08x, sense_len = %d, residual = %d\n", (ULONG)Srb->Cdb[0], rep->rslt, rep->sense_len, rep->residual_len));
        Srb->SrbStatus = SRB_STATUS_ERROR;

        //for (j = 0; j < Srb->SenseInfoBufferLength; j++)
        //  KdPrint((__DRIVER_NAME "     sense %02x: %02x\n", j, (ULONG)((PUCHAR)Srb->SenseInfoBuffer)[j]));

        if (rep->sense_len > 0 && !(Srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE) && Srb->SenseInfoBuffer != NULL)
        {
          KdPrint((__DRIVER_NAME "     Doing autosense\n"));
          Srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
        }
        else if (Srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
        {
          PXENSCSI_LU_DATA lud = ScsiPortGetLogicalUnit(DeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun);
          KdPrint((__DRIVER_NAME "     Autosense disabled\n"));
          if (lud != NULL)
          {
            KdPrint((__DRIVER_NAME "     Saving sense data\n"));
            lud->sense_len = rep->sense_len;
            memcpy(lud->sense_buffer, Srb->SenseInfoBuffer, lud->sense_len);
          }
        }
      }

      /* work around a bug in scsiback that gives an incorrect result to REPORT_LUNS - fail it if the output is only 8 bytes */
      if (Srb->Cdb[0] == 0xa0 && Srb->SrbStatus == SRB_STATUS_SUCCESS &&
        Srb->DataTransferLength - rep->residual_len == 8)
      {
        /* SRB_STATUS_ERROR appears to be sufficient here - no need to worry about sense data or anything */
        KdPrint((__DRIVER_NAME "     Worked around bad REPORT_LUNS emulation for %d:%d:%d\n",
          Srb->PathId, Srb->TargetId, Srb->Lun));
        Srb->SrbStatus = SRB_STATUS_ERROR;
      }
      //remaining = Srb->DataTransferLength;
      for (j = 0; j < shadow->req.nr_segments; j++)
      {
        xsdd->vectors.GntTbl_EndAccess(xsdd->vectors.context, shadow->req.seg[j].gref, TRUE, (ULONG)'SCSI');
        put_grant_on_freelist(xsdd, shadow->req.seg[j].gref);
        shadow->req.seg[j].gref = 0;
      }

      if (Srb->SrbStatus == SRB_STATUS_SUCCESS && rep->residual_len)
      {
//        KdPrint((__DRIVER_NAME "     SRB_STATUS_DATA_OVERRUN DataTransferLength = %d, adjusted = %d\n",
//          Srb->DataTransferLength, Srb->DataTransferLength - rep->residual_len));
        Srb->DataTransferLength -= rep->residual_len;
        Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
      }

      put_shadow_on_freelist(xsdd, shadow);
      ScsiPortNotification(RequestComplete, xsdd, Srb);
      if (!xsdd->scsiport_paused)
        ScsiPortNotification(NextRequest, DeviceExtension);
    }

    xsdd->ring.rsp_cons = i;
    if (i != xsdd->ring.req_prod_pvt)
    {
      RING_FINAL_CHECK_FOR_RESPONSES(&xsdd->ring, more_to_do);
    }
    else
    {
      xsdd->ring.sring->rsp_event = i + 1;
      more_to_do = FALSE;
    }
  }

  //FUNCTION_EXIT();
  
  return last_interrupt;
}