ReactOS  0.4.14-dev-57-g333b8f1
atapi.c File Reference
#include <ntddk.h>
#include "atapi.h"
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <ntddstor.h>
#include <debug.h>
Include dependency graph for atapi.c:

Go to the source code of this file.

Classes

struct  _HW_DEVICE_EXTENSION
 
struct  _HW_LU_EXTENSION
 

Typedefs

typedef struct _HW_DEVICE_EXTENSION HW_DEVICE_EXTENSION
 
typedef struct _HW_DEVICE_EXTENSIONPHW_DEVICE_EXTENSION
 
typedef struct _HW_LU_EXTENSION HW_LU_EXTENSION
 
typedef struct _HW_LU_EXTENSIONPHW_LU_EXTENSION
 

Functions

PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb (IN PVOID HwDeviceExtension, IN ULONG PathId, IN ULONG TargetId)
 
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb (IN PVOID HwDeviceExtension, IN ULONG PathId, IN ULONG TargetId)
 
VOID NTAPI AtapiHwInitializeChanger (IN PVOID HwDeviceExtension, IN ULONG TargetId, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
 
ULONG NTAPI AtapiSendCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI AtapiZeroMemory (IN PUCHAR Buffer, IN ULONG Count)
 
VOID NTAPI AtapiHexToString (ULONG Value, PCHAR *Buffer)
 
LONG NTAPI AtapiStringCmp (PCHAR FirstStr, PCHAR SecondStr, ULONG Count)
 
BOOLEAN NTAPI AtapiInterrupt (IN PVOID HwDeviceExtension)
 
BOOLEAN NTAPI AtapiHwInitialize (IN PVOID HwDeviceExtension)
 
ULONG NTAPI IdeBuildSenseBuffer (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI IdeMediaStatus (IN BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG Channel)
 
BOOLEAN NTAPI IssueIdentify (IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR Command)
 
BOOLEAN NTAPI SetDriveParameters (IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel)
 
BOOLEAN NTAPI AtapiResetController (IN PVOID HwDeviceExtension, IN ULONG PathId)
 
ULONG NTAPI MapError (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
BOOLEAN NTAPI FindDevices (IN PVOID HwDeviceExtension, IN BOOLEAN AtapiOnly, IN ULONG Channel)
 
ULONG NTAPI AtapiParseArgumentString (IN PCHAR String, IN PCHAR KeyWord)
 
ULONG NTAPI AtapiFindController (IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
 
BOOLEAN NTAPI FindBrokenController (IN PVOID DeviceExtension, IN PUCHAR VendorID, IN ULONG VendorIDLength, IN PUCHAR DeviceID, IN ULONG DeviceIDLength, IN OUT PULONG FunctionNumber, IN OUT PULONG SlotNumber, IN ULONG BusNumber, OUT PBOOLEAN LastSlot)
 
ULONG NTAPI AtapiFindNativeModeController (IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
 
ULONG NTAPI AtapiFindPCIController (IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
 
ULONG NTAPI Atapi2Scsi (IN PSCSI_REQUEST_BLOCK Srb, IN char *DataBuffer, IN ULONG ByteCount)
 
VOID NTAPI AtapiCallBack (IN PVOID HwDeviceExtension)
 
ULONG NTAPI IdeSendSmartCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
ULONG NTAPI IdeReadWrite (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
ULONG NTAPI IdeVerify (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI Scsi2Atapi (IN PSCSI_REQUEST_BLOCK Srb)
 
ULONG NTAPI IdeSendCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI IdeMediaStatus (BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, ULONG Channel)
 
BOOLEAN NTAPI AtapiStartIo (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
ULONG NTAPI DriverEntry (IN PVOID DriverObject, IN PVOID Argument2)
 
VOID NTAPI AtapiHexToString (IN ULONG Value, IN OUT PCHAR *Buffer)
 

Typedef Documentation

◆ HW_DEVICE_EXTENSION

◆ HW_LU_EXTENSION

◆ PHW_DEVICE_EXTENSION

◆ PHW_LU_EXTENSION

Function Documentation

◆ Atapi2Scsi()

ULONG NTAPI Atapi2Scsi ( IN PSCSI_REQUEST_BLOCK  Srb,
IN char DataBuffer,
IN ULONG  ByteCount 
)

Definition at line 3360 of file atapi.c.

3365 {
3366  ULONG bytesAdjust = 0;
3367  if (Srb->Cdb[0] == ATAPI_MODE_SENSE) {
3368 
3369  PMODE_PARAMETER_HEADER_10 header_10 = (PMODE_PARAMETER_HEADER_10)DataBuffer;
3371 
3372  header->ModeDataLength = header_10->ModeDataLengthLsb;
3373  header->MediumType = header_10->MediumType;
3374 
3375  //
3376  // ATAPI Mode Parameter Header doesn't have these fields.
3377  //
3378 
3379  header->DeviceSpecificParameter = header_10->Reserved[0];
3380  header->BlockDescriptorLength = header_10->Reserved[1];
3381 
3383  if (ByteCount > 0)
3384  ScsiPortMoveMemory(DataBuffer+sizeof(MODE_PARAMETER_HEADER),
3385  DataBuffer+sizeof(MODE_PARAMETER_HEADER_10),
3386  ByteCount);
3387 
3388  //
3389  // Change ATAPI_MODE_SENSE opcode back to SCSIOP_MODE_SENSE
3390  // so that we don't convert again.
3391  //
3392 
3393  Srb->Cdb[0] = SCSIOP_MODE_SENSE;
3394 
3395  bytesAdjust = sizeof(MODE_PARAMETER_HEADER_10) -
3396  sizeof(MODE_PARAMETER_HEADER);
3397 
3398 
3399  }
3400 
3401  //
3402  // Convert to words.
3403  //
3404 
3405  return bytesAdjust >> 1;
3406 }
struct _MODE_PARAMETER_HEADER_10 * PMODE_PARAMETER_HEADER_10
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
struct _MODE_PARAMETER_HEADER_10 MODE_PARAMETER_HEADER_10
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
unsigned int ULONG
Definition: retypes.h:1
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
#define ATAPI_MODE_SENSE
Definition: atapi.h:61
struct CFHEADER header
Definition: fdi.c:109
VOID NTAPI ScsiPortMoveMemory(IN PVOID WriteBuffer, IN PVOID ReadBuffer, IN ULONG Length)
Definition: scsiport.c:1298

Referenced by AtapiInterrupt().

◆ AtapiCallBack()

VOID NTAPI AtapiCallBack ( IN PVOID  HwDeviceExtension)

Definition at line 3411 of file atapi.c.

3414 {
3415  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
3416  PSCSI_REQUEST_BLOCK srb = deviceExtension->CurrentSrb;
3417  PATAPI_REGISTERS_2 baseIoAddress2;
3418  UCHAR statusByte;
3419 
3420  //
3421  // If the last command was DSC restrictive, see if it's set. If so, the device is
3422  // ready for a new request. Otherwise, reset the timer and come back to here later.
3423  //
3424 
3425  if (srb && (!(deviceExtension->ExpectingInterrupt))) {
3426 #if DBG
3427  if (!IS_RDP((srb->Cdb[0]))) {
3428  DebugPrint((1,
3429  "AtapiCallBack: Invalid CDB marked as RDP - %x\n",
3430  srb->Cdb[0]));
3431  }
3432 #endif
3433 
3434  baseIoAddress2 = (PATAPI_REGISTERS_2)deviceExtension->BaseIoAddress2[srb->TargetId >> 1];
3435  if (deviceExtension->RDP) {
3436  GetStatus(baseIoAddress2, statusByte);
3437  if (statusByte & IDE_STATUS_DSC) {
3438 
3440  deviceExtension,
3441  srb);
3442 
3443  //
3444  // Clear current SRB.
3445  //
3446 
3447  deviceExtension->CurrentSrb = NULL;
3448  deviceExtension->RDP = FALSE;
3449 
3450  //
3451  // Ask for next request.
3452  //
3453 
3455  deviceExtension,
3456  NULL);
3457 
3458 
3459  return;
3460 
3461  } else {
3462 
3463  DebugPrint((3,
3464  "AtapiCallBack: Requesting another timer for Op %x\n",
3465  deviceExtension->CurrentSrb->Cdb[0]));
3466 
3468  HwDeviceExtension,
3469  AtapiCallBack,
3470  1000);
3471  return;
3472  }
3473  }
3474  }
3475 
3476  DebugPrint((2,
3477  "AtapiCallBack: Calling ISR directly due to BUSY\n"));
3478  AtapiInterrupt(HwDeviceExtension);
3479 }
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
UCHAR Cdb[16]
Definition: srb.h:271
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
VOID NTAPI AtapiCallBack(IN PVOID HwDeviceExtension)
Definition: atapi.c:3411
smooth NULL
Definition: ftsmooth.c:416
UCHAR TargetId
Definition: srb.h:246
if(!(yy_init))
Definition: macro.lex.yy.c:714
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1308
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IS_RDP(OperationCode)
Definition: atapi.h:453
PSCSI_REQUEST_BLOCK CurrentSrb
Definition: atapi.c:28
struct _ATAPI_REGISTERS_2 * PATAPI_REGISTERS_2
#define IDE_STATUS_DSC
Definition: atapi.h:129
BOOLEAN NTAPI AtapiInterrupt(IN PVOID HwDeviceExtension)
Definition: atapi.c:3484

Referenced by AtapiInterrupt().

◆ AtapiFindController()

ULONG NTAPI AtapiFindController ( IN PVOID  HwDeviceExtension,
IN PVOID  Context,
IN PVOID  BusInformation,
IN PCHAR  ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
OUT PBOOLEAN  Again 
)

Definition at line 2106 of file atapi.c.

2136 {
2137  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
2138  PULONG adapterCount = (PULONG)Context;
2139  PUCHAR ioSpace = NULL;
2140  ULONG i;
2141  ULONG irq;
2142  ULONG portBase;
2143  ULONG retryCount;
2144  PCI_SLOT_NUMBER slotData;
2145  PPCI_COMMON_CONFIG pciData;
2146  ULONG pciBuffer;
2147  BOOLEAN atapiOnly;
2148  UCHAR statusByte;
2149  BOOLEAN preConfig = FALSE;
2150  //
2151  // The following table specifies the ports to be checked when searching for
2152  // an IDE controller. A zero entry terminates the search.
2153  //
2154 
2155  CONST ULONG AdapterAddresses[5] = {0x1F0, 0x170, 0x1e8, 0x168, 0};
2156 
2157  //
2158  // The following table specifies interrupt levels corresponding to the
2159  // port addresses in the previous table.
2160  //
2161 
2162  CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0};
2163 
2164  if (!deviceExtension) {
2165  return SP_RETURN_ERROR;
2166  }
2167 
2168  //
2169  // Check to see if this is a special configuration environment.
2170  //
2171 
2172  portBase = irq = 0;
2173  if (ArgumentString) {
2174 
2175  irq = AtapiParseArgumentString(ArgumentString, "Interrupt");
2176  if (irq ) {
2177 
2178  //
2179  // Both parameters must be present to proceed
2180  //
2181 
2182  portBase = AtapiParseArgumentString(ArgumentString, "BaseAddress");
2183  if (!portBase) {
2184 
2185  //
2186  // Try a default search for the part.
2187  //
2188 
2189  irq = 0;
2190  }
2191  }
2192  }
2193 
2194 
2195 
2196  //
2197  // Scan though the adapter address looking for adapters.
2198  //
2199  if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart) != 0) {
2200  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
2201  ConfigInfo->AdapterInterfaceType,
2202  ConfigInfo->SystemIoBusNumber,
2203  (*ConfigInfo->AccessRanges)[0].RangeStart,
2204  (*ConfigInfo->AccessRanges)[0].RangeLength,
2205  (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory));
2206  *Again = FALSE;
2207  //
2208  // Since we have pre-configured information we only need to go through this loop once
2209  //
2210  preConfig = TRUE;
2211  portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart);
2212 
2213  }
2214 
2215 
2216 
2217  while (AdapterAddresses[*adapterCount] != 0) {
2218 
2219  retryCount = 4;
2220 
2221  for (i = 0; i < 4; i++) {
2222 
2223  //
2224  // Zero device fields to ensure that if earlier devices were found,
2225  // but not claimed, the fields are cleared.
2226  //
2227 
2229  }
2230 
2231  //
2232  // Get the system physical address for this IO range.
2233  //
2234 
2235 
2236  //
2237  // Check if configInfo has the default information
2238  // if not, we go and find ourselves
2239  //
2240 
2241  if (preConfig == FALSE) {
2242 
2243  if (portBase) {
2244  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
2245  ConfigInfo->AdapterInterfaceType,
2246  ConfigInfo->SystemIoBusNumber,
2248  8,
2249  TRUE);
2250  } else {
2251  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
2252  ConfigInfo->AdapterInterfaceType,
2253  ConfigInfo->SystemIoBusNumber,
2254  ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount]),
2255  8,
2256  TRUE);
2257  }
2258 
2259  }// ConfigInfo check
2260  //
2261  // Update the adapter count.
2262  //
2263 
2264  (*adapterCount)++;
2265 
2266  //
2267  // Check if ioSpace accessible.
2268  //
2269 
2270  if (!ioSpace) {
2271  continue;
2272  }
2273 
2274 retryIdentifier:
2275 
2276  //
2277  // Select master.
2278  //
2279 
2280  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xA0);
2281 
2282  //
2283  // Check if card at this address.
2284  //
2285 
2286  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);
2287 
2288  //
2289  // Check if identifier can be read back.
2290  //
2291 
2292  if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {
2293 
2294  DebugPrint((2,
2295  "AtapiFindController: Identifier read back from Master (%x)\n",
2296  statusByte));
2297 
2298  statusByte = ScsiPortReadPortUchar(&((PATAPI_REGISTERS_2)ioSpace)->AlternateStatus);
2299 
2300  if (statusByte & IDE_STATUS_BUSY) {
2301 
2302  i = 0;
2303 
2304  //
2305  // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2306  // warm boots don't clear.
2307  //
2308 
2309  do {
2310  ScsiPortStallExecution(1000);
2311  statusByte = ScsiPortReadPortUchar(&((PATAPI_REGISTERS_1)ioSpace)->Command);
2312  DebugPrint((3,
2313  "AtapiFindController: First access to status %x\n",
2314  statusByte));
2315  } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10);
2316 
2317  if (retryCount-- && (!(statusByte & IDE_STATUS_BUSY))) {
2318  goto retryIdentifier;
2319  }
2320  }
2321 
2322  //
2323  // Select slave.
2324  //
2325 
2326  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xB0);
2327 
2328  //
2329  // See if slave is present.
2330  //
2331 
2332  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);
2333 
2334  if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {
2335 
2336  DebugPrint((2,
2337  "AtapiFindController: Identifier read back from Slave (%x)\n",
2338  statusByte));
2339 
2340  //
2341  //
2342  // No controller at this base address.
2343  //
2344 
2345  ScsiPortFreeDeviceBase(HwDeviceExtension,
2346  ioSpace);
2347 
2348  continue;
2349  }
2350  }
2351 
2352  //
2353  // Record base IO address.
2354  //
2355 
2356  deviceExtension->BaseIoAddress1[0] = (PIDE_REGISTERS_1)(ioSpace);
2357 
2358  //
2359  // Fill in the access array information only if default params are not in there.
2360  //
2361  if (preConfig == FALSE) {
2362 
2363  //
2364  // An adapter has been found request another call, only if we didn't get preconfigured info.
2365  //
2366  *Again = TRUE;
2367 
2368  if (portBase) {
2369  (*ConfigInfo->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(portBase);
2370  } else {
2371  (*ConfigInfo->AccessRanges)[0].RangeStart =
2372  ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]);
2373  }
2374 
2375  (*ConfigInfo->AccessRanges)[0].RangeLength = 8;
2376  (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
2377 
2378  //
2379  // Indicate the interrupt level corresponding to this IO range.
2380  //
2381 
2382  if (irq) {
2383  ConfigInfo->BusInterruptLevel = irq;
2384  } else {
2385  ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1];
2386  }
2387 
2388  if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
2389  ConfigInfo->InterruptMode = LevelSensitive;
2390  } else {
2391  ConfigInfo->InterruptMode = Latched;
2392  }
2393  }
2394  //
2395  // Get the system physical address for the second IO range.
2396  //
2397 
2398 
2399  if (portBase) {
2400  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
2401  ConfigInfo->AdapterInterfaceType,
2402  ConfigInfo->SystemIoBusNumber,
2403  ScsiPortConvertUlongToPhysicalAddress(portBase + 0x206),
2404  1,
2405  TRUE);
2406  } else {
2407  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
2408  ConfigInfo->AdapterInterfaceType,
2409  ConfigInfo->SystemIoBusNumber,
2410  ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1] + 0x206),
2411  1,
2412  TRUE);
2413  }
2414 
2415  deviceExtension->BaseIoAddress2[0] = (PIDE_REGISTERS_2)(ioSpace);
2416 
2417  deviceExtension->NumberChannels = 1;
2418 
2419  ConfigInfo->NumberOfBuses = 1;
2420  ConfigInfo->MaximumNumberOfTargets = 2;
2421 
2422  //
2423  // Indicate maximum transfer length is 64k.
2424  //
2425 
2426  ConfigInfo->MaximumTransferLength = 0x10000;
2427 
2428  DebugPrint((1,
2429  "AtapiFindController: Found IDE at %x\n",
2430  deviceExtension->BaseIoAddress1[0]));
2431 
2432 
2433  //
2434  // For Daytona, the atdisk driver gets the first shot at the
2435  // primary and secondary controllers.
2436  //
2437 
2438  if (preConfig == FALSE) {
2439 
2440 
2441  if (*adapterCount - 1 < 2) {
2442 
2443  //
2444  // Determine whether this driver is being initialized by the
2445  // system or as a crash dump driver.
2446  //
2447 
2448  if (ArgumentString) {
2449 
2450  if (AtapiParseArgumentString(ArgumentString, "dump") == 1) {
2451  DebugPrint((3,
2452  "AtapiFindController: Crash dump\n"));
2453  atapiOnly = FALSE;
2454  deviceExtension->DriverMustPoll = TRUE;
2455  } else {
2456  DebugPrint((3,
2457  "AtapiFindController: Atapi Only\n"));
2458  atapiOnly = TRUE;
2459  deviceExtension->DriverMustPoll = FALSE;
2460  }
2461  } else {
2462 
2463  DebugPrint((3,
2464  "AtapiFindController: Atapi Only\n"));
2465  atapiOnly = TRUE;
2466  deviceExtension->DriverMustPoll = FALSE;
2467  }
2468 
2469  } else {
2470  atapiOnly = FALSE;
2471  }
2472 
2473  //
2474  // If this is a PCI machine, pick up all devices.
2475  //
2476 
2477 
2478  pciData = (PPCI_COMMON_CONFIG)&pciBuffer;
2479 
2480  slotData.u.bits.DeviceNumber = 0;
2481  slotData.u.bits.FunctionNumber = 0;
2482 
2483  if (ScsiPortGetBusData(deviceExtension,
2485  0, // BusNumber
2486  slotData.u.AsULONG,
2487  pciData,
2488  sizeof(ULONG))) {
2489 
2490  atapiOnly = FALSE;
2491 
2492  //
2493  // Wait on doing this, until a reliable method
2494  // of determining support is found.
2495  //
2496 
2497  #if 0
2498  deviceExtension->DWordIO = TRUE;
2499  #endif
2500 
2501  } else {
2502  deviceExtension->DWordIO = FALSE;
2503  }
2504 
2505  } else {
2506 
2507  atapiOnly = FALSE;
2508  deviceExtension->DriverMustPoll = FALSE;
2509 
2510  }// preConfig check
2511 
2512  //
2513  // Save the Interrupt Mode for later use
2514  //
2515  deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
2516 
2517  //
2518  // Search for devices on this controller.
2519  //
2520 
2521  if (FindDevices(HwDeviceExtension,
2522  atapiOnly,
2523  0)) {
2524 
2525  //
2526  // Claim primary or secondary ATA IO range.
2527  //
2528 
2529  if (portBase) {
2530  switch (portBase) {
2531  case 0x170:
2532  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2533  deviceExtension->PrimaryAddress = FALSE;
2534  break;
2535  case 0x1f0:
2536  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2537  deviceExtension->PrimaryAddress = TRUE;
2538  break;
2539  default:
2540  break;
2541  }
2542  } else {
2543  if (*adapterCount == 1) {
2544  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2545  deviceExtension->PrimaryAddress = TRUE;
2546  } else if (*adapterCount == 2) {
2547  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2548  deviceExtension->PrimaryAddress = FALSE;
2549  }
2550  }
2551 
2552  return(SP_RETURN_FOUND);
2553  }
2554  }
2555 
2556  //
2557  // The entire table has been searched and no adapters have been found.
2558  // There is no need to call again and the device base can now be freed.
2559  // Clear the adapter count for the next bus.
2560  //
2561 
2562  *Again = FALSE;
2563  *(adapterCount) = 0;
2564 
2565  return(SP_RETURN_NOT_FOUND);
2566 
2567 } // end AtapiFindController()
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:949
struct _PCI_COMMON_CONFIG * PPCI_COMMON_CONFIG
BOOLEAN DWordIO
Definition: atapi.c:117
struct _IDE_REGISTERS_2 * PIDE_REGISTERS_2
BOOLEAN NTAPI FindDevices(IN PVOID HwDeviceExtension, IN BOOLEAN AtapiOnly, IN ULONG Channel)
Definition: atapi.c:1489
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
Definition: shell.h:41
ULONG NTAPI AtapiParseArgumentString(IN PCHAR String, IN PCHAR KeyWord)
Definition: atapi.c:1852
unsigned char irq
Definition: dsp.h:13
PVOID NTAPI ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:562
VOID NTAPI ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
Definition: scsiport.c:540
USHORT DeviceFlags[4]
Definition: atapi.c:86
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
ULONG InterruptMode
Definition: atapi.c:47
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortConvertUlongToPhysicalAddress(IN ULONG_PTR UlongAddress)
Definition: scsiport.c:520
#define SP_RETURN_NOT_FOUND
Definition: srb.h:513
#define SP_RETURN_FOUND
Definition: srb.h:514
VOID NTAPI ScsiPortWritePortUchar(IN PUCHAR Port, IN UCHAR Value)
Definition: scsiport.c:1531
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN PrimaryAddress
Definition: atapi.c:124
union _PCI_SLOT_NUMBER::@3636 u
struct _PCI_SLOT_NUMBER::@3636::@3637 bits
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
ULONG NTAPI ScsiPortGetBusData(IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length)
Definition: scsiport.c:549
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
BOOLEAN DriverMustPoll
Definition: atapi.c:111
#define IDE_STATUS_BUSY
Definition: atapi.h:132
unsigned int * PULONG
Definition: retypes.h:1
UCHAR NTAPI ScsiPortReadPortUchar(IN PUCHAR Port)
Definition: scsiport.c:1374
unsigned int ULONG
Definition: retypes.h:1
#define SP_RETURN_ERROR
Definition: srb.h:515
#define CONST
Definition: pedump.c:81
ULONG NumberChannels
Definition: atapi.c:68
struct _IDE_REGISTERS_1 * PIDE_REGISTERS_1
VOID NTAPI ScsiPortStallExecution(IN ULONG Delay)
Definition: scsiport.c:1473
UCHAR pciBuffer[256]
Definition: id_probe.cpp:66

Referenced by AtapiFindPCIController(), and DriverEntry().

◆ AtapiFindNativeModeController()

ULONG NTAPI AtapiFindNativeModeController ( IN PVOID  HwDeviceExtension,
IN PVOID  Context,
IN PVOID  BusInformation,
IN PCHAR  ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
OUT PBOOLEAN  Again 
)

Definition at line 2712 of file atapi.c.

2743 {
2744  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
2745  ULONG nativeModeAdapterTableIndex = (ULONG_PTR)Context;
2746  ULONG channel;
2747  PUCHAR ioSpace;
2748  BOOLEAN atapiOnly,
2749  deviceFound = FALSE;
2750  UCHAR statusByte;
2751  PCI_SLOT_NUMBER slotData;
2752  PCI_COMMON_CONFIG pciData;
2753  ULONG funcNumber;
2754  ULONG busDataRead;
2755  UCHAR vendorString[5];
2756  UCHAR deviceString[5];
2757  PUCHAR vendorStrPtr;
2758  PUCHAR deviceStrPtr;
2759  SCSI_PHYSICAL_ADDRESS IoBasePort1;
2760  SCSI_PHYSICAL_ADDRESS IoBasePort2;
2761 
2762  //
2763  // The following table specifies the ports to be checked when searching for
2764  // an IDE controller. A zero entry terminates the search.
2765  //
2766 
2767  CONST ULONG AdapterAddresses[3] = {0x1F0, 0x170, 0};
2768 
2769  if (!deviceExtension) {
2770  return SP_RETURN_ERROR;
2771  }
2772 
2773  *Again = FALSE;
2774 
2775  slotData.u.AsULONG = 0;
2776  slotData.u.bits.DeviceNumber = ConfigInfo->SlotNumber;
2777 
2778  for (funcNumber= 0; funcNumber < 8; funcNumber++) {
2779 
2780  slotData.u.bits.FunctionNumber = funcNumber;
2781 
2782  busDataRead = ScsiPortGetBusData(HwDeviceExtension,
2784  ConfigInfo->SystemIoBusNumber,
2785  slotData.u.AsULONG,
2786  &pciData,
2787  sizeof (pciData));
2788  if (busDataRead != sizeof (pciData)) {
2789  return SP_RETURN_ERROR;
2790  }
2791  if (pciData.VendorID == PCI_INVALID_VENDORID) {
2792  return SP_RETURN_ERROR;
2793  }
2794 
2795  //
2796  // Translate hex ids to strings.
2797  //
2798 
2799  vendorStrPtr = vendorString;
2800  deviceStrPtr = deviceString;
2801  AtapiHexToString(pciData.VendorID, (PCHAR*)&vendorStrPtr);
2802  AtapiHexToString(pciData.DeviceID, (PCHAR*)&deviceStrPtr);
2803 
2804  //
2805  // Compare strings.
2806  //
2807 
2808  if (AtapiStringCmp((PCHAR)vendorString,
2809  NativeModeAdapters[nativeModeAdapterTableIndex].VendorId,
2810  NativeModeAdapters[nativeModeAdapterTableIndex].VendorIdLength) ||
2811  AtapiStringCmp((PCHAR)deviceString,
2812  NativeModeAdapters[nativeModeAdapterTableIndex].DeviceId,
2813  NativeModeAdapters[nativeModeAdapterTableIndex].DeviceIdLength)) {
2814  continue;
2815  }
2816 
2817  if (pciData.ProgIf & ((1 << 2) | (1 << 0))) {
2818  // both primary and secondary channel are in native mode
2819 
2820  // Found our device
2821  *Again = TRUE;
2822 
2823  break;
2824  }
2825  }
2826 
2827  if (*Again != FALSE) {
2828 
2829  for (channel = 0; channel < 2; channel++) {
2830 
2831  IoBasePort1 = (*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart;
2832  IoBasePort2 = (*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart;
2834 
2835  //
2836  // Get the system physical address for this IO range.
2837  //
2838 
2839  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
2840  ConfigInfo->AdapterInterfaceType,
2841  ConfigInfo->SystemIoBusNumber,
2842  IoBasePort1,
2843  8,
2844  TRUE);
2845 
2846  //
2847  // Check if ioSpace accessible.
2848  //
2849 
2850  if (!ioSpace) {
2851  continue;
2852  }
2853 
2854  //
2855  // Select master.
2856  //
2857 
2858  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xA0);
2859 
2860  //
2861  // Check if card at this address.
2862  //
2863 
2864  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);
2865 
2866  //
2867  // Check if identifier can be read back.
2868  //
2869 
2870  if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {
2871 
2872  DebugPrint((2,
2873  "AtapiFindPciController: Identifier read back from Master (%x)\n",
2874  statusByte));
2875 
2876 
2877  //
2878  // Select slave.
2879  //
2880 
2881  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xB0);
2882 
2883  //
2884  // See if slave is present.
2885  //
2886 
2887  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);
2888 
2889  if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {
2890 
2891  DebugPrint((2,
2892  "AtapiFindPciController: Identifier read back from Slave (%x)\n",
2893  statusByte));
2894 
2895  //
2896  //
2897  // No controller at this base address.
2898  //
2899 
2900  ScsiPortFreeDeviceBase(HwDeviceExtension,
2901  ioSpace);
2902 
2903  //
2904  // If the chip is there, but we couldn't find the primary channel, try the secondary.
2905  // If we couldn't find a secondary, who cares.
2906  //
2907 
2908  if (channel == 1) {
2909 
2910  goto setStatusAndExit;
2911 
2912  } else {
2913  continue;
2914  }
2915  }
2916  }
2917 
2918  //
2919  // Record base IO address.
2920  //
2921 
2922  deviceExtension->BaseIoAddress1[channel] = (PIDE_REGISTERS_1)(ioSpace);
2923 
2924  //
2925  // Get the system physical address for the second IO range.
2926  //
2927 
2928  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
2929  ConfigInfo->AdapterInterfaceType,
2930  ConfigInfo->SystemIoBusNumber,
2931  IoBasePort2,
2932  1,
2933  TRUE);
2934 
2935  deviceExtension->BaseIoAddress2[channel] = (PIDE_REGISTERS_2)(ioSpace);
2936 
2937  deviceExtension->NumberChannels = 2;
2938 
2939  //
2940  // Indicate only one bus.
2941  //
2942 
2943  ConfigInfo->NumberOfBuses = 1;
2944 
2945  //
2946  // Indicate four devices can be attached to the adapter, since we
2947  // have to serialize access to the two channels.
2948  //
2949 
2950  ConfigInfo->MaximumNumberOfTargets = 4;
2951 
2952  //
2953  // Indicate maximum transfer length is 64k.
2954  //
2955 
2956  ConfigInfo->MaximumTransferLength = 0x10000;
2957 
2958  DebugPrint((1,
2959  "AtapiFindPciController: Found native mode IDE at %x\n",
2960  deviceExtension->BaseIoAddress1[channel]));
2961 
2962  //
2963  // Since we will always pick up this part, and not atdisk, so indicate.
2964  //
2965 
2966  atapiOnly = FALSE;
2967 
2968  //
2969  // Save the Interrupt Mode for later use
2970  //
2971  deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
2972 
2973  //
2974  // Search for devices on this controller.
2975  //
2976 
2977  if (FindDevices(HwDeviceExtension,
2978  atapiOnly,
2979  channel)){
2980  deviceFound = TRUE;
2981  }
2982 
2983  //
2984  // Claim primary or secondary ATA IO range.
2985  //
2986 
2987  if (ScsiPortConvertPhysicalAddressToUlong(IoBasePort1) == AdapterAddresses[0]) {
2988  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2989  deviceExtension->PrimaryAddress = TRUE;
2990 
2991  } else if (ScsiPortConvertPhysicalAddressToUlong(IoBasePort2) == AdapterAddresses[1]) {
2992  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2993  deviceExtension->PrimaryAddress = FALSE;
2994  }
2995  }
2996  }
2997 
2998 setStatusAndExit:
2999 
3000  if (deviceFound) {
3001 
3002  *Again = TRUE;
3003  return SP_RETURN_FOUND;
3004  }
3005 
3006  *Again = FALSE;
3007  return SP_RETURN_NOT_FOUND;
3008 
3009 } // end AtapiFindNativeModeController()
signed char * PCHAR
Definition: retypes.h:7
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define TRUE
Definition: types.h:120
VOID NTAPI AtapiHexToString(ULONG Value, PCHAR *Buffer)
NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[]
Definition: atapi.h:319
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
unsigned char * PUCHAR
Definition: retypes.h:3
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:949
struct _IDE_REGISTERS_2 * PIDE_REGISTERS_2
BOOLEAN NTAPI FindDevices(IN PVOID HwDeviceExtension, IN BOOLEAN AtapiOnly, IN ULONG Channel)
Definition: atapi.c:1489
PVOID NTAPI ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:562
VOID NTAPI ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
Definition: scsiport.c:540
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
unsigned char BOOLEAN
ULONG InterruptMode
Definition: atapi.c:47
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3245
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortConvertUlongToPhysicalAddress(IN ULONG_PTR UlongAddress)
Definition: scsiport.c:520
#define SP_RETURN_NOT_FOUND
Definition: srb.h:513
#define SP_RETURN_FOUND
Definition: srb.h:514
VOID NTAPI ScsiPortWritePortUchar(IN PUCHAR Port, IN UCHAR Value)
Definition: scsiport.c:1531
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN PrimaryAddress
Definition: atapi.c:124
union _PCI_SLOT_NUMBER::@3636 u
struct _PCI_SLOT_NUMBER::@3636::@3637 bits
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
ULONG NTAPI ScsiPortGetBusData(IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length)
Definition: scsiport.c:549
LONG NTAPI AtapiStringCmp(PCHAR FirstStr, PCHAR SecondStr, ULONG Count)
Definition: atapi.c:6333
UCHAR NTAPI ScsiPortReadPortUchar(IN PUCHAR Port)
Definition: scsiport.c:1374
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define SP_RETURN_ERROR
Definition: srb.h:515
#define CONST
Definition: pedump.c:81
ULONG NumberChannels
Definition: atapi.c:68
struct _IDE_REGISTERS_1 * PIDE_REGISTERS_1

Referenced by DriverEntry().

◆ AtapiFindPCIController()

ULONG NTAPI AtapiFindPCIController ( IN PVOID  HwDeviceExtension,
IN PVOID  Context,
IN PVOID  BusInformation,
IN PCHAR  ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
OUT PBOOLEAN  Again 
)

Definition at line 3014 of file atapi.c.

3045 {
3046  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
3047  PULONG adapterCount = (PULONG)Context;
3048  ULONG channel = 0;
3049  static ULONG functionNumber,
3050  slotNumber,
3051  controllers;
3052  ULONG i,j;
3053  PUCHAR ioSpace;
3054  BOOLEAN atapiOnly,
3055  lastSlot,
3056  controllerFound = FALSE,
3057  deviceFound = FALSE;
3058  UCHAR statusByte;
3059 
3060  //
3061  // The following table specifies the ports to be checked when searching for
3062  // an IDE controller. A zero entry terminates the search.
3063  //
3064 
3065  CONST ULONG AdapterAddresses[5] = {0x1F0, 0x170, 0x1e8, 0x168, 0};
3066 
3067  //
3068  // The following table specifies interrupt levels corresponding to the
3069  // port addresses in the previous table.
3070  //
3071 
3072  CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0};
3073 
3074  if (!deviceExtension) {
3075  return SP_RETURN_ERROR;
3076  }
3077 
3078  //
3079  // Since scsiport will call this function first before it calls AtapiFindController
3080  // we need to bypass it if we have data installed in ConfigInfo, by the pcmcia driver.
3081  // In that case atapifindcontroller should be called first.
3082  // Instead of modifying atapi driverEntry to search of PCIBus first (now its ISA)
3083  // the check is put here.
3084  //
3085 
3086  if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart) != 0) {
3087 
3088  return AtapiFindController(HwDeviceExtension,
3089  Context,
3090  BusInformation,
3091  ArgumentString,
3092  ConfigInfo,
3093  Again);
3094  }
3095 
3096 
3097  //
3098  // Gronk PCI config space looking for the broken PCI IDE controllers that have only
3099  // one FIFO for both channels.
3100  // Don't do this. It's incorrect and nasty. It has to be done to work around these
3101  // broken parts, no other reason can justify this.
3102  //
3103 
3104  for (i = controllers; i < BROKEN_ADAPTERS; i++) {
3105 
3106  //
3107  // Determine if both channels are enabled and have devices.
3108  //
3109 
3110  lastSlot = FALSE;
3111 
3112  if (FindBrokenController(deviceExtension,
3113  (PUCHAR)BrokenAdapters[i].VendorId,
3114  BrokenAdapters[i].VendorIdLength,
3115  (PUCHAR)BrokenAdapters[i].DeviceId,
3116  BrokenAdapters[i].DeviceIdLength,
3117  &functionNumber,
3118  &slotNumber,
3119  ConfigInfo->SystemIoBusNumber,
3120  &lastSlot)) {
3121 
3122  slotNumber++;
3123  functionNumber = 0;
3124  controllerFound = TRUE;
3125 
3126  DebugPrint((1,
3127  "Found broken PCI IDE controller: VendorId %s, DeviceId %s\n",
3128  BrokenAdapters[i].VendorId,
3129  BrokenAdapters[i].DeviceId));
3130 
3131  if (AdapterAddresses[*adapterCount] != 0) {
3132 
3133  for (j = 0; j < 2; j++) {
3134 
3135  //
3136  // Get the system physical address for this IO range.
3137  //
3138 
3139  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
3140  ConfigInfo->AdapterInterfaceType,
3141  ConfigInfo->SystemIoBusNumber,
3142  ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount]),
3143  8,
3144  TRUE);
3145 
3146  //
3147  // Update the adapter count.
3148  //
3149 
3150  (*adapterCount)++;
3151 
3152  //
3153  // Check if ioSpace accessible.
3154  //
3155 
3156  if (!ioSpace) {
3157  continue;
3158  }
3159 
3160  //
3161  // Select master.
3162  //
3163 
3164  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xA0);
3165 
3166  //
3167  // Check if card at this address.
3168  //
3169 
3170  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);
3171 
3172  //
3173  // Check if identifier can be read back.
3174  //
3175 
3176  if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {
3177 
3178  DebugPrint((2,
3179  "AtapiFindPciController: Identifier read back from Master (%x)\n",
3180  statusByte));
3181 
3182 
3183  //
3184  // Select slave.
3185  //
3186 
3187  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect, 0xB0);
3188 
3189  //
3190  // See if slave is present.
3191  //
3192 
3193  ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow, 0xAA);
3194 
3195  if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {
3196 
3197  DebugPrint((2,
3198  "AtapiFindPciController: Identifier read back from Slave (%x)\n",
3199  statusByte));
3200 
3201  //
3202  //
3203  // No controller at this base address.
3204  //
3205 
3206  ScsiPortFreeDeviceBase(HwDeviceExtension,
3207  ioSpace);
3208 
3209  //
3210  // If the chip is there, but we couldn't find the primary channel, try the secondary.
3211  // If we couldn't find a secondary, who cares.
3212  //
3213 
3214  if (j == 1) {
3215 
3216  goto setStatusAndExit;
3217 
3218  } else {
3219  continue;
3220  }
3221  }
3222  }
3223 
3224  if (controllerFound) {
3225 
3226  //
3227  // Record base IO address.
3228  //
3229 
3230  deviceExtension->BaseIoAddress1[channel] = (PIDE_REGISTERS_1)(ioSpace);
3231 
3232  //
3233  // Fill in the access array information.
3234  //
3235 
3236  (*ConfigInfo->AccessRanges)[channel].RangeStart =
3237  ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]);
3238 
3239  (*ConfigInfo->AccessRanges)[channel].RangeLength = 8;
3240  (*ConfigInfo->AccessRanges)[channel].RangeInMemory = FALSE;
3241 
3242  //
3243  // Indicate the interrupt level corresponding to this IO range.
3244  //
3245 
3246  if (channel == 0) {
3247  ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1];
3248  ConfigInfo->InterruptMode = Latched;
3249  } else {
3250  ConfigInfo->BusInterruptLevel2 = InterruptLevels[*adapterCount - 1];
3251  ConfigInfo->InterruptMode2 = Latched;
3252  }
3253 
3254  //
3255  // Get the system physical address for the second IO range.
3256  //
3257 
3258  ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,
3259  ConfigInfo->AdapterInterfaceType,
3260  ConfigInfo->SystemIoBusNumber,
3261  ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1] + 0x206),
3262  1,
3263  TRUE);
3264 
3265  deviceExtension->BaseIoAddress2[channel] = (PIDE_REGISTERS_2)(ioSpace);
3266 
3267  deviceExtension->NumberChannels = 2;
3268 
3269  //
3270  // Indicate only one bus.
3271  //
3272 
3273  ConfigInfo->NumberOfBuses = 1;
3274 
3275  //
3276  // Indicate four devices can be attached to the adapter, since we
3277  // have to serialize access to the two channels.
3278  //
3279 
3280  ConfigInfo->MaximumNumberOfTargets = 4;
3281 
3282  //
3283  // Indicate maximum transfer length is 64k.
3284  //
3285 
3286  ConfigInfo->MaximumTransferLength = 0x10000;
3287 
3288  DebugPrint((1,
3289  "AtapiFindPciController: Found broken IDE at %x\n",
3290  deviceExtension->BaseIoAddress1[channel]));
3291 
3292  //
3293  // Since we will always pick up this part, and not atdisk, so indicate.
3294  //
3295 
3296  atapiOnly = FALSE;
3297 
3298  //
3299  // Save the Interrupt Mode for later use
3300  //
3301  deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
3302 
3303  //
3304  // Search for devices on this controller.
3305  //
3306 
3307  if (FindDevices(HwDeviceExtension,
3308  atapiOnly,
3309  channel++)){
3310  deviceFound = TRUE;
3311  }
3312 
3313  //
3314  // Claim primary or secondary ATA IO range.
3315  //
3316 
3317  if (*adapterCount == 1) {
3318  ConfigInfo->AtdiskPrimaryClaimed = TRUE;
3319  deviceExtension->PrimaryAddress = TRUE;
3320 
3321  } else if (*adapterCount == 2) {
3322  ConfigInfo->AtdiskSecondaryClaimed = TRUE;
3323  deviceExtension->PrimaryAddress = FALSE;
3324  }
3325  }
3326  }
3327  }
3328  }
3329 
3330 setStatusAndExit:
3331 
3332  if (lastSlot) {
3333  slotNumber = 0;
3334  functionNumber = 0;
3335  }
3336 
3337  controllers = i;
3338 
3339  if (controllerFound && deviceFound) {
3340 
3341  *Again = TRUE;
3342  return SP_RETURN_FOUND;
3343  }
3344  }
3345 
3346 
3347  //
3348  // The entire table has been searched and no adapters have been found.
3349  //
3350 
3351  *Again = FALSE;
3352 
3353  return SP_RETURN_NOT_FOUND;
3354 
3355 } // end AtapiFindPCIController()
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:949
struct _IDE_REGISTERS_2 * PIDE_REGISTERS_2
BOOLEAN NTAPI FindDevices(IN PVOID HwDeviceExtension, IN BOOLEAN AtapiOnly, IN ULONG Channel)
Definition: atapi.c:1489
PVOID NTAPI ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:562
VOID NTAPI ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
Definition: scsiport.c:540
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
ULONG NTAPI AtapiFindController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: atapi.c:2106
BOOLEAN NTAPI FindBrokenController(IN PVOID DeviceExtension, IN PUCHAR VendorID, IN ULONG VendorIDLength, IN PUCHAR DeviceID, IN ULONG DeviceIDLength, IN OUT PULONG FunctionNumber, IN OUT PULONG SlotNumber, IN ULONG BusNumber, OUT PBOOLEAN LastSlot)
Definition: atapi.c:2575
unsigned char BOOLEAN
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
ULONG InterruptMode
Definition: atapi.c:47
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortConvertUlongToPhysicalAddress(IN ULONG_PTR UlongAddress)
Definition: scsiport.c:520
#define SP_RETURN_NOT_FOUND
Definition: srb.h:513
#define SP_RETURN_FOUND
Definition: srb.h:514
VOID NTAPI ScsiPortWritePortUchar(IN PUCHAR Port, IN UCHAR Value)
Definition: scsiport.c:1531
BROKEN_CONTROLLER_INFORMATION const BrokenAdapters[]
Definition: atapi.h:305
#define BROKEN_ADAPTERS
Definition: atapi.h:310
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN PrimaryAddress
Definition: atapi.c:124
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
unsigned int * PULONG
Definition: retypes.h:1
UCHAR NTAPI ScsiPortReadPortUchar(IN PUCHAR Port)
Definition: scsiport.c:1374
unsigned int ULONG
Definition: retypes.h:1
#define SP_RETURN_ERROR
Definition: srb.h:515
struct @577 controllers[XUSER_MAX_COUNT]
#define CONST
Definition: pedump.c:81
ULONG NumberChannels
Definition: atapi.c:68
struct _IDE_REGISTERS_1 * PIDE_REGISTERS_1

Referenced by DriverEntry().

◆ AtapiHexToString() [1/2]

VOID NTAPI AtapiHexToString ( ULONG  Value,
PCHAR Buffer 
)

◆ AtapiHexToString() [2/2]

VOID NTAPI AtapiHexToString ( IN ULONG  Value,
IN OUT PCHAR Buffer 
)

Definition at line 6396 of file atapi.c.

6400 {
6401  PCHAR string;
6402  PCHAR firstdig;
6403  CHAR temp;
6404  ULONG i;
6405  USHORT digval;
6406 
6407  string = *Buffer;
6408 
6409  firstdig = string;
6410 
6411  for (i = 0; i < 4; i++) {
6412  digval = (USHORT)(Value % 16);
6413  Value /= 16;
6414 
6415  //
6416  // convert to ascii and store. Note this will create
6417  // the buffer with the digits reversed.
6418  //
6419 
6420  if (digval > 9) {
6421  *string++ = (char) (digval - 10 + 'a');
6422  } else {
6423  *string++ = (char) (digval + '0');
6424  }
6425 
6426  }
6427 
6428  //
6429  // Reverse the digits.
6430  //
6431 
6432  *string-- = '\0';
6433 
6434  do {
6435  temp = *string;
6436  *string = *firstdig;
6437  *firstdig = temp;
6438  --string;
6439  ++firstdig;
6440  } while (firstdig < string);
6441 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
signed char * PCHAR
Definition: retypes.h:7
char CHAR
Definition: xmlstorage.h:175
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned char
Definition: typeof.h:29
char string[160]
Definition: util.h:11
unsigned short USHORT
Definition: pedump.c:61
static calc_node_t temp
Definition: rpn_ieee.c:38
unsigned int ULONG
Definition: retypes.h:1
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34

◆ AtapiHwInitialize()

BOOLEAN NTAPI AtapiHwInitialize ( IN PVOID  HwDeviceExtension)

Definition at line 1282 of file atapi.c.

1301 {
1302  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
1303  PIDE_REGISTERS_1 baseIoAddress;
1304  ULONG i;
1305  UCHAR statusByte, errorByte;
1306 
1307 
1308  for (i = 0; i < 4; i++) {
1309  if (deviceExtension->DeviceFlags[i] & DFLAGS_DEVICE_PRESENT) {
1310 
1311  if (!(deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE)) {
1312 
1313  //
1314  // Enable media status notification
1315  //
1316 
1317  baseIoAddress = deviceExtension->BaseIoAddress1[i >> 1];
1318 
1319  IdeMediaStatus(TRUE,HwDeviceExtension,i);
1320 
1321  //
1322  // If supported, setup Multi-block transfers.
1323  //
1324  if (deviceExtension->MaximumBlockXfer[i]) {
1325 
1326  //
1327  // Select the device.
1328  //
1329 
1330  ScsiPortWritePortUchar(&baseIoAddress->DriveSelect,
1331  (UCHAR)(((i & 0x1) << 4) | 0xA0));
1332 
1333  //
1334  // Setup sector count to reflect the # of blocks.
1335  //
1336 
1337  ScsiPortWritePortUchar(&baseIoAddress->BlockCount,
1338  deviceExtension->MaximumBlockXfer[i]);
1339 
1340  //
1341  // Issue the command.
1342  //
1343 
1344  ScsiPortWritePortUchar(&baseIoAddress->Command,
1346 
1347  //
1348  // Wait for busy to drop.
1349  //
1350 
1351  WaitOnBaseBusy(baseIoAddress,statusByte);
1352 
1353  //
1354  // Check for errors. Reset the value to 0 (disable MultiBlock) if the
1355  // command was aborted.
1356  //
1357 
1358  if (statusByte & IDE_STATUS_ERROR) {
1359 
1360  //
1361  // Read the error register.
1362  //
1363 
1364  errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress + 1);
1365 
1366  DebugPrint((1,
1367  "AtapiHwInitialize: Error setting multiple mode. Status %x, error byte %x\n",
1368  statusByte,
1369  errorByte));
1370  //
1371  // Adjust the devExt. value, if necessary.
1372  //
1373 
1374  deviceExtension->MaximumBlockXfer[i] = 0;
1375 
1376  } else {
1377  DebugPrint((2,
1378  "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
1379  i,
1380  deviceExtension->MaximumBlockXfer[i]));
1381  }
1382  }
1383  } else if (!(deviceExtension->DeviceFlags[i] & DFLAGS_CHANGER_INITED)){
1384 
1385  ULONG j;
1386  UCHAR vendorId[26];
1387 
1388  //
1389  // Attempt to identify any special-case devices - psuedo-atapi changers, atapi changers, etc.
1390  //
1391 
1392  for (j = 0; j < 13; j += 2) {
1393 
1394  //
1395  // Build a buffer based on the identify data.
1396  //
1397 
1398  vendorId[j] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j + 1];
1399  vendorId[j+1] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j];
1400  }
1401 
1402  if (!AtapiStringCmp ((PCHAR)vendorId, "CD-ROM CDR", 11)) {
1403 
1404  //
1405  // Inquiry string for older model had a '-', newer is '_'
1406  //
1407 
1408  if (vendorId[12] == 'C') {
1409 
1410  //
1411  // Torisan changer. Set the bit. This will be used in several places
1412  // acting like 1) a multi-lun device and 2) building the 'special' TUR's.
1413  //
1414 
1416  deviceExtension->DiscsPresent[i] = 3;
1417  }
1418  }
1419  }
1420 
1421  //
1422  // We need to get our device ready for action before
1423  // returning from this function
1424  //
1425  // According to the atapi spec 2.5 or 2.6, an atapi device
1426  // clears its status BSY bit when it is ready for atapi commands.
1427  // However, some devices (Panasonic SQ-TC500N) are still
1428  // not ready even when the status BSY is clear. They don't react
1429  // to atapi commands.
1430  //
1431  // Since there is really no other indication that tells us
1432  // the drive is really ready for action. We are going to check BSY
1433  // is clear and then just wait for an arbitrary amount of time!
1434  //
1435  if (deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE) {
1436  //PIDE_REGISTERS_1 baseIoAddress1 = deviceExtension->BaseIoAddress1[i >> 1];
1437  PIDE_REGISTERS_2 baseIoAddress2 = deviceExtension->BaseIoAddress2[i >> 1];
1438  ULONG waitCount;
1439 
1440  // have to get out of the loop sometime!
1441  // 10000 * 100us = 1000,000us = 1000ms = 1s
1442  waitCount = 10000;
1443  GetStatus(baseIoAddress2, statusByte);
1444  while ((statusByte & IDE_STATUS_BUSY) && waitCount) {
1445  //
1446  // Wait for Busy to drop.
1447  //
1449  GetStatus(baseIoAddress2, statusByte);
1450  waitCount--;
1451  }
1452 
1453  // 5000 * 100us = 500,000us = 500ms = 0.5s
1454  waitCount = 5000;
1455  do {
1457  } while (waitCount--);
1458  }
1459  }
1460  }
1461 
1462  return TRUE;
1463 
1464 } // end AtapiHwInitialize()
signed char * PCHAR
Definition: retypes.h:7
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define TRUE
Definition: types.h:120
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
UCHAR DriveSelect
Definition: atapi.h:22
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
UCHAR BlockCount
Definition: atapi.h:18
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define WaitOnBaseBusy(BaseIoAddress, Status)
Definition: atapi.h:373
USHORT DeviceFlags[4]
Definition: atapi.c:86
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
UCHAR Command
Definition: atapi.h:23
USHORT ModelNumber[20]
Definition: atapi.h:262
#define DFLAGS_CHANGER_INITED
Definition: atapi.h:50
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
ULONG DiscsPresent[4]
Definition: atapi.c:80
UCHAR MaximumBlockXfer[4]
Definition: atapi.c:93
VOID NTAPI ScsiPortWritePortUchar(IN PUCHAR Port, IN UCHAR Value)
Definition: scsiport.c:1531
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID NTAPI IdeMediaStatus(IN BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG Channel)
#define IDE_COMMAND_SET_MULTIPLE
Definition: atapi.h:113
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
#define IDE_STATUS_BUSY
Definition: atapi.h:132
LONG NTAPI AtapiStringCmp(PCHAR FirstStr, PCHAR SecondStr, ULONG Count)
Definition: atapi.c:6333
#define DFLAGS_SANYO_ATAPI_CHANGER
Definition: atapi.h:49
UCHAR NTAPI ScsiPortReadPortUchar(IN PUCHAR Port)
Definition: scsiport.c:1374
IDENTIFY_DATA2 IdentifyData[4]
Definition: atapi.c:146
#define IDE_STATUS_ERROR
Definition: atapi.h:125
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI ScsiPortStallExecution(IN ULONG Delay)
Definition: scsiport.c:1473

Referenced by AtapiResetController(), and DriverEntry().

◆ AtapiHwInitializeChanger()

VOID NTAPI AtapiHwInitializeChanger ( IN PVOID  HwDeviceExtension,
IN ULONG  TargetId,
IN PMECHANICAL_STATUS_INFORMATION_HEADER  MechanismStatus 
)

Definition at line 1469 of file atapi.c.

1473 {
1474  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
1475 
1476  if (MechanismStatus) {
1477  deviceExtension->DiscsPresent[TargetId] = MechanismStatus->NumberAvailableSlots;
1478  if (deviceExtension->DiscsPresent[TargetId] > 1) {
1479  deviceExtension->DeviceFlags[TargetId] |= DFLAGS_ATAPI_CHANGER;
1480  }
1481  }
1482  return;
1483 }
#define DFLAGS_ATAPI_CHANGER
Definition: atapi.h:48
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
USHORT DeviceFlags[4]
Definition: atapi.c:86
ULONG DiscsPresent[4]
Definition: atapi.c:80

Referenced by AtapiInterrupt(), and AtapiSendCommand().

◆ AtapiInterrupt()

BOOLEAN NTAPI AtapiInterrupt ( IN PVOID  HwDeviceExtension)

Definition at line 3484 of file atapi.c.

3504 {
3505  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
3506  PSCSI_REQUEST_BLOCK srb = deviceExtension->CurrentSrb;
3507  PATAPI_REGISTERS_1 baseIoAddress1;
3508  PATAPI_REGISTERS_2 baseIoAddress2;
3509  ULONG wordCount = 0, wordsThisInterrupt = 256;
3510  ULONG status;
3511  ULONG i;
3512  UCHAR statusByte,interruptReason;
3513  BOOLEAN atapiDev = FALSE;
3514 
3515  if (srb) {
3516  baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[srb->TargetId >> 1];
3517  baseIoAddress2 = (PATAPI_REGISTERS_2)deviceExtension->BaseIoAddress2[srb->TargetId >> 1];
3518  } else {
3519  DebugPrint((2,
3520  "AtapiInterrupt: CurrentSrb is NULL\n"));
3521  //
3522  // We can only support one ATAPI IDE master on Carolina, so find
3523  // the base address that is non NULL and clear its interrupt before
3524  // returning.
3525  //
3526 
3527 #ifdef _PPC_
3528 
3529  if ((PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0] != NULL) {
3530  baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0];
3531  } else {
3532  baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[1];
3533  }
3534 
3535  GetBaseStatus(baseIoAddress1, statusByte);
3536 #else
3537 
3538  if (deviceExtension->InterruptMode == LevelSensitive) {
3539  if (deviceExtension->BaseIoAddress1[0] != NULL) {
3540  baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0];
3541  GetBaseStatus(baseIoAddress1, statusByte);
3542  }
3543  if (deviceExtension->BaseIoAddress1[1] != NULL) {
3544  baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[1];
3545  GetBaseStatus(baseIoAddress1, statusByte);
3546  }
3547  }
3548 #endif
3549  return FALSE;
3550  }
3551 
3552  if (!(deviceExtension->ExpectingInterrupt)) {
3553 
3554  DebugPrint((3,
3555  "AtapiInterrupt: Unexpected interrupt.\n"));
3556  return FALSE;
3557  }
3558 
3559  //
3560  // Clear interrupt by reading status.
3561  //
3562 
3563  GetBaseStatus(baseIoAddress1, statusByte);
3564 
3565  DebugPrint((3,
3566  "AtapiInterrupt: Entered with status (%x)\n",
3567  statusByte));
3568 
3569 
3570  if (statusByte & IDE_STATUS_BUSY) {
3571  if (deviceExtension->DriverMustPoll) {
3572 
3573  //
3574  // Crashdump is polling and we got caught with busy asserted.
3575  // Just go away, and we will be polled again shortly.
3576  //
3577 
3578  DebugPrint((3,
3579  "AtapiInterrupt: Hit BUSY while polling during crashdump.\n"));
3580 
3581  return TRUE;
3582  }
3583 
3584  //
3585  // Ensure BUSY is non-asserted.
3586  //
3587 
3588  for (i = 0; i < 10; i++) {
3589 
3590  GetBaseStatus(baseIoAddress1, statusByte);
3591  if (!(statusByte & IDE_STATUS_BUSY)) {
3592  break;
3593  }
3594  ScsiPortStallExecution(5000);
3595  }
3596 
3597  if (i == 10) {
3598 
3599  DebugPrint((2,
3600  "AtapiInterrupt: BUSY on entry. Status %x, Base IO %x\n",
3601  statusByte,
3602  baseIoAddress1));
3603 
3605  HwDeviceExtension,
3606  AtapiCallBack,
3607  500);
3608  return TRUE;
3609  }
3610  }
3611 
3612 
3613  //
3614  // Check for error conditions.
3615  //
3616 
3617  if (statusByte & IDE_STATUS_ERROR) {
3618 
3619  if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
3620 
3621  //
3622  // Fail this request.
3623  //
3624 
3626  goto CompleteRequest;
3627  }
3628  }
3629 
3630  //
3631  // check reason for this interrupt.
3632  //
3633 
3634  if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3635 
3636  interruptReason = (ScsiPortReadPortUchar(&baseIoAddress1->InterruptReason) & 0x3);
3637  atapiDev = TRUE;
3638  wordsThisInterrupt = 256;
3639 
3640  } else {
3641 
3642  if (statusByte & IDE_STATUS_DRQ) {
3643 
3644  if (deviceExtension->MaximumBlockXfer[srb->TargetId]) {
3645  wordsThisInterrupt = 256 * deviceExtension->MaximumBlockXfer[srb->TargetId];
3646 
3647  }
3648 
3649  if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
3650 
3651  interruptReason = 0x2;
3652 
3653  } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
3654  interruptReason = 0x0;
3655 
3656  } else {
3658  goto CompleteRequest;
3659  }
3660 
3661  } else if (statusByte & IDE_STATUS_BUSY) {
3662 
3663  return FALSE;
3664 
3665  } else {
3666 
3667  if (deviceExtension->WordsLeft) {
3668 
3669  ULONG k;
3670 
3671  //
3672  // Funky behaviour seen with PCI IDE (not all, just one).
3673  // The ISR hits with DRQ low, but comes up later.
3674  //
3675 
3676  for (k = 0; k < 5000; k++) {
3677  GetStatus(baseIoAddress2,statusByte);
3678  if (!(statusByte & IDE_STATUS_DRQ)) {
3680  } else {
3681  break;
3682  }
3683  }
3684 
3685  if (k == 5000) {
3686 
3687  //
3688  // reset the controller.
3689  //
3690 
3691  DebugPrint((1,
3692  "AtapiInterrupt: Resetting due to DRQ not up. Status %x, Base IO %x\n",
3693  statusByte,
3694  baseIoAddress1));
3695 
3696  AtapiResetController(HwDeviceExtension,srb->PathId);
3697  return TRUE;
3698  } else {
3699 
3700  interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x2 : 0x0;
3701  }
3702 
3703  } else {
3704 
3705  //
3706  // Command complete - verify, write, or the SMART enable/disable.
3707  //
3708  // Also get_media_status
3709 
3710  interruptReason = 0x3;
3711  }
3712  }
3713  }
3714 
3715  if (interruptReason == 0x1 && (statusByte & IDE_STATUS_DRQ)) {
3716 
3717  //
3718  // Write the packet.
3719  //
3720 
3721  DebugPrint((2,
3722  "AtapiInterrupt: Writing Atapi packet.\n"));
3723 
3724  //
3725  // Send CDB to device.
3726  //
3727 
3728  WriteBuffer(baseIoAddress1,
3729  (PUSHORT)srb->Cdb,
3730  6);
3731 
3732  return TRUE;
3733 
3734  } else if (interruptReason == 0x0 && (statusByte & IDE_STATUS_DRQ)) {
3735 
3736  //
3737  // Write the data.
3738  //
3739 
3740  if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3741 
3742  //
3743  // Pick up bytes to transfer and convert to words.
3744  //
3745 
3746  wordCount =
3747  ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);
3748 
3749  wordCount |=
3750  ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh) << 8;
3751 
3752  //
3753  // Covert bytes to words.
3754  //
3755 
3756  wordCount >>= 1;
3757 
3758  if (wordCount != deviceExtension->WordsLeft) {
3759  DebugPrint((3,
3760  "AtapiInterrupt: %d words requested; %d words xferred\n",
3761  deviceExtension->WordsLeft,
3762  wordCount));
3763  }
3764 
3765  //
3766  // Verify this makes sense.
3767  //
3768 
3769  if (wordCount > deviceExtension->WordsLeft) {
3770  wordCount = deviceExtension->WordsLeft;
3771  }
3772 
3773  } else {
3774 
3775  //
3776  // IDE path. Check if words left is at least 256.
3777  //
3778 
3779  if (deviceExtension->WordsLeft < wordsThisInterrupt) {
3780 
3781  //
3782  // Transfer only words requested.
3783  //
3784 
3785  wordCount = deviceExtension->WordsLeft;
3786 
3787  } else {
3788 
3789  //
3790  // Transfer next block.
3791  //
3792 
3793  wordCount = wordsThisInterrupt;
3794  }
3795  }
3796 
3797  //
3798  // Ensure that this is a write command.
3799  //
3800 
3801  if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
3802 
3803  DebugPrint((3,
3804  "AtapiInterrupt: Write interrupt\n"));
3805 
3806  WaitOnBusy(baseIoAddress2,statusByte);
3807 
3808  if (atapiDev || !deviceExtension->DWordIO) {
3809 
3810  WriteBuffer(baseIoAddress1,
3811  deviceExtension->DataBuffer,
3812  wordCount);
3813  } else {
3814 
3815  PIDE_REGISTERS_3 address3 = (PIDE_REGISTERS_3)baseIoAddress1;
3816 
3817  WriteBuffer2(address3,
3818  (PULONG)(deviceExtension->DataBuffer),
3819  wordCount / 2);
3820  }
3821  } else {
3822 
3823  DebugPrint((1,
3824  "AtapiInterrupt: Int reason %x, but srb is for a write %x.\n",
3825  interruptReason,
3826  srb));
3827 
3828  //
3829  // Fail this request.
3830  //
3831 
3833  goto CompleteRequest;
3834  }
3835 
3836 
3837  //
3838  // Advance data buffer pointer and bytes left.
3839  //
3840 
3841  deviceExtension->DataBuffer += wordCount;
3842  deviceExtension->WordsLeft -= wordCount;
3843 
3844  return TRUE;
3845 
3846  } else if (interruptReason == 0x2 && (statusByte & IDE_STATUS_DRQ)) {
3847 
3848 
3849  if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3850 
3851  //
3852  // Pick up bytes to transfer and convert to words.
3853  //
3854 
3855  wordCount =
3856  ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);
3857 
3858  wordCount |=
3859  ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh) << 8;
3860 
3861  //
3862  // Covert bytes to words.
3863  //
3864 
3865  wordCount >>= 1;
3866 
3867  if (wordCount != deviceExtension->WordsLeft) {
3868  DebugPrint((3,
3869  "AtapiInterrupt: %d words requested; %d words xferred\n",
3870  deviceExtension->WordsLeft,
3871  wordCount));
3872  }
3873 
3874  //
3875  // Verify this makes sense.
3876  //
3877 
3878  if (wordCount > deviceExtension->WordsLeft) {
3879  wordCount = deviceExtension->WordsLeft;
3880  }
3881 
3882  } else {
3883 
3884  //
3885  // Check if words left is at least 256.
3886  //
3887 
3888  if (deviceExtension->WordsLeft < wordsThisInterrupt) {
3889 
3890  //
3891  // Transfer only words requested.
3892  //
3893 
3894  wordCount = deviceExtension->WordsLeft;
3895 
3896  } else {
3897 
3898  //
3899  // Transfer next block.
3900  //
3901 
3902  wordCount = wordsThisInterrupt;
3903  }
3904  }
3905 
3906  //
3907  // Ensure that this is a read command.
3908  //
3909 
3910  if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
3911 
3912  DebugPrint((3,
3913  "AtapiInterrupt: Read interrupt\n"));
3914 
3915  WaitOnBusy(baseIoAddress2,statusByte);
3916 
3917  if (atapiDev || !deviceExtension->DWordIO) {
3918  ReadBuffer(baseIoAddress1,
3919  deviceExtension->DataBuffer,
3920  wordCount);
3921 
3922  } else {
3923  PIDE_REGISTERS_3 address3 = (PIDE_REGISTERS_3)baseIoAddress1;
3924 
3925  ReadBuffer2(address3,
3926  (PULONG)(deviceExtension->DataBuffer),
3927  wordCount / 2);
3928  }
3929  } else {
3930 
3931  DebugPrint((1,
3932  "AtapiInterrupt: Int reason %x, but srb is for a read %x.\n",
3933  interruptReason,
3934  srb));
3935 
3936  //
3937  // Fail this request.
3938  //
3939 
3941  goto CompleteRequest;
3942  }
3943 
3944  //
3945  // Translate ATAPI data back to SCSI data if needed
3946  //
3947 
3948  if (srb->Cdb[0] == ATAPI_MODE_SENSE &&
3949  deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3950 
3951  //
3952  //convert and adjust the wordCount
3953  //
3954 
3955  wordCount -= Atapi2Scsi(srb, (char *)deviceExtension->DataBuffer,
3956  wordCount << 1);
3957  }
3958  //
3959  // Advance data buffer pointer and bytes left.
3960  //
3961 
3962  deviceExtension->DataBuffer += wordCount;
3963  deviceExtension->WordsLeft -= wordCount;
3964 
3965  //
3966  // Check for read command complete.
3967  //
3968 
3969  if (deviceExtension->WordsLeft == 0) {
3970 
3971  if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3972 
3973  //
3974  // Work around to make many atapi devices return correct sector size
3975  // of 2048. Also certain devices will have sector count == 0x00, check
3976  // for that also.
3977  //
3978 
3979  if ((srb->Cdb[0] == 0x25) &&
3980  ((deviceExtension->IdentifyData[srb->TargetId].GeneralConfiguration >> 8) & 0x1f) == 0x05) {
3981 
3982  deviceExtension->DataBuffer -= wordCount;
3983  if (deviceExtension->DataBuffer[0] == 0x00) {
3984 
3985  *((ULONG *) &(deviceExtension->DataBuffer[0])) = 0xFFFFFF7F;
3986 
3987  }
3988 
3989  *((ULONG *) &(deviceExtension->DataBuffer[2])) = 0x00080000;
3990  deviceExtension->DataBuffer += wordCount;
3991  }
3992  } else {
3993 
3994  //
3995  // Completion for IDE drives.
3996  //
3997 
3998 
3999  if (deviceExtension->WordsLeft) {
4000 
4002 
4003  } else {
4004 
4006 
4007  }
4008 
4009  goto CompleteRequest;
4010 
4011  }
4012  }
4013 
4014  return TRUE;
4015 
4016  } else if (interruptReason == 0x3 && !(statusByte & IDE_STATUS_DRQ)) {
4017 
4018  //
4019  // Command complete.
4020  //
4021 
4022  if (deviceExtension->WordsLeft) {
4023 
4025 
4026  } else {
4027 
4029 
4030  }
4031 
4033 
4034  //
4035  // Check and see if we are processing our secret (mechanism status/request sense) srb
4036  //
4037  if (deviceExtension->OriginalSrb) {
4038 
4039  ULONG srbStatus;
4040 
4041  if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
4042 
4043  if (status == SRB_STATUS_SUCCESS) {
4044  // Bingo!!
4045  AtapiHwInitializeChanger (HwDeviceExtension,
4046  srb->TargetId,
4048 
4049  // Get ready to issue the original srb
4050  srb = deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
4051  deviceExtension->OriginalSrb = NULL;
4052 
4053  } else {
4054  // failed! Get the sense key and maybe try again
4055  srb = deviceExtension->CurrentSrb = BuildRequestSenseSrb (
4056  HwDeviceExtension,
4057  deviceExtension->OriginalSrb->PathId,
4058  deviceExtension->OriginalSrb->TargetId);
4059  }
4060 
4061  srbStatus = AtapiSendCommand(HwDeviceExtension, deviceExtension->CurrentSrb);
4062  if (srbStatus == SRB_STATUS_PENDING) {
4063  return TRUE;
4064  }
4065 
4066  } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE)
4067 
4068  PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
4069 
4071  // Check to see if we at least get minimum number of bytes
4072  if ((srb->DataTransferLength - deviceExtension->WordsLeft) >
4073  (FIELD_OFFSET (SENSE_DATA, AdditionalSenseLength) + sizeof(senseData->AdditionalSenseLength))) {
4075  }
4076  }
4077 
4078  if (status == SRB_STATUS_SUCCESS) {
4079  if ((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) &&
4080  deviceExtension->MechStatusRetryCount) {
4081 
4082  // The sense key doesn't say the last request is illegal, so try again
4083  deviceExtension->MechStatusRetryCount--;
4084  srb = deviceExtension->CurrentSrb = BuildMechanismStatusSrb (
4085  HwDeviceExtension,
4086  deviceExtension->OriginalSrb->PathId,
4087  deviceExtension->OriginalSrb->TargetId);
4088  } else {
4089 
4090  // last request was illegal. No point trying again
4091 
4092  AtapiHwInitializeChanger (HwDeviceExtension,
4093  srb->TargetId,
4095 
4096  // Get ready to issue the original srb
4097  srb = deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
4098  deviceExtension->OriginalSrb = NULL;
4099  }
4100 
4101  srbStatus = AtapiSendCommand(HwDeviceExtension, deviceExtension->CurrentSrb);
4102  if (srbStatus == SRB_STATUS_PENDING) {
4103  return TRUE;
4104  }
4105  }
4106  }
4107 
4108  // If we get here, it means AtapiSendCommand() has failed
4109  // Can't recover. Pretend the original srb has failed and complete it.
4110 
4111  if (deviceExtension->OriginalSrb) {
4112  AtapiHwInitializeChanger (HwDeviceExtension,
4113  srb->TargetId,
4115  srb = deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
4116  deviceExtension->OriginalSrb = NULL;
4117  }
4118 
4119  // fake an error and read no data
4121  srb->ScsiStatus = 0;
4122  deviceExtension->DataBuffer = srb->DataBuffer;
4123  deviceExtension->WordsLeft = srb->DataTransferLength;
4124  deviceExtension->RDP = FALSE;
4125 
4126  } else if (status == SRB_STATUS_ERROR) {
4127 
4128  //
4129  // Map error to specific SRB status and handle request sense.
4130  //
4131 
4132  status = MapError(deviceExtension,
4133  srb);
4134 
4135  deviceExtension->RDP = FALSE;
4136 
4137  } else {
4138 
4139  //
4140  // Wait for busy to drop.
4141  //
4142 
4143  for (i = 0; i < 30; i++) {
4144  GetStatus(baseIoAddress2,statusByte);
4145  if (!(statusByte & IDE_STATUS_BUSY)) {
4146  break;
4147  }
4149  }
4150 
4151  if (i == 30) {
4152 
4153  //
4154  // reset the controller.
4155  //
4156 
4157  DebugPrint((1,
4158  "AtapiInterrupt: Resetting due to BSY still up - %x. Base Io %x\n",
4159  statusByte,
4160  baseIoAddress1));
4161  AtapiResetController(HwDeviceExtension,srb->PathId);
4162  return TRUE;
4163  }
4164 
4165  //
4166  // Check to see if DRQ is still up.
4167  //
4168 
4169  if (statusByte & IDE_STATUS_DRQ) {
4170 
4171  for (i = 0; i < 500; i++) {
4172  GetStatus(baseIoAddress2,statusByte);
4173  if (!(statusByte & IDE_STATUS_DRQ)) {
4174  break;
4175  }
4177 
4178  }
4179 
4180  if (i == 500) {
4181 
4182  //
4183  // reset the controller.
4184  //
4185 
4186  DebugPrint((1,
4187  "AtapiInterrupt: Resetting due to DRQ still up - %x\n",
4188  statusByte));
4189  AtapiResetController(HwDeviceExtension,srb->PathId);
4190  return TRUE;
4191  }
4192 
4193  }
4194  }
4195 
4196 
4197  //
4198  // Clear interrupt expecting flag.
4199  //
4200 
4201  deviceExtension->ExpectingInterrupt = FALSE;
4202 
4203  //
4204  // Sanity check that there is a current request.
4205  //
4206 
4207  if (srb != NULL) {
4208 
4209  //
4210  // Set status in SRB.
4211  //
4212 
4213  srb->SrbStatus = (UCHAR)status;
4214 
4215  //
4216  // Check for underflow.
4217  //
4218 
4219  if (deviceExtension->WordsLeft) {
4220 
4221  //
4222  // Subtract out residual words and update if filemark hit,
4223  // setmark hit , end of data, end of media...
4224  //
4225 
4226  if (!(deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_TAPE_DEVICE)) {
4228  srb->DataTransferLength -= deviceExtension->WordsLeft;
4229  } else {
4230  srb->DataTransferLength = 0;
4231  }
4232  } else {
4233  srb->DataTransferLength -= deviceExtension->WordsLeft;
4234  }
4235  }
4236 
4237  if (srb->Function != SRB_FUNCTION_IO_CONTROL) {
4238 
4239  //
4240  // Indicate command complete.
4241  //
4242 
4243  if (!(deviceExtension->RDP)) {
4245  deviceExtension,
4246  srb);
4247 
4248  }
4249  } else {
4250 
4251  PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
4252  UCHAR error = 0;
4253 
4254  if (status != SRB_STATUS_SUCCESS) {
4255  error = ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1);
4256  }
4257 
4258  //
4259  // Build the SMART status block depending upon the completion status.
4260  //
4261 
4262  cmdOutParameters->cBufferSize = wordCount;
4263  cmdOutParameters->DriverStatus.bDriverError = (error) ? SMART_IDE_ERROR : 0;
4264  cmdOutParameters->DriverStatus.bIDEError = error;
4265 
4266  //
4267  // If the sub-command is return smart status, jam the value from cylinder low and high, into the
4268  // data buffer.
4269  //
4270 
4271  if (deviceExtension->SmartCommand == RETURN_SMART_STATUS) {
4272  cmdOutParameters->bBuffer[0] = RETURN_SMART_STATUS;
4273  cmdOutParameters->bBuffer[1] = ScsiPortReadPortUchar(&baseIoAddress1->InterruptReason);
4274  cmdOutParameters->bBuffer[2] = ScsiPortReadPortUchar(&baseIoAddress1->Unused1);
4275  cmdOutParameters->bBuffer[3] = ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);
4276  cmdOutParameters->bBuffer[4] = ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh);
4277  cmdOutParameters->bBuffer[5] = ScsiPortReadPortUchar(&baseIoAddress1->DriveSelect);
4278  cmdOutParameters->bBuffer[6] = SMART_CMD;
4279  cmdOutParameters->cBufferSize = 8;
4280  }
4281 
4282  //
4283  // Indicate command complete.
4284  //
4285 
4287  deviceExtension,
4288  srb);
4289 
4290  }
4291 
4292  } else {
4293 
4294  DebugPrint((1,
4295  "AtapiInterrupt: No SRB!\n"));
4296  }
4297 
4298  //
4299  // Indicate ready for next request.
4300  //
4301 
4302  if (!(deviceExtension->RDP)) {
4303 
4304  //
4305  // Clear current SRB.
4306  //
4307 
4308  deviceExtension->CurrentSrb = NULL;
4309 
4311  deviceExtension,
4312  NULL);
4313  } else {
4314 
4316  HwDeviceExtension,
4317  AtapiCallBack,
4318  2000);
4319  }
4320 
4321  return TRUE;
4322 
4323  } else {
4324 
4325  //
4326  // Unexpected int.
4327  //
4328 
4329  DebugPrint((3,
4330  "AtapiInterrupt: Unexpected interrupt. InterruptReason %x. Status %x.\n",
4331  interruptReason,
4332  statusByte));
4333  return FALSE;
4334  }
4335 
4336  return TRUE;
4337 
4338 } // end AtapiInterrupt()
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb(IN PVOID HwDeviceExtension, IN ULONG PathId, IN ULONG TargetId)
Definition: atapi.c:6447
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
UCHAR SenseKey
Definition: cdrw_hw.h:1167
USHORT GeneralConfiguration
Definition: atapi.h:249
#define TRUE
Definition: types.h:120
ULONG SrbFlags
Definition: srb.h:252
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
BOOLEAN NTAPI AtapiResetController(IN PVOID HwDeviceExtension, IN ULONG PathId)
Definition: atapi.c:733
UCHAR Cdb[16]
Definition: srb.h:271
#define error(str)
Definition: mkdosfs.c:1605
GLint x0
Definition: linetemp.h:95
UCHAR SmartCommand
Definition: atapi.c:131
#define IDE_STATUS_DRQ
Definition: atapi.h:128
PVOID DataBuffer
Definition: srb.h:255
ULONG MechStatusRetryCount
Definition: atapi.c:155
#define WriteBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:354
unsigned char * PUCHAR
Definition: retypes.h:3
DRIVERSTATUS DriverStatus
Definition: helper.h:26
ULONG DataTransferLength
Definition: srb.h:253
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
BOOLEAN DWordIO
Definition: atapi.c:117
#define SMART_IDE_ERROR
Definition: ntdddisk.h:590
PUSHORT DataBuffer
Definition: atapi.c:53
UCHAR ByteCountHigh
Definition: atapi.h:171
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
UCHAR SrbStatus
Definition: srb.h:243
UCHAR DriveSelect
Definition: atapi.h:172
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
#define SRB_STATUS_ERROR
Definition: srb.h:336
USHORT DeviceFlags[4]
Definition: atapi.c:86
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ReadBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:349
VOID NTAPI AtapiCallBack(IN PVOID HwDeviceExtension)
Definition: atapi.c:3411
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
UCHAR ScsiStatus
Definition: srb.h:244
#define SRB_STATUS_PENDING
Definition: srb.h:332
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
UCHAR bDriverError
Definition: helper.h:2
UCHAR InterruptReason
Definition: atapi.h:168
UCHAR TargetId
Definition: srb.h:246
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:637
UCHAR ByteCountLow
Definition: atapi.h:170
ULONG InterruptMode
Definition: atapi.c:47
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
ULONG NTAPI MapError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:905
if(!(yy_init))
Definition: macro.lex.yy.c:714
UCHAR Function
Definition: srb.h:242
UCHAR MaximumBlockXfer[4]
Definition: atapi.c:93
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1308
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:309
struct _IDE_REGISTERS_3 * PIDE_REGISTERS_3
UCHAR bIDEError
Definition: helper.h:3
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define SMART_CMD
Definition: helper.h:21
#define SCSIOP_MECHANISM_STATUS
Definition: cdrw_hw.h:966
BOOLEAN DriverMustPoll
Definition: atapi.c:111
struct _ATAPI_REGISTERS_1 * PATAPI_REGISTERS_1
UCHAR PathId
Definition: srb.h:245
struct _SRB_IO_CONTROL SRB_IO_CONTROL
#define IDE_STATUS_BUSY
Definition: atapi.h:132
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb(IN PVOID HwDeviceExtension, IN ULONG PathId, IN ULONG TargetId)
Definition: atapi.c:6493
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
PSCSI_REQUEST_BLOCK OriginalSrb
Definition: atapi.c:151
ULONG NTAPI AtapiSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:4981
UCHAR NTAPI ScsiPortReadPortUchar(IN PUCHAR Port)
Definition: scsiport.c:1374
IDENTIFY_DATA2 IdentifyData[4]
Definition: atapi.c:146
UCHAR bBuffer[1]
Definition: helper.h:27
struct _SENSE_DATA * PSENSE_DATA
VOID NTAPI AtapiHwInitializeChanger(IN PVOID HwDeviceExtension, IN ULONG TargetId, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
Definition: atapi.c:1469
PSCSI_REQUEST_BLOCK CurrentSrb
Definition: atapi.c:28
#define IDE_STATUS_ERROR
Definition: atapi.h:125
unsigned int ULONG
Definition: retypes.h:1
#define WaitOnBusy(BaseIoAddress, Status)
Definition: atapi.h:359
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
ULONG NTAPI Atapi2Scsi(IN PSCSI_REQUEST_BLOCK Srb, IN char *DataBuffer, IN ULONG ByteCount)
Definition: atapi.c:3360
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
static SERVICE_STATUS status
Definition: service.c:31
int k
Definition: mpi.c:3369
#define ATAPI_MODE_SENSE
Definition: atapi.h:61
unsigned short * PUSHORT
Definition: retypes.h:2
#define WriteBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:344
ULONG cBufferSize
Definition: helper.h:25
VOID NTAPI ScsiPortStallExecution(IN ULONG Delay)
Definition: scsiport.c:1473
Definition: ps.c:97

Referenced by AtapiCallBack(), and DriverEntry().

◆ AtapiParseArgumentString()

ULONG NTAPI AtapiParseArgumentString ( IN PCHAR  String,
IN PCHAR  KeyWord 
)

Definition at line 1852 of file atapi.c.

1876 {
1877  PCHAR cptr;
1878  PCHAR kptr;
1879  ULONG value;
1880  ULONG stringLength = 0;
1881  ULONG keyWordLength = 0;
1882  ULONG index;
1883 
1884  if (!String) {
1885  return 0;
1886  }
1887  if (!KeyWord) {
1888  return 0;
1889  }
1890 
1891  //
1892  // Calculate the string length and lower case all characters.
1893  //
1894 
1895  cptr = String;
1896  while (*cptr) {
1897  if (*cptr >= 'A' && *cptr <= 'Z') {
1898  *cptr = *cptr + ('a' - 'A');
1899  }
1900  cptr++;
1901  stringLength++;
1902  }
1903 
1904  //
1905  // Calculate the keyword length and lower case all characters.
1906  //
1907 
1908  cptr = KeyWord;
1909  while (*cptr) {
1910 
1911  if (*cptr >= 'A' && *cptr <= 'Z') {
1912  *cptr = *cptr + ('a' - 'A');
1913  }
1914  cptr++;
1915  keyWordLength++;
1916  }
1917 
1918  if (keyWordLength > stringLength) {
1919 
1920  //
1921  // Can't possibly have a match.
1922  //
1923 
1924  return 0;
1925  }
1926 
1927  //
1928  // Now setup and start the compare.
1929  //
1930 
1931  cptr = String;
1932 
1933 ContinueSearch:
1934 
1935  //
1936  // The input string may start with white space. Skip it.
1937  //
1938 
1939  while (*cptr == ' ' || *cptr == '\t') {
1940  cptr++;
1941  }
1942 
1943  if (*cptr == '\0') {
1944 
1945  //
1946  // end of string.
1947  //
1948 
1949  return 0;
1950  }
1951 
1952  kptr = KeyWord;
1953  while (*cptr++ == *kptr++) {
1954 
1955  if (*(cptr - 1) == '\0') {
1956 
1957  //
1958  // end of string
1959  //
1960 
1961  return 0;
1962  }
1963  }
1964 
1965  if (*(kptr - 1) == '\0') {
1966 
1967  //
1968  // May have a match backup and check for blank or equals.
1969  //
1970 
1971  cptr--;
1972  while (*cptr == ' ' || *cptr == '\t') {
1973  cptr++;
1974  }
1975 
1976  //
1977  // Found a match. Make sure there is an equals.
1978  //
1979 
1980  if (*cptr != '=') {
1981 
1982  //
1983  // Not a match so move to the next semicolon.
1984  //
1985 
1986  while (*cptr) {
1987  if (*cptr++ == ';') {
1988  goto ContinueSearch;
1989  }
1990  }
1991  return 0;
1992  }
1993 
1994  //
1995  // Skip the equals sign.
1996  //
1997 
1998  cptr++;
1999 
2000  //
2001  // Skip white space.
2002  //
2003 
2004  while ((*cptr == ' ') || (*cptr == '\t')) {
2005  cptr++;
2006  }
2007 
2008  if (*cptr == '\0') {
2009 
2010  //
2011  // Early end of string, return not found
2012  //
2013 
2014  return 0;
2015  }
2016 
2017  if (*cptr == ';') {
2018 
2019  //
2020  // This isn't it either.
2021  //
2022 
2023  cptr++;
2024  goto ContinueSearch;
2025  }
2026 
2027  value = 0;
2028  if ((*cptr == '0') && (*(cptr + 1) == 'x')) {
2029 
2030  //
2031  // Value is in Hex. Skip the "0x"
2032  //
2033 
2034  cptr += 2;
2035  for (index = 0; *(cptr + index); index++) {
2036 
2037  if (*(cptr + index) == ' ' ||
2038  *(cptr + index) == '\t' ||
2039  *(cptr + index) == ';') {
2040  break;
2041  }
2042 
2043  if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
2044  value = (16 * value) + (*(cptr + index) - '0');
2045  } else {
2046  if ((*(cptr + index) >= 'a') && (*(cptr + index) <= 'f')) {
2047  value = (16 * value) + (*(cptr + index) - 'a' + 10);
2048  } else {
2049 
2050  //
2051  // Syntax error, return not found.
2052  //
2053  return 0;
2054  }
2055  }
2056  }
2057  } else {
2058 
2059  //
2060  // Value is in Decimal.
2061  //
2062 
2063  for (index = 0; *(cptr + index); index++) {
2064 
2065  if (*(cptr + index) == ' ' ||
2066  *(cptr + index) == '\t' ||
2067  *(cptr + index) == ';') {
2068  break;
2069  }
2070 
2071  if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
2072  value = (10 * value) + (*(cptr + index) - '0');
2073  } else {
2074 
2075  //
2076  // Syntax error return not found.
2077  //
2078  return 0;
2079  }
2080  }
2081  }
2082 
2083  return value;
2084  } else {
2085 
2086  //
2087  // Not a match check for ';' to continue search.
2088  //
2089 
2090  while (*cptr) {
2091  if (*cptr++ == ';') {
2092  goto ContinueSearch;
2093  }
2094  }
2095 
2096  return 0;
2097  }
2098 }
signed char * PCHAR
Definition: retypes.h:7
static WCHAR String[]
Definition: stringtable.c:55
GLuint index
Definition: glext.h:6031
#define index(s, c)
Definition: various.h:29
GLsizei const GLfloat * value
Definition: glext.h:6069
unsigned int ULONG
Definition: retypes.h:1

Referenced by AtapiFindController(), AtapiFindIsaController(), and AtapiReadArgumentString().

◆ AtapiResetController()

BOOLEAN NTAPI AtapiResetController ( IN PVOID  HwDeviceExtension,
IN ULONG  PathId 
)

Definition at line 733 of file atapi.c.

755 {
756  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
757  ULONG numberChannels = deviceExtension->NumberChannels;
758  PIDE_REGISTERS_1 baseIoAddress1;
759  PIDE_REGISTERS_2 baseIoAddress2;
760  BOOLEAN result = FALSE;
761  ULONG i,j;
762  UCHAR statusByte;
763 
764  DebugPrint((2,"AtapiResetController: Reset IDE\n"));
765 
766  //
767  // Check and see if we are processing an internal srb
768  //
769  if (deviceExtension->OriginalSrb) {
770  deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
771  deviceExtension->OriginalSrb = NULL;
772  }
773 
774  //
775  // Check if request is in progress.
776  //
777 
778  if (deviceExtension->CurrentSrb) {
779 
780  //
781  // Complete outstanding request with SRB_STATUS_BUS_RESET.
782  //
783 
784  ScsiPortCompleteRequest(deviceExtension,
785  deviceExtension->CurrentSrb->PathId,
786  deviceExtension->CurrentSrb->TargetId,
787  deviceExtension->CurrentSrb->Lun,
789 
790  //
791  // Clear request tracking fields.
792  //
793 
794  deviceExtension->CurrentSrb = NULL;
795  deviceExtension->WordsLeft = 0;
796  deviceExtension->DataBuffer = NULL;
797 
798  //
799  // Indicate ready for next request.
800  //
801 
803  deviceExtension,
804  NULL);
805  }
806 
807  //
808  // Clear expecting interrupt flag.
809  //
810 
811  deviceExtension->ExpectingInterrupt = FALSE;
812  deviceExtension->RDP = FALSE;
813 
814  for (j = 0; j < numberChannels; j++) {
815 
816  baseIoAddress1 = deviceExtension->BaseIoAddress1[j];
817  baseIoAddress2 = deviceExtension->BaseIoAddress2[j];
818 
819  //
820  // Do special processing for ATAPI and IDE disk devices.
821  //
822 
823  for (i = 0; i < 2; i++) {
824 
825  //
826  // Check if device present.
827  //
828 
829  if (deviceExtension->DeviceFlags[i + (j * 2)] & DFLAGS_DEVICE_PRESENT) {
830 
831  //
832  // Check for ATAPI disk.
833  //
834 
835  if (deviceExtension->DeviceFlags[i + (j * 2)] & DFLAGS_ATAPI_DEVICE) {
836 
837  //
838  // Issue soft reset and issue identify.
839  //
840 
841  GetStatus(baseIoAddress2,statusByte);
842  DebugPrint((1,
843  "AtapiResetController: Status before Atapi reset (%x).\n",
844  statusByte));
845 
846  AtapiSoftReset(baseIoAddress1,i);
847 
848  GetStatus(baseIoAddress2,statusByte);
849 
850  if (statusByte == 0x0) {
851 
852  IssueIdentify(HwDeviceExtension,
853  i,
854  j,
856  } else {
857 
858  DebugPrint((1,
859  "AtapiResetController: Status after soft reset %x\n",
860  statusByte));
861  }
862 
863  } else {
864 
865  //
866  // Write IDE reset controller bits.
867  //
868 
869  IdeHardReset(baseIoAddress2,result);
870 
871  if (!result) {
872  return FALSE;
873  }
874 
875  //
876  // Set disk geometry parameters.
877  //
878 
879  if (!SetDriveParameters(HwDeviceExtension,
880  i,
881  j)) {
882 
883  DebugPrint((1,
884  "AtapiResetController: SetDriveParameters failed\n"));
885  }
886  }
887  }
888  }
889  }
890 
891  //
892  // Call the HwInitialize routine to setup multi-block.
893  //
894 
895  AtapiHwInitialize(HwDeviceExtension);
896 
897  return TRUE;
898 
899 } // end AtapiResetController()
#define SRB_STATUS_BUS_RESET
Definition: srb.h:345
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
#define TRUE
Definition: types.h:120
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
GLint x0
Definition: linetemp.h:95
#define IdeHardReset(BaseIoAddress, result)
Definition: atapi.h:432
PUSHORT DataBuffer
Definition: atapi.c:53
VOID NTAPI ScsiPortCompleteRequest(IN PVOID HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR SrbStatus)
Definition: scsiport.c:498
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
USHORT DeviceFlags[4]
Definition: atapi.c:86
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
BOOLEAN NTAPI SetDriveParameters(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel)
Definition: atapi.c:636
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
UCHAR TargetId
Definition: srb.h:246
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BOOLEAN NTAPI IssueIdentify(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR Command)
Definition: atapi.c:251
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1308
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
UCHAR PathId
Definition: srb.h:245
BOOLEAN NTAPI AtapiHwInitialize(IN PVOID HwDeviceExtension)
Definition: atapi.c:1282
PSCSI_REQUEST_BLOCK OriginalSrb
Definition: atapi.c:151
PSCSI_REQUEST_BLOCK CurrentSrb
Definition: atapi.c:28
unsigned int ULONG
Definition: retypes.h:1
GLuint64EXT * result
Definition: glext.h:11304
ULONG NumberChannels
Definition: atapi.c:68

Referenced by AtapiInterrupt(), AtapiStartIo(), and DriverEntry().

◆ AtapiSendCommand()

ULONG NTAPI AtapiSendCommand ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 4981 of file atapi.c.

5002 {
5003  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
5004  PATAPI_REGISTERS_1 baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[Srb->TargetId >> 1];
5005  PATAPI_REGISTERS_2 baseIoAddress2 = (PATAPI_REGISTERS_2)deviceExtension->BaseIoAddress2[Srb->TargetId >> 1];
5006  ULONG i;
5007  ULONG flags;
5008  UCHAR statusByte,byteCountLow,byteCountHigh;
5009 
5010  //
5011  // We need to know how many platters our atapi cd-rom device might have.
5012  // Before anyone tries to send a srb to our target for the first time,
5013  // we must "secretly" send down a separate mechanism status srb in order to
5014  // initialize our device extension changer data. That's how we know how
5015  // many platters our target has.
5016  //
5017  if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_CHANGER_INITED) &&
5018  !deviceExtension->OriginalSrb) {
5019 
5020  ULONG srbStatus;
5021 
5022  //
5023  // Set this flag now. If the device hangs on the mech. status
5024  // command, we will not have the change to set it.
5025  //
5026  deviceExtension->DeviceFlags[Srb->TargetId] |= DFLAGS_CHANGER_INITED;
5027 
5028  deviceExtension->MechStatusRetryCount = 3;
5029  deviceExtension->CurrentSrb = BuildMechanismStatusSrb (
5030  HwDeviceExtension,
5031  Srb->PathId,
5032  Srb->TargetId);
5033  deviceExtension->OriginalSrb = Srb;
5034 
5035  srbStatus = AtapiSendCommand(HwDeviceExtension, deviceExtension->CurrentSrb);
5036  if (srbStatus == SRB_STATUS_PENDING) {
5037  return srbStatus;
5038  } else {
5039  deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
5040  deviceExtension->OriginalSrb = NULL;
5041  AtapiHwInitializeChanger (HwDeviceExtension,
5042  Srb->TargetId,
5044  // fall out
5045  }
5046  }
5047 
5048  DebugPrint((2,
5049  "AtapiSendCommand: Command %x to TargetId %d lun %d\n",
5050  Srb->Cdb[0],
5051  Srb->TargetId,
5052  Srb->Lun));
5053 
5054  //
5055  // Make sure command is to ATAPI device.
5056  //
5057 
5058  flags = deviceExtension->DeviceFlags[Srb->TargetId];
5060  if ((Srb->Lun) > (deviceExtension->DiscsPresent[Srb->TargetId] - 1)) {
5061 
5062  //
5063  // Indicate no device found at this address.
5064  //
5065 
5067  }
5068  } else if (Srb->Lun > 0) {
5070  }
5071 
5072  if (!(flags & DFLAGS_ATAPI_DEVICE)) {
5074  }
5075 
5076  //
5077  // Select device 0 or 1.
5078  //
5079 
5080  ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,
5081  (UCHAR)(((Srb->TargetId & 0x1) << 4) | 0xA0));
5082 
5083  //
5084  // Verify that controller is ready for next command.
5085  //
5086 
5087  GetStatus(baseIoAddress2,statusByte);
5088 
5089  DebugPrint((2,
5090  "AtapiSendCommand: Entered with status %x\n",
5091  statusByte));
5092 
5093  if (statusByte & IDE_STATUS_BUSY) {
5094  DebugPrint((1,
5095  "AtapiSendCommand: Device busy (%x)\n",
5096  statusByte));
5097  return SRB_STATUS_BUSY;
5098 
5099  }
5100 
5101  if (statusByte & IDE_STATUS_ERROR) {
5102  if (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
5103 
5104  DebugPrint((1,
5105  "AtapiSendCommand: Error on entry: (%x)\n",
5106  statusByte));
5107  //
5108  // Read the error reg. to clear it and fail this request.
5109  //
5110 
5111  return MapError(deviceExtension,
5112  Srb);
5113  }
5114  }
5115 
5116  //
5117  // If a tape drive has doesn't have DSC set and the last command is restrictive, don't send
5118  // the next command. See discussion of Restrictive Delayed Process commands in QIC-157.
5119  //
5120 
5121  if ((!(statusByte & IDE_STATUS_DSC)) &&
5122  (flags & DFLAGS_TAPE_DEVICE) && deviceExtension->RDP) {
5123  ScsiPortStallExecution(1000);
5124  DebugPrint((2,"AtapiSendCommand: DSC not set. %x\n",statusByte));
5125  return SRB_STATUS_BUSY;
5126  }
5127 
5128  if (IS_RDP(Srb->Cdb[0])) {
5129 
5130  deviceExtension->RDP = TRUE;
5131 
5132  DebugPrint((3,
5133  "AtapiSendCommand: %x mapped as DSC restrictive\n",
5134  Srb->Cdb[0]));
5135 
5136  } else {
5137 
5138  deviceExtension->RDP = FALSE;
5139  }
5140 
5141  if (statusByte & IDE_STATUS_DRQ) {
5142 
5143  DebugPrint((1,
5144  "AtapiSendCommand: Entered with status (%x). Attempting to recover.\n",
5145  statusByte));
5146  //
5147  // Try to drain the data that one preliminary device thinks that it has
5148  // to transfer. Hopefully this random assertion of DRQ will not be present
5149  // in production devices.
5150  //
5151 
5152  for (i = 0; i < 0x10000; i++) {
5153 
5154  GetStatus(baseIoAddress2, statusByte);
5155 
5156  if (statusByte & IDE_STATUS_DRQ) {
5157 
5158  ScsiPortReadPortUshort(&baseIoAddress1->Data);
5159 
5160  } else {
5161 
5162  break;
5163  }
5164  }
5165 
5166  if (i == 0x10000) {
5167 
5168  DebugPrint((1,
5169  "AtapiSendCommand: DRQ still asserted.Status (%x)\n",
5170  statusByte));
5171 
5172  AtapiSoftReset(baseIoAddress1,Srb->TargetId);
5173 
5174  DebugPrint((1,
5175  "AtapiSendCommand: Issued soft reset to Atapi device. \n"));
5176 
5177  //
5178  // Re-initialize Atapi device.
5179  //
5180 
5181  IssueIdentify(HwDeviceExtension,
5182  (Srb->TargetId & 0x1),
5183  (Srb->TargetId >> 1),
5185 
5186  //
5187  // Inform the port driver that the bus has been reset.
5188  //
5189 
5190  ScsiPortNotification(ResetDetected, HwDeviceExtension, 0);
5191 
5192  //
5193  // Clean up device extension fields that AtapiStartIo won't.
5194  //
5195 
5196  deviceExtension->ExpectingInterrupt = FALSE;
5197  deviceExtension->RDP = FALSE;
5198 
5199  return SRB_STATUS_BUS_RESET;
5200 
5201  }
5202  }
5203 
5205 
5206  //
5207  // As the cdrom driver sets the LUN field in the cdb, it must be removed.
5208  //
5209 
5210  Srb->Cdb[1] &= ~0xE0;
5211 
5212  if ((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY) && (flags & DFLAGS_SANYO_ATAPI_CHANGER)) {
5213 
5214  //
5215  // Torisan changer. TUR's are overloaded to be platter switches.
5216  //
5217 
5218  Srb->Cdb[7] = Srb->Lun;
5219 
5220  }
5221  }
5222 
5223  //
5224  // Convert SCSI to ATAPI commands if needed
5225  //
5226 
5227  switch (Srb->Cdb[0]) {
5228  case SCSIOP_MODE_SENSE:
5229  case SCSIOP_MODE_SELECT:
5230  case SCSIOP_FORMAT_UNIT:
5231  if (!(flags & DFLAGS_TAPE_DEVICE)) {
5232  Scsi2Atapi(Srb);
5233  }
5234 
5235  break;
5236  }
5237 
5238  //
5239  // Set data buffer pointer and words left.
5240  //
5241 
5242  deviceExtension->DataBuffer = (PUSHORT)Srb->DataBuffer;
5243  deviceExtension->WordsLeft = Srb->DataTransferLength / 2;
5244 
5245  WaitOnBusy(baseIoAddress2,statusByte);
5246 
5247  //
5248  // Write transfer byte count to registers.
5249  //
5250 
5251  byteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF);
5252  byteCountHigh = (UCHAR)(Srb->DataTransferLength >> 8);
5253 
5254  if (Srb->DataTransferLength >= 0x10000) {
5255  byteCountLow = byteCountHigh = 0xFF;
5256  }
5257 
5258  ScsiPortWritePortUchar(&baseIoAddress1->ByteCountLow,byteCountLow);
5259  ScsiPortWritePortUchar(&baseIoAddress1->ByteCountHigh, byteCountHigh);
5260 
5261  ScsiPortWritePortUchar((PUCHAR)baseIoAddress1 + 1,0);
5262 
5263 
5264  if (flags & DFLAGS_INT_DRQ) {
5265 
5266  //
5267  // This device interrupts when ready to receive the packet.
5268  //
5269  // Write ATAPI packet command.
5270  //
5271 
5272  ScsiPortWritePortUchar(&baseIoAddress1->Command,
5274 
5275  DebugPrint((3,
5276  "AtapiSendCommand: Wait for int. to send packet. Status (%x)\n",
5277  statusByte));
5278 
5279  deviceExtension->ExpectingInterrupt = TRUE;
5280 
5281  return SRB_STATUS_PENDING;
5282 
5283  } else {
5284 
5285  //
5286  // Write ATAPI packet command.
5287  //
5288 
5289  ScsiPortWritePortUchar(&baseIoAddress1->Command,
5291 
5292  //
5293  // Wait for DRQ.
5294  //
5295 
5296  WaitOnBusy(baseIoAddress2, statusByte);
5297  WaitForDrq(baseIoAddress2, statusByte);
5298 
5299  if (!(statusByte & IDE_STATUS_DRQ)) {
5300 
5301  DebugPrint((1,
5302  "AtapiSendCommand: DRQ never asserted (%x)\n",
5303  statusByte));
5304  return SRB_STATUS_ERROR;
5305  }
5306  }
5307 
5308  //
5309  // Need to read status register.
5310  //
5311 
5312  GetBaseStatus(baseIoAddress1, statusByte);
5313 
5314  //
5315  // Send CDB to device.
5316  //
5317 
5318  WaitOnBusy(baseIoAddress2,statusByte);
5319 
5320  WriteBuffer(baseIoAddress1,
5321  (PUSHORT)Srb->Cdb,
5322  6);
5323 
5324  //
5325  // Indicate expecting an interrupt and wait for it.
5326  //
5327 
5328  deviceExtension->ExpectingInterrupt = TRUE;
5329 
5330  return SRB_STATUS_PENDING;
5331 
5332 } // end AtapiSendCommand()
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb(IN PVOID HwDeviceExtension, IN ULONG PathId, IN ULONG TargetId)
Definition: atapi.c:6447
#define DFLAGS_INT_DRQ
Definition: atapi.h:43
#define SRB_STATUS_BUS_RESET
Definition: srb.h:345
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
#define TRUE
Definition: types.h:120
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
#define IDE_STATUS_DRQ
Definition: atapi.h:128
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define DFLAGS_ATAPI_CHANGER
Definition: atapi.h:48
ULONG MechStatusRetryCount
Definition: atapi.c:155
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
PUSHORT DataBuffer
Definition: atapi.c:53
UCHAR ByteCountHigh
Definition: atapi.h:171
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
UCHAR DriveSelect
Definition: atapi.h:172
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
#define SRB_STATUS_ERROR
Definition: srb.h:336
USHORT DeviceFlags[4]
Definition: atapi.c:86
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
#define SRB_STATUS_PENDING
Definition: srb.h:332
smooth NULL
Definition: ftsmooth.c:416
#define DFLAGS_CHANGER_INITED
Definition: atapi.h:50
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define SRB_STATUS_BUSY
Definition: srb.h:337
UCHAR ByteCountLow
Definition: atapi.h:170
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
ULONG NTAPI MapError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:905
BOOLEAN NTAPI IssueIdentify(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR Command)
Definition: atapi.c:251
ULONG DiscsPresent[4]
Definition: atapi.c:80
GLbitfield flags
Definition: glext.h:7161
VOID NTAPI ScsiPortWritePortUchar(IN PUCHAR Port, IN UCHAR Value)
Definition: scsiport.c:1531
#define WaitForDrq(BaseIoAddress, Status)
Definition: atapi.h:387
unsigned char UCHAR
Definition: xmlstorage.h:181
USHORT NTAPI ScsiPortReadPortUshort(IN PUSHORT Port)
Definition: scsiport.c:1392
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1308
#define SCSIOP_FORMAT_UNIT
Definition: cdrw_hw.h:871
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
struct _ATAPI_REGISTERS_1 * PATAPI_REGISTERS_1
#define IS_RDP(OperationCode)
Definition: atapi.h:453
#define IDE_STATUS_BUSY
Definition: atapi.h:132
#define DFLAGS_SANYO_ATAPI_CHANGER
Definition: atapi.h:49
PSCSI_REQUEST_BLOCK OriginalSrb
Definition: atapi.c:151
VOID NTAPI Scsi2Atapi(IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:4913
ULONG NTAPI AtapiSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:4981
VOID NTAPI AtapiHwInitializeChanger(IN PVOID HwDeviceExtension, IN ULONG TargetId, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
Definition: atapi.c:1469
PSCSI_REQUEST_BLOCK CurrentSrb
Definition: atapi.c:28
#define IDE_STATUS_ERROR
Definition: atapi.h:125
unsigned int ULONG
Definition: retypes.h:1
#define WaitOnBusy(BaseIoAddress, Status)
Definition: atapi.h:359
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
#define IDE_STATUS_DSC
Definition: atapi.h:129
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
unsigned short * PUSHORT
Definition: retypes.h:2
#define WriteBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:344
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
VOID NTAPI ScsiPortStallExecution(IN ULONG Delay)
Definition: scsiport.c:1473

Referenced by AtapiInterrupt(), and AtapiStartIo().

◆ AtapiStartIo()

BOOLEAN NTAPI AtapiStartIo ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 5811 of file atapi.c.

5834 {
5835  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
5836  ULONG status;
5837 
5838  //
5839  // Determine which function.
5840  //
5841 
5842  switch (Srb->Function) {
5843 
5845 
5846  //
5847  // Sanity check. Only one request can be outstanding on a
5848  // controller.
5849  //
5850 
5851  if (deviceExtension->CurrentSrb) {
5852 
5853  DebugPrint((1,
5854  "AtapiStartIo: Already have a request!\n"));
5855  Srb->SrbStatus = SRB_STATUS_BUSY;
5857  deviceExtension,
5858  Srb);
5859  return FALSE;
5860  }
5861 
5862  //
5863  // Indicate that a request is active on the controller.
5864  //
5865 
5866  deviceExtension->CurrentSrb = Srb;
5867 
5868  //
5869  // Send command to device.
5870  //
5871 
5872  if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
5873 
5874  status = AtapiSendCommand(HwDeviceExtension,
5875  Srb);
5876 
5877  } else if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) {
5878 
5879  status = IdeSendCommand(HwDeviceExtension,
5880  Srb);
5881  } else {
5882 
5884  }
5885 
5886  break;
5887 
5889 
5890  //
5891  // Verify that SRB to abort is still outstanding.
5892  //
5893 
5894  if (!deviceExtension->CurrentSrb) {
5895 
5896  DebugPrint((1, "AtapiStartIo: SRB to abort already completed\n"));
5897 
5898  //
5899  // Complete abort SRB.
5900  //
5901 
5903 
5904  break;
5905  }
5906 
5907  //
5908  // Abort function indicates that a request timed out.
5909  // Call reset routine. Card will only be reset if
5910  // status indicates something is wrong.
5911  // Fall through to reset code.
5912  //
5913 
5915 
5916  //
5917  // Reset Atapi and SCSI bus.
5918  //
5919 
5920  DebugPrint((1, "AtapiStartIo: Reset bus request received\n"));
5921 
5922  if (!AtapiResetController(deviceExtension,
5923  Srb->PathId)) {
5924 
5925  DebugPrint((1,"AtapiStartIo: Reset bus failed\n"));
5926 
5927  //
5928  // Log reset failure.
5929  //
5930 
5932  HwDeviceExtension,
5933  NULL,
5934  0,
5935  0,
5936  0,
5938  5 << 8
5939  );
5940 
5942 
5943  } else {
5944 
5946  }
5947 
5948  break;
5949 
5951 
5952  if (deviceExtension->CurrentSrb) {
5953 
5954  DebugPrint((1,
5955  "AtapiStartIo: Already have a request!\n"));
5956  Srb->SrbStatus = SRB_STATUS_BUSY;
5958  deviceExtension,
5959  Srb);
5960  return FALSE;
5961  }
5962 
5963  //
5964  // Indicate that a request is active on the controller.
5965  //
5966 
5967  deviceExtension->CurrentSrb = Srb;
5968 
5969  if (AtapiStringCmp( (PCHAR)((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,"SCSIDISK",strlen("SCSIDISK"))) {
5970 
5971  DebugPrint((1,
5972  "AtapiStartIo: IoControl signature incorrect. Send %s, expected %s\n",
5973  ((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,
5974  "SCSIDISK"));
5975 
5977  break;
5978  }
5979 
5980  switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
5981 
5983 
5984  PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
5985  UCHAR deviceNumber;
5986 
5987  //
5988  // Version and revision per SMART 1.03
5989  //
5990 
5991  versionParameters->bVersion = 1;
5992  versionParameters->bRevision = 1;
5993  versionParameters->bReserved = 0;
5994 
5995  //
5996  // Indicate that support for IDE IDENTIFY, ATAPI IDENTIFY and SMART commands.
5997  //
5998 
5999  versionParameters->fCapabilities = (CAP_ATA_ID_CMD | CAP_ATAPI_ID_CMD | CAP_SMART_CMD);
6000 
6001  //
6002  // This is done because of how the IOCTL_SCSI_MINIPORT
6003  // determines 'targetid's'. Disk.sys places the real target id value
6004  // in the DeviceMap field. Once we do some parameter checking, the value passed
6005  // back to the application will be determined.
6006  //
6007 
6008  deviceNumber = versionParameters->bIDEDeviceMap;
6009 
6010  if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) ||
6011  (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE)) {
6012 
6014  break;
6015  }
6016 
6017  //
6018  // NOTE: This will only set the bit
6019  // corresponding to this drive's target id.
6020  // The bit mask is as follows:
6021  //
6022  // Sec Pri
6023  // S M S M
6024  // 3 2 1 0
6025  //
6026 
6027  if (deviceExtension->NumberChannels == 1) {
6028  if (deviceExtension->PrimaryAddress) {
6029  deviceNumber = 1 << Srb->TargetId;
6030  } else {
6031  deviceNumber = 4 << Srb->TargetId;
6032  }
6033  } else {
6034  deviceNumber = 1 << Srb->TargetId;
6035  }
6036 
6037  versionParameters->bIDEDeviceMap = deviceNumber;
6038 
6040  break;
6041  }
6042 
6044 
6045  PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6046  SENDCMDINPARAMS cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6047  ULONG i;
6048  UCHAR targetId;
6049 
6050 
6051  if (cmdInParameters.irDriveRegs.bCommandReg == ID_CMD) {
6052 
6053  //
6054  // Extract the target.
6055  //
6056 
6057  targetId = cmdInParameters.bDriveNumber;
6058 
6059  if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) ||
6060  (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE)) {
6061 
6063  break;
6064  }
6065 
6066  //
6067  // Zero the output buffer
6068  //
6069 
6070  for (i = 0; i < (sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1); i++) {
6071  ((PUCHAR)cmdOutParameters)[i] = 0;
6072  }
6073 
6074  //
6075  // Build status block.
6076  //
6077 
6078  cmdOutParameters->cBufferSize = IDENTIFY_BUFFER_SIZE;
6079  cmdOutParameters->DriverStatus.bDriverError = 0;
6080  cmdOutParameters->DriverStatus.bIDEError = 0;
6081 
6082  //
6083  // Extract the identify data from the device extension.
6084  //
6085 
6086  ScsiPortMoveMemory (cmdOutParameters->bBuffer, &deviceExtension->IdentifyData[targetId], IDENTIFY_DATA_SIZE);
6087 
6089 
6090 
6091  } else {
6093  }
6094  break;
6095  }
6096 
6105 
6106  status = IdeSendSmartCommand(HwDeviceExtension,Srb);
6107  break;
6108 
6109  default :
6110 
6112  break;
6113 
6114  }
6115 
6116  break;
6117 
6118  default:
6119 
6120  //
6121  // Indicate unsupported command.
6122  //
6123 
6125 
6126  break;
6127 
6128  } // end switch
6129 
6130  //
6131  // Check if command complete.
6132  //
6133 
6134  if (status != SRB_STATUS_PENDING) {
6135 
6136  DebugPrint((2,
6137  "AtapiStartIo: Srb %x complete with status %x\n",
6138  Srb,
6139  status));
6140 
6141  //
6142  // Clear current SRB.
6143  //
6144 
6145  deviceExtension->CurrentSrb = NULL;
6146 
6147  //
6148  // Set status in SRB.
6149  //
6150 
6151  Srb->SrbStatus = (UCHAR)status;
6152 
6153  //
6154  // Indicate command complete.
6155  //
6156 
6158  deviceExtension,
6159  Srb);
6160 
6161  //
6162  // Indicate ready for next request.
6163  //
6164 
6166  deviceExtension,
6167  NULL);
6168  }
6169 
6170  return TRUE;
6171 
6172 } // end AtapiStartIo()
signed char * PCHAR
Definition: retypes.h:7
#define SRB_STATUS_INVALID_REQUEST
Definition: srb.h:338
#define IDENTIFY_DATA_SIZE
Definition: atapi.h:280
#define TRUE
Definition: types.h:120
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS
Definition: cdrw_hw.h:1459
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
BOOLEAN NTAPI AtapiResetController(IN PVOID HwDeviceExtension, IN ULONG PathId)
Definition: atapi.c:733
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define SRB_STATUS_ABORT_FAILED
Definition: srb.h:335
unsigned char * PUCHAR
Definition: retypes.h:3
DRIVERSTATUS DriverStatus
Definition: helper.h:26
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
#define IDENTIFY_BUFFER_SIZE
Definition: ntdddisk.h:616
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define SRB_STATUS_ERROR
Definition: srb.h:336
USHORT DeviceFlags[4]
Definition: atapi.c:86
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE
Definition: cdrw_hw.h:1464
#define SP_INTERNAL_ADAPTER_ERROR
Definition: srb.h:501
struct _GETVERSIONINPARAMS * PGETVERSIONINPARAMS
#define SRB_STATUS_PENDING
Definition: srb.h:332
smooth NULL
Definition: ftsmooth.c:416
UCHAR bDriverError
Definition: helper.h:2
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS
Definition: cdrw_hw.h:1460
#define SRB_STATUS_BUSY
Definition: srb.h:337
#define CAP_SMART_CMD
Definition: ntdddisk.h:547
#define ID_CMD
Definition: helper.h:20
ULONG NTAPI IdeSendSmartCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:4343
#define CAP_ATA_ID_CMD
Definition: ntdddisk.h:545
IDEREGS irDriveRegs
Definition: helper.h:32
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS
Definition: cdrw_hw.h:1466
#define IOCTL_SCSI_MINIPORT_RETURN_STATUS
Definition: cdrw_hw.h:1463
UCHAR bCommandReg
Definition: helper.h:15
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART
Definition: cdrw_hw.h:1461
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES
Definition: cdrw_hw.h:1465
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN PrimaryAddress
Definition: atapi.c:124
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1308
#define CAP_ATAPI_ID_CMD
Definition: ntdddisk.h:546
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:309
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
#define SRB_FUNCTION_RESET_BUS
Definition: srb.h:318
UCHAR bIDEError
Definition: helper.h:3
ULONG NTAPI IdeSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:5336
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define SRB_FUNCTION_ABORT_COMMAND
Definition: srb.h:316
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
struct _SRB_IO_CONTROL SRB_IO_CONTROL
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
LONG NTAPI AtapiStringCmp(PCHAR FirstStr, PCHAR SecondStr, ULONG Count)
Definition: atapi.c:6333
#define IOCTL_SCSI_MINIPORT_SMART_VERSION
Definition: cdrw_hw.h:1457
ULONG NTAPI AtapiSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:4981
IDENTIFY_DATA2 IdentifyData[4]
Definition: atapi.c:146
UCHAR bBuffer[1]
Definition: helper.h:27
PSCSI_REQUEST_BLOCK CurrentSrb
Definition: atapi.c:28
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI ScsiPortLogError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb OPTIONAL, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN ULONG ErrorCode, IN ULONG UniqueId)
Definition: scsiport.c:1283
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART
Definition: cdrw_hw.h:1462
UCHAR bDriveNumber
Definition: helper.h:33
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
static SERVICE_STATUS status
Definition: service.c:31
ULONG NumberChannels
Definition: atapi.c:68
VOID NTAPI ScsiPortMoveMemory(IN PVOID WriteBuffer, IN PVOID ReadBuffer, IN ULONG Length)
Definition: scsiport.c:1298
ULONG cBufferSize
Definition: helper.h:25
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
Definition: ps.c:97

Referenced by DriverEntry().

◆ AtapiStringCmp()

LONG NTAPI AtapiStringCmp ( PCHAR  FirstStr,
PCHAR  SecondStr,
ULONG  Count 
)

Definition at line 6333 of file atapi.c.

6338 {
6339  UCHAR first ,last;
6340 
6341  if (Count) {
6342  do {
6343 
6344  //
6345  // Get next char.
6346  //
6347 
6348  first = *FirstStr++;
6349  last = *SecondStr++;
6350 
6351  if (first != last) {
6352 
6353  //
6354  // If no match, try lower-casing.
6355  //
6356 
6357  if (first>='A' && first<='Z') {
6358  first = first - 'A' + 'a';
6359  }
6360  if (last>='A' && last<='Z') {
6361  last = last - 'A' + 'a';
6362  }
6363  if (first != last) {
6364 
6365  //
6366  // No match
6367  //
6368 
6369  return first - last;
6370  }
6371  }
6372  }while (--Count && first);
6373  }
6374 
6375  return 0;
6376 }
POINT last
Definition: font.c:46
const GLint * first
Definition: glext.h:5794
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by AtapiFindNativeModeController(), AtapiHwInitialize(), AtapiHwInitialize__(), AtapiInterrupt__(), AtapiStartIo(), AtapiStartIo__(), FindBrokenController(), and IssueIdentify().

◆ AtapiZeroMemory()

VOID NTAPI AtapiZeroMemory ( IN PUCHAR  Buffer,
IN ULONG  Count 
)

Definition at line 6381 of file atapi.c.

6385 {
6386  ULONG i;
6387 
6388  for (i = 0; i < Count; i++) {
6389  Buffer[i] = 0;
6390  }
6391 }
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: bufpool.h:45
unsigned int ULONG
Definition: retypes.h:1

Referenced by BuildMechanismStatusSrb(), BuildRequestSenseSrb(), DriverEntry(), and Scsi2Atapi().

◆ BuildMechanismStatusSrb()

PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb ( IN PVOID  HwDeviceExtension,
IN ULONG  PathId,
IN ULONG  TargetId 
)

Definition at line 6447 of file atapi.c.

6452 {
6453  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
6454  PSCSI_REQUEST_BLOCK srb;
6455  PCDB cdb;
6456 
6457  srb = &deviceExtension->InternalSrb;
6458 
6459  AtapiZeroMemory((PUCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
6460 
6461  srb->PathId = (UCHAR) PathId;
6462  srb->TargetId = (UCHAR) TargetId;
6463  srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
6464  srb->Length = sizeof(SCSI_REQUEST_BLOCK);
6465 
6466  //
6467  // Set flags to disable synchronous negotiation.
6468  //
6470 
6471  //
6472  // Set timeout to 2 seconds.
6473  //
6474  srb->TimeOutValue = 4;
6475 
6476  srb->CdbLength = 6;
6477  srb->DataBuffer = &deviceExtension->MechStatusData;
6478  srb->DataTransferLength = sizeof(MECHANICAL_STATUS_INFORMATION_HEADER);
6479 
6480  //
6481  // Set CDB operation code.
6482  //
6483  cdb = (PCDB)srb->Cdb;
6484  cdb->MECH_STATUS.OperationCode = SCSIOP_MECHANISM_STATUS;
6485  cdb->MECH_STATUS.AllocationLength[1] = sizeof(MECHANICAL_STATUS_INFORMATION_HEADER);
6486 
6487  return srb;
6488 }
MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
Definition: atapi.c:153
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
struct _MECHANICAL_STATUS_INFORMATION_HEADER MECHANICAL_STATUS_INFORMATION_HEADER
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
struct _CDB::_MECH_STATUS MECH_STATUS
union _CDB * PCDB
VOID NTAPI AtapiZeroMemory(IN PUCHAR Buffer, IN ULONG Count)
Definition: atapi.c:6381
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SCSIOP_MECHANISM_STATUS
Definition: cdrw_hw.h:966
SCSI_REQUEST_BLOCK InternalSrb
Definition: atapi.c:152
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307

Referenced by AtapiInterrupt(), and AtapiSendCommand().

◆ BuildRequestSenseSrb()

PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb ( IN PVOID  HwDeviceExtension,
IN ULONG  PathId,
IN ULONG  TargetId 
)

Definition at line 6493 of file atapi.c.

6498 {
6499  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
6500  PSCSI_REQUEST_BLOCK srb;
6501  PCDB cdb;
6502 
6503  srb = &deviceExtension->InternalSrb;
6504 
6505  AtapiZeroMemory((PUCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
6506 
6507  srb->PathId = (UCHAR) PathId;
6508  srb->TargetId = (UCHAR) TargetId;
6509  srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
6510  srb->Length = sizeof(SCSI_REQUEST_BLOCK);
6511 
6512  //
6513  // Set flags to disable synchronous negotiation.
6514  //
6516 
6517  //
6518  // Set timeout to 2 seconds.
6519  //
6520  srb->TimeOutValue = 4;
6521 
6522  srb->CdbLength = 6;
6523  srb->DataBuffer = &deviceExtension->MechStatusSense;
6524  srb->DataTransferLength = sizeof(SENSE_DATA);
6525 
6526  //
6527  // Set CDB operation code.
6528  //
6529  cdb = (PCDB)srb->Cdb;
6530  cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
6531  cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
6532 
6533  return srb;
6534 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
SENSE_DATA MechStatusSense
Definition: atapi.c:154
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
unsigned char * PUCHAR
Definition: retypes.h:3
Definition: cdrw_hw.h:28
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
struct _SENSE_DATA SENSE_DATA
union _CDB * PCDB
VOID NTAPI AtapiZeroMemory(IN PUCHAR Buffer, IN ULONG Count)
Definition: atapi.c:6381
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
unsigned char UCHAR
Definition: xmlstorage.h:181
SCSI_REQUEST_BLOCK InternalSrb
Definition: atapi.c:152
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
struct _CDB::_CDB6INQUIRY CDB6INQUIRY

Referenced by AtapiInterrupt().

◆ DriverEntry()

ULONG NTAPI DriverEntry ( IN PVOID  DriverObject,
IN PVOID  Argument2 
)

Definition at line 6177 of file atapi.c.

6198 {
6199  HW_INITIALIZATION_DATA hwInitializationData;
6200  ULONG adapterCount;
6201  ULONG i;
6202  ULONG statusToReturn, newStatus;
6203 
6204  DebugPrint((1,"\n\nATAPI IDE MiniPort Driver\n"));
6205 
6206  statusToReturn = 0xffffffff;
6207 
6208  //
6209  // Zero out structure.
6210  //
6211 
6212  AtapiZeroMemory(((PUCHAR)&hwInitializationData), sizeof(HW_INITIALIZATION_DATA));
6213 
6214  //
6215  // Set size of hwInitializationData.
6216  //
6217 
6218  hwInitializationData.HwInitializationDataSize =
6219  sizeof(HW_INITIALIZATION_DATA);
6220 
6221  //
6222  // Set entry points.
6223  //
6224 
6225  hwInitializationData.HwInitialize = AtapiHwInitialize;
6226  hwInitializationData.HwResetBus = AtapiResetController;
6227  hwInitializationData.HwStartIo = AtapiStartIo;
6228  hwInitializationData.HwInterrupt = AtapiInterrupt;
6229 
6230  //
6231  // Specify size of extensions.
6232  //
6233 
6234  hwInitializationData.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
6235  hwInitializationData.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
6236 
6237  //
6238  // Indicate PIO device.
6239  //
6240 
6241  hwInitializationData.MapBuffers = TRUE;
6242 
6243  //
6244  // Native Mode Devices
6245  //
6246  for (i=0; i <NUM_NATIVE_MODE_ADAPTERS; i++) {
6247  hwInitializationData.HwFindAdapter = AtapiFindNativeModeController;
6248  hwInitializationData.NumberOfAccessRanges = 4;
6249  hwInitializationData.AdapterInterfaceType = PCIBus;
6250 
6251  hwInitializationData.VendorId = NativeModeAdapters[i].VendorId;
6252  hwInitializationData.VendorIdLength = (USHORT) NativeModeAdapters[i].VendorIdLength;
6253  hwInitializationData.DeviceId = NativeModeAdapters[i].DeviceId;
6254  hwInitializationData.DeviceIdLength = (USHORT) NativeModeAdapters[i].DeviceIdLength;
6255 
6256  newStatus = ScsiPortInitialize(DriverObject,
6257  Argument2,
6258  &hwInitializationData,
6259  (PVOID)(ULONG_PTR)i);
6260  if (newStatus < statusToReturn)
6261  statusToReturn = newStatus;
6262  }
6263 
6264  hwInitializationData.VendorId = 0;
6265  hwInitializationData.VendorIdLength = 0;
6266  hwInitializationData.DeviceId = 0;
6267  hwInitializationData.DeviceIdLength = 0;
6268 
6269  //
6270  // The adapter count is used by the find adapter routine to track how
6271  // which adapter addresses have been tested.
6272  //
6273 
6274  adapterCount = 0;
6275 
6276  hwInitializationData.HwFindAdapter = AtapiFindPCIController;
6277  hwInitializationData.NumberOfAccessRanges = 4;
6278  hwInitializationData.AdapterInterfaceType = Isa;
6279 
6280  newStatus = ScsiPortInitialize(DriverObject,
6281  Argument2,
6282  &hwInitializationData,
6283  &adapterCount);
6284  if (newStatus < statusToReturn)
6285  statusToReturn = newStatus;
6286 
6287  //
6288  // Indicate 2 access ranges and reset FindAdapter.
6289  //
6290 
6291  hwInitializationData.NumberOfAccessRanges = 2;
6292  hwInitializationData.HwFindAdapter = AtapiFindController;
6293 
6294  //
6295  // Indicate ISA bustype.
6296  //
6297 
6298  hwInitializationData.AdapterInterfaceType = Isa;
6299 
6300  //
6301  // Call initialization for ISA bustype.
6302  //
6303 
6304  newStatus = ScsiPortInitialize(DriverObject,
6305  Argument2,
6306  &hwInitializationData,
6307  &adapterCount);
6308  if (newStatus < statusToReturn)
6309  statusToReturn = newStatus;
6310 
6311  //
6312  // Set up for MCA
6313  //
6314 
6315  hwInitializationData.AdapterInterfaceType = MicroChannel;
6316  adapterCount = 0;
6317 
6318  newStatus = ScsiPortInitialize(DriverObject,
6319  Argument2,
6320  &hwInitializationData,
6321  &adapterCount);
6322  if (newStatus < statusToReturn)
6323  statusToReturn = newStatus;
6324 
6325  return statusToReturn;
6326 
6327 } // end DriverEntry()
#define TRUE
Definition: types.h:120
NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[]
Definition: atapi.h:319
BOOLEAN NTAPI AtapiResetController(IN PVOID HwDeviceExtension, IN ULONG PathId)
Definition: atapi.c:733
BOOLEAN NTAPI AtapiStartIo(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:5811
unsigned char * PUCHAR
Definition: retypes.h:3
struct _HW_INITIALIZATION_DATA HW_INITIALIZATION_DATA
#define NUM_NATIVE_MODE_ADAPTERS
Definition: atapi.h:322
uint32_t ULONG_PTR
Definition: typedefs.h:63
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG NTAPI AtapiFindNativeModeController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: atapi.c:2712
struct _HW_LU_EXTENSION HW_LU_EXTENSION
ULONG NTAPI AtapiFindController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: atapi.c:2106
ULONG NTAPI ScsiPortInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PHW_INITIALIZATION_DATA HwInitializationData, IN PVOID HwContext OPTIONAL)
Definition: scsiport.c:1117
struct _HW_DEVICE_EXTENSION HW_DEVICE_EXTENSION
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
_In_ PVOID Argument2
Definition: classpnp.h:680
VOID NTAPI AtapiZeroMemory(IN PUCHAR Buffer, IN ULONG Count)
Definition: atapi.c:6381
ULONG NTAPI AtapiFindPCIController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: atapi.c:3014
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
BOOLEAN NTAPI AtapiHwInitialize(IN PVOID HwDeviceExtension)
Definition: atapi.c:1282
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI AtapiInterrupt(IN PVOID HwDeviceExtension)
Definition: atapi.c:3484

◆ FindBrokenController()

BOOLEAN NTAPI FindBrokenController ( IN PVOID  DeviceExtension,
IN PUCHAR  VendorID,
IN ULONG  VendorIDLength,
IN PUCHAR  DeviceID,
IN ULONG  DeviceIDLength,
IN OUT PULONG  FunctionNumber,
IN OUT PULONG  SlotNumber,
IN ULONG  BusNumber,
OUT PBOOLEAN  LastSlot 
)

Definition at line 2575 of file atapi.c.

2600 {
2601  ULONG pciBuffer;
2602  ULONG slotNumber;
2603  ULONG functionNumber;
2604  PCI_SLOT_NUMBER slotData;
2605  PPCI_COMMON_CONFIG pciData;
2606  UCHAR vendorString[5];
2607  UCHAR deviceString[5];
2608  PUCHAR vendorStrPtr;
2609  PUCHAR deviceStrPtr;
2610 
2611  pciData = (PPCI_COMMON_CONFIG)&pciBuffer;
2612 
2613  slotData.u.AsULONG = 0;
2614 
2615  //
2616  // Look at each device.
2617  //
2618 
2619  for (slotNumber = *SlotNumber;
2620  slotNumber < 32;
2621  slotNumber++) {
2622 
2623  slotData.u.bits.DeviceNumber = slotNumber;
2624 
2625  //
2626  // Look at each function.
2627  //
2628 
2629  for (functionNumber= *FunctionNumber;
2630  functionNumber < 8;
2631  functionNumber++) {
2632 
2633  slotData.u.bits.FunctionNumber = functionNumber;
2634 
2635  if (!ScsiPortGetBusData(DeviceExtension,
2637  BusNumber,
2638  slotData.u.AsULONG,
2639  pciData,
2640  sizeof(ULONG))) {
2641 
2642  //
2643  // Out of PCI data.
2644  //
2645 
2646  *LastSlot = TRUE;
2647  return FALSE;
2648  }
2649 
2650  if (pciData->VendorID == PCI_INVALID_VENDORID) {
2651 
2652  //
2653  // No PCI device, or no more functions on device
2654  // move to next PCI device.
2655  //
2656 
2657  break;
2658  }
2659 
2660  //
2661  // Translate hex ids to strings.
2662  //
2663 
2664  vendorStrPtr = vendorString;
2665  deviceStrPtr = deviceString;
2666  AtapiHexToString(pciData->VendorID, (PCHAR*)&vendorStrPtr);
2667  AtapiHexToString(pciData->DeviceID, (PCHAR*)&deviceStrPtr);
2668 
2669  DebugPrint((2,
2670  "FindBrokenController: Bus %x Slot %x Function %x Vendor %s Product %s\n",
2671  BusNumber,
2672  slotNumber,
2673  functionNumber,
2674  vendorString,
2675  deviceString));
2676 
2677  //
2678  // Compare strings.
2679  //
2680 
2681  if (AtapiStringCmp((PCHAR)vendorString,
2682  (PCHAR)VendorID,
2683  VendorIDLength) ||
2684  AtapiStringCmp((PCHAR)deviceString,
2685  (PCHAR)DeviceID,
2686  DeviceIDLength)) {
2687 
2688  //
2689  // Not our PCI device. Try next device/function
2690  //
2691 
2692  continue;
2693  }
2694 
2695  *FunctionNumber = functionNumber;
2696  *SlotNumber = slotNumber;
2697  return TRUE;
2698 
2699  } // next PCI function
2700 
2701  *FunctionNumber = 0;
2702 
2703  } // next PCI slot
2704 
2705  *LastSlot = TRUE;
2706  return FALSE;
2707 } // end FindBrokenController
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
VOID NTAPI AtapiHexToString(ULONG Value, PCHAR *Buffer)
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ USHORT DeviceID
Definition: iotypes.h:860
struct _PCI_COMMON_CONFIG * PPCI_COMMON_CONFIG
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3245
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG _In_ ULONG SlotNumber
Definition: halfuncs.h:156
unsigned char UCHAR
Definition: xmlstorage.h:181
union _PCI_SLOT_NUMBER::@3636 u
struct _PCI_SLOT_NUMBER::@3636::@3637 bits
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
ULONG NTAPI ScsiPortGetBusData(IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length)
Definition: scsiport.c:549
LONG NTAPI AtapiStringCmp(PCHAR FirstStr, PCHAR SecondStr, ULONG Count)
Definition: atapi.c:6333
unsigned int ULONG
Definition: retypes.h:1
UCHAR pciBuffer[256]
Definition: id_probe.cpp:66

Referenced by AtapiFindPCIController().

◆ FindDevices()

BOOLEAN NTAPI FindDevices ( IN PVOID  HwDeviceExtension,
IN BOOLEAN  AtapiOnly,
IN ULONG  Channel 
)

Definition at line 1489 of file atapi.c.

1514 {
1515  PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
1516  PIDE_REGISTERS_1 baseIoAddress1 = deviceExtension->BaseIoAddress1[Channel];
1517  PIDE_REGISTERS_2 baseIoAddress2 = deviceExtension->BaseIoAddress2[Channel];
1518  BOOLEAN deviceResponded = FALSE,
1519  skipSetParameters = FALSE;
1520  ULONG waitCount = 10000;
1521  ULONG deviceNumber;
1522  ULONG i;
1523  UCHAR signatureLow,
1524  signatureHigh;
1525  UCHAR statusByte;
1526 
1527  //
1528  // Clear expecting interrupt flag and current SRB field.
1529  //
1530 
1531  deviceExtension->ExpectingInterrupt = FALSE;
1532  deviceExtension->CurrentSrb = NULL;
1533 
1534  //
1535  // Search for devices.
1536  //
1537 
1538  for (deviceNumber = 0; deviceNumber < 2; deviceNumber++) {
1539 
1540  //
1541  // Select the device.
1542  //
1543 
1544  ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,
1545  (UCHAR)((deviceNumber << 4) | 0xA0));
1546 
1547  //
1548  // Check here for some SCSI adapters that incorporate IDE emulation.
1549  //
1550 
1551  GetStatus(baseIoAddress2, statusByte);
1552  if (statusByte == 0xFF) {
1553  continue;
1554  }
1555 
1556  AtapiSoftReset(baseIoAddress1,deviceNumber);
1557  WaitOnBusy(baseIoAddress2,statusByte);
1558 
1559  signatureLow = ScsiPortReadPortUchar(&baseIoAddress1->CylinderLow);
1560  signatureHigh = ScsiPortReadPortUchar(&baseIoAddress1->CylinderHigh);
1561 
1562  if (signatureLow == 0x14 && signatureHigh == 0xEB) {
1563 
1564  //
1565  // ATAPI signature found.
1566  // Issue the ATAPI identify command if this
1567  // is not for the crash dump utility.
1568  //
1569 
1570 atapiIssueId:
1571 
1572  if (!deviceExtension->DriverMustPoll) {
1573 
1574  //
1575  // Issue ATAPI packet identify command.
1576  //
1577 
1578  if (IssueIdentify(HwDeviceExtension,
1579  deviceNumber,
1580  Channel,
1582 
1583  //
1584  // Indicate ATAPI device.
1585  //
1586 
1587  DebugPrint((1,
1588  "FindDevices: Device %x is ATAPI\n",
1589  deviceNumber));
1590 
1591  deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] |= DFLAGS_ATAPI_DEVICE;
1592  deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] |= DFLAGS_DEVICE_PRESENT;
1593 
1594  deviceResponded = TRUE;
1595 
1596  GetStatus(baseIoAddress2, statusByte);
1597  if (statusByte & IDE_STATUS_ERROR) {
1598  AtapiSoftReset(baseIoAddress1, deviceNumber);
1599  }
1600 
1601 
1602  } else {
1603 
1604  //
1605  // Indicate no working device.
1606  //
1607 
1608  DebugPrint((1,
1609  "FindDevices: Device %x not responding\n",
1610  deviceNumber));
1611 
1612  deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] &= ~DFLAGS_DEVICE_PRESENT;
1613  }
1614 
1615  }
1616 
1617  } else {
1618 
1619  //
1620  // Issue IDE Identify. If an Atapi device is actually present, the signature
1621  // will be asserted, and the drive will be recognized as such.
1622  //
1623 
1624  if (IssueIdentify(HwDeviceExtension,
1625  deviceNumber,
1626  Channel,
1628 
1629  //
1630  // IDE drive found.
1631  //
1632 
1633 
1634  DebugPrint((1,
1635  "FindDevices: Device %x is IDE\n",
1636  deviceNumber));
1637 
1638  deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] |= DFLAGS_DEVICE_PRESENT;
1639 
1640  if (!AtapiOnly) {
1641  deviceResponded = TRUE;
1642  }
1643 
1644  //
1645  // Indicate IDE - not ATAPI device.
1646  //
1647 
1648  deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] &= ~DFLAGS_ATAPI_DEVICE;
1649 
1650 
1651  } else {
1652 
1653  //
1654  // Look to see if an Atapi device is present.
1655  //
1656 
1657  AtapiSoftReset(baseIoAddress1,deviceNumber);
1658 
1659  WaitOnBusy(baseIoAddress2,statusByte);
1660 
1661  signatureLow = ScsiPortReadPortUchar(&baseIoAddress1->CylinderLow);
1662  signatureHigh = ScsiPortReadPortUchar(&baseIoAddress1->CylinderHigh);
1663 
1664  if (signatureLow == 0x14 && signatureHigh == 0xEB) {
1665  goto atapiIssueId;
1666  }
1667  }
1668  }
1669  }
1670 
1671  for (i = 0; i < 2; i++) {
1672  if ((deviceExtension->DeviceFlags[i + (Channel * 2)] & DFLAGS_DEVICE_PRESENT) &&
1673  (!(deviceExtension->DeviceFlags[i + (Channel * 2)] & DFLAGS_ATAPI_DEVICE)) && deviceResponded) {
1674 
1675  //
1676  // This hideous hack is to deal with ESDI devices that return
1677  // garbage geometry in the IDENTIFY data.
1678  // This is ONLY for the crashdump environment as
1679  // these are ESDI devices.
1680  //
1681 
1682  if (deviceExtension->IdentifyData[i].SectorsPerTrack ==
1683  0x35 &&
1684  deviceExtension->IdentifyData[i].NumberOfHeads ==
1685  0x07) {
1686 
1687  DebugPrint((1,
1688  "FindDevices: Found nasty Compaq ESDI!\n"));
1689 
1690  //
1691  // Change these values to something reasonable.
1692  //
1693 
1694  deviceExtension->IdentifyData[i].SectorsPerTrack =
1695  0x34;
1696  deviceExtension->IdentifyData[i].NumberOfHeads =
1697  0x0E;
1698  }
1699 
1700  if (deviceExtension->IdentifyData[i].SectorsPerTrack ==
1701  0x35 &&
1702  deviceExtension->IdentifyData[i].NumberOfHeads ==
1703  0x0F) {
1704 
1705  DebugPrint((1,
1706  "FindDevices: Found nasty Compaq ESDI!\n"));
1707 
1708  //
1709  // Change these values to something reasonable.
1710  //
1711 
1712  deviceExtension->IdentifyData[i].SectorsPerTrack =
1713  0x34;
1714  deviceExtension->IdentifyData[i].NumberOfHeads =
1715  0x0F;
1716  }
1717 
1718 
1719  if (deviceExtension->IdentifyData[i].SectorsPerTrack ==
1720  0x36 &&
1721  deviceExtension->IdentifyData[i].NumberOfHeads ==
1722  0x07) {
1723 
1724  DebugPrint((1,
1725  "FindDevices: Found nasty UltraStor ESDI!\n"));
1726 
1727  //
1728  // Change these values to something reasonable.
1729  //
1730 
1731  deviceExtension->IdentifyData[i].SectorsPerTrack =
1732  0x3F;
1733  deviceExtension->IdentifyData[i].NumberOfHeads =
1734  0x10;
1735  skipSetParameters = TRUE;
1736  }
1737 
1738 
1739  if (!skipSetParameters) {
1740 
1741  WaitOnBusy(baseIoAddress2,statusByte);
1742 
1743  //
1744  // Select the device.
1745  //
1746 
1747  ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,
1748  (UCHAR)((i << 4) | 0xA0));
1749 
1750  GetStatus(baseIoAddress2, statusByte);
1751 
1752  if (statusByte & IDE_STATUS_ERROR) {
1753 
1754  //
1755  // Reset the device.
1756  //
1757 
1758  DebugPrint((2,
1759  "FindDevices: Resetting controller before SetDriveParameters.\n"));
1760 
1762  ScsiPortStallExecution(500 * 1000);
1764  ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,
1765  (UCHAR)((i << 4) | 0xA0));
1766 
1767  do {
1768 
1769  //
1770  // Wait for Busy to drop.
1771  //
1772 
1774  GetStatus(baseIoAddress2, statusByte);
1775 
1776  } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
1777  }
1778 
1779  WaitOnBusy(baseIoAddress2,statusByte);
1780  DebugPrint((2,
1781  "FindDevices: Status before SetDriveParameters: (%x) (%x)\n",
1782  statusByte,
1783  ScsiPortReadPortUchar(&baseIoAddress1->DriveSelect)));
1784 
1785  //
1786  // Use the IDENTIFY data to set drive parameters.
1787  //
1788 
1789  if (!SetDriveParameters(HwDeviceExtension,i,Channel)) {
1790 
1791  DebugPrint((0,
1792  "AtapHwInitialize: Set drive parameters for device %d failed\n",
1793  i));
1794 
1795  //
1796  // Don't use this device as writes could cause corruption.
1797  //
1798 
1799  deviceExtension->DeviceFlags[i + Channel] = 0;
1800  continue;
1801 
1802  }
1803  if (deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] & DFLAGS_REMOVABLE_DRIVE) {
1804 
1805  //
1806  // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
1807  //
1808 
1809  AtapiOnly = FALSE;
1810  }
1811 
1812 
1813  //
1814  // Indicate that a device was found.
1815  //
1816 
1817  if (!AtapiOnly) {
1818  deviceResponded = TRUE;
1819  }
1820  }
1821  }
1822  }
1823 
1824  //
1825  // Make sure master device is selected on exit.
1826  //
1827 
1828  ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect, 0xA0);
1829 
1830  //
1831  // Reset the controller. This is a feeble attempt to leave the ESDI
1832  // controllers in a state that ATDISK driver will recognize them.
1833  // The problem in ATDISK has to do with timings as it is not reproducible
1834  // in debug. The reset should restore the controller to its poweron state
1835  // and give the system enough time to settle.
1836  //
1837 
1838  if (!deviceResponded) {
1839 
1841  ScsiPortStallExecution(50 * 1000);
1843  }
1844 
1845  return deviceResponded;
1846 
1847 } // end FindDevices()
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
#define IDE_DC_RESET_CONTROLLER
Definition: atapi.h:146
#define TRUE
Definition: types.h:120
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
UCHAR DriveSelect
Definition: atapi.h:22
USHORT SectorsPerTrack
Definition: