Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1561 lines
46 KiB

  1. /*-------------------------------------------------------------------
  2. | initrk.c - main init code for RocketPort/Modem NT device driver.
  3. Contains mostly initialization code.
  4. Copyright 1996-98 Comtrol Corporation. All rights reserved.
  5. |--------------------------------------------------------------------*/
  6. #include "precomp.h"
  7. char *szResourceClassName = {"Resources RocketPort"};
  8. MODEM_IMAGE * ReadModemFile(MODEM_IMAGE *mi);
  9. void FreeModemFiles();
  10. /*----------------------------------------------------------------------
  11. FindPCIBus -
  12. Purpose: To query system for pci bus. If there is a PCI bus
  13. call FindPCIRocket to check for PCI rocket cards.
  14. Returns: Bus number of the PCI bus, or 0 if no PCI bus found.
  15. |----------------------------------------------------------------------*/
  16. UCHAR FindPCIBus(void)
  17. {
  18. NTSTATUS Status;
  19. int i,NumPCIBuses=0;
  20. unsigned char tmpstr[8]; // place to put data
  21. for(i=0;i<255;++i)
  22. {
  23. Status = HalGetBusData(PCIConfiguration,
  24. i, // bus
  25. 0, // slot
  26. (PCI_COMMON_CONFIG *) tmpstr, // ptr to buffer
  27. 2); // get two bytes of data
  28. if (Status == 0) // No more PCI buses
  29. break;
  30. if (Status >= 2) // the bus exists
  31. ++NumPCIBuses;
  32. }
  33. MyKdPrint(
  34. D_Init,
  35. ("Found %d PCI Bu%s\n",
  36. NumPCIBuses,
  37. (NumPCIBuses != 1 ? "sses" : "s")))
  38. return((UCHAR)NumPCIBuses);
  39. }
  40. /*----------------------------------------------------------------------
  41. FindPCIRockets - Gather info on all rocketport pci boards in the system.
  42. Returns: 0 if found, 1 if not found.
  43. |----------------------------------------------------------------------*/
  44. int FindPCIRockets(UCHAR NumPCI)
  45. {
  46. PCI_COMMON_CONFIG *PCIDev;
  47. UCHAR i;
  48. NTSTATUS Status;
  49. int Slot;
  50. int find_index = 0;
  51. MyKdPrint(D_Init,("FindPciRocket\n"))
  52. RtlZeroMemory(&PciConfig,sizeof(PciConfig));
  53. PCIDev = ExAllocatePool(NonPagedPool,sizeof(PCI_COMMON_CONFIG));
  54. if ( PCIDev == NULL ) {
  55. Eprintf("FindPCIRockets no memory");
  56. return 1;
  57. }
  58. for(i=0;i<NumPCI;++i)
  59. {
  60. for(Slot = 0;Slot < 32;++Slot) /*5 bits for device 32 = 2^5*/
  61. {
  62. // get a few bytes of pci-config space(vendor-id & device-id).
  63. Status = HalGetBusData(PCIConfiguration,i,Slot,PCIDev,0x4);
  64. if (Status == 0)
  65. {
  66. Eprintf("PCI Bus %d does not exist.",i);
  67. }
  68. if (Status > 2) /* Found Device Is it ours? */
  69. {
  70. if (PCIDev->VendorID == PCI_VENDOR_ID)
  71. {
  72. ////////////////new///////////////////////
  73. switch (PCIDev->DeviceID)
  74. {
  75. case PCI_DEVICE_4Q: // 4 Port Quadcable
  76. case PCI_DEVICE_4RJ: // 4 Port RJ
  77. case PCI_DEVICE_8RJ: // 8 Port RJ
  78. case PCI_DEVICE_8O: // 8 Port Octacable
  79. case PCI_DEVICE_8I: // 8 Port interface
  80. case PCI_DEVICE_SIEMENS8:
  81. case PCI_DEVICE_SIEMENS16:
  82. case PCI_DEVICE_16I: //16 Port interface
  83. case PCI_DEVICE_32I: // 32 Port interface
  84. case PCI_DEVICE_RPLUS2:
  85. case PCI_DEVICE_422RPLUS2:
  86. case PCI_DEVICE_RPLUS4:
  87. case PCI_DEVICE_RPLUS8:
  88. case PCI_DEVICE_RMODEM6:
  89. case PCI_DEVICE_RMODEM4:
  90. break;
  91. default:
  92. continue;
  93. } // switch
  94. //////////////////////////////////////////
  95. // get 0x40 worth of pci-config space(includes irq, addr, etc.)
  96. Status = HalGetBusData(PCIConfiguration,i,Slot,PCIDev,0x40);
  97. if (Driver.VerboseLog)
  98. Eprintf("PCI Board found, IO:%xh, Int:%d ID:%d.",
  99. PCIDev->u.type0.BaseAddresses[0]-1,
  100. PCIDev->u.type0.InterruptLine,
  101. PCIDev->DeviceID);
  102. PciConfig[find_index].BusNumber = i; //get from previous halquerysysin
  103. PciConfig[find_index].PCI_Slot = Slot;
  104. PciConfig[find_index].PCI_DevID = PCIDev->DeviceID;
  105. PciConfig[find_index].PCI_RevID = PCIDev->RevisionID;
  106. PciConfig[find_index].PCI_SVID = PCIDev->u.type0.SubVendorID;
  107. PciConfig[find_index].PCI_SID = PCIDev->u.type0.SubSystemID;
  108. PciConfig[find_index].BaseIoAddr =
  109. PCIDev->u.type0.BaseAddresses[0]-1;
  110. PciConfig[find_index].NumPorts = id_to_num_ports(PCIDev->DeviceID);
  111. if (PCIDev->u.type0.InterruptLine != 255)
  112. {
  113. MyKdPrint(D_Init,("Saving the Interrupt: %d\n",
  114. PCIDev->u.type0.InterruptLine))
  115. PciConfig[find_index].Irq = PCIDev->u.type0.InterruptLine;
  116. }
  117. if (Driver.VerboseLog)
  118. Eprintf("Bus:%d,Slt:%x,Dev:%x,Pin:%x",
  119. i, Slot, PCIDev->DeviceID, PCIDev->u.type0.InterruptPin);
  120. if ((PCIDev->Command & 1) == 0)
  121. {
  122. if (Driver.VerboseLog)
  123. Eprintf("Turn on PCI io access");
  124. PCIDev->Command = PCI_ENABLE_IO_SPACE;
  125. Status = HalSetBusDataByOffset(PCIConfiguration,
  126. i, // bus
  127. Slot, // slot
  128. &PCIDev->Command,
  129. FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
  130. sizeof(PCIDev->Command)); // len of buffer
  131. }
  132. MyKdPrint(D_Init,("Ctlr: __ Slot: %x Device: %x, Base0: %x, IPin: %x, ILine: %x\n",
  133. Slot,PCIDev->DeviceID,PCIDev->u.type0.BaseAddresses[0]-1,
  134. PCIDev->u.type0.InterruptPin,
  135. PCIDev->u.type0.InterruptLine))
  136. if (find_index < MAX_NUM_BOXES)
  137. ++find_index;
  138. } // if (PCIDev->VendorID == PCI_VENDOR_ID)
  139. } // if (Status > 2)
  140. } // pci slots
  141. } // pci buses
  142. ExFreePool(PCIDev);
  143. if (find_index > 0)
  144. return 0; // ok: found
  145. return 1; // err: not found
  146. }
  147. /*----------------------------------------------------------------------
  148. FindPCIRocket - Help enumerate Rocketport PCI devices. Fills in
  149. enties in config structure.
  150. match_option : 0 - match exact, 1 - match if desired ports <= actual.
  151. Returns: 0 if found, 1 if not found.
  152. |----------------------------------------------------------------------*/
  153. int FindPCIRocket(DEVICE_CONFIG *config, int match_option)
  154. {
  155. int brd = 0;
  156. int good;
  157. while (PciConfig[brd].BaseIoAddr != 0)
  158. {
  159. good = 1;
  160. if (PciConfig[brd].Claimed) // used
  161. good = 0;
  162. switch (match_option)
  163. {
  164. case 0:
  165. if (id_to_num_ports(PciConfig[brd].PCI_DevID) != config->NumPorts)
  166. good = 0;
  167. break;
  168. case 1:
  169. if (id_to_num_ports(PciConfig[brd].PCI_DevID) < config->NumPorts)
  170. good = 0;
  171. break;
  172. }
  173. if (good) // assign it.
  174. {
  175. config->BusNumber = PciConfig[brd].BusNumber;
  176. config->PCI_Slot = PciConfig[brd].PCI_Slot;
  177. config->PCI_DevID = PciConfig[brd].PCI_DevID;
  178. config->PCI_RevID = PciConfig[brd].PCI_RevID;
  179. config->PCI_SVID = PciConfig[brd].PCI_SVID;
  180. config->PCI_SID = PciConfig[brd].PCI_SID;
  181. config->BaseIoAddr = PciConfig[brd].BaseIoAddr;
  182. config->Irq = PciConfig[brd].Irq;
  183. config->BusType = PCIBus;
  184. config->AiopIO[0] = config->BaseIoAddr;
  185. // bugfix, 9-30-98 9:20 A.M.
  186. PciConfig[brd].Claimed = 1; // used
  187. return 0; // ok, found
  188. //SetupConfig(config); // fill in NumPorts based on model, etc
  189. }
  190. ++brd;
  191. }
  192. return 1; // err, not found
  193. }
  194. /*----------------------------------------------------------------------
  195. RcktConnectInt - Connect the Driver.isr to an Interrupt
  196. |----------------------------------------------------------------------*/
  197. NTSTATUS RcktConnectInt(IN PDRIVER_OBJECT DriverObject)
  198. {
  199. NTSTATUS status;
  200. KINTERRUPT_MODE InterruptMode;
  201. BOOLEAN ShareVector;
  202. ULONG Vector;
  203. KIRQL Irql;
  204. KAFFINITY ProcessorAffinity;
  205. MyKdPrint(D_Init,("RcktConnectInt\n"))
  206. status = STATUS_SUCCESS;
  207. //------ Get an interrupt vector from HAL
  208. Vector = HalGetInterruptVector(
  209. Driver.irq_ext->config->BusType,
  210. Driver.irq_ext->config->BusNumber,
  211. Driver.irq_ext->config->Irq,
  212. Driver.irq_ext->config->Irq,
  213. &Irql,
  214. &ProcessorAffinity);
  215. #if DBG
  216. //Eprintf("b:%d,n:%d,i:%d",
  217. // Driver.irq_ext->config->BusType,
  218. // Driver.irq_ext->config->BusNumber,
  219. // Driver.irq_ext->config->Irq);
  220. #endif
  221. MyKdPrint(D_Init,("Vector %x Irql %x Affinity %x\n",
  222. Vector, Irql, ProcessorAffinity))
  223. MyKdPrint(D_Init,("Connecting To IRQ %x on a %x bus \n",
  224. Driver.irq_ext->config->Irq,
  225. Driver.irq_ext->config->BusType))
  226. // Rocket port doesn't need a context for the ISR
  227. //Driver.OurIsrContext = NULL;
  228. //Driver.OurIsr = SerialISR;
  229. if(Driver.irq_ext->config->BusType == PCIBus)
  230. {
  231. InterruptMode = LevelSensitive; //PCI style
  232. ShareVector = TRUE;
  233. }
  234. else // ISA
  235. {
  236. InterruptMode = Latched; //ISA style
  237. ShareVector = FALSE;
  238. }
  239. status = IoConnectInterrupt(
  240. &Driver.InterruptObject,
  241. (PKSERVICE_ROUTINE) SerialISR, // Driver.OurIsr,
  242. NULL, // Driver.OurIsrContext,
  243. NULL,
  244. Vector,
  245. Irql,
  246. Irql,
  247. InterruptMode,
  248. ShareVector,
  249. ProcessorAffinity,
  250. FALSE);
  251. MyKdPrint(D_Init,("Vector %x Irql %x Affity %x Irq %x\n",
  252. Vector, Irql,
  253. ProcessorAffinity,
  254. Driver.irq_ext->config->Irq))
  255. if (!NT_SUCCESS(status))
  256. {
  257. Driver.InterruptObject = NULL;
  258. MyKdPrint(D_Init,("Not Avalable IRQ:%d, Status:%xH",
  259. Driver.irq_ext->config->Irq, status))
  260. }
  261. return status;
  262. }
  263. /*----------------------------------------------------------------------
  264. VerboseLogBoards - Log the Board IO, IRQ configuration.
  265. |----------------------------------------------------------------------*/
  266. void VerboseLogBoards(char *prefix)
  267. {
  268. int k;
  269. char tmpstr[80];
  270. PSERIAL_DEVICE_EXTENSION board_ext;
  271. MyKdPrint(D_Init,("VerboseLogBoards\n"))
  272. k = 0;
  273. board_ext = Driver.board_ext;
  274. while (board_ext != NULL)
  275. {
  276. strcpy(tmpstr, prefix);
  277. Sprintf(&tmpstr[strlen(tmpstr)], " Brd:%d,IO:%xH,NumCh:%d,NumA:%d,Bus:%d",
  278. k+1,
  279. board_ext->config->AiopIO[0],
  280. board_ext->config->NumPorts,
  281. board_ext->config->NumAiop,
  282. board_ext->config->BusType);
  283. //Sprintf(&tmpstr[strlen(tmpstr)], ",Irq:%d", board_ext->config->.Irq);
  284. Eprintf(tmpstr); // Log it
  285. board_ext = board_ext->board_ext;
  286. ++k;
  287. }
  288. }
  289. /*-----------------------------------------------------------------------
  290. SetupRocketCfg - Sets up the details in the DEVICE_CONFIG structure
  291. based on the information passed to it from DriverEntry() or PnP.
  292. The NT4.0 DriverEntry handling should be easy, because our boards
  293. are ordered by us. NT5.0 is more complex, because we may not see
  294. the "first" rocketport board in the correct order.
  295. |-----------------------------------------------------------------------*/
  296. int SetupRocketCfg(int pnp_flag)
  297. {
  298. //int i,j;
  299. //DEVICE_CONFIG *cfctl;
  300. int have_isa_boards = 0;
  301. PSERIAL_DEVICE_EXTENSION first_isa_ext;
  302. PSERIAL_DEVICE_EXTENSION ext;
  303. int pnp_isa_index = 1;
  304. ULONG first_isa_MudbacIO;
  305. MyKdPrint(D_Init,("SetupRocketCfg\n"))
  306. // Set up the Mudbac I/O addresses
  307. // see if we have any isa-boards, and mark a ptr to this first board.
  308. ext = Driver.board_ext;
  309. while (ext)
  310. {
  311. if (ext->config->BusType == Isa)
  312. {
  313. have_isa_boards = 1;
  314. }
  315. ext = ext->board_ext; // next in chain
  316. } // while ext
  317. if (have_isa_boards)
  318. {
  319. MyKdPrint(D_Init,("Stp1\n"))
  320. first_isa_ext = FindPrimaryIsaBoard();
  321. if (first_isa_ext == NULL)
  322. {
  323. MyKdPrint(D_Init,("Err1X\n"))
  324. if (Driver.VerboseLog)
  325. Eprintf("First Isa-brd not 44H io");
  326. // return 1; // err
  327. first_isa_MudbacIO = 0x1c0; // this is cheating
  328. }
  329. else
  330. {
  331. MyKdPrint(D_Init,("Stp2\n"))
  332. //----- setup the initial Mudback IO
  333. if (first_isa_ext->config->MudbacIO == 0)
  334. first_isa_ext->config->MudbacIO = first_isa_ext->config->AiopIO[0] + 0x40;
  335. first_isa_MudbacIO = first_isa_ext->config->MudbacIO;
  336. }
  337. //----- setup any remaining Mudback IO addresses
  338. ext = Driver.board_ext;
  339. while (ext)
  340. {
  341. if (ext->config->BusType == Isa)
  342. {
  343. if ((ext != first_isa_ext) && (ext->config->BaseIoSize == 0x44))
  344. {
  345. MyKdPrint(D_Init,("Unused MudbackIO\n"))
  346. // don't allow them to configure two boards with space for mudback.
  347. ext->config->BaseIoSize = 0x40;
  348. }
  349. if ((ext != first_isa_ext) && (ext->config->BaseIoSize == 0x40))
  350. {
  351. if (ext->config->ISABrdIndex == 0)
  352. {
  353. // this case shouldn't come up, pnpadd.c code generates index
  354. // and saves it to the registry. Or nt40 driverentry does it.
  355. MyKdPrint(D_Init,("Bad IsaIndx\n"))
  356. ext->config->ISABrdIndex = pnp_isa_index;
  357. }
  358. ++pnp_isa_index;
  359. // setup the Mudback IO
  360. ext->config->MudbacIO = first_isa_MudbacIO +
  361. (ext->config->ISABrdIndex * 0x400);
  362. }
  363. }
  364. ext = ext->board_ext; // next in chain
  365. } // while ext
  366. }
  367. // Set up the rest of the Aiop addresses
  368. ext = Driver.board_ext;
  369. while (ext)
  370. {
  371. ConfigAIOP(ext->config); //SetupConfig(ext->config);
  372. ext = ext->board_ext; // next in chain
  373. } // while ext
  374. return(0);
  375. }
  376. /*-----------------------------------------------------------------------
  377. ConfigAIOP - Setup the number of AIOP's based on:
  378. * if PCI, use the pci-id to determine number of ports, since
  379. detecting is unreliable do to back-to-back aiop-is slots possibility.
  380. * if ISA, set to max and let init controller figure it out.
  381. |-----------------------------------------------------------------------*/
  382. int ConfigAIOP(DEVICE_CONFIG *config)
  383. {
  384. int j;
  385. int found_ports=0;
  386. MyKdPrint(D_Init,("ConfigAIOP\n"))
  387. if (config->BusType == Isa) /* Set up ISA adrs */
  388. {
  389. if (config->NumPorts == 0)
  390. config->NumAiop=AIOP_CTL_SIZE; // let init figure it out
  391. else if (config->NumPorts <= 8)
  392. config->NumAiop=1;
  393. else if (config->NumPorts <= 16)
  394. config->NumAiop=2;
  395. else if (config->NumPorts <= 32)
  396. config->NumAiop=4;
  397. for(j = 1;j < config->NumAiop;j++) /* AIOP aliases */
  398. config->AiopIO[j] = config->AiopIO[j - 1] + 0x400;
  399. }
  400. if (config->BusType == PCIBus) // Set up PCI adrs
  401. {
  402. switch (config->PCI_DevID)
  403. {
  404. case PCI_DEVICE_4Q: // 4 Port Quadcable
  405. case PCI_DEVICE_4RJ: // 4 Port RJ
  406. found_ports=4;
  407. config->NumAiop=1;
  408. config->AiopIO[0] = config->BaseIoAddr;
  409. break;
  410. case PCI_DEVICE_8RJ: // 8 Port RJ
  411. case PCI_DEVICE_8O: // 8 Port Octacable
  412. case PCI_DEVICE_8I: // 8 Port interface
  413. case PCI_DEVICE_SIEMENS8:
  414. found_ports=8;
  415. config->NumAiop=1;
  416. config->AiopIO[0] = config->BaseIoAddr;
  417. break;
  418. case PCI_DEVICE_SIEMENS16:
  419. case PCI_DEVICE_16I: //16 Port interface
  420. found_ports=16;
  421. config->NumAiop=2;
  422. config->AiopIO[0] = config->BaseIoAddr;
  423. config->AiopIO[1] = config->BaseIoAddr + 0x40;
  424. break;
  425. case PCI_DEVICE_32I: // 32 Port interface
  426. found_ports=32;
  427. config->NumAiop=4;
  428. config->AiopIO[0] = config->BaseIoAddr;
  429. config->AiopIO[1] = config->BaseIoAddr + 0x40;
  430. config->AiopIO[2] = config->BaseIoAddr + 0x80;
  431. config->AiopIO[3] = config->BaseIoAddr + 0xC0;
  432. break;
  433. case PCI_DEVICE_RPLUS2:
  434. case PCI_DEVICE_422RPLUS2:
  435. found_ports=2;
  436. config->NumAiop=1;
  437. config->AiopIO[0] = config->BaseIoAddr;
  438. config->AiopIO[1] = 0;
  439. break;
  440. case PCI_DEVICE_RPLUS4:
  441. found_ports=4;
  442. config->NumAiop=1;
  443. config->AiopIO[0] = config->BaseIoAddr;
  444. config->AiopIO[1] = 0;
  445. break;
  446. case PCI_DEVICE_RPLUS8:
  447. found_ports=8;
  448. config->NumAiop=2;
  449. config->AiopIO[0] = config->BaseIoAddr;
  450. config->AiopIO[1] = config->BaseIoAddr + 0x40;
  451. config->AiopIO[2] = 0;
  452. break;
  453. case PCI_DEVICE_RMODEM6:
  454. found_ports=6;
  455. config->NumAiop=1;
  456. config->AiopIO[0] = config->BaseIoAddr;
  457. break;
  458. case PCI_DEVICE_RMODEM4:
  459. found_ports=4;
  460. config->NumAiop=1;
  461. config->AiopIO[0] = config->BaseIoAddr;
  462. break;
  463. default:
  464. found_ports=0;
  465. config->NumAiop=0;
  466. Eprintf("Err,Bad PCI Dev ID!");
  467. break;
  468. } // switch
  469. // allow for user configured smaller number of ports
  470. if ((config->NumPorts == 0) || (config->NumPorts > found_ports))
  471. config->NumPorts = found_ports;
  472. } // if pci
  473. return 0; // ok
  474. }
  475. /*-----------------------------------------------------------------------
  476. SerialUnReportResourcesDevice -
  477. This routine unreports the resources used for the board.
  478. |-----------------------------------------------------------------------*/
  479. VOID SerialUnReportResourcesDevice(IN PSERIAL_DEVICE_EXTENSION Extension)
  480. {
  481. CM_RESOURCE_LIST resourceList;
  482. ULONG sizeOfResourceList = 0;
  483. char name[70];
  484. BOOLEAN junkBoolean;
  485. MyKdPrint(D_Init,("UnReportResourcesDevice\n"))
  486. RtlZeroMemory(&resourceList, sizeof(CM_RESOURCE_LIST));
  487. resourceList.Count = 0;
  488. strcpy(name, szResourceClassName);
  489. our_ultoa(Extension->UniqueId, &name[strlen(name)], 10);
  490. IoReportResourceUsage(
  491. CToU1(name),
  492. Extension->DeviceObject->DriverObject,
  493. NULL,
  494. 0,
  495. Extension->DeviceObject,
  496. &resourceList,
  497. sizeof(CM_RESOURCE_LIST),
  498. FALSE,
  499. &junkBoolean);
  500. }
  501. /*-----------------------------------------------------------------------
  502. RocketReportResources -
  503. |-----------------------------------------------------------------------*/
  504. int RocketReportResources(IN PSERIAL_DEVICE_EXTENSION extension)
  505. {
  506. PCM_RESOURCE_LIST resourceList;
  507. ULONG sizeOfResourceList;
  508. ULONG countOfPartials;
  509. PCM_PARTIAL_RESOURCE_DESCRIPTOR partial;
  510. NTSTATUS status;
  511. PHYSICAL_ADDRESS MyPort;
  512. BOOLEAN ConflictDetected;
  513. BOOLEAN MappedFlag;
  514. int i,j;
  515. int brd = extension->UniqueId;
  516. DEVICE_CONFIG *Ctl;
  517. char name[70];
  518. MyKdPrint(D_Init,("ReportResources\n"))
  519. ConflictDetected=FALSE;
  520. countOfPartials=0;
  521. Ctl = extension->config;
  522. #ifdef USE_HAL_ASSIGNSLOT
  523. if (Ctl->BusType == PCIBus)
  524. {
  525. //-------- Report the resources indicated by partial list (resourceList)
  526. strcpy(name, szResourceClassName);
  527. our_ultoa(extension->UniqueId, &name[strlen(name)], 10);
  528. status= HalAssignSlotResources (
  529. &Driver.RegPath, // RegistryPath
  530. CToU1(name), // DriverClassName(optional)
  531. extension->DeviceObject->DriverObject, // DriverObject
  532. // Driver.GlobalDriverObject, //
  533. NULL, // DeviceObject(optional)
  534. Ctl->BusType, // PCIBus
  535. Ctl->BusNumber, // Bus Num
  536. Ctl->PCI_Slot, // slot num
  537. &resourceList); // IN OUT PCM_RESOURCE_LIST *AllocatedResources
  538. if (status != STATUS_SUCCESS)
  539. {
  540. if (Driver.VerboseLog)
  541. Eprintf("Err RR21");
  542. return(1);
  543. }
  544. if (resourceList == NULL)
  545. {
  546. if (Driver.VerboseLog)
  547. Eprintf("Err RR22");
  548. return(2);
  549. }
  550. if (resourceList->Count != 1)
  551. {
  552. if (Driver.VerboseLog)
  553. Eprintf("Err ResCnt RR23");
  554. return(3);
  555. }
  556. countOfPartials = resourceList->List[0].PartialResourceList.Count;
  557. if ( ((countOfPartials > 2) &&
  558. (Ctl->PCI_SVID != PCI_VENDOR_ID)) ||
  559. (countOfPartials < 1)) {
  560. if (Driver.VerboseLog)
  561. Eprintf("Err ResCnt RR24");
  562. return(4);
  563. }
  564. if (resourceList->List[0].InterfaceType != PCIBus)
  565. {
  566. if (Driver.VerboseLog)
  567. Eprintf("Err ResCnt RR25");
  568. return(5);
  569. }
  570. partial = &resourceList->List[0].PartialResourceList.PartialDescriptors[0];
  571. for (i=0; i<(int)countOfPartials; i++)
  572. {
  573. // partial->u.Port.Start = MyPort;
  574. // partial->u.Port.Length = SPANOFMUDBAC;
  575. switch(partial->Type)
  576. {
  577. case CmResourceTypePort:
  578. if ((partial->u.Port.Length != SPANOFAIOP) &&
  579. (partial->u.Port.Length != (SPANOFAIOP*2)) &&
  580. (partial->u.Port.Length != (SPANOFAIOP*3)) &&
  581. (partial->u.Port.Length != (SPANOFAIOP*4)) )
  582. {
  583. if (Driver.VerboseLog)
  584. Eprintf("Err RR35");
  585. return 6;
  586. }
  587. Ctl->pAiopIO[0] =
  588. SerialGetMappedAddress(Ctl->BusType,
  589. Ctl->BusNumber,
  590. partial->u.Port.Start,
  591. partial->u.Port.Length,
  592. 1, // port-io
  593. &MappedFlag,1);
  594. if (Ctl->pAiopIO[0] == NULL)
  595. {
  596. if (Driver.VerboseLog)
  597. Eprintf("Err RR36");
  598. return 7;
  599. }
  600. Ctl->pAiopIO[1] = Ctl->pAiopIO[0] + 0x40;
  601. Ctl->pAiopIO[2] = Ctl->pAiopIO[0] + 0x80;
  602. Ctl->pAiopIO[3] = Ctl->pAiopIO[0] + 0xc0;
  603. Ctl->AiopIO[0] = partial->u.Port.Start.LowPart;
  604. Ctl->AiopIO[1] = partial->u.Port.Start.LowPart + 0x40;
  605. Ctl->AiopIO[2] = partial->u.Port.Start.LowPart + 0x80;
  606. Ctl->AiopIO[3] = partial->u.Port.Start.LowPart + 0xc0;
  607. break;
  608. case CmResourceTypeInterrupt:
  609. #ifdef DO_LATER
  610. #endif
  611. break;
  612. case CmResourceTypeMemory:
  613. #ifdef DO_LATER
  614. #endif
  615. break;
  616. default:
  617. if (Driver.VerboseLog)
  618. Eprintf("Err ResCnt RR26");
  619. return(8);
  620. }
  621. ++partial; // to next io-resource in list.
  622. }
  623. // Release the memory used for the resourceList
  624. if (resourceList)
  625. ExFreePool(resourceList);
  626. resourceList = NULL;
  627. return(0);
  628. }
  629. #endif
  630. if (Ctl->BusType == Isa)
  631. countOfPartials++; //Mudbacs only exist on ISA Boards
  632. MyKdPrint(D_Init,("Report Resources brd:%d bus:%d\n",brd+1, Ctl->BusType))
  633. for (j=0; j<Ctl->NumAiop; j++)
  634. {
  635. if (Ctl->AiopIO[j] > 0)
  636. countOfPartials++; // For each Aiop, we will get resources
  637. }
  638. if (Driver.irq_ext == extension)
  639. {
  640. MyKdPrint(D_Init,("IRQ:%d\n",Driver.SetupIrq))
  641. countOfPartials++; // plus 1 for IRQ info
  642. }
  643. sizeOfResourceList = sizeof(CM_RESOURCE_LIST) +
  644. sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + // add, kpb
  645. (sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)*
  646. countOfPartials);
  647. // add 64 for slop -kpb(this structure sucks)
  648. resourceList = ExAllocatePool(PagedPool, sizeOfResourceList+64);
  649. if (!resourceList)
  650. {
  651. if (Driver.VerboseLog)
  652. Eprintf("No ResourceList");
  653. EventLog(extension->DeviceObject->DriverObject,
  654. ////Driver.GlobalDriverObject,
  655. STATUS_SUCCESS,
  656. SERIAL_INSUFFICIENT_RESOURCES,
  657. 0, NULL);
  658. return(9);
  659. }
  660. RtlZeroMemory(resourceList, sizeOfResourceList);
  661. resourceList->Count = 1;
  662. resourceList->List[0].InterfaceType = Ctl->BusType;
  663. resourceList->List[0].BusNumber = Ctl->BusNumber; //change for multibus
  664. resourceList->List[0].PartialResourceList.Count = countOfPartials;
  665. partial = &resourceList->List[0].PartialResourceList.PartialDescriptors[0];
  666. // Account for the space used by the Rocket.
  667. // Report the use of the Mudbacs on Isa boards only
  668. if (Ctl->BusType == Isa)
  669. {
  670. MyPort.HighPart=0x0;
  671. MyPort.LowPart=Ctl->MudbacIO;
  672. partial->Type = CmResourceTypePort;
  673. partial->ShareDisposition = CmResourceShareDeviceExclusive;
  674. partial->Flags = CM_RESOURCE_PORT_IO;
  675. partial->u.Port.Start = MyPort;
  676. partial->u.Port.Length = SPANOFMUDBAC;
  677. partial++;
  678. }
  679. for (j=0; j<Ctl->NumAiop; j++)
  680. {
  681. // Report the use of the AIOPs.
  682. if (Ctl->AiopIO[j] > 0)
  683. {
  684. MyPort.HighPart=0x0;
  685. MyPort.LowPart=Ctl->AiopIO[j];
  686. partial->Type = CmResourceTypePort;
  687. partial->ShareDisposition = CmResourceShareDeviceExclusive;
  688. partial->Flags = CM_RESOURCE_PORT_IO;
  689. partial->u.Port.Start = MyPort;
  690. partial->u.Port.Length = SPANOFAIOP;
  691. partial++;
  692. }
  693. else
  694. {
  695. MyKdPrint(D_Init,("Aiop Count Wrong, A.\n"))
  696. if (Driver.VerboseLog)
  697. Eprintf("Error RR12");
  698. }
  699. } // end for j
  700. if (Driver.irq_ext == extension)
  701. {
  702. // Report the interrupt information.
  703. partial->Type = CmResourceTypeInterrupt;
  704. if(Ctl->BusType == PCIBus)
  705. {
  706. partial->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
  707. partial->ShareDisposition = CmResourceShareShared;
  708. }
  709. else // if (Ctl->BusType == Isa) //Isa and Pci use differnt int mech
  710. {
  711. partial->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
  712. partial->ShareDisposition = CmResourceShareDriverExclusive;
  713. }
  714. partial->u.Interrupt.Vector = Driver.SetupIrq;
  715. partial->u.Interrupt.Level = Driver.SetupIrq;
  716. #ifdef DO_LATER
  717. // is the above wrong???
  718. #endif
  719. // partial->u.Interrupt.Affinity = -1; //per CM_PARTIAL_RESOURCE_DESCRIPTOR
  720. partial++; // definition DbgPrintf
  721. }
  722. //-------- Report the resources indicated by partial list (resourceList)
  723. strcpy(name, szResourceClassName);
  724. our_ultoa(extension->UniqueId, &name[strlen(name)], 10);
  725. MyKdPrint(D_Init,("Reporting Resources To system\n"))
  726. status=IoReportResourceUsage(
  727. CToU1(name), // DriverClassName OPTIONAL,
  728. extension->DeviceObject->DriverObject, // DriverObject,
  729. // Driver.GlobalDriverObject,
  730. NULL, // DriverList OPTIONAL,
  731. 0, // DriverListSize OPTIONAL,
  732. extension->DeviceObject, // DeviceObject
  733. resourceList, // DeviceList OPTIONAL,
  734. sizeOfResourceList, // DeviceListSize OPTIONAL,
  735. FALSE, // OverrideConflict,
  736. &ConflictDetected); // ConflictDetected
  737. if (!NT_SUCCESS(status))
  738. {
  739. if (Driver.VerboseLog)
  740. Eprintf("Err RR13");
  741. MyKdPrint(D_Init,("Error from IoReportResourceUsage.\n"))
  742. }
  743. if (ConflictDetected)
  744. {
  745. Eprintf("Error, Resource Conflict.");
  746. if (resourceList)
  747. ExFreePool(resourceList);
  748. resourceList = NULL;
  749. EventLog(extension->DeviceObject->DriverObject,
  750. ////Driver.GlobalDriverObject,
  751. STATUS_SUCCESS,
  752. SERIAL_INSUFFICIENT_RESOURCES,
  753. 0, NULL);
  754. MyKdPrint(D_Init,("Resource Conflict Detected.\n"))
  755. return(10);
  756. }
  757. // OK, even more important than reporting resources is getting
  758. // the pointers to the I/O ports!!
  759. if (Ctl->BusType == Isa)
  760. {
  761. MyPort.HighPart=0x0;
  762. MyPort.LowPart=Ctl->MudbacIO;
  763. Ctl->pMudbacIO =
  764. SerialGetMappedAddress(Isa,Ctl->BusNumber,MyPort,SPANOFMUDBAC,1,&MappedFlag,1);
  765. if (Ctl->pMudbacIO == NULL)
  766. {
  767. if (Driver.VerboseLog)
  768. Eprintf("Err RR15");
  769. MyKdPrint(D_Init,("Resource Error A.\n"))
  770. return 11;
  771. }
  772. }
  773. for (j=0; j<Ctl->NumAiop; j++)
  774. {
  775. if (Ctl->AiopIO[j] > 0)
  776. {
  777. MyPort.HighPart=0x0;
  778. MyPort.LowPart=Ctl->AiopIO[j];
  779. Ctl->pAiopIO[j] =
  780. SerialGetMappedAddress(Ctl->BusType,
  781. Ctl->BusNumber,MyPort,SPANOFAIOP,1,&MappedFlag,1);
  782. if (Ctl->pAiopIO[j] == NULL)
  783. {
  784. if (Driver.VerboseLog)
  785. Eprintf("Err RR16");
  786. MyKdPrint(D_Init,("Resource Error B.\n"))
  787. return 12;
  788. }
  789. }
  790. else
  791. {
  792. if (Driver.VerboseLog)
  793. Eprintf("Err RR17");
  794. MyKdPrint(D_Init,("Aiop Count Wrong, B.\n"))
  795. return 13;
  796. }
  797. }
  798. extension->io_reported = 1; // tells that we should deallocate on unload.
  799. // Release the memory used for the resourceList
  800. if (resourceList)
  801. ExFreePool(resourceList);
  802. resourceList = NULL;
  803. MyKdPrint(D_Init,("Done Reporting Resources\n"))
  804. return 0;
  805. }
  806. /*-----------------------------------------------------------------------
  807. InitController -
  808. |-----------------------------------------------------------------------*/
  809. int InitController(PSERIAL_DEVICE_EXTENSION ext)
  810. {
  811. int Aiop; /* AIOP number */
  812. CONTROLLER_T *CtlP; /* ptr to controller structure */
  813. int periodic_only = 1;
  814. CHANNEL_T *Chan; /* channel structure */
  815. CHANNEL_T ch; /* channel structure */
  816. int Irq;
  817. int freq; // poll frequency
  818. int Ch; /* channel number */
  819. int NumChan;
  820. static int Dev = 0;
  821. int Ctl = (int) ext->UniqueId;
  822. DEVICE_CONFIG *pConfig = ext->config;
  823. // if (pConfig->pMudbacIO,
  824. MyKdPrint(D_Init,("InitController\n"))
  825. if (ext == Driver.irq_ext) // irq extension
  826. {
  827. Irq = pConfig->Irq;
  828. #if DBG
  829. // Eprintf("Irq Used:%d", Irq);
  830. #endif
  831. if (Driver.ScanRate == 0)
  832. freq = FREQ_137HZ;
  833. else if (Driver.ScanRate <= 2)
  834. {
  835. if (pConfig->BusType == PCIBus)
  836. freq = FREQ_560HZ;
  837. else
  838. freq = FREQ_274HZ;
  839. }
  840. else if (Driver.ScanRate <= 5) freq = FREQ_274HZ;
  841. else if (Driver.ScanRate <= 10) freq = FREQ_137HZ;
  842. else if (Driver.ScanRate <= 20) freq = FREQ_69HZ;
  843. else if (Driver.ScanRate <= 35) freq = FREQ_34HZ;
  844. else if (Driver.ScanRate <= 70) freq = FREQ_17HZ;
  845. else freq = FREQ_137HZ;
  846. }
  847. else
  848. {
  849. freq = 0;
  850. Irq=0;
  851. }
  852. if ( (ext->config->BusType == PCIBus) &&
  853. ((ext->config->PCI_DevID == PCI_DEVICE_RPLUS2) ||
  854. (ext->config->PCI_DevID == PCI_DEVICE_422RPLUS2) ||
  855. (ext->config->PCI_DevID == PCI_DEVICE_RPLUS4) ||
  856. (ext->config->PCI_DevID == PCI_DEVICE_RPLUS8)) )
  857. ext->config->IsRocketPortPlus = 1; // true if rocketport plus hardware
  858. // setup default ClkRate if not specified
  859. if (ext->config->ClkRate == 0)
  860. {
  861. // use default
  862. if (ext->config->IsRocketPortPlus) // true if rocketport plus hardware
  863. ext->config->ClkRate = DEF_RPLUS_CLOCKRATE;
  864. else
  865. ext->config->ClkRate = DEF_ROCKETPORT_CLOCKRATE;
  866. }
  867. // setup default PreScaler if not specified
  868. if (ext->config->ClkPrescaler == 0)
  869. {
  870. // use default
  871. if (ext->config->IsRocketPortPlus) // true if rocketport plus hardware
  872. ext->config->ClkPrescaler = DEF_RPLUS_PRESCALER;
  873. else
  874. ext->config->ClkPrescaler = DEF_ROCKETPORT_PRESCALER;
  875. }
  876. // --- stop doing this, 5-7-98, setup now sets, we could check!
  877. //pConfig->NumPorts = 0; // this gets calculated in initcontroller
  878. CtlP = ext->CtlP; // point to our board struct
  879. CtlP->ClkPrescaler = (BYTE)ext->config->ClkPrescaler;
  880. CtlP->ClkRate = ext->config->ClkRate;
  881. // Initialize PCI Bus and Dev
  882. CtlP->BusNumber = (UCHAR)pConfig->BusNumber;
  883. CtlP->PCI_Slot = (UCHAR)pConfig->PCI_Slot;
  884. CtlP->PCI_DevID = pConfig->PCI_DevID;
  885. CtlP->PCI_SVID = pConfig->PCI_SVID;
  886. CtlP->PCI_SID = pConfig->PCI_SID;
  887. #ifdef TRY_EVENT_IRQ
  888. periodic_only = 0;
  889. #endif
  890. if (pConfig->BusType == Isa)
  891. {
  892. MyKdPrint(D_Init,("Mbio:%x %x IO len:%x\n",
  893. pConfig->MudbacIO, pConfig->pMudbacIO, pConfig->BaseIoSize))
  894. }
  895. MyKdPrint(D_Init,("Aiopio:%x %x num:%x\n",
  896. pConfig->AiopIO[0], pConfig->pAiopIO[0], pConfig->NumAiop))
  897. if (sInitController(CtlP, // Ctl,
  898. pConfig->pMudbacIO,
  899. pConfig->pAiopIO,
  900. pConfig->AiopIO,
  901. pConfig->NumAiop,
  902. Irq,
  903. (unsigned char)freq,
  904. TRUE,
  905. pConfig->BusType,
  906. pConfig->ClkPrescaler) != 0)
  907. {
  908. Eprintf("Error, Failed Init, Brd:%d, IO:%xH",
  909. Ctl, pConfig->AiopIO[0]);
  910. if (Driver.VerboseLog)
  911. {
  912. Eprintf("Init: pM:%x,pA:%x,N:%d,B:%d",
  913. pConfig->pMudbacIO, pConfig->pAiopIO[0], pConfig->NumAiop,
  914. pConfig->BusType);
  915. }
  916. // This controller was in the registry, but it couldn't be initialized
  917. pConfig->RocketPortFound = FALSE;
  918. //pConfig->NumChan = 0; stop messing with NumPorts
  919. return 2; // err
  920. }
  921. else
  922. {
  923. // this controller was successfully initialized
  924. // if it's the first one found, tell the rest of the init that
  925. // it should be the one to interrupt.
  926. pConfig->RocketPortFound = TRUE;
  927. }
  928. for(Aiop = 0;Aiop < CtlP->NumAiop; Aiop++)
  929. {
  930. if (CtlP->BusType == Isa)
  931. sEnAiop(CtlP,Aiop);
  932. NumChan = CtlP->AiopNumChan[Aiop];
  933. for(Ch = 0; Ch < NumChan; Ch++)
  934. {
  935. Chan = &ch;
  936. //MyKdPrint(D_Init,("sInitChan %d\n", Ch+1))
  937. if(!sInitChan(CtlP,Chan,Aiop,(unsigned char)Ch))
  938. {
  939. if (Driver.VerboseLog)
  940. Eprintf("Err Ch %d on Brd %d", Ch+1, Ctl+1);
  941. MyKdPrint(D_Error,("sInitChan %d\n", Ch+1))
  942. return (-1);
  943. }
  944. Dev++;
  945. } // for ch
  946. // pConfig->NumChan += NumChan; [kpb, 5-7-98, stop messing with config]
  947. } // for Aiop
  948. if (Driver.VerboseLog)
  949. {
  950. Eprintf("Initialized OK, Brd:%d, IO:%xH",
  951. Ctl+1, pConfig->AiopIO[0]);
  952. }
  953. return 0;
  954. }
  955. /*----------------------------------------------------------------------
  956. StartRocketIRQorTimer -
  957. |----------------------------------------------------------------------*/
  958. void StartRocketIRQorTimer(void)
  959. {
  960. #ifdef DO_ROCKET_IRQ
  961. //--------------- Connect to IRQ, or start Timer.
  962. if (Driver.irq_ext)
  963. {
  964. status = RcktConnectInt(DriverObject);
  965. if (!NT_SUCCESS(status))
  966. {
  967. Eprintf("Error,IRQ not found, using Timer!");
  968. Driver.irq_ext = NULL;
  969. Driver.SetupIrq = 0; // use timer instead
  970. }
  971. }
  972. //--- kick start the interrupts
  973. if (Driver.irq_ext) // if using interrupt
  974. {
  975. CtlP = Driver.irq_ext->CtlP; // first boards struct
  976. if(CtlP->BusType == Isa)
  977. {
  978. MyKdPrint(D_Init,("ISA IRQ Enable.\n"))
  979. sEnGlobalInt(CtlP);
  980. }
  981. if(CtlP->BusType == PCIBus)
  982. {
  983. MyKdPrint(D_Init,("PCI IRQ Enable.\n"))
  984. sEnGlobalIntPCI(CtlP);
  985. }
  986. }
  987. else
  988. #endif
  989. {
  990. MyKdPrint(D_Init,("Initializing Timer\n"))
  991. RcktInitPollTimer();
  992. MyKdPrint(D_Init,("Set Timer\n"))
  993. KeSetTimer(&Driver.PollTimer,
  994. Driver.PollIntervalTime,
  995. &Driver.TimerDpc);
  996. }
  997. }
  998. #ifdef DO_ROCKET_IRQ
  999. /*----------------------------------------------------------------------
  1000. SetupRocketIRQ -
  1001. |----------------------------------------------------------------------*/
  1002. void SetupRocketIRQ(void)
  1003. {
  1004. PSERIAL_DEVICE_EXTENSION ext;
  1005. //------ Determine a board to use for interrupts
  1006. Driver.irq_ext = NULL;
  1007. if (Driver.SetupIrq != 0)
  1008. {
  1009. ext = Driver.board_ext;
  1010. while(ext)
  1011. {
  1012. if (Driver.SetupIrq == 1) // auto-pci irq pick
  1013. {
  1014. if ((ext->config->BusType == PCIBus) &&
  1015. (ext->config->Irq != 0))
  1016. {
  1017. Driver.irq_ext = ext; // found a pci-board with irq
  1018. break; // bail from while
  1019. }
  1020. }
  1021. else
  1022. {
  1023. if (ext->config->BusType == Isa)
  1024. {
  1025. ext->config->Irq = Driver.SetupIrq;
  1026. Driver.irq_ext = ext; // found a isa-board with irq
  1027. break; // bail from while
  1028. }
  1029. }
  1030. ext = ext->board_ext; // next
  1031. }
  1032. if (Driver.irq_ext == NULL) // board for irq not found
  1033. {
  1034. Eprintf("Warning, IRQ not available");
  1035. }
  1036. }
  1037. }
  1038. #endif
  1039. /*----------------------------------------------------------------------
  1040. init_cfg_rocket - rocketport specific startup code. Setup some of
  1041. the config structs, look for PCI boards in system, match them up.
  1042. |----------------------------------------------------------------------*/
  1043. NTSTATUS init_cfg_rocket(IN PDRIVER_OBJECT DriverObject)
  1044. {
  1045. // Holds status information return by various OS and driver
  1046. // initialization routines.
  1047. UCHAR NumPCIBuses, NumPCIRockets, NumISARockets, all_found;
  1048. PSERIAL_DEVICE_EXTENSION board_ext;
  1049. int do_pci_search = 0;
  1050. //------ get the Box information from setup.exe
  1051. board_ext = Driver.board_ext;
  1052. while (board_ext != NULL)
  1053. {
  1054. if (board_ext->config->IoAddress == 1) // PCI board setup
  1055. do_pci_search = 1;
  1056. board_ext = board_ext->board_ext;
  1057. }
  1058. //---- tally up boards
  1059. //---- interrupting board always first.
  1060. NumPCIRockets = 0;
  1061. NumISARockets = 0;
  1062. // configure ISA boards, and see if we have any pci boards
  1063. board_ext = Driver.board_ext;
  1064. while (board_ext != NULL)
  1065. {
  1066. if (board_ext->config->IoAddress >= 0x100) // ISA io address
  1067. {
  1068. board_ext->config->BusType = Isa;
  1069. board_ext->config->AiopIO[0] = board_ext->config->IoAddress;
  1070. board_ext->config->BaseIoAddr = board_ext->config->IoAddress;
  1071. board_ext->config->ISABrdIndex = NumISARockets;
  1072. if (NumISARockets == 0)
  1073. board_ext->config->BaseIoSize = 0x44;
  1074. else board_ext->config->BaseIoSize = 0x40;
  1075. ++NumISARockets;
  1076. }
  1077. else if (board_ext->config->IoAddress == 1) // PCI board setup
  1078. {
  1079. ++NumPCIRockets; // we have some pci boards configured
  1080. }
  1081. else if (board_ext->config->IoAddress == 0) // bad setup
  1082. {
  1083. Eprintf("Error, Io Address is 0.");
  1084. EventLog(DriverObject, STATUS_SUCCESS, SERIAL_RP_INIT_FAIL, 0, NULL);
  1085. return STATUS_SERIAL_NO_DEVICE_INITED;
  1086. }
  1087. board_ext = board_ext->board_ext; // next
  1088. }
  1089. // configure PCI boards, and see if we have any pci boards
  1090. if (NumPCIRockets > 0) // we have some pci boards configured
  1091. {
  1092. NumPCIBuses = FindPCIBus();
  1093. if (NumPCIBuses == 0)
  1094. {
  1095. Eprintf("Error, No PCI BUS");
  1096. return STATUS_SERIAL_NO_DEVICE_INITED;
  1097. }
  1098. if (FindPCIRockets(NumPCIBuses) != 0) // err, none found
  1099. {
  1100. Eprintf("Error, PCI board not found");
  1101. return STATUS_SERIAL_NO_DEVICE_INITED;
  1102. }
  1103. all_found = 1;
  1104. board_ext = Driver.board_ext;
  1105. while (board_ext != NULL)
  1106. {
  1107. if (board_ext->config->IoAddress == 1) // PCI board setup
  1108. {
  1109. // see if direct matches exist
  1110. if (FindPCIRocket(board_ext->config, 0) != 0)
  1111. {
  1112. all_found = 0; // not found
  1113. }
  1114. }
  1115. board_ext = board_ext->board_ext; // next
  1116. } // while more boards
  1117. // try again, this time allowing NumPorts <= actual_ports
  1118. if (!all_found)
  1119. {
  1120. board_ext = Driver.board_ext;
  1121. while (board_ext != NULL)
  1122. {
  1123. if ((board_ext->config->IoAddress == 1) && // PCI board setup
  1124. (board_ext->config->BaseIoAddr == 0)) // not setup yet
  1125. {
  1126. // see if match exist, NumPorts <= actual_ports
  1127. if (FindPCIRocket(board_ext->config, 1) != 0)
  1128. {
  1129. Eprintf("Error, PCI brd %d setup", BoardExtToNumber(board_ext)+1);
  1130. return STATUS_SERIAL_NO_DEVICE_INITED;
  1131. }
  1132. }
  1133. board_ext = board_ext->board_ext; // next
  1134. } // while more boards
  1135. Eprintf("Warning, PCI num-ports mismatch");
  1136. } // if (!all_found)
  1137. } // if (NumPCIRockets > 0)
  1138. return STATUS_SUCCESS;
  1139. }
  1140. /********************************************************************
  1141. load up the modem microcode from disk.
  1142. ********************************************************************/
  1143. int LoadModemCode(char *Firm_pathname,char *Loader_pathname)
  1144. {
  1145. #ifdef S_RK
  1146. MODEM_IMAGE Mi;
  1147. MODEM_IMAGE *pMi;
  1148. static char *Firm_def_pathname = {MODEM_CSREC_PATH};
  1149. static char *Loader_def_pathname = {MODEM_CSM_SREC_PATH};
  1150. #define MLOADER_TYPE "CSM"
  1151. #define FIRM_TYPE "MFW"
  1152. // flush any leftovers...
  1153. FreeModemFiles();
  1154. pMi = &Mi;
  1155. // first, do the FLM or CSM loader...
  1156. pMi->imagepath = Loader_pathname;
  1157. pMi->image = (UCHAR *)NULL;
  1158. pMi->imagesize = (ULONG)0;
  1159. pMi->imagetype = MLOADER_TYPE;
  1160. pMi->rc = 0;
  1161. if (pMi->imagepath == (char *)NULL)
  1162. pMi->imagepath = Loader_def_pathname;
  1163. pMi = ReadModemFile(pMi);
  1164. if (pMi->rc)
  1165. return(pMi->rc);
  1166. Driver.ModemLoaderCodeImage = pMi->image;
  1167. Driver.ModemLoaderCodeSize = pMi->imagesize;
  1168. // tinydump(Driver.ModemLoaderCodeImage,Driver.ModemLoaderCodeSize);
  1169. pMi->imagepath = Firm_pathname;
  1170. pMi->image = (UCHAR *)NULL;
  1171. pMi->imagesize = (ULONG)0;
  1172. pMi->imagetype = FIRM_TYPE;
  1173. pMi->rc = 0;
  1174. if (pMi->imagepath == (char *)NULL)
  1175. pMi->imagepath = Firm_def_pathname;
  1176. pMi = ReadModemFile(pMi);
  1177. if (pMi->rc) {
  1178. // earlier read of CSM should have been successful, so we should dump
  1179. // the CSM buffer before we bail...
  1180. if (Driver.ModemLoaderCodeImage)
  1181. {
  1182. our_free(Driver.ModemLoaderCodeImage,MLOADER_TYPE);
  1183. Driver.ModemLoaderCodeImage = (UCHAR *)NULL;
  1184. Driver.ModemLoaderCodeSize = 0;
  1185. }
  1186. return(pMi->rc);
  1187. }
  1188. Driver.ModemCodeImage = pMi->image;
  1189. Driver.ModemCodeSize = pMi->imagesize;
  1190. // tinydump(Driver.ModemCodeImage,Driver.ModemCodeSize);
  1191. #endif
  1192. return(0);
  1193. }
  1194. /********************************************************************
  1195. free up space no longer necessary...
  1196. ********************************************************************/
  1197. void FreeModemFiles(void)
  1198. {
  1199. #ifdef S_RK
  1200. if (Driver.ModemLoaderCodeImage)
  1201. {
  1202. our_free(Driver.ModemLoaderCodeImage,MLOADER_TYPE);
  1203. Driver.ModemLoaderCodeImage = (UCHAR *)NULL;
  1204. Driver.ModemLoaderCodeSize = 0;
  1205. }
  1206. if (Driver.ModemCodeImage)
  1207. {
  1208. our_free(Driver.ModemCodeImage,FIRM_TYPE);
  1209. Driver.ModemCodeImage = (UCHAR *)NULL;
  1210. Driver.ModemCodeSize = 0;
  1211. }
  1212. #endif
  1213. }
  1214. /********************************************************************
  1215. load up a specified file from disk...
  1216. ********************************************************************/
  1217. MODEM_IMAGE * ReadModemFile(MODEM_IMAGE *pMi)
  1218. {
  1219. #ifdef S_RK
  1220. NTSTATUS ntStatus;
  1221. HANDLE NtFileHandle;
  1222. OBJECT_ATTRIBUTES ObjectAttributes;
  1223. IO_STATUS_BLOCK IoStatus;
  1224. USTR_160 uname;
  1225. FILE_STANDARD_INFORMATION StandardInfo;
  1226. ULONG LengthOfFile;
  1227. CToUStr((PUNICODE_STRING)&uname,
  1228. pMi->imagepath,
  1229. sizeof(uname));
  1230. InitializeObjectAttributes(&ObjectAttributes,
  1231. &uname.ustr,
  1232. OBJ_CASE_INSENSITIVE,
  1233. NULL,
  1234. NULL);
  1235. ntStatus = ZwCreateFile(&NtFileHandle,
  1236. SYNCHRONIZE | FILE_READ_DATA,
  1237. &ObjectAttributes,
  1238. &IoStatus,
  1239. NULL, // alloc size = none
  1240. FILE_ATTRIBUTE_NORMAL,
  1241. FILE_SHARE_READ,
  1242. FILE_OPEN,
  1243. FILE_SYNCHRONOUS_IO_NONALERT,
  1244. NULL, // eabuffer
  1245. 0); // ealength
  1246. if (!NT_SUCCESS(ntStatus))
  1247. {
  1248. pMi->rc = 1;
  1249. return(pMi);
  1250. }
  1251. // query the object to determine its length...
  1252. ntStatus = ZwQueryInformationFile(NtFileHandle,
  1253. &IoStatus,
  1254. &StandardInfo,
  1255. sizeof(FILE_STANDARD_INFORMATION),
  1256. FileStandardInformation );
  1257. if (!NT_SUCCESS(ntStatus))
  1258. {
  1259. ZwClose(NtFileHandle);
  1260. pMi->rc = 2;
  1261. return(pMi);
  1262. }
  1263. LengthOfFile = StandardInfo.EndOfFile.LowPart;
  1264. if (LengthOfFile < 1)
  1265. {
  1266. ZwClose(NtFileHandle);
  1267. pMi->rc = 3;
  1268. return(pMi);
  1269. }
  1270. // allocate buffer for this file...
  1271. pMi->image = (UCHAR *)our_locked_alloc(LengthOfFile,pMi->imagetype);
  1272. if (pMi->image == (UCHAR *)NULL )
  1273. {
  1274. ZwClose(NtFileHandle );
  1275. pMi->rc = 4;
  1276. return(pMi);
  1277. }
  1278. // read the file into our buffer...
  1279. ntStatus = ZwReadFile(NtFileHandle,
  1280. NULL,
  1281. NULL,
  1282. NULL,
  1283. &IoStatus,
  1284. pMi->image,
  1285. LengthOfFile,
  1286. NULL,
  1287. NULL);
  1288. if((!NT_SUCCESS(ntStatus)) || (IoStatus.Information != LengthOfFile))
  1289. {
  1290. our_free(pMi->image,pMi->imagetype);
  1291. pMi->rc = 5;
  1292. return(pMi);
  1293. }
  1294. ZwClose(NtFileHandle);
  1295. pMi->imagesize = LengthOfFile;
  1296. #endif
  1297. return(pMi);
  1298. }
  1299. #ifdef DUMPFILE
  1300. /********************************************************************
  1301. grind through S3 files, dumping out each line. assumes there
  1302. are embedded CRs/LFs in the stream...
  1303. ********************************************************************/
  1304. void tinydump(char *ptr, int count)
  1305. {
  1306. int tbcount;
  1307. char tinybuf[128];
  1308. while (count > 0)
  1309. {
  1310. tbcount = 0;
  1311. if (*ptr >= '0')
  1312. {
  1313. while (*ptr >= '0')
  1314. {
  1315. --count;
  1316. tinybuf[tbcount++] = *(ptr++);
  1317. }
  1318. }
  1319. else
  1320. {
  1321. while (*ptr < '0')
  1322. {
  1323. --count;
  1324. ++ptr;
  1325. }
  1326. }
  1327. tinybuf[tbcount] = 0;
  1328. if (tbcount)
  1329. MyKdPrint(D_Init,("%s\r",tinybuf));
  1330. }
  1331. MyKdPrint(D_Init,("\r"));
  1332. }
  1333. #endif