home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / DDJ9403A.ZIP / CDROM.ZIP / CDNOW.C next >
Text File  |  1993-10-13  |  14KB  |  535 lines

  1. /********************************************************************
  2. Copyright (c) 1993  Sing Li, Media Synergy Inc.  All Rights Reserved
  3.  
  4. Module Name:
  5.  
  6.     CDnow.c
  7.  
  8. Abstract:
  9.     This is the Scsi miniport driver for Panasonic 52x using
  10.      native or compatible controllers.
  11.  
  12.      This module contains general routines which are independent
  13.      of specific drive models.
  14. **********************************************************************/
  15.  
  16. #include "ntddk.h"
  17. #include "stdarg.h"
  18. #include "CDnow.h"      // includes scsi.h
  19.  
  20. //***********************************************
  21. //*           Function ProtoTyping                  
  22. //***********************************************
  23.  
  24. USHORT
  25. LocateAdapterSpecific(
  26.     PSPECIFIC_DEVICE_EXTENSION    deviceExtension,
  27.      IN PVOID                    Context,
  28.     IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo
  29.     
  30. );
  31.  
  32. BOOLEAN
  33. CDnowInitialize(
  34.     IN PVOID Context
  35.     );
  36.  
  37.  
  38. NTSTATUS
  39. CDRead(  //)
  40.  ULONG LogAddr,
  41.  USHORT LogBlkRead,
  42.  PUCHAR userBuffer,
  43.  PSPECIFIC_DEVICE_EXTENSION dExt
  44. );
  45.  
  46. ULONG
  47. DriverEntry(
  48.     IN PVOID DriverObject,
  49.     IN PVOID Argument2
  50.     );
  51.  
  52. ULONG
  53. CDnowFindAdapter(
  54.     IN PVOID                    Context,
  55.     IN PVOID                    AdaptersFound,
  56.     IN PVOID                    BusInformation,
  57.     IN PCHAR                    ArgumentString,
  58.     IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
  59.     OUT PBOOLEAN                Again
  60.     );
  61. BOOLEAN
  62. CDnowStartIo(
  63.     IN PVOID           Context,
  64.     IN PSCSI_REQUEST_BLOCK Srb
  65.     );
  66.  
  67. BOOLEAN
  68. CDnowInterrupt(
  69.     IN PVOID Context
  70.     );
  71.  
  72. BOOLEAN
  73. CDnowResetBus(
  74.     IN PVOID Context,
  75.     IN ULONG PathId
  76.     );
  77.  
  78. /*****************************************************************/
  79. /*
  80. Routine Description:
  81.     This dummy routine handles the interrupts for the CDnow.    This was
  82.      necessary for March Beta of Windows NT.  It was left in for
  83.      compatibility purposes.
  84.  
  85. Arguments:
  86.     Context - Device adapter context pointer.
  87.  
  88. Return Value:
  89.     FALSE indicates that this interrupt was NOT from us.
  90.                                  */
  91. /*****************************************************************/
  92. BOOLEAN
  93. CDnowInterrupt(
  94.     IN PVOID Context
  95.     )
  96. {
  97.     PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
  98.  
  99.     return FALSE;
  100.  
  101. } // end CDnowInterrupt()
  102.  
  103.  
  104. /*****************************************************************/
  105. /*
  106. Routine Description:
  107.     Reset Bus from the SCSI Port driver.  We basically do nothing
  108.      here.
  109.                                  */
  110. /*****************************************************************/
  111. BOOLEAN
  112. CDnowResetBus(
  113.     IN PVOID Context,
  114.     IN ULONG PathId
  115.     )
  116. {
  117.     PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
  118.  
  119.  
  120.     return TRUE;
  121. } // end CDnowResetBus()
  122.  
  123.  
  124. /*****************************************************************/
  125. /* Routine Description:
  126. /*    Simulate response the SCSI INQUIRY op-code.  We make the port
  127. /*    driver believe that a SCSI CD-ROM is connected.
  128. /*****************************************************************/
  129. void
  130. Cdrom_Inquiry(PSPECIFIC_LU_EXTENSION luExtension)
  131. {
  132. INQUIRYDATA *cdromInquiry;
  133.  
  134. cdromInquiry = (INQUIRYDATA *) luExtension->SavedDataPointer;
  135.  
  136. cdromInquiry->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
  137. cdromInquiry->DeviceTypeQualifier = DEVICE_CONNECTED;
  138.  
  139. memcpy(cdromInquiry->VendorId, "MedSyn", 8);
  140. memcpy(cdromInquiry->ProductId, "Cd-Rom Now", 11);
  141. }
  142. /****************************************************************/
  143. /*
  144. Routine Description:
  145.     Simulate a response to the SCSI Read Capacity opcode.  We
  146.      hardcode the sector size and volume size here for compatibility
  147.      with drives which cannot determine capacity.
  148.  
  149.      The little endian to big endian conversion was a major gottcha.
  150. */    
  151. /*****************************************************************/
  152. VOID CapacityRead(PSPECIFIC_LU_EXTENSION luExtension)
  153. {
  154. READ_CAPACITY_DATA *capacityRead;
  155. ULONG FixBlockEnd;
  156. ULONG FixBlockSize;
  157. PFOUR_BYTE pEnd = (PFOUR_BYTE)&FixBlockEnd;
  158. PFOUR_BYTE pSize = (PFOUR_BYTE)&FixBlockSize;
  159.  
  160. // Convert to big Endian
  161. capacityRead = (READ_CAPACITY_DATA *) luExtension->SavedDataPointer;
  162. FixBlockEnd = 270000;
  163. FixBlockSize = 2048;
  164. ((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte3=  
  165.    pEnd->Byte0;
  166. ((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte2=  
  167.    pEnd->Byte1;
  168. ((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte1=  
  169.    pEnd->Byte2;
  170. ((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte0=  
  171.    pEnd->Byte3;
  172. ((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte3=  
  173.    pSize->Byte0;
  174. ((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte2=  
  175.    pSize->Byte1;
  176. ((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte2=  
  177.    pSize->Byte2;
  178. ((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte0=  
  179.    pSize->Byte3;
  180.  
  181.  
  182. }
  183.  
  184.  
  185. /*****************************************************************/
  186. /*                                                                                       */
  187. /*         ReadCDRom                                                               */
  188. /*     Transform the Logical block address and size into our      */
  189. /*     format for access by our read routine                             */
  190. /*                                                                                       */
  191. /*****************************************************************/
  192. NTSTATUS ReadCDRom(PSPECIFIC_DEVICE_EXTENSION  deviceExtension,
  193.            PSPECIFIC_LU_EXTENSION       luExtension)
  194. {
  195.   struct MYCDB {
  196.     UCHAR OperationCode;
  197.     UCHAR RelativeAddress : 1;
  198.     UCHAR Reserved1 : 2;
  199.     UCHAR ForceUnitAccess : 1;
  200.     UCHAR DisablePageOut : 1;
  201.     UCHAR LogicalUnitNumber : 3;
  202.     UCHAR LogicalBlockByte0;
  203.     UCHAR LogicalBlockByte1;
  204.     UCHAR LogicalBlockByte2;
  205.     UCHAR LogicalBlockByte3;
  206.     UCHAR Reserved2;
  207.     UCHAR TransferBlocksMsb;
  208.     UCHAR TransferBlocksLsb;
  209.     UCHAR Control;
  210.     } *cdb;
  211.  
  212. ULONG logicalBlockAddress;
  213. USHORT transferBlocks;
  214.  
  215. cdb =(struct MYCDB *) luExtension->ActiveLuRequest->Cdb;
  216.  
  217. ((PFOUR_BYTE)&logicalBlockAddress)->Byte3=  cdb->LogicalBlockByte0;
  218. ((PFOUR_BYTE)&logicalBlockAddress)->Byte2=  cdb->LogicalBlockByte1;
  219. ((PFOUR_BYTE)&logicalBlockAddress)->Byte1=  cdb->LogicalBlockByte2;
  220. ((PFOUR_BYTE)&logicalBlockAddress)->Byte0=  cdb->LogicalBlockByte3;
  221.  
  222. ((PFOUR_BYTE)&transferBlocks)->Byte1= cdb->TransferBlocksMsb;
  223. ((PFOUR_BYTE)&transferBlocks)->Byte0= cdb->TransferBlocksLsb;
  224.  
  225. return( CDRead(logicalBlockAddress, transferBlocks,
  226.        luExtension->ActiveLuRequest->DataBuffer, deviceExtension));
  227. }
  228.  
  229.  
  230. /*****************************************************************/
  231. /*
  232. Routine Description:
  233.  
  234.     This routine is called from the SCSI port driver synchronized
  235.     with the kernel with a request to be executed.
  236.  
  237.                                  */
  238. /*****************************************************************/
  239.  
  240. BOOLEAN
  241. CDnowStartIo(
  242.     IN PVOID           Context,
  243.     IN PSCSI_REQUEST_BLOCK Srb
  244.     )
  245.  
  246. {
  247.     PSPECIFIC_DEVICE_EXTENSION    deviceExtension = Context;
  248.     PSPECIFIC_LU_EXTENSION    luExtension;
  249.  
  250.  
  251.     //
  252.     // Determine the logical unit that this request is for.
  253.     //
  254.     deviceExtension->PathId = Srb->PathId;
  255.  
  256.     luExtension = ScsiPortGetLogicalUnit(deviceExtension,
  257.                      deviceExtension->PathId,
  258.                      Srb->TargetId,
  259.                      Srb->Lun);
  260.     Srb->SrbStatus = SRB_STATUS_PENDING;
  261.  
  262.     switch (Srb->Function) {
  263.        case SRB_FUNCTION_ABORT_COMMAND:
  264.         Srb->SrbStatus = SRB_STATUS_SUCCESS;
  265.         break;
  266.  
  267.     case SRB_FUNCTION_RESET_BUS:
  268.  
  269.         Srb->SrbStatus = SRB_STATUS_SUCCESS;
  270.         break;
  271.  
  272.     case SRB_FUNCTION_EXECUTE_SCSI:
  273.     if ((Srb->TargetId == 3)  && (Srb->Lun == 0))     // not at 0 or 1
  274.      {
  275.         luExtension->ActiveLuRequest = Srb;
  276.         luExtension->LuState = LS_COMPLETE;
  277.         luExtension->SavedDataPointer = (ULONG) Srb->DataBuffer;
  278.         luExtension->SavedDataLength = Srb->DataTransferLength;
  279.         switch( Srb->Cdb[0])
  280.              {
  281.              // Get CD-ROM Inquiry Data
  282.              case (SCSIOP_INQUIRY):
  283.                 //
  284.                 // Setup the context for this target/lun.
  285.                 //
  286.                  Cdrom_Inquiry(luExtension);
  287.                 Srb->SrbStatus = SRB_STATUS_SUCCESS;
  288.                 break;
  289.              // ReadCapacity: Hardwired data
  290.              case(SCSIOP_READ_CAPACITY):
  291.                  CapacityRead(luExtension);
  292.                  Srb->SrbStatus = SRB_STATUS_SUCCESS;
  293.                 break;
  294.              // Read Cd-ROM
  295.              case(SCSIOP_READ):
  296.                  if NT_SUCCESS(ReadCDRom(deviceExtension,
  297.                        luExtension))
  298.                     Srb->SrbStatus = SRB_STATUS_SUCCESS;
  299.                  else
  300.                       Srb->SrbStatus = SRB_STATUS_ERROR;
  301.                 break;
  302.               case (SCSIOP_TEST_UNIT_READY):
  303.                  Srb->SrbStatus = SRB_STATUS_SUCCESS;
  304.                break;
  305.              // Invalid Scsi Op code
  306.              default:
  307.                  Srb->SrbStatus = SRB_STATUS_SUCCESS;
  308.                 break;
  309.              } // of switch
  310.         } // of if
  311.         else
  312.         {
  313.            Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID;
  314.         }
  315.         ScsiPortNotification(RequestComplete,
  316.                  (PVOID) deviceExtension,
  317.                  Srb);
  318.         break;
  319.  
  320.     // Unexpected Scsi Function Call
  321.     default:
  322.         Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
  323.         ScsiPortNotification(RequestComplete,
  324.                  (PVOID) deviceExtension,
  325.                  Srb);
  326.         break;
  327.  
  328.     }
  329.     // Adapter ready for next request.
  330.     ScsiPortNotification(NextRequest,
  331.              deviceExtension,
  332.              NULL);
  333.     return TRUE;
  334. } // end CDnowStartIo()
  335.  
  336.  
  337. /*****************************************************************/
  338. /*                                 */
  339. /*          findAdapterPort                     */
  340. /*   - locate the Io port address of the adaptor         */
  341. /*                                 */
  342. /*****************************************************************/
  343. USHORT findAdapterPort(
  344.     PSPECIFIC_DEVICE_EXTENSION    deviceExtension,
  345.     IN PVOID                    Context,
  346.     IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo
  347.      )
  348. {
  349.      ULONG PortBase = BASE_PORT;
  350.  
  351.  
  352.      deviceExtension->PortBase = PortBase;
  353.     return LocateAdapterSpecific(deviceExtension, Context, ConfigInfo);   // PortBase;
  354. }
  355.  
  356. /*****************************************************************/
  357. /*
  358. Routine Description:
  359.     This routine locates the CD controller card, and allocate
  360.      the IO ports from NT IO manager.
  361.  
  362. Return Value:
  363.     SP_RETURN_FOUND    - if an adapter is found.
  364.     SP_RETURN_NOT_FOUND - if no adapter is found.
  365.                                  */
  366. /*****************************************************************/
  367. ULONG
  368. CDnowFindAdapter(
  369.     IN PVOID                    Context,
  370.     IN PVOID                    AdaptersFound,
  371.     IN PVOID                    BusInformation,
  372.     IN PCHAR                    ArgumentString,
  373.     IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
  374.     OUT PBOOLEAN                Again
  375.     )
  376. {
  377.     USHORT            portAddress;
  378.     USHORT            adaptersFound;
  379.     ULONG            returnStatus = SP_RETURN_NOT_FOUND;
  380.     PSPECIFIC_DEVICE_EXTENSION    deviceExtension = Context;
  381.  
  382.     *Again = FALSE;
  383.  
  384.     returnStatus = SP_RETURN_FOUND;  // assum found  a valid card
  385.  
  386.     //
  387.     // If there was no previously configured value for the IRQ,
  388.     // look at the other way to configure the value or use a default.
  389.     //
  390.  
  391.     ConfigInfo->BusInterruptLevel = 10;
  392.  
  393.     //    fill in a default a target ID.
  394.     ConfigInfo->NumberOfBuses = 1;
  395.  
  396.     ConfigInfo->ScatterGather = FALSE;
  397.     ConfigInfo->Master = FALSE;
  398.  
  399.     portAddress= findAdapterPort(deviceExtension, Context, ConfigInfo);
  400.     deviceExtension->PortBase = portAddress;
  401.      if(portAddress == 0)
  402.      {
  403.     returnStatus = SP_RETURN_NOT_FOUND;
  404.      goto NotFound;
  405.      }
  406.    // Fill in the access array information.
  407.    ConfigInfo->NumberOfAccessRanges = 1;
  408.    (*ConfigInfo->AccessRanges)[0].RangeStart =
  409.            ScsiPortConvertUlongToPhysicalAddress(portAddress);
  410.    (*ConfigInfo->AccessRanges)[0].RangeLength = 4;
  411.    (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
  412.  
  413.    ConfigInfo->NumberOfBuses = 1;
  414.    adaptersFound = 1;
  415.    *((PULONG) AdaptersFound) == (ULONG) adaptersFound;
  416.  
  417.     returnStatus = SP_RETURN_FOUND;  // assum found  a valid card
  418. NotFound:
  419.           return (returnStatus);
  420. } // end CDnowFindAdapter()
  421.  
  422.  
  423. /*****************************************************************/
  424. /*
  425.  
  426. Routine Description:
  427.     Driver initialization entry point for system.
  428.  
  429.                                  */
  430. /*****************************************************************/
  431. ULONG
  432. DriverEntry(
  433.     IN PVOID DriverObject,
  434.     IN PVOID Argument2
  435.     )
  436.  {
  437.     HW_INITIALIZATION_DATA  hwInitializationData;
  438.     ULONG            i,status;
  439.  
  440.     //
  441.     // Zero out the hwInitializationData structure.
  442.     //
  443.     for (i = 0; i < sizeof(HW_INITIALIZATION_DATA); i++) {
  444.  
  445.     *(((PUCHAR)&hwInitializationData + i)) = 0;
  446.     }
  447.  
  448.     hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
  449.  
  450.     //
  451.     // Set entry points.
  452.     //
  453.     hwInitializationData.HwInitialize    = CDnowInitialize;
  454.     hwInitializationData.HwStartIo    = CDnowStartIo;
  455.     hwInitializationData.HwInterrupt    = CDnowInterrupt;
  456.     hwInitializationData.HwFindAdapter    = CDnowFindAdapter;
  457.     hwInitializationData.HwResetBus    = CDnowResetBus;
  458.  
  459.     // features not supported
  460.     hwInitializationData.HwDmaStarted    = NULL;
  461.     hwInitializationData.HwAdapterState = NULL;
  462.  
  463.  
  464.     hwInitializationData.NeedPhysicalAddresses = FALSE;
  465.  
  466.     //
  467.     // Specify size of extensions.
  468.     //
  469.  
  470.     //
  471.     // Indicate need buffer mapping but not physical addresses.
  472.     //
  473.     hwInitializationData.MapBuffers        = TRUE;
  474.     hwInitializationData.NeedPhysicalAddresses    = FALSE;
  475.     hwInitializationData.NumberOfAccessRanges    = 1;
  476.  
  477.     //
  478.     // Specify size of device extension.
  479.     //
  480.     hwInitializationData.DeviceExtensionSize = sizeof(SPECIFIC_DEVICE_EXTENSION);
  481.  
  482.     //
  483.     // Specify size of logical unit extension.
  484.     //
  485.     hwInitializationData.SpecificLuExtensionSize = sizeof(SPECIFIC_LU_EXTENSION);
  486.  
  487.     //
  488.     // The fourth parameter below (i.e., "i") will show up as the
  489.     // "AdaptersFound" parameter when FindAdapter() is called.
  490.     //
  491.     // First try to configure for the Isa bus.
  492.     //
  493.     hwInitializationData.AdapterInterfaceType = Isa;
  494.  
  495.     i = 0;
  496.     status = ScsiPortInitialize(DriverObject, Argument2,
  497.                 &hwInitializationData, &(i));
  498.  
  499.  
  500.     return status;
  501.  
  502. } // end DriverEntry()
  503.  
  504.  
  505. /*****************************************************************/
  506. /*
  507. Routine Description:
  508.  
  509.     Inititialize adapter.  We have dummied out this function for
  510.      compatibility purposes.
  511.  
  512. Arguments:
  513.  
  514.     Context - Adapter object device extension.
  515.  
  516. Return Value:
  517.  
  518.     Status.
  519.                                  */
  520. /*****************************************************************/
  521. BOOLEAN
  522. CDnowInitialize(
  523.     IN PVOID Context
  524.     )
  525. {
  526.     PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
  527.  
  528.  
  529.     return TRUE;
  530. } // end CDnow<Initialize()
  531.  
  532.  
  533.  
  534.  
  535.