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.

3239 lines
105 KiB

  1. /*-------------------------------------------------------------------
  2. | ioctl.c - handle all the misc. serial ioctl calls.
  3. 4-05-00 - Add address (&) operator to actual parameter passed to sWriteTxBlk
  4. 5-13-99 - enable RTS toggling for VS
  5. 2-15-99 - make SerialSetHandflow() public, so pnp can call it. kpb
  6. 1-21-99 - fix immed char send to trigger EV_TXEMPTY, add some support
  7. for VS immediate char send.
  8. 11-24-98 - update DBG kdprint messages for event handling tests - kpb
  9. 9-24-98 - include tx-shift-reg in getcommstat report - kpb.
  10. 4-29-98 - adjust break output to start immediately if possible - kpb.
  11. Copyright 1993-98 Comtrol Corporation. All rights reserved.
  12. |--------------------------------------------------------------------*/
  13. #include "precomp.h"
  14. typedef struct {
  15. ULONG struct_size;
  16. ULONG num_ports;
  17. ULONG total_loads;
  18. ULONG good_loads;
  19. ULONG backup_server;
  20. ULONG state;
  21. ULONG iframes_sent;
  22. ULONG rawframes_sent; // was send_rawframes
  23. ULONG ctlframes_sent; // was send_ctlframes
  24. ULONG iframes_resent; // was pkt_resends
  25. ULONG iframes_outofseq; // was ErrBadIndex
  26. ULONG frames_rcvd; // was: rec_pkts
  27. ULONG nic_index;
  28. unsigned char dest_addr[6];
  29. } PROBE_DEVICE_STRUCT;
  30. typedef struct {
  31. ULONG struct_size;
  32. ULONG Open;
  33. ULONG pkt_sent;
  34. ULONG pkt_rcvd_ours;
  35. ULONG pkt_rcvd_not_ours;
  36. char NicName[64];
  37. unsigned char address[6];
  38. } PROBE_NIC_STRUCT;
  39. static PSERIAL_DEVICE_EXTENSION find_ext_mac_match(unsigned char *mac_addr);
  40. static int ProbeDevices(unsigned char *pPtr, int availableLength);
  41. static int ProbeNic(unsigned char *pPtr, int availableLength);
  42. /*-------------------------------------------------------------------
  43. Function : SerialIoControl
  44. Purpose: Process Ioctls for a device.
  45. Call: SerialIoControl(DeviceObject,Irp)
  46. PDEVICE_OBJECT DeviceObject: Pointer to the Device Object
  47. PIRP Irp: Pointer to the I/O Request Packet
  48. Return: STATUS_SUCCESS: always
  49. STATUS_FAIL: if request couldn't be fulfilled
  50. Comments: This function is the device driver IOCTL entry point.
  51. |--------------------------------------------------------------------*/
  52. NTSTATUS SerialIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  53. {
  54. NTSTATUS Status = STATUS_SUCCESS;
  55. PIO_STACK_LOCATION IrpSp;
  56. PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
  57. KIRQL OldIrql;
  58. BOOLEAN acceptingIRPs;
  59. acceptingIRPs = SerialIRPPrologue(Extension);
  60. if (acceptingIRPs == FALSE) {
  61. MyKdPrint(D_Ioctl,("Ioctl:no irps accepted!\n"))
  62. Irp->IoStatus.Information = 0;
  63. Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
  64. SerialCompleteRequest(Extension, Irp, IO_NO_INCREMENT);
  65. return STATUS_NO_SUCH_DEVICE;
  66. }
  67. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  68. Irp->IoStatus.Information = 0L;
  69. MyKdPrint(D_Ioctl,("SerialIoControl: %x\n",
  70. IrpSp->Parameters.DeviceIoControl.IoControlCode))
  71. // Make sure we aren't aborting due to error (ERROR_ABORT)
  72. if (Extension->ErrorWord)
  73. {
  74. if (Extension->DeviceType == DEV_PORT)
  75. {
  76. if (SerialCompleteIfError(DeviceObject, Irp) != STATUS_SUCCESS)
  77. {
  78. MyKdPrint(D_Ioctl,("ErrSet, Cancel!\n"))
  79. {ExtTrace(Extension,D_Ioctl,"ErrSet!");}
  80. return STATUS_CANCELLED;
  81. }
  82. }
  83. }
  84. //
  85. // Make sure IOCTL is applicable for the device type (i.e. ignore port
  86. // level IOCTL's if board object is specified
  87. //
  88. if (Extension->DeviceType == DEV_BOARD)
  89. {
  90. switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
  91. {
  92. case IOCTL_SERIAL_CONFIG_SIZE:
  93. case IOCTL_SERIAL_GET_COMMCONFIG:
  94. case IOCTL_SERIAL_SET_COMMCONFIG:
  95. case IOCTL_RCKT_GET_STATS:
  96. case IOCTL_RCKT_ISR_CNT:
  97. case IOCTL_RCKT_CHECK:
  98. case IOCTL_RCKT_MONALL:
  99. case IOCTL_RCKT_SET_MODEM_RESET:
  100. case IOCTL_RCKT_CLEAR_MODEM_RESET:
  101. case IOCTL_RCKT_SEND_MODEM_ROW:
  102. case IOCTL_RCKT_SET_MODEM_RESET_OLD:
  103. case IOCTL_RCKT_CLEAR_MODEM_RESET_OLD:
  104. case IOCTL_RCKT_GET_RCKTMDM_INFO_OLD:
  105. case IOCTL_RCKT_SEND_MODEM_ROW_OLD:
  106. break; // Allowable board level IOCTL's
  107. default:
  108. MyKdPrint (D_Ioctl, (" Bad Status: %xH on IIOCTL: %xH\n", Status,
  109. IrpSp->Parameters.DeviceIoControl.IoControlCode));
  110. ExtTrace2 (Extension, D_Ioctl, " Bad Status:%xH on IIOCTL:%xH",
  111. Status, IrpSp->Parameters.DeviceIoControl.IoControlCode);
  112. Irp->IoStatus.Information = 0;
  113. Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  114. SerialCompleteRequest(Extension, Irp, IO_NO_INCREMENT);
  115. return STATUS_INVALID_DEVICE_REQUEST;
  116. }
  117. };
  118. // Main IOCTL switch
  119. //ExtTrace1(Extension,D_Ioctl,"Ioctl:%x",
  120. // IrpSp->Parameters.DeviceIoControl.IoControlCode);
  121. switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
  122. {
  123. //******************************
  124. case IOCTL_SERIAL_GET_STATS : // get performace stats
  125. {
  126. PSERIALPERF_STATS sp = Irp->AssociatedIrp.SystemBuffer;
  127. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  128. sizeof(SERIALPERF_STATS)) {
  129. Status = STATUS_BUFFER_TOO_SMALL;
  130. break;
  131. }
  132. Irp->IoStatus.Information = sizeof(SERIALPERF_STATS);
  133. Status = STATUS_SUCCESS;
  134. sp->TransmittedCount = Extension->OurStats.TransmittedCount -
  135. Extension->OldStats.TransmittedCount;
  136. sp->FrameErrorCount = Extension->OurStats.FrameErrorCount -
  137. Extension->OldStats.FrameErrorCount;
  138. sp->SerialOverrunErrorCount = Extension->OurStats.SerialOverrunErrorCount -
  139. Extension->OldStats.SerialOverrunErrorCount;
  140. sp->BufferOverrunErrorCount = Extension->OurStats.BufferOverrunErrorCount -
  141. Extension->OldStats.BufferOverrunErrorCount;
  142. sp->ParityErrorCount = Extension->OurStats.ParityErrorCount -
  143. Extension->OldStats.ParityErrorCount;
  144. }
  145. break;
  146. //******************************
  147. case IOCTL_SERIAL_CLEAR_STATS : // clear performace stats
  148. {
  149. Extension->OldStats.TransmittedCount =
  150. Extension->OurStats.TransmittedCount;
  151. Extension->OldStats.FrameErrorCount =
  152. Extension->OurStats.FrameErrorCount;
  153. Extension->OldStats.SerialOverrunErrorCount =
  154. Extension->OurStats.SerialOverrunErrorCount;
  155. Extension->OldStats.BufferOverrunErrorCount =
  156. Extension->OurStats.BufferOverrunErrorCount;
  157. Extension->OldStats.ParityErrorCount =
  158. Extension->OurStats.ParityErrorCount;
  159. Irp->IoStatus.Information = 0;
  160. Status = STATUS_SUCCESS;
  161. }
  162. break;
  163. //******************************
  164. case IOCTL_SERIAL_SET_BAUD_RATE :
  165. {
  166. ULONG DesiredBaudRate;
  167. MyKdPrint(D_Ioctl,("[Set Baud Rate]\n"))
  168. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  169. sizeof(SERIAL_BAUD_RATE))
  170. {
  171. Status = STATUS_BUFFER_TOO_SMALL;
  172. MyKdPrint(D_Ioctl,("[Buffer too Small]\n"))
  173. break;
  174. }
  175. DesiredBaudRate =
  176. ((PSERIAL_BAUD_RATE)(Irp->AssociatedIrp.SystemBuffer))->BaudRate;
  177. ExtTrace1(Extension,D_Ioctl,"Set Baud Rate:%d",DesiredBaudRate);
  178. Status = ProgramBaudRate(Extension,DesiredBaudRate);
  179. break;
  180. }
  181. //******************************
  182. case IOCTL_SERIAL_GET_BAUD_RATE:
  183. {
  184. PSERIAL_BAUD_RATE Br =
  185. (PSERIAL_BAUD_RATE)Irp->AssociatedIrp.SystemBuffer;
  186. MyKdPrint(D_Ioctl,("[Get Baud Rate]\n"))
  187. ExtTrace1(Extension,D_Ioctl,"Get Baud Rate:%d",Extension->BaudRate);
  188. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  189. sizeof(SERIAL_BAUD_RATE))
  190. {
  191. Status = STATUS_BUFFER_TOO_SMALL;
  192. break;
  193. }
  194. KeAcquireSpinLock(&Extension->ControlLock,&OldIrql);
  195. Br->BaudRate = Extension->BaudRate;
  196. KeReleaseSpinLock(&Extension->ControlLock,OldIrql);
  197. Irp->IoStatus.Information = sizeof(SERIAL_BAUD_RATE);
  198. break;
  199. }
  200. //*********************************
  201. case IOCTL_SERIAL_SET_LINE_CONTROL:
  202. {
  203. PSERIAL_LINE_CONTROL DesiredLineControl;
  204. MyKdPrint(D_Ioctl,("[Set Line Control]\n"))
  205. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  206. sizeof(SERIAL_LINE_CONTROL))
  207. {
  208. Status = STATUS_BUFFER_TOO_SMALL;
  209. break;
  210. }
  211. DesiredLineControl =
  212. ((PSERIAL_LINE_CONTROL)(Irp->AssociatedIrp.SystemBuffer));
  213. ExtTrace(Extension,D_Ioctl, "Set Line Ctrl");
  214. Status = ProgramLineControl(Extension,DesiredLineControl);
  215. break;
  216. }
  217. //*********************************
  218. case IOCTL_SERIAL_GET_LINE_CONTROL:
  219. {
  220. PSERIAL_LINE_CONTROL Lc =
  221. (PSERIAL_LINE_CONTROL)Irp->AssociatedIrp.SystemBuffer;
  222. MyKdPrint(D_Ioctl,("[Get Line Control]\n"))
  223. ExtTrace(Extension,D_Ioctl,"Get Line Ctrl");
  224. Irp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);
  225. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  226. sizeof(SERIAL_LINE_CONTROL))
  227. {
  228. Status = STATUS_BUFFER_TOO_SMALL;
  229. break;
  230. }
  231. Lc->Parity=Extension->LineCtl.Parity;
  232. Lc->WordLength=Extension->LineCtl.WordLength;
  233. Lc->StopBits=Extension->LineCtl.StopBits;
  234. break;
  235. }
  236. //******************************
  237. case IOCTL_SERIAL_SET_TIMEOUTS:
  238. {
  239. PSERIAL_TIMEOUTS NewTimeouts =
  240. ((PSERIAL_TIMEOUTS)(Irp->AssociatedIrp.SystemBuffer));
  241. MyKdPrint(D_Ioctl,("[Set Timeouts]\n"))
  242. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  243. sizeof(SERIAL_TIMEOUTS))
  244. {
  245. Status = STATUS_BUFFER_TOO_SMALL;
  246. break;
  247. }
  248. if ((NewTimeouts->ReadIntervalTimeout == MAXULONG) &&
  249. (NewTimeouts->ReadTotalTimeoutMultiplier == MAXULONG) &&
  250. (NewTimeouts->ReadTotalTimeoutConstant == MAXULONG))
  251. {
  252. Status = STATUS_INVALID_PARAMETER;
  253. break;
  254. }
  255. ExtTrace3(Extension,D_Ioctl,"Timeouts-RIT:%xH RM:%xH RC:%xH",
  256. NewTimeouts->ReadIntervalTimeout,
  257. NewTimeouts->ReadTotalTimeoutMultiplier,
  258. NewTimeouts->ReadTotalTimeoutConstant);
  259. ExtTrace2(Extension,D_Ioctl," WM:%xH WC:%xH",
  260. NewTimeouts->WriteTotalTimeoutMultiplier,
  261. NewTimeouts->WriteTotalTimeoutConstant);
  262. KeAcquireSpinLock( &Extension->ControlLock, &OldIrql );
  263. Extension->Timeouts.ReadIntervalTimeout =
  264. NewTimeouts->ReadIntervalTimeout;
  265. Extension->Timeouts.ReadTotalTimeoutMultiplier =
  266. NewTimeouts->ReadTotalTimeoutMultiplier;
  267. Extension->Timeouts.ReadTotalTimeoutConstant =
  268. NewTimeouts->ReadTotalTimeoutConstant;
  269. Extension->Timeouts.WriteTotalTimeoutMultiplier =
  270. NewTimeouts->WriteTotalTimeoutMultiplier;
  271. Extension->Timeouts.WriteTotalTimeoutConstant =
  272. NewTimeouts->WriteTotalTimeoutConstant;
  273. KeReleaseSpinLock( &Extension->ControlLock, OldIrql );
  274. break;
  275. }
  276. //******************************
  277. case IOCTL_SERIAL_GET_TIMEOUTS:
  278. {
  279. MyKdPrint(D_Ioctl,("[Get Timeouts]\n"))
  280. ExtTrace(Extension,D_Ioctl,"Get Timeouts");
  281. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  282. sizeof(SERIAL_TIMEOUTS))
  283. {
  284. Status = STATUS_BUFFER_TOO_SMALL;
  285. break;
  286. }
  287. KeAcquireSpinLock( &Extension->ControlLock, &OldIrql );
  288. *((PSERIAL_TIMEOUTS)Irp->AssociatedIrp.SystemBuffer) = Extension->Timeouts;
  289. Irp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);
  290. KeReleaseSpinLock( &Extension->ControlLock, OldIrql );
  291. break;
  292. }
  293. //**************************
  294. case IOCTL_SERIAL_SET_CHARS:
  295. {
  296. SERIAL_IOCTL_SYNC S;
  297. PSERIAL_CHARS NewChars =
  298. ((PSERIAL_CHARS)(Irp->AssociatedIrp.SystemBuffer));
  299. MyKdPrint(D_Ioctl,("[Set Xon/Xoff Chars]\n"))
  300. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  301. sizeof(SERIAL_CHARS))
  302. {
  303. Status = STATUS_BUFFER_TOO_SMALL;
  304. break;
  305. }
  306. ExtTrace3(Extension,D_Ioctl,"Set Chars Xon:%xH, Xoff:%xH Evt:%xH",
  307. NewChars->XonChar,NewChars->XoffChar, NewChars->EventChar);
  308. // The only thing that can be wrong with the chars
  309. // is that the xon and xoff characters are the same.
  310. #ifdef COMMENT_OUT
  311. // comment out kpb, problem with hardware flow control, nt
  312. // may connect and do this(Delrina WinFaxPro, SAPS modem pooling
  313. // had trouble erroring out, but not on standard microsoft port.
  314. if (NewChars->XonChar == NewChars->XoffChar)
  315. {
  316. Status = STATUS_INVALID_PARAMETER;
  317. break;
  318. }
  319. #endif
  320. // We acquire the control lock so that only
  321. // one request can GET or SET the characters
  322. // at a time. The sets could be synchronized
  323. // by the interrupt spinlock, but that wouldn't
  324. // prevent multiple gets at the same time.
  325. S.Extension = Extension;
  326. S.Data = NewChars;
  327. KeAcquireSpinLock(&Extension->ControlLock,&OldIrql);
  328. Extension->SpecialChars.EofChar = NewChars->EofChar;
  329. Extension->SpecialChars.ErrorChar = NewChars->ErrorChar;
  330. Extension->SpecialChars.BreakChar=NewChars->BreakChar;
  331. // Only set up byte in case we're already EventChar-ing it,
  332. // Actual programming of interrupt is done in wait on mask call.
  333. Extension->SpecialChars.EventChar=NewChars->EventChar;
  334. Extension->SpecialChars.XonChar=NewChars->XonChar;
  335. Extension->SpecialChars.XoffChar=NewChars->XoffChar;
  336. #ifdef S_RK
  337. sSetRxCmpVal1(Extension->ChP,NewChars->EventChar);
  338. sSetTxXONChar(Extension->ChP,NewChars->XonChar);
  339. sSetTxXOFFChar(Extension->ChP,NewChars->XoffChar);
  340. #else
  341. pSetEventChar(Extension->Port,NewChars->EventChar);
  342. pSetXONChar(Extension->Port,NewChars->XonChar);
  343. pSetXOFFChar(Extension->Port,NewChars->XoffChar);
  344. #endif
  345. KeReleaseSpinLock(&Extension->ControlLock,OldIrql);
  346. break;
  347. }
  348. //**************************
  349. case IOCTL_SERIAL_GET_CHARS:
  350. {
  351. MyKdPrint(D_Ioctl,("[Get Xon/Xoff Chars]\n"))
  352. ExtTrace(Extension,D_Ioctl,"Get Xon/Xoff Chars");
  353. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  354. sizeof(SERIAL_CHARS))
  355. {
  356. Status = STATUS_BUFFER_TOO_SMALL;
  357. break;
  358. }
  359. KeAcquireSpinLock(&Extension->ControlLock,&OldIrql);
  360. // Copy the whole struct over to the buffer
  361. *((PSERIAL_CHARS)Irp->AssociatedIrp.SystemBuffer) =
  362. Extension->SpecialChars;
  363. Irp->IoStatus.Information = sizeof(SERIAL_CHARS);
  364. KeReleaseSpinLock(&Extension->ControlLock,OldIrql);
  365. break;
  366. }
  367. case IOCTL_SERIAL_SET_DTR:
  368. case IOCTL_SERIAL_CLR_DTR:
  369. {
  370. MyKdPrint(D_Ioctl,("[Set and Clr DTR]\n"))
  371. // We acquire the lock so that we can check whether
  372. // automatic dtr flow control is enabled. If it is,
  373. // then return an error since the app is not allowed
  374. // to touch this if it is automatic.
  375. KeAcquireSpinLock(&Extension->ControlLock, &OldIrql);
  376. if ((Extension->HandFlow.ControlHandShake & SERIAL_DTR_MASK)
  377. == SERIAL_DTR_HANDSHAKE)
  378. { // bogus
  379. //Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  380. //Status = STATUS_INVALID_PARAMETER;
  381. }
  382. else
  383. {
  384. if(IrpSp->Parameters.DeviceIoControl.IoControlCode ==
  385. IOCTL_SERIAL_SET_DTR )
  386. {
  387. ExtTrace(Extension,D_Ioctl,"Set DTR");
  388. #ifdef S_VS
  389. pSetDTR(Extension->Port);
  390. #else
  391. sSetDTR(Extension->ChP);
  392. #endif
  393. Extension->DTRRTSStatus |= SERIAL_DTR_STATE;
  394. }
  395. else
  396. {
  397. //must be IOCTL_SERIAL_CLR_DTR
  398. ExtTrace(Extension,D_Ioctl,"Clr DTR");
  399. #ifdef S_VS
  400. pClrDTR(Extension->Port);
  401. #else
  402. sClrDTR(Extension->ChP);
  403. #endif
  404. Extension->DTRRTSStatus &= ~SERIAL_DTR_STATE;
  405. }
  406. }
  407. KeReleaseSpinLock(&Extension->ControlLock, OldIrql);
  408. break;
  409. }
  410. //************************
  411. case IOCTL_SERIAL_RESET_DEVICE:
  412. MyKdPrint(D_Ioctl,("[Reset Device]\n"));
  413. ExtTrace(Extension,D_Ioctl,"Reset Device");
  414. // Example driver also takes no action
  415. break;
  416. //************************
  417. case IOCTL_SERIAL_SET_RTS:
  418. MyKdPrint(D_Ioctl,("[Set RTS]\n"));
  419. ExtTrace(Extension,D_Ioctl,"Set RTS");
  420. // Make sure RTS isn't already used for handshake or toggle
  421. if( ( (Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
  422. SERIAL_RTS_HANDSHAKE) ||
  423. ( (Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
  424. SERIAL_TRANSMIT_TOGGLE)
  425. )
  426. {
  427. Status = STATUS_INVALID_PARAMETER;
  428. ExtTrace(Extension,D_Ioctl," not set,flow");
  429. }
  430. else
  431. {
  432. if (!(Extension->Option & OPTION_RS485_OVERRIDE))
  433. {
  434. #ifdef S_VS
  435. pSetRTS(Extension->Port);
  436. #else
  437. sSetRTS(Extension->ChP);
  438. #endif
  439. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  440. }
  441. else
  442. {
  443. ExtTrace(Extension,D_Ioctl," not set,485");
  444. }
  445. }
  446. break;
  447. //************************
  448. case IOCTL_SERIAL_CLR_RTS:
  449. MyKdPrint(D_Ioctl,("[Clr RTS]\n"));
  450. ExtTrace(Extension,D_Ioctl,"Clr RTS");
  451. // Make sure RTS isn't already used for handshake or toggle
  452. if( ( (Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
  453. SERIAL_RTS_HANDSHAKE) ||
  454. ( (Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) ==
  455. SERIAL_TRANSMIT_TOGGLE)
  456. )
  457. {
  458. Status = STATUS_INVALID_PARAMETER;
  459. ExtTrace(Extension,D_Ioctl," not clr,flow");
  460. }
  461. else
  462. {
  463. if (!(Extension->Option & OPTION_RS485_OVERRIDE))
  464. {
  465. #ifdef S_VS
  466. pClrRTS(Extension->Port);
  467. #else
  468. sClrRTS(Extension->ChP);
  469. #endif
  470. Extension->DTRRTSStatus &= ~SERIAL_RTS_STATE;
  471. }
  472. else
  473. {
  474. ExtTrace(Extension,D_Ioctl," not clr,485");
  475. }
  476. }
  477. break;
  478. //*************************
  479. case IOCTL_SERIAL_SET_XOFF:
  480. MyKdPrint(D_Ioctl,("[Set Xoff]\n"));
  481. ExtTrace(Extension,D_Ioctl,"Set Xoff");
  482. #ifdef S_RK
  483. if (sIsTxSoftFlowCtlEnabled(Extension->ChP))
  484. {
  485. sDisTxSoftFlowCtl(Extension->ChP); // turn off Tx software flow control
  486. sDisTransmit(Extension->ChP); // Stop the transmitter
  487. sEnRxIntCompare2(Extension->ChP,(unsigned char) Extension->SpecialChars.XonChar);
  488. Extension->TXHolding |= SERIAL_TX_XOFF;
  489. Extension->TXHolding |= ST_XOFF_FAKE;
  490. }
  491. #else
  492. if (Extension->HandFlow.FlowReplace & SERIAL_AUTO_TRANSMIT)
  493. {
  494. Extension->TXHolding |= SERIAL_TX_XOFF;
  495. pOverrideSetXoff(Extension->Port);
  496. }
  497. #endif
  498. break;
  499. //************************
  500. case IOCTL_SERIAL_SET_XON:
  501. MyKdPrint(D_Ioctl,("[Set Xon]\n"));
  502. ExtTrace(Extension,D_Ioctl,"Set Xon");
  503. #ifdef S_VS
  504. {
  505. pOverrideClearXoff(Extension->Port);
  506. Extension->TXHolding &= ~SERIAL_TX_XOFF;
  507. }
  508. #else
  509. if (Extension->TXHolding & ST_XOFF_FAKE)
  510. {
  511. Extension->TXHolding &= ~SERIAL_TX_XOFF;
  512. Extension->TXHolding &= ~ST_XOFF_FAKE;
  513. if ((Extension->TXHolding &
  514. (SERIAL_TX_DCD | SERIAL_TX_DSR | ST_XOFF_FAKE)) == 0)
  515. sEnTransmit(Extension->ChP); // Start up the transmitter
  516. sDisRxCompare2(Extension->ChP);
  517. sEnTxSoftFlowCtl(Extension->ChP); // turn off Tx software flow control
  518. }
  519. // override an actual XOFF from remote
  520. sClrTxXOFF(Extension->ChP);
  521. // check for IOCTL_SERIAL_SET_XOFF state
  522. if(Extension->TXHolding & SERIAL_TX_XOFF)
  523. {
  524. // Make sure BREAK state hasn't disabled the Transmitter
  525. if(!(Extension->TXHolding & SERIAL_TX_BREAK))
  526. sEnTransmit(Extension->ChP);
  527. Extension->TXHolding &= ~SERIAL_TX_XOFF;
  528. }
  529. #endif
  530. break;
  531. //******************************
  532. case IOCTL_SERIAL_SET_BREAK_ON:
  533. {
  534. ExtTrace(Extension,D_Ioctl,"Set Break on");
  535. #ifdef S_VS
  536. pSetBreak(Extension->Port);
  537. Extension->TXHolding |= SERIAL_TX_BREAK;
  538. #else
  539. IoAcquireCancelSpinLock(&OldIrql);
  540. if( !(Extension->TXHolding & SERIAL_TX_BREAK) )
  541. {
  542. // Stop the transmitter
  543. sDisTransmit(Extension->ChP);
  544. // Request break, Polling will check on Transmitter empty
  545. Extension->TXHolding |= SERIAL_TX_BREAK;
  546. // Make sure Transmitter is empty before slamming BREAK
  547. // Check the bit twice in case of time between buf and txshr load
  548. if( (sGetChanStatusLo(Extension->ChP) & TXSHRMT) &&
  549. (sGetChanStatusLo(Extension->ChP) & TXSHRMT) )
  550. {
  551. sSendBreak(Extension->ChP);
  552. Extension->DevStatus &= ~COM_REQUEST_BREAK;
  553. }
  554. else
  555. Extension->DevStatus |= COM_REQUEST_BREAK;
  556. }
  557. IoReleaseCancelSpinLock(OldIrql);
  558. #endif
  559. break;
  560. }
  561. //******************************
  562. case IOCTL_SERIAL_SET_BREAK_OFF:
  563. {
  564. ExtTrace(Extension,D_Ioctl,"Set Break Off");
  565. #ifdef S_VS
  566. if (Extension->TXHolding & SERIAL_TX_BREAK)
  567. {
  568. Extension->TXHolding &= ~SERIAL_TX_BREAK;
  569. pClrBreak(Extension->Port);
  570. }
  571. #else
  572. IoAcquireCancelSpinLock(&OldIrql);
  573. if(Extension->TXHolding & SERIAL_TX_BREAK)
  574. {
  575. Extension->TXHolding &= ~SERIAL_TX_BREAK;
  576. sClrBreak(Extension->ChP);
  577. if(!(Extension->TXHolding & SERIAL_TX_XOFF))
  578. {
  579. sEnTransmit(Extension->ChP);
  580. }
  581. }
  582. if(Extension->DevStatus & COM_REQUEST_BREAK)
  583. {
  584. // If we hit this code, the requested BREAK will not have gone out
  585. Extension->DevStatus &= ~COM_REQUEST_BREAK;
  586. }
  587. IoReleaseCancelSpinLock(OldIrql);
  588. #endif
  589. break;
  590. }
  591. //******************************
  592. case IOCTL_SERIAL_SET_QUEUE_SIZE:
  593. {
  594. LONG new_size;
  595. PUCHAR NewBuf;
  596. PSERIAL_QUEUE_SIZE Rs =
  597. ((PSERIAL_QUEUE_SIZE)(Irp->AssociatedIrp.SystemBuffer));
  598. MyKdPrint(D_Ioctl,("[Set Queue Size]\n"));
  599. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  600. sizeof(SERIAL_QUEUE_SIZE))
  601. {
  602. Status = STATUS_BUFFER_TOO_SMALL;
  603. break;
  604. }
  605. new_size = (LONG) Rs->InSize;
  606. ExtTrace1(Extension,D_Ioctl,"Set Queue Size, In:%d", new_size);
  607. if (new_size > 0x20000L)
  608. new_size = 0x20000L; /// limit to about 128K
  609. // try to allocate buffer here if user requests larger buffer
  610. // don't resize if they want to shrink(why bother)
  611. if (new_size <= Extension->RxQ.QSize)
  612. {
  613. Status = STATUS_SUCCESS;
  614. break;
  615. }
  616. ++new_size; // some circular queue wierdness
  617. IoAcquireCancelSpinLock(&OldIrql);
  618. NewBuf = our_locked_alloc(new_size+16, "exRX"); // add some slop
  619. if (NewBuf != NULL)
  620. {
  621. // Eprintf("Resized Buffer, new:%d, old:%d",new_size-1, Extension->RxQ.QSize-1);
  622. Extension->RxQ.QSize = new_size;
  623. our_free(Extension->RxQ.QBase, "exRX");
  624. Extension->RxQ.QBase= NewBuf;
  625. Extension->RxQ.QGet = 0;
  626. Extension->RxQ.QPut = 0;
  627. Status = STATUS_SUCCESS;
  628. }
  629. else
  630. {
  631. Status = STATUS_INVALID_PARAMETER; // not the greatest choise
  632. }
  633. IoReleaseCancelSpinLock(OldIrql);
  634. break;
  635. }
  636. //******************************
  637. case IOCTL_SERIAL_GET_WAIT_MASK:
  638. // This mask contains the various Events the WaitIrp is waiting
  639. // for from SetCommMask(), such as EV_BREAK, EV_CTS, EV_DSR,
  640. // EV_ERR, EV_RING, EV_RLSD, EV_RXCHAR, EV_RXFLAG, EV_TXEMPTY
  641. MyKdPrint(D_Ioctl,("[Get Wait Mask:%xH\n]",Extension->IsrWaitMask))
  642. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  643. sizeof(ULONG))
  644. {
  645. Status = STATUS_BUFFER_TOO_SMALL;
  646. break;
  647. }
  648. ExtTrace1(Extension,D_Ioctl,"Get Wait Mask:%xH",Extension->IsrWaitMask);
  649. Irp->IoStatus.Information = sizeof(ULONG);
  650. *((ULONG *)Irp->AssociatedIrp.SystemBuffer) = Extension->IsrWaitMask;
  651. break;
  652. //******************************
  653. case IOCTL_SERIAL_SET_WAIT_MASK:
  654. {
  655. ULONG NewMask;
  656. if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  657. sizeof(ULONG) )
  658. {
  659. Status = STATUS_BUFFER_TOO_SMALL;
  660. break;
  661. }
  662. else
  663. {
  664. NewMask = *((ULONG *)Irp->AssociatedIrp.SystemBuffer);
  665. MyKdPrint(D_Ioctl,("set wait mask:%xH\n",NewMask))
  666. ExtTrace1(Extension,D_Ioctl,"Set Wait Mask:%xH",NewMask);
  667. }
  668. //------- Complete the old wait if there is one.
  669. #ifdef NEW_WAIT_SYNC_LOCK
  670. SyncUp(Driver.InterruptObject,
  671. &Driver.TimerLock,
  672. SerialGrabWaitFromIsr,
  673. Extension);
  674. #endif
  675. IoAcquireCancelSpinLock(&OldIrql);
  676. if (Extension->CurrentWaitIrp)
  677. {
  678. PIRP Irp;
  679. Extension->IrpMaskLocation = NULL;
  680. MyKdPrint(D_Ioctl,("[kill old wait]\n"))
  681. ExtTrace(Extension,D_Ioctl, " Kill Old Wait");
  682. *(ULONG *)Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer = 0;
  683. Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
  684. Extension->CurrentWaitIrp->IoStatus.Status = STATUS_SUCCESS;
  685. Irp = Extension->CurrentWaitIrp;
  686. IoSetCancelRoutine(Irp, NULL);
  687. Extension->CurrentWaitIrp = 0;
  688. IoReleaseCancelSpinLock(OldIrql);
  689. SerialCompleteRequest(Extension, Irp, IO_SERIAL_INCREMENT);
  690. }
  691. else
  692. IoReleaseCancelSpinLock(OldIrql);
  693. //----- retain any bits from when no WaitIrp present
  694. Extension->HistoryMask &= NewMask;
  695. //----- set the mask of interested events
  696. Extension->IsrWaitMask = NewMask;
  697. // move this from wait_on_mask call to here, kpb, 1-16-97
  698. #ifdef S_RK
  699. if (Extension->IsrWaitMask & SERIAL_EV_RXFLAG)
  700. {
  701. sEnRxIntCompare1(Extension->ChP,
  702. Extension->SpecialChars.EventChar);
  703. }
  704. else
  705. {
  706. sDisRxCompare1(Extension->ChP);
  707. }
  708. #endif
  709. }
  710. break;
  711. //******************************
  712. case IOCTL_SERIAL_WAIT_ON_MASK:
  713. {
  714. MyKdPrint(D_Ioctl,("[wait on mask]\n"))
  715. ExtTrace(Extension,D_Ioctl,"Wait On Mask");
  716. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  717. sizeof(ULONG))
  718. {
  719. ExtTrace(Extension,D_Ioctl,"Wait IRP, Bad Size");
  720. Status = STATUS_BUFFER_TOO_SMALL;
  721. break;
  722. }
  723. // put this in to fix an incompatibility with WaitOnMultipleObjects()
  724. // 6-26-98 kpb
  725. if (Extension->CurrentWaitIrp)
  726. {
  727. MyKdPrint(D_Ioctl,("[Already pending]\n"))
  728. Status = STATUS_INVALID_PARAMETER;
  729. break;
  730. }
  731. #ifdef NEW_WAIT_SYNC_LOCK
  732. SyncUp(Driver.InterruptObject,
  733. &Driver.TimerLock,
  734. SerialGrabWaitFromIsr,
  735. Extension);
  736. #else
  737. Extension->WaitIsISRs = 0;
  738. Extension->IrpMaskLocation = &Extension->DummyIrpMaskLoc;
  739. #endif
  740. IoAcquireCancelSpinLock(&OldIrql);
  741. //------- Complete the old wait if there is one.
  742. if (Extension->CurrentWaitIrp)
  743. {
  744. PIRP Irp;
  745. MyKdPrint(D_Ioctl,("[kill old wait]\n"))
  746. ExtTrace(Extension,D_Ioctl, " Kill Old Wait");
  747. *(ULONG *)Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer = 0;
  748. Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
  749. Extension->CurrentWaitIrp->IoStatus.Status = STATUS_SUCCESS;
  750. Irp = Extension->CurrentWaitIrp;
  751. IoSetCancelRoutine(Irp, NULL);
  752. Extension->CurrentWaitIrp = 0;
  753. IoReleaseCancelSpinLock(OldIrql);
  754. SerialCompleteRequest(Extension, Irp, IO_SERIAL_INCREMENT);
  755. }
  756. else
  757. IoReleaseCancelSpinLock(OldIrql);
  758. if (Extension->IsrWaitMask == 0)
  759. {
  760. ExtTrace(Extension,D_Ioctl," WaitMask==0");
  761. Status = STATUS_INVALID_PARAMETER;
  762. }
  763. else
  764. {
  765. IoAcquireCancelSpinLock(&OldIrql);
  766. if (Irp->Cancel)
  767. {
  768. IoReleaseCancelSpinLock(OldIrql);
  769. Irp->IoStatus.Status = STATUS_CANCELLED;
  770. SerialCompleteRequest(Extension, Irp, 0);
  771. Status = STATUS_CANCELLED;
  772. }
  773. else
  774. {
  775. Extension->CurrentWaitIrp = Irp;
  776. Irp->IoStatus.Status = STATUS_PENDING;
  777. IoMarkIrpPending(Irp);
  778. IoSetCancelRoutine(Extension->CurrentWaitIrp, SerialCancelWait);
  779. IoReleaseCancelSpinLock(OldIrql);
  780. // give to ISR to process
  781. Extension->IrpMaskLocation = (ULONG *)
  782. Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer;
  783. Extension->WaitIsISRs = 1; // give to ISR
  784. ExtTrace(Extension,D_Ioctl," PENDING.");
  785. return STATUS_PENDING;
  786. }
  787. }
  788. }
  789. break;
  790. case IOCTL_SERIAL_IMMEDIATE_CHAR:
  791. {
  792. UCHAR TxByte;
  793. KIRQL OldIrql;
  794. ExtTrace(Extension,D_Ioctl,"Immed. Char");
  795. if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  796. sizeof(UCHAR) )
  797. {
  798. Status = STATUS_BUFFER_TOO_SMALL;
  799. break;
  800. }
  801. IoAcquireCancelSpinLock(&OldIrql);
  802. TxByte = *((UCHAR *)(Irp->AssociatedIrp.SystemBuffer));
  803. Extension->ISR_Flags |= TX_NOT_EMPTY; // fix for EV_TXEMPTY 1-21-99
  804. #ifdef S_RK
  805. if(!sWriteTxPrioByte(Extension->ChP,TxByte))
  806. {
  807. // No room for immediate character in Priority queue
  808. Status = STATUS_INVALID_PARAMETER;
  809. }
  810. #else
  811. if ( (ULONG)(PortGetTxRoom(Extension->Port)) > 0)
  812. {
  813. // Send the byte
  814. q_put(&Extension->Port->QOut,
  815. (PUCHAR) &TxByte,
  816. 1);
  817. }
  818. #endif
  819. IoReleaseCancelSpinLock(OldIrql);
  820. break;
  821. }
  822. //**********************
  823. case IOCTL_SERIAL_PURGE:
  824. {
  825. ULONG Mask;
  826. MyKdPrint(D_Ioctl,("[Serial Purge]"));
  827. // Check to make sure that the mask only has 0 or the other
  828. // appropriate values. A null mask is equivalent to a mask of 0
  829. if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  830. sizeof(ULONG) )
  831. {
  832. Status = STATUS_INVALID_PARAMETER;
  833. break;
  834. };
  835. if ( Irp->AssociatedIrp.SystemBuffer )
  836. {
  837. Mask = *((ULONG *)(Irp->AssociatedIrp.SystemBuffer));
  838. ExtTrace1(Extension,D_Ioctl,"Serial Purge:%xH",Mask);
  839. }
  840. else
  841. {
  842. Mask = 0;
  843. }
  844. if ((!Mask) || (Mask & (~(SERIAL_PURGE_TXABORT |
  845. SERIAL_PURGE_RXABORT |
  846. SERIAL_PURGE_TXCLEAR |
  847. SERIAL_PURGE_RXCLEAR )
  848. ) ))
  849. {
  850. Status = STATUS_INVALID_PARAMETER;
  851. break;
  852. }
  853. return SerialStartOrQueue(Extension,
  854. Irp,
  855. &Extension->PurgeQueue,
  856. &Extension->CurrentPurgeIrp,
  857. SerialStartPurge );
  858. }
  859. //*****************************
  860. case IOCTL_SERIAL_GET_HANDFLOW:
  861. {
  862. MyKdPrint(D_Ioctl,("[Get Handflow]\n"))
  863. ExtTrace(Extension,D_Ioctl,"Get Handflow");
  864. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  865. sizeof(SERIAL_HANDFLOW))
  866. {
  867. Status = STATUS_BUFFER_TOO_SMALL;
  868. break;
  869. }
  870. Irp->IoStatus.Information = sizeof(SERIAL_HANDFLOW);
  871. *((PSERIAL_HANDFLOW)Irp->AssociatedIrp.SystemBuffer) =
  872. Extension->HandFlow;
  873. break;
  874. }
  875. //*****************************
  876. case IOCTL_SERIAL_SET_HANDFLOW:
  877. {
  878. ULONG trace_flags = 0;
  879. SERIAL_IOCTL_SYNC S;
  880. PSERIAL_HANDFLOW HandFlow = Irp->AssociatedIrp.SystemBuffer;
  881. MyKdPrint(D_Ioctl,("[Set HandFlow]\n"))
  882. ExtTrace(Extension,D_Ioctl,"Set HandFlow");
  883. // Make sure that the buffer is big enough
  884. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  885. sizeof(SERIAL_HANDFLOW))
  886. {
  887. ExtTrace(Extension,D_Ioctl,"ErZ!");
  888. Status = STATUS_BUFFER_TOO_SMALL;
  889. break;
  890. }
  891. ///////////////////////////////////////////////////////
  892. // Make sure that no invalid parameters have been set
  893. // Check ControlHandShake first
  894. // For Rocket, we or in several that can't be supported
  895. if(HandFlow->ControlHandShake & (SERIAL_CONTROL_INVALID |
  896. SERIAL_DSR_SENSITIVITY
  897. ) )
  898. {
  899. { ExtTrace(Extension,D_Ioctl,"Err M!"); }
  900. if(HandFlow->ControlHandShake & SERIAL_DSR_SENSITIVITY)
  901. { ExtTrace(Extension,D_Ioctl,"No DSR Sen!"); }
  902. if(HandFlow->ControlHandShake & SERIAL_CONTROL_INVALID)
  903. { ExtTrace(Extension,D_Ioctl,"Invalid con!"); }
  904. // don't bail out - kpb(5-23-96)
  905. //Status = STATUS_INVALID_PARAMETER;
  906. //break;
  907. }
  908. if (HandFlow->FlowReplace & SERIAL_FLOW_INVALID)
  909. {
  910. ExtTrace(Extension,D_Ioctl,"ErA!");
  911. Status = STATUS_INVALID_PARAMETER;
  912. break;
  913. }
  914. // Make sure that the app hasn't set an invalid DTR mode.
  915. // Both options can't be set
  916. if((HandFlow->ControlHandShake & SERIAL_DTR_MASK) == SERIAL_DTR_MASK)
  917. {
  918. ExtTrace(Extension,D_Ioctl,"ErB!");
  919. Status = STATUS_INVALID_PARAMETER;
  920. break;
  921. }
  922. // Xon/Xoff limits unused for RocketPort (they're internal).
  923. HandFlow->XonLimit=0;
  924. HandFlow->XoffLimit=0;
  925. S.Extension = Extension;
  926. S.Data = HandFlow;
  927. KeAcquireSpinLock(&Extension->ControlLock,&OldIrql);
  928. SerialSetHandFlow(Extension, HandFlow);
  929. KeReleaseSpinLock(&Extension->ControlLock,OldIrql);
  930. if ((Extension->HandFlow.ControlHandShake & SERIAL_RTS_MASK) ==
  931. SERIAL_RTS_HANDSHAKE)
  932. {ExtTrace(Extension,D_Ioctl,"RTS-Auto");}
  933. if (Extension->HandFlow.ControlHandShake & SERIAL_CTS_HANDSHAKE)
  934. {ExtTrace(Extension,D_Ioctl,"CTS-Auto");}
  935. if ((Extension->HandFlow.ControlHandShake & SERIAL_DTR_MASK) ==
  936. SERIAL_DTR_HANDSHAKE)
  937. {ExtTrace(Extension,D_Ioctl,"DTR-Auto");}
  938. if (Extension->HandFlow.ControlHandShake & SERIAL_DSR_HANDSHAKE)
  939. {ExtTrace(Extension,D_Ioctl,"DSR-Auto");}
  940. if (Extension->HandFlow.FlowReplace & SERIAL_AUTO_TRANSMIT)
  941. {ExtTrace(Extension,D_Ioctl,"Xon-Auto");}
  942. }
  943. break;
  944. //********************************
  945. case IOCTL_SERIAL_GET_MODEMSTATUS:
  946. {
  947. if ( IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  948. sizeof(ULONG) )
  949. { Status = STATUS_BUFFER_TOO_SMALL;
  950. break;
  951. }
  952. Irp->IoStatus.Information = sizeof(ULONG);
  953. //Irp->IoStatus.Status = STATUS_SUCCESS; bogus(set at end)
  954. Status = STATUS_SUCCESS; // don't need, default
  955. #ifdef S_RK
  956. // Update the modem inputs, fn() reads and converts the bits
  957. SetExtensionModemStatus(Extension);
  958. #endif
  959. ExtTrace1(Extension,D_Ioctl,"Get ModemStatus:%xH",Extension->ModemStatus);
  960. *(PULONG)Irp->AssociatedIrp.SystemBuffer = Extension->ModemStatus;
  961. break;
  962. }
  963. //***************************
  964. case IOCTL_SERIAL_GET_DTRRTS:
  965. {
  966. MyKdPrint(D_Ioctl,("[Get DTR/RTS]\n"))
  967. // The Rocket cannot truly reflect RTS setting, best guess is returned
  968. if ( IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  969. sizeof(ULONG) )
  970. {
  971. Status = STATUS_BUFFER_TOO_SMALL;
  972. break;
  973. }
  974. Irp->IoStatus.Information = sizeof(ULONG);
  975. //Irp->IoStatus.Status = STATUS_SUCCESS; bogus, set at end
  976. Status = STATUS_SUCCESS; // don't need
  977. *(PULONG)Irp->AssociatedIrp.SystemBuffer = Extension->DTRRTSStatus;
  978. ExtTrace1(Extension,D_Ioctl,"Get DTR/RTS:%xH",Extension->DTRRTSStatus);
  979. break;
  980. }
  981. //*******************************
  982. case IOCTL_SERIAL_GET_COMMSTATUS:
  983. {
  984. PSERIAL_STATUS Stat;
  985. LONG RxCount;
  986. LONG TxCount;
  987. if ( IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  988. sizeof(SERIAL_STATUS) )
  989. {
  990. Status = STATUS_BUFFER_TOO_SMALL;
  991. break;
  992. }
  993. Irp->IoStatus.Information = sizeof(SERIAL_STATUS);
  994. Stat = Irp->AssociatedIrp.SystemBuffer;
  995. // EOF is always off, NT only supports binary mode
  996. // This in keeping with the example driver
  997. Stat->EofReceived = FALSE;
  998. // Reading error status clears out the errors.
  999. Stat->Errors = Extension->ErrorWord;
  1000. Extension->ErrorWord = 0;
  1001. // We only report here what can be read immediately by the next read
  1002. // The RocketPort's hardware FIFO is not added into this count
  1003. RxCount = q_count(&Extension->RxQ);
  1004. Stat->AmountInInQueue = RxCount;
  1005. #ifdef NEW_Q
  1006. #ifdef S_VS
  1007. {
  1008. LONG tx_remote;
  1009. tx_remote = PortGetTxCntRemote(Extension->Port);
  1010. TxCount = PortGetTxCnt(Extension->Port);
  1011. Stat->AmountInOutQueue = Extension->TotalCharsQueued + TxCount + tx_remote;
  1012. ExtTrace4(Extension,D_Ioctl,"Get CommStat,In:%d IRPOut:%d BufOut:%d Remote:%d",
  1013. RxCount, Extension->TotalCharsQueued, TxCount, tx_remote);
  1014. }
  1015. #else
  1016. TxCount = sGetTxCnt(Extension->ChP);
  1017. if ((sGetChanStatusLo(Extension->ChP) & DRAINED) != DRAINED)
  1018. ++TxCount;
  1019. Stat->AmountInOutQueue = Extension->TotalCharsQueued + TxCount;
  1020. ExtTrace3(Extension,D_Ioctl,"Get CommStat,In:%d IRPOut:%d HardOut:%d",
  1021. RxCount, Extension->TotalCharsQueued, TxCount);
  1022. #endif
  1023. #else
  1024. // older q-tracking code....
  1025. #ifdef S_VS
  1026. TxCount = PortGetTxCnt(Extension->Port);
  1027. #else
  1028. TxCount = sGetTxCnt(Extension->ChP);
  1029. #endif
  1030. Stat->AmountInOutQueue = Extension->TotalCharsQueued + TxCount;
  1031. ExtTrace3(Extension,D_Ioctl,"Get CommStat,In:%d SoftOut:%d HardOut:%d",
  1032. RxCount, Extension->TotalCharsQueued, TxCount);
  1033. // end older q-tracking code....
  1034. #endif
  1035. #ifdef S_RK
  1036. // NOTE: this can fail due to the Priority buffer bug.
  1037. // If the immediate byte ended up in the FIFO, this will
  1038. // not accurately reflect the Immediate char state.
  1039. if(sGetTxPriorityCnt(Extension->ChP))
  1040. Stat->WaitForImmediate = TRUE;
  1041. else
  1042. Stat->WaitForImmediate = FALSE;
  1043. #else
  1044. Stat->WaitForImmediate = FALSE;
  1045. #endif
  1046. // Holding reasons are hidden in the part
  1047. // Hardware takes care of all the details
  1048. Stat->HoldReasons = 0;
  1049. if (Extension->TXHolding)
  1050. {
  1051. if (Extension->TXHolding & SERIAL_TX_XOFF)
  1052. Stat->HoldReasons |= SERIAL_TX_WAITING_FOR_XON;
  1053. if (Extension->TXHolding & SERIAL_TX_CTS)
  1054. Stat->HoldReasons |= SERIAL_TX_WAITING_FOR_CTS;
  1055. if (Extension->TXHolding & SERIAL_TX_DSR)
  1056. Stat->HoldReasons |= SERIAL_TX_WAITING_FOR_DSR;
  1057. if (Extension->TXHolding & SERIAL_TX_BREAK)
  1058. Stat->HoldReasons |= SERIAL_TX_WAITING_ON_BREAK;
  1059. if (Extension->TXHolding & SERIAL_TX_DCD)
  1060. Stat->HoldReasons |= SERIAL_TX_WAITING_FOR_DCD;
  1061. }
  1062. if (Extension->RXHolding & SERIAL_RX_DSR)
  1063. Stat->HoldReasons |= SERIAL_RX_WAITING_FOR_DSR;
  1064. if (Extension->RXHolding & SERIAL_RX_XOFF)
  1065. Stat->HoldReasons |= SERIAL_TX_WAITING_XOFF_SENT;
  1066. Status = STATUS_SUCCESS;
  1067. Irp->IoStatus.Information = sizeof(SERIAL_STATUS);
  1068. break;
  1069. }
  1070. //*******************************
  1071. case IOCTL_SERIAL_GET_PROPERTIES:
  1072. {
  1073. PSERIAL_COMMPROP Properties;
  1074. MyKdPrint(D_Ioctl,("[Get Properties]\n"))
  1075. ExtTrace(Extension,D_Ioctl,"Get Properties");
  1076. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  1077. sizeof(SERIAL_COMMPROP))
  1078. {
  1079. Status = STATUS_BUFFER_TOO_SMALL;
  1080. break;
  1081. }
  1082. Properties=(PSERIAL_COMMPROP)Irp->AssociatedIrp.SystemBuffer;
  1083. RtlZeroMemory(Properties,sizeof(SERIAL_COMMPROP));
  1084. Properties->PacketLength = sizeof(SERIAL_COMMPROP);
  1085. Properties->PacketVersion = 2;
  1086. Properties->ServiceMask = SERIAL_SP_SERIALCOMM;
  1087. Properties->MaxTxQueue = 0;
  1088. Properties->MaxRxQueue = 0;
  1089. Properties->MaxBaud = SERIAL_BAUD_USER;
  1090. Properties->SettableBaud = SERIAL_BAUD_075 |
  1091. SERIAL_BAUD_110 |
  1092. SERIAL_BAUD_134_5 |
  1093. SERIAL_BAUD_150 |
  1094. SERIAL_BAUD_300 |
  1095. SERIAL_BAUD_600 |
  1096. SERIAL_BAUD_1200 |
  1097. SERIAL_BAUD_1800 |
  1098. SERIAL_BAUD_2400 |
  1099. SERIAL_BAUD_4800 |
  1100. SERIAL_BAUD_7200 |
  1101. SERIAL_BAUD_9600 |
  1102. SERIAL_BAUD_14400 |
  1103. SERIAL_BAUD_19200 |
  1104. SERIAL_BAUD_38400 |
  1105. SERIAL_BAUD_56K |
  1106. SERIAL_BAUD_128K |
  1107. SERIAL_BAUD_115200 |
  1108. SERIAL_BAUD_57600 |
  1109. SERIAL_BAUD_USER;
  1110. Properties->ProvSubType = SERIAL_SP_RS232;
  1111. Properties->ProvCapabilities = SERIAL_PCF_RTSCTS |
  1112. SERIAL_PCF_CD |
  1113. SERIAL_PCF_PARITY_CHECK |
  1114. SERIAL_PCF_XONXOFF |
  1115. SERIAL_PCF_SETXCHAR |
  1116. SERIAL_PCF_TOTALTIMEOUTS |
  1117. SERIAL_PCF_INTTIMEOUTS;
  1118. Properties->SettableParams = SERIAL_SP_PARITY |
  1119. SERIAL_SP_BAUD |
  1120. SERIAL_SP_DATABITS |
  1121. SERIAL_SP_STOPBITS |
  1122. SERIAL_SP_HANDSHAKING |
  1123. SERIAL_SP_PARITY_CHECK |
  1124. SERIAL_SP_CARRIER_DETECT;
  1125. Properties->SettableData = SERIAL_DATABITS_7 |
  1126. SERIAL_DATABITS_8;
  1127. Properties->SettableStopParity = SERIAL_STOPBITS_10 |
  1128. SERIAL_STOPBITS_20 |
  1129. SERIAL_PARITY_NONE |
  1130. SERIAL_PARITY_ODD |
  1131. SERIAL_PARITY_EVEN;
  1132. Properties->CurrentTxQueue = 0; // as per MS
  1133. // circular buffer req's -1
  1134. Properties->CurrentRxQueue = Extension->RxQ.QSize -1;
  1135. Irp->IoStatus.Information = sizeof(SERIAL_COMMPROP);
  1136. //Irp->IoStatus.Status = STATUS_SUCCESS; bogus, set at end
  1137. Status = STATUS_SUCCESS; // don't need
  1138. break;
  1139. }
  1140. //*****************************
  1141. case IOCTL_SERIAL_XOFF_COUNTER:
  1142. {
  1143. PSERIAL_XOFF_COUNTER Xc = Irp->AssociatedIrp.SystemBuffer;
  1144. MyKdPrint(D_Ioctl,("[Xoff Counter]\n"));
  1145. ExtTrace(Extension,D_Ioctl,"Xoff Counter");
  1146. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1147. sizeof(SERIAL_XOFF_COUNTER))
  1148. {
  1149. Status = STATUS_BUFFER_TOO_SMALL;
  1150. break;
  1151. }
  1152. if (Xc->Counter <= 0)
  1153. { Status = STATUS_INVALID_PARAMETER;
  1154. break;
  1155. }
  1156. // write the 13H(don't play the xoff-counter game)
  1157. // which queues things up in the write queue. We may
  1158. // screw up the order of outgoing data if other writes
  1159. // pended, but thats life, and this xoff-counter nonsense
  1160. // sucks. Its used in the msdos 16450 uart emuluation on
  1161. // com1-com4.
  1162. #ifdef S_RK
  1163. sWriteTxBlk( Extension->ChP, (PUCHAR) &Xc->XoffChar, 1);
  1164. #else
  1165. q_put(&Extension->Port->QOut,(unsigned char *)&Xc->XoffChar,1);
  1166. #endif
  1167. Status = STATUS_SUCCESS;
  1168. break;
  1169. }
  1170. //******************************
  1171. case IOCTL_SERIAL_CONFIG_SIZE:
  1172. {
  1173. ExtTrace(Extension,D_Ioctl,"Config Size");
  1174. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  1175. sizeof(ULONG))
  1176. {
  1177. Status = STATUS_BUFFER_TOO_SMALL;
  1178. break;
  1179. }
  1180. Irp->IoStatus.Information = sizeof(ULONG);
  1181. Status = STATUS_SUCCESS;
  1182. *(PULONG)Irp->AssociatedIrp.SystemBuffer = 0;
  1183. break;
  1184. }
  1185. //******************************
  1186. case IOCTL_SERIAL_GET_COMMCONFIG:
  1187. {
  1188. // this function is not defined or used in the sample driver.
  1189. ExtTrace(Extension,D_Ioctl,"Get Config");
  1190. Status = STATUS_INVALID_PARAMETER;
  1191. break;
  1192. }
  1193. //******************************
  1194. case IOCTL_SERIAL_SET_COMMCONFIG:
  1195. {
  1196. // this function is not defined or used in the sample driver.
  1197. ExtTrace(Extension,D_Ioctl,"Set Config");
  1198. Status = STATUS_INVALID_PARAMETER;
  1199. break;
  1200. }
  1201. //******************************
  1202. case IOCTL_SERIAL_LSRMST_INSERT:
  1203. {
  1204. PUCHAR escapeChar;
  1205. if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1206. sizeof (ULONG) )
  1207. {
  1208. Status = STATUS_INVALID_PARAMETER;
  1209. break;
  1210. }
  1211. else
  1212. {
  1213. escapeChar = Irp->AssociatedIrp.SystemBuffer;
  1214. };
  1215. ExtTrace1(Extension,D_Ioctl,"LSRMST Insert, Esc=%xH",
  1216. (ULONG) *escapeChar);
  1217. MyKdPrint(D_Ioctl,("[LSRMST Insert]\n"))
  1218. // this "feature" allows setting a escape character, which when
  1219. // non-zero will cause it to be used as an escape character for
  1220. // changes in MSR/LSR registers. If the Escape char is seen in
  1221. // from the port, it is escaped also. Oh what fun.
  1222. // used in Virtual driver of microsofts.
  1223. Extension->escapechar = *escapeChar;
  1224. #ifdef S_RK
  1225. if (Extension->escapechar != 0)
  1226. {sEnRxIntCompare2(Extension->ChP,Extension->escapechar);}
  1227. else
  1228. {sDisRxCompare2(Extension->ChP);}
  1229. #endif
  1230. // Status = STATUS_INVALID_PARAMETER;
  1231. break;
  1232. }
  1233. #ifdef NT50
  1234. //******************************
  1235. case IOCTL_SERIAL_GET_MODEM_CONTROL:
  1236. {
  1237. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  1238. sizeof(ULONG)) {
  1239. Status = STATUS_BUFFER_TOO_SMALL;
  1240. break;
  1241. }
  1242. Irp->IoStatus.Information = sizeof(ULONG);
  1243. //#define SERIAL_DTR_STATE ((ULONG)0x00000001)
  1244. //#define SERIAL_RTS_STATE ((ULONG)0x00000002)
  1245. //#define SERIAL_IOC_MCR_DTR ((ULONG)0x00000001)
  1246. //#define SERIAL_IOC_MCR_RTS ((ULONG)0x00000002)
  1247. //#define SERIAL_IOC_MCR_OUT1 ((ULONG)0x00000004)
  1248. //#define SERIAL_IOC_MCR_OUT2 ((ULONG)0x00000008)
  1249. //#define SERIAL_IOC_MCR_LOOP ((ULONG)0x00000010)
  1250. *((ULONG *)Irp->AssociatedIrp.SystemBuffer) =
  1251. (Extension->DTRRTSStatus & 3);
  1252. ExtTrace1(Extension,D_Ioctl,"get MCR:=%xH",
  1253. *((ULONG *)Irp->AssociatedIrp.SystemBuffer) );
  1254. }
  1255. break;
  1256. //******************************
  1257. case IOCTL_SERIAL_SET_MODEM_CONTROL:
  1258. {
  1259. ULONG mcr;
  1260. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1261. sizeof(ULONG)) {
  1262. Status = STATUS_BUFFER_TOO_SMALL;
  1263. break;
  1264. }
  1265. mcr = *((ULONG *)Irp->AssociatedIrp.SystemBuffer);
  1266. #ifdef S_VS
  1267. pDisRTSFlowCtl(Extension->Port);
  1268. #else
  1269. sDisRTSFlowCtl(Extension->ChP);
  1270. #endif
  1271. if (mcr & SERIAL_RTS_STATE)
  1272. {
  1273. #ifdef S_VS
  1274. pSetRTS(Extension->Port);
  1275. #else
  1276. sSetRTS(Extension->ChP);
  1277. #endif
  1278. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  1279. }
  1280. else
  1281. {
  1282. #ifdef S_VS
  1283. pClrRTS(Extension->Port);
  1284. #else
  1285. sClrRTS(Extension->ChP);
  1286. #endif
  1287. Extension->DTRRTSStatus &= ~SERIAL_RTS_STATE;
  1288. }
  1289. if (mcr & SERIAL_DTR_STATE)
  1290. {
  1291. #ifdef S_VS
  1292. pSetDTR(Extension->Port);
  1293. #else
  1294. sSetDTR(Extension->ChP);
  1295. #endif
  1296. Extension->DTRRTSStatus |= SERIAL_DTR_STATE;
  1297. }
  1298. else
  1299. {
  1300. #ifdef S_VS
  1301. pClrDTR(Extension->Port);
  1302. #else
  1303. sClrDTR(Extension->ChP);
  1304. #endif
  1305. Extension->DTRRTSStatus &= ~SERIAL_DTR_STATE;
  1306. }
  1307. ExtTrace1(Extension,D_Ioctl,"set MCR:=%xH", mcr);
  1308. }
  1309. break;
  1310. //******************************
  1311. case IOCTL_SERIAL_SET_FIFO_CONTROL:
  1312. {
  1313. }
  1314. break;
  1315. #endif
  1316. //******************************
  1317. case IOCTL_RCKT_CLR_STATS:
  1318. {
  1319. Tracer *tr;
  1320. PSERIAL_DEVICE_EXTENSION ComDevExt;
  1321. // PortStats *Stats;
  1322. MyKdPrint(D_Ioctl,("[Get Stats]\n"))
  1323. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1324. sizeof(Tracer))
  1325. {
  1326. Status = STATUS_BUFFER_TOO_SMALL;
  1327. MyKdPrint(D_Ioctl,("[Buffer too small]\n"))
  1328. break;
  1329. }
  1330. tr = (Tracer *)Irp->AssociatedIrp.SystemBuffer;
  1331. MyKdPrint(D_Ioctl,("Com_port: %s\n",tr->port_name))
  1332. ComDevExt = FindDevExt(tr->port_name);
  1333. if (ComDevExt == NULL)
  1334. {
  1335. Status = STATUS_INVALID_PARAMETER;
  1336. break;
  1337. }
  1338. ComDevExt->OurStats.TransmittedCount = 0;
  1339. ComDevExt->OurStats.ReceivedCount = 0;
  1340. ComDevExt->OurStats.ParityErrorCount = 0;
  1341. ComDevExt->OurStats.FrameErrorCount = 0;
  1342. ComDevExt->OurStats.SerialOverrunErrorCount = 0;
  1343. ComDevExt->OurStats.BufferOverrunErrorCount = 0;
  1344. tr->status = 0;
  1345. Irp->IoStatus.Information = sizeof(Tracer);
  1346. Status = STATUS_SUCCESS;
  1347. break;
  1348. }
  1349. //******************************
  1350. case IOCTL_RCKT_SET_LOOPBACK_ON:
  1351. {
  1352. ExtTrace(Extension,D_Ioctl,"LoopBk On");
  1353. MyKdPrint(D_Ioctl,("[Set LoopBack On]"))
  1354. #ifdef S_VS
  1355. pEnLocalLoopback(Extension->Port);
  1356. #else
  1357. sEnLocalLoopback(Extension->ChP);
  1358. #endif
  1359. }
  1360. break;
  1361. //******************************
  1362. case IOCTL_RCKT_SET_LOOPBACK_OFF:
  1363. {
  1364. ExtTrace(Extension,D_Ioctl,"LoopBk Off");
  1365. MyKdPrint(D_Ioctl,("[Set LoopBack Off]"))
  1366. #ifdef S_VS
  1367. pDisLocalLoopback(Extension->Port);
  1368. #else
  1369. sDisLocalLoopback(Extension->ChP);
  1370. #endif
  1371. }
  1372. break;
  1373. //******************************
  1374. case IOCTL_RCKT_SET_TOGGLE_LOW:
  1375. {
  1376. ExtTrace(Extension,D_Ioctl,"Set 485 Low");
  1377. Extension->Option &= ~OPTION_RS485_HIGH_ACTIVE;
  1378. Extension->Option &= ~OPTION_RS485_SOFTWARE_TOGGLE;
  1379. Extension->Option |= OPTION_RS485_OVERRIDE;
  1380. // hardware reverse case
  1381. #ifdef S_VS
  1382. pEnRTSToggleLow(Extension->Port);
  1383. #else
  1384. sEnRTSToggle(Extension->ChP);
  1385. #endif
  1386. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  1387. }
  1388. break;
  1389. case IOCTL_RCKT_CLEAR_TOGGLE_LOW:
  1390. {
  1391. ExtTrace(Extension,D_Ioctl,"Clear 485 Low");
  1392. Extension->Option &= ~OPTION_RS485_HIGH_ACTIVE;
  1393. Extension->Option &= ~OPTION_RS485_SOFTWARE_TOGGLE;
  1394. Extension->Option &= ~OPTION_RS485_OVERRIDE;
  1395. // hardware reverse case
  1396. #ifdef S_VS
  1397. pDisRTSToggle(Extension->Port);
  1398. pSetRTS(Extension->Port);
  1399. #else
  1400. sDisRTSToggle(Extension->ChP);
  1401. sSetRTS(Extension->ChP);
  1402. #endif
  1403. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  1404. }
  1405. break;
  1406. //******************************
  1407. case IOCTL_RCKT_GET_STATS:
  1408. {
  1409. Tracer *tr;
  1410. PSERIAL_DEVICE_EXTENSION ComDevExt;
  1411. PortStats *Stats;
  1412. ExtTrace(Extension,D_Ioctl,"Get_Stats");
  1413. MyKdPrint(D_Ioctl,("[Get Stats]\n"));
  1414. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1415. sizeof(Tracer))
  1416. {
  1417. Status = STATUS_BUFFER_TOO_SMALL;
  1418. MyKdPrint(D_Ioctl,("[Buffer too small]\n"))
  1419. break;
  1420. }
  1421. tr = (Tracer *)Irp->AssociatedIrp.SystemBuffer;
  1422. MyKdPrint(D_Ioctl,("Com_port: %s\n",tr->port_name))
  1423. ComDevExt = FindDevExt(tr->port_name);
  1424. if (ComDevExt == NULL)
  1425. {
  1426. Status = STATUS_INVALID_PARAMETER;
  1427. break;
  1428. }
  1429. Stats = (PortStats *)tr->data;
  1430. if(ComDevExt->DeviceIsOpen)
  1431. {
  1432. #ifdef S_VS
  1433. Stats->transmitFifo = (LONG) (PortGetTxCnt(ComDevExt->Port));
  1434. Stats->receiveFifo = (LONG) (PortGetRxCnt(ComDevExt->Port));
  1435. #else
  1436. Stats->transmitFifo = (LONG) sGetTxCnt(ComDevExt->ChP);
  1437. Stats->receiveFifo = (LONG) sGetRxCnt(ComDevExt->ChP);
  1438. #endif
  1439. }
  1440. else
  1441. {
  1442. Stats->transmitFifo = 0;
  1443. Stats->receiveFifo = 0;
  1444. }
  1445. Stats->transmitBytes = ComDevExt->OurStats.TransmittedCount;
  1446. Stats->receiveBytes = ComDevExt->OurStats.ReceivedCount;
  1447. Stats->parityErrors = ComDevExt->OurStats.ParityErrorCount;
  1448. Stats->framingErrors = ComDevExt->OurStats.FrameErrorCount;
  1449. Stats->overrunHardware = ComDevExt->OurStats.SerialOverrunErrorCount;
  1450. Stats->overrunSoftware = ComDevExt->OurStats.BufferOverrunErrorCount;
  1451. tr->status = 0;
  1452. Irp->IoStatus.Information = sizeof(Tracer);
  1453. Status = STATUS_SUCCESS;
  1454. break;
  1455. }
  1456. //******************************
  1457. case IOCTL_RCKT_ISR_CNT:
  1458. {
  1459. Tracer *tr;
  1460. Global_Track *Gt;
  1461. ExtTrace(Extension,D_Ioctl,"Isr_Cnt");
  1462. MyKdPrint(D_Ioctl,("[Get Stats]\n"))
  1463. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1464. sizeof(Tracer))
  1465. {
  1466. Status = STATUS_BUFFER_TOO_SMALL;
  1467. MyKdPrint(D_Ioctl,("[Buffer too small]\n"))
  1468. break;
  1469. }
  1470. tr = (Tracer *)Irp->AssociatedIrp.SystemBuffer;
  1471. tr->status = 0;
  1472. Gt = (Global_Track *)tr->data;
  1473. Gt->int_counter = Driver.PollCnt;
  1474. Gt->WriteDpc_counter = Driver.WriteDpcCnt;
  1475. Gt->Timer_counter = 0;
  1476. Gt->Poll_counter = Driver.PollCnt;
  1477. Irp->IoStatus.Information = sizeof(Tracer);
  1478. Status = STATUS_SUCCESS;
  1479. }
  1480. break;
  1481. //******************************
  1482. case IOCTL_RCKT_CHECK:
  1483. {
  1484. Tracer *tr;
  1485. ExtTrace(Extension,D_Ioctl,"Rckt_Chk");
  1486. MyKdPrint(D_Ioctl,("[Check]\n"))
  1487. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1488. sizeof(Tracer))
  1489. {
  1490. Status = STATUS_BUFFER_TOO_SMALL;
  1491. MyKdPrint(D_Ioctl,("[Buffer too small]\n"))
  1492. break;
  1493. }
  1494. tr = (Tracer *)Irp->AssociatedIrp.SystemBuffer;
  1495. MyKdPrint(D_Ioctl,("Com_port: %s\n",tr->port_name))
  1496. tr->status = 0x5555;
  1497. Irp->IoStatus.Information = sizeof(Tracer);
  1498. Status = STATUS_SUCCESS;
  1499. }
  1500. break;
  1501. //****************************** monitor
  1502. case IOCTL_RCKT_MONALL:
  1503. {
  1504. PSERIAL_DEVICE_EXTENSION extension;
  1505. PSERIAL_DEVICE_EXTENSION board_ext;
  1506. int Dev;
  1507. // int total_size;
  1508. PortMonBase *pmb;
  1509. PortMonNames *pmn;
  1510. PortMonStatus *pms;
  1511. char *buf;
  1512. MyKdPrint(D_Ioctl,("[MonAll..]"))
  1513. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1514. sizeof (PortMonBase) )
  1515. {
  1516. Status = STATUS_INVALID_PARAMETER;
  1517. break;
  1518. }
  1519. else
  1520. {
  1521. pmb = (PortMonBase *)Irp->AssociatedIrp.SystemBuffer;
  1522. };
  1523. switch (pmb->struct_type)
  1524. {
  1525. case 9: // old probe ioctl
  1526. Status = STATUS_SUCCESS; // don't need, default
  1527. break;
  1528. //***************
  1529. case 10: // name array [12] bytes
  1530. pmn = (PortMonNames *) &pmb[1]; // ptr to after first struct
  1531. if (pmb->struct_size != sizeof(PortMonNames))
  1532. {
  1533. MyKdPrint(D_Ioctl,("Err1L"))
  1534. Status = STATUS_BUFFER_TOO_SMALL;
  1535. break;
  1536. }
  1537. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1538. (((NumPorts(NULL)+1) * sizeof(PortMonNames)) + sizeof(PortMonBase)) )
  1539. {
  1540. MyKdPrint(D_Ioctl,("Err4M, size:%d needed:%d\n",
  1541. IrpSp->Parameters.DeviceIoControl.InputBufferLength,
  1542. (((NumPorts(NULL)+1) * sizeof(PortMonNames)) + sizeof(PortMonBase))
  1543. ))
  1544. Status = STATUS_BUFFER_TOO_SMALL;
  1545. break;
  1546. }
  1547. Dev=0;
  1548. board_ext = Driver.board_ext;
  1549. while (board_ext)
  1550. {
  1551. extension = board_ext->port_ext;
  1552. while (extension)
  1553. {
  1554. strcpy(pmn->port_name, extension->SymbolicLinkName);
  1555. ++pmn;
  1556. ++Dev;
  1557. extension = extension->port_ext; // next in chain
  1558. } // while port extension
  1559. board_ext = board_ext->board_ext;
  1560. } // while port extension
  1561. pmb->num_structs = Dev;
  1562. pmn->port_name[0] = 0; // null terminate list.
  1563. Irp->IoStatus.Information = (sizeof(PortMonBase) +
  1564. sizeof(PortMonNames) *(Dev+1));
  1565. Status = STATUS_SUCCESS;
  1566. break; // case 10, names
  1567. //***************
  1568. case 11: // status array
  1569. pms = (PortMonStatus *) &pmb[1]; // ptr to after first struct
  1570. if (pmb->struct_size != sizeof(PortMonStatus))
  1571. {
  1572. MyKdPrint(D_Ioctl,("Err1M"))
  1573. Status = STATUS_BUFFER_TOO_SMALL;
  1574. break;
  1575. }
  1576. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1577. ((NumPorts(NULL) * sizeof(PortMonStatus)) + sizeof(PortMonBase)) )
  1578. {
  1579. MyKdPrint(D_Ioctl,("Err3M"))
  1580. Status = STATUS_BUFFER_TOO_SMALL;
  1581. break;
  1582. }
  1583. Dev=0;
  1584. board_ext = Driver.board_ext;
  1585. while (board_ext)
  1586. {
  1587. extension = board_ext->port_ext;
  1588. while (extension)
  1589. {
  1590. pms->sent_bytes = extension->OurStats.TransmittedCount; // total number of sent bytes
  1591. pms->rec_bytes = extension->OurStats.ReceivedCount; // total number of receive bytes
  1592. pms->sent_packets = extension->sent_packets; // number of write() packets
  1593. pms->rec_packets = extension->rec_packets; // number of read() packets
  1594. pms->overrun_errors = (USHORT)(extension->OurStats.SerialOverrunErrorCount +
  1595. extension->OurStats.BufferOverrunErrorCount);
  1596. pms->framing_errors = (USHORT)(extension->OurStats.FrameErrorCount);
  1597. pms->parity_errors = (USHORT)(extension->OurStats.ParityErrorCount);
  1598. #ifdef S_VS
  1599. if (extension->Port != NULL)
  1600. pms->status_flags = // 20H, 10H, 8H
  1601. (extension->Port->msr_value & (CTS_ACT | DSR_ACT | CD_ACT)) |
  1602. // 1H, 2H
  1603. (WORD)(extension->DTRRTSStatus & (SERIAL_DTR_STATE | SERIAL_RTS_STATE));
  1604. #else
  1605. pms->status_flags = // 20H, 10H, 8H
  1606. (extension->ModemCtl & (CTS_ACT | DSR_ACT | CD_ACT)) |
  1607. // 1H, 2H
  1608. (WORD)(extension->DTRRTSStatus & (SERIAL_DTR_STATE | SERIAL_RTS_STATE));
  1609. #endif
  1610. if (extension->DeviceIsOpen)
  1611. pms->status_flags |= 0x100;
  1612. #ifdef COMMENT_OUT
  1613. if (sIsCTSFlowCtlEnabled(sIsComDevExt->ChP))
  1614. pms->status_flags |= 0x1000;
  1615. if (sIsRTSFlowCtlEnabled(sIsComDevExt->ChP))
  1616. pms->status_flags |= 0x2000;
  1617. if (sIsTxSoftFlowCtlEnabled(sIsComDevExt->ChP))
  1618. pms->status_flags |= 0x4000;
  1619. #endif
  1620. ++pms;
  1621. ++Dev;
  1622. extension = extension->port_ext; // next in chain
  1623. } // while port extension
  1624. board_ext = board_ext->board_ext; // next in chain
  1625. } // while board extension
  1626. Irp->IoStatus.Information = (sizeof(PortMonBase) +
  1627. sizeof(PortMonStatus)*Dev);
  1628. Status = STATUS_SUCCESS;
  1629. break; // case 11(status)
  1630. #ifdef COMMENT_OUT
  1631. //****************************** debug PCI
  1632. case 12: // debug in/out instructions
  1633. {
  1634. char *str;
  1635. int i,j,k;
  1636. // KIRQL newlevel, oldlevel;
  1637. Status = STATUS_SUCCESS;
  1638. buf = (char *) &pmb[1]; // ptr to after first struct
  1639. // Eprintf("dump %s",buf);
  1640. str = buf;
  1641. while ((*str != 0) && (*str != ' '))
  1642. ++str;
  1643. if (*str == ' ')
  1644. ++str;
  1645. // newlevel = 2;
  1646. // KeRaiseIrql(newlevel, &oldlevel);
  1647. // KeLowerIrql(oldlevel);
  1648. +
  1649. if ((buf[0] == 'i') && (buf[1] == 'n'))
  1650. {
  1651. j = 0;
  1652. i = gethint(str, &j);
  1653. if (buf[2] == 'w')
  1654. {
  1655. str = (char *) i;
  1656. k = READ_PORT_USHORT((PUSHORT) str);
  1657. Sprintf(buf, "InW[%x] = %x\n",i, k);
  1658. }
  1659. else
  1660. {
  1661. str = (char *) i;
  1662. k = READ_PORT_UCHAR((PUCHAR) str);
  1663. // k = inp(i);
  1664. Sprintf(buf, "InB[%x] = %x\n",i, k);
  1665. }
  1666. }
  1667. else if ((buf[0] == 'o') && (buf[1] == 'u'))
  1668. {
  1669. j = 0;
  1670. i = gethint(str, &j);
  1671. k = gethint(&str[j], &j);
  1672. str = (char *) i;
  1673. buf[0] = 0;
  1674. if (buf[3] == 'd')
  1675. {
  1676. //sOutDW(i, k);
  1677. WRITE_PORT_ULONG((PULONG) str, (ULONG) k);
  1678. Sprintf(buf, "OutDW[%x] = %x\n",i, k);
  1679. }
  1680. else if (buf[3] == 'w')
  1681. {
  1682. //sOutW(i, k);
  1683. WRITE_PORT_USHORT((PUSHORT) str, (USHORT) k);
  1684. Sprintf(buf, "OutW[%x] = %x\n",i, k);
  1685. }
  1686. else
  1687. {
  1688. WRITE_PORT_UCHAR((PUCHAR) str, (UCHAR) k);
  1689. //sOutB(i, k);
  1690. Sprintf(buf, "OutB[%x] = %x\n",i, k);
  1691. }
  1692. // Eprintf("Out[%x] = %x\n",i, k);
  1693. }
  1694. else
  1695. {
  1696. Status = STATUS_BUFFER_TOO_SMALL; // return an error
  1697. strcpy(buf, "Bad ioctl");
  1698. Eprintf("bad io ioctl %s",buf);
  1699. }
  1700. Irp->IoStatus.Information = sizeof(PortMonBase) +
  1701. strlen(buf) + 1;
  1702. }
  1703. break; // case 12(in/out)
  1704. #endif
  1705. //*************** driver debug log
  1706. case 13: // driver debug log
  1707. {
  1708. char *str;
  1709. int i;
  1710. Status = STATUS_SUCCESS;
  1711. // someone is actively running the debugger, so don't timeout
  1712. if (Driver.DebugTimeOut > 0) // used to timeout inactive debug sessions.
  1713. Driver.DebugTimeOut = 100; // about 600 second seconds timeout
  1714. buf = (char *) &pmb[1]; // ptr to after first struct
  1715. // Eprintf("dump %s",buf);
  1716. str = buf;
  1717. //----- limit incoming line buffer size
  1718. i = 0;
  1719. while ((*str != 0) && (i < 160))
  1720. {
  1721. ++str;
  1722. ++i;
  1723. }
  1724. *str = 0;
  1725. str = buf;
  1726. if (*str != 0)
  1727. do_cmd_line(str);
  1728. if (!q_empty(&Driver.DebugQ))
  1729. {
  1730. int q_cnt;
  1731. q_cnt = q_count(&Driver.DebugQ);
  1732. if (q_cnt > 1000)
  1733. q_cnt = 1000;
  1734. Irp->IoStatus.Information = sizeof(PortMonBase) + q_cnt;
  1735. pmb->struct_size = (ULONG) q_cnt;
  1736. buf = (char *) &pmb[1]; // ptr to after first struct
  1737. q_get(&Driver.DebugQ, (BYTE *) &pmb[1], q_cnt);
  1738. }
  1739. else
  1740. {
  1741. pmb->struct_size = (ULONG) 0;
  1742. Irp->IoStatus.Information = sizeof(PortMonBase);
  1743. }
  1744. }
  1745. break; // driver debug log
  1746. //*************** driver option set
  1747. case 14:
  1748. {
  1749. int stat;
  1750. Status = STATUS_SUCCESS;
  1751. buf = (char *) &pmb[1]; // ptr to after first struct
  1752. MyKdPrint(D_Init, ("Ioctl Option:%s\n", buf))
  1753. stat = SetOptionStr(buf);
  1754. Sprintf(buf, "Option stat:%d\n",stat);
  1755. if (stat != 0)
  1756. {
  1757. MyKdPrint(D_Init, (" Err:%d\n", stat))
  1758. }
  1759. Irp->IoStatus.Information = sizeof(PortMonBase) +
  1760. strlen(buf) + 1;
  1761. }
  1762. break; // driver option set
  1763. #ifdef S_VS
  1764. //*************** mac-address list
  1765. case 15:
  1766. {
  1767. MyKdPrint(D_Ioctl,("start mac list\n"))
  1768. Status = STATUS_SUCCESS;
  1769. buf = (char *) &pmb[1]; // ptr to after first struct
  1770. buf[0] = 0;
  1771. MyKdPrint(D_Ioctl,("do find\n"))
  1772. find_all_boxes(0); // get list of all boxes out on networks
  1773. find_all_boxes(1); // do 2nd scan just to be sure
  1774. memcpy(buf, Driver.BoxMacs, 8*Driver.NumBoxMacs);
  1775. Irp->IoStatus.Information = sizeof(PortMonBase) +
  1776. 8*Driver.NumBoxMacs;
  1777. MyKdPrint(D_Ioctl,("end mac list\n"))
  1778. }
  1779. break;
  1780. case 16: // advisor sheet: probe NIC status
  1781. MyKdPrint(D_Ioctl,("start nic probe"))
  1782. Irp->IoStatus.Information =
  1783. (ProbeNic((unsigned char *)&pmb[1],
  1784. (int)pmb->struct_size)) + sizeof(PortMonBase);
  1785. Status = STATUS_SUCCESS; // don't need, default
  1786. MyKdPrint(D_Ioctl,("end nic probe"))
  1787. break;
  1788. case 17: // advisor sheet: probe VS status
  1789. MyKdPrint(D_Ioctl,("start vs probe"))
  1790. Irp->IoStatus.Information =
  1791. (ProbeDevices((unsigned char *)&pmb[1],
  1792. (int)pmb->struct_size)) + sizeof(PortMonBase);
  1793. MyKdPrint(D_Ioctl,("end vs probe"))
  1794. Status = STATUS_SUCCESS; // don't need, default
  1795. break;
  1796. #endif
  1797. default:
  1798. Status = STATUS_BUFFER_TOO_SMALL;
  1799. break;
  1800. } // switch
  1801. }
  1802. break;
  1803. //******************************
  1804. case IOCTL_RCKT_SET_MODEM_RESET:
  1805. {
  1806. char *ResetData;
  1807. PSERIAL_DEVICE_EXTENSION ext;
  1808. ExtTrace(Extension,D_Ioctl,"Set Modem Reset");
  1809. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1810. sizeof (char *) )
  1811. {
  1812. Status = STATUS_INVALID_PARAMETER;
  1813. }
  1814. else
  1815. {
  1816. ResetData = (char *)Irp->AssociatedIrp.SystemBuffer;
  1817. MyKdPrint(D_Ioctl,("Set reset on Port: %s\n", ResetData))
  1818. ext = find_ext_by_name(ResetData, NULL);
  1819. if (ext)
  1820. ModemReset(ext, 1);
  1821. Irp->IoStatus.Information = 0;
  1822. Status = STATUS_SUCCESS;
  1823. };
  1824. break;
  1825. }
  1826. case IOCTL_RCKT_CLEAR_MODEM_RESET:
  1827. {
  1828. char *ResetData;
  1829. PSERIAL_DEVICE_EXTENSION ext;
  1830. ExtTrace(Extension,D_Ioctl,"Clear Modem Reset");
  1831. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1832. sizeof (char *) )
  1833. {
  1834. Status = STATUS_INVALID_PARAMETER;
  1835. }
  1836. else
  1837. {
  1838. ResetData = (char *)Irp->AssociatedIrp.SystemBuffer;
  1839. MyKdPrint(D_Ioctl,("Clear reset on Port: %s\n", ResetData))
  1840. ext = find_ext_by_name(ResetData, NULL);
  1841. if (ext)
  1842. ModemReset(ext, 0);
  1843. Irp->IoStatus.Information = 0;
  1844. Status = STATUS_SUCCESS;
  1845. };
  1846. break;
  1847. }
  1848. case IOCTL_RCKT_SEND_MODEM_ROW:
  1849. {
  1850. char *ResetData;
  1851. PSERIAL_DEVICE_EXTENSION ext;
  1852. ExtTrace(Extension,D_Ioctl,"Send Modem ROW");
  1853. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1854. sizeof (char *) )
  1855. {
  1856. Status = STATUS_INVALID_PARAMETER;
  1857. }
  1858. else
  1859. {
  1860. ResetData = (char *)Irp->AssociatedIrp.SystemBuffer;
  1861. MyKdPrint(D_Ioctl,("ROW write on Port: %s\n", ResetData))
  1862. ext = find_ext_by_name(ResetData, NULL);
  1863. if (ext)
  1864. ModemWriteROW(ext, Driver.MdmCountryCode);
  1865. Irp->IoStatus.Information = 0;
  1866. Status = STATUS_SUCCESS;
  1867. };
  1868. break;
  1869. }
  1870. #ifdef S_RK
  1871. //******************************
  1872. // These are the old versions of
  1873. // the Reset/ROW ioctls and are
  1874. // provided here only for
  1875. // compatibility with RktReset
  1876. case IOCTL_RCKT_SET_MODEM_RESET_OLD:
  1877. {
  1878. int *ResetData;
  1879. int ChanNum;
  1880. int DevNum;
  1881. PSERIAL_DEVICE_EXTENSION ext;
  1882. ExtTrace(Extension,D_Ioctl,"Set Modem Reset");
  1883. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1884. sizeof (int *) )
  1885. {
  1886. Status = STATUS_INVALID_PARAMETER;
  1887. }
  1888. else
  1889. {
  1890. ResetData = (int *)Irp->AssociatedIrp.SystemBuffer;
  1891. ChanNum = (*ResetData) & 0xFFFF;
  1892. DevNum = (*ResetData) >> 0x10;
  1893. MyKdPrint(D_Ioctl,("Set reset on Dev: %x, Chan: %x\n", DevNum, ChanNum))
  1894. ext = find_ext_by_index(DevNum, ChanNum);
  1895. if (ext)
  1896. sModemReset(ext->ChP, 1);
  1897. Irp->IoStatus.Information = 0;
  1898. Status = STATUS_SUCCESS;
  1899. };
  1900. break;
  1901. }
  1902. case IOCTL_RCKT_CLEAR_MODEM_RESET_OLD:
  1903. {
  1904. int *ResetData;
  1905. int ChanNum;
  1906. int DevNum;
  1907. PSERIAL_DEVICE_EXTENSION ext;
  1908. ExtTrace(Extension,D_Ioctl,"Clear Modem Reset");
  1909. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1910. sizeof (int *) )
  1911. {
  1912. Status = STATUS_INVALID_PARAMETER;
  1913. }
  1914. else
  1915. {
  1916. ResetData = (int *)Irp->AssociatedIrp.SystemBuffer;
  1917. ChanNum = (*ResetData) & 0xFFFF;
  1918. DevNum = (*ResetData) >> 0x10;
  1919. MyKdPrint(D_Ioctl,("Clear reset on Dev: %x, Chan: %x\n", DevNum, ChanNum))
  1920. ext = find_ext_by_index(DevNum, ChanNum);
  1921. if (ext)
  1922. sModemReset(ext->ChP, 0);
  1923. Irp->IoStatus.Information = 0;
  1924. Status = STATUS_SUCCESS;
  1925. };
  1926. break;
  1927. }
  1928. case IOCTL_RCKT_GET_RCKTMDM_INFO_OLD:
  1929. {
  1930. // to maintain compatibility with RktReset, only the first
  1931. // four boards are reported and only the first eight ports
  1932. // on each are allowed.
  1933. RocketModemConfig *RMCfg;
  1934. int BoardNum;
  1935. int PortNum;
  1936. int np;
  1937. PSERIAL_DEVICE_EXTENSION ext_p; // port extension
  1938. PSERIAL_DEVICE_EXTENSION ext_b; // board extension
  1939. MyKdPrint(D_Ioctl, ("[Get RktMdm Cfg]\n"))
  1940. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1941. sizeof(RocketModemConfig))
  1942. {
  1943. Status = STATUS_BUFFER_TOO_SMALL;
  1944. MyKdPrint(D_Ioctl, ("[Buffer too small]\n"))
  1945. break;
  1946. }
  1947. RMCfg = (RocketModemConfig *)Irp->AssociatedIrp.SystemBuffer;
  1948. RMCfg->rm_country_code = Driver.MdmCountryCode;
  1949. RMCfg->rm_settle_time = Driver.MdmSettleTime;
  1950. ext_b = Driver.board_ext;
  1951. BoardNum = 0;
  1952. while ((ext_b) && (BoardNum < 4) )
  1953. {
  1954. if (ext_b->config->ModemDevice) {
  1955. //np = ext_b->config->NumChan; [kpb, 5-7-98]
  1956. np = ext_b->config->NumPorts;
  1957. if (np > 8)
  1958. np = 8; // force to 8 since structure only has room for 8
  1959. RMCfg->rm_board_cfg[BoardNum].num_rktmdm_ports = np;
  1960. PortNum = 0;
  1961. ext_p = find_ext_by_index(BoardNum, PortNum);
  1962. while ( (ext_p) && (PortNum < np) )
  1963. {
  1964. if (ext_p)
  1965. strcpy(RMCfg->rm_board_cfg[BoardNum].port_names[PortNum],
  1966. ext_p->SymbolicLinkName);
  1967. else
  1968. strcpy(RMCfg->rm_board_cfg[BoardNum].port_names[PortNum], 0);
  1969. PortNum++;
  1970. ext_p = find_ext_by_index(BoardNum, PortNum);
  1971. }
  1972. }
  1973. ext_b = ext_b->board_ext;
  1974. BoardNum++;
  1975. }
  1976. Irp->IoStatus.Information = sizeof(RocketModemConfig);
  1977. Status = STATUS_SUCCESS;
  1978. break;
  1979. }
  1980. case IOCTL_RCKT_SEND_MODEM_ROW_OLD:
  1981. {
  1982. int *ResetData;
  1983. int ChanNum;
  1984. int DevNum;
  1985. PSERIAL_DEVICE_EXTENSION ext;
  1986. ExtTrace(Extension,D_Ioctl,"Send Modem ROW");
  1987. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
  1988. sizeof (int *) )
  1989. {
  1990. Status = STATUS_INVALID_PARAMETER;
  1991. }
  1992. else
  1993. {
  1994. ResetData = (int *)Irp->AssociatedIrp.SystemBuffer;
  1995. ChanNum = (*ResetData) & 0xFFFF;
  1996. DevNum = (*ResetData) >> 0x10;
  1997. MyKdPrint(D_Ioctl,("ROW write on Dev: %x, Chan: %x\n", DevNum, ChanNum))
  1998. ext = find_ext_by_index(DevNum, ChanNum);
  1999. if (ext)
  2000. sModemWriteROW(ext->ChP, Driver.MdmCountryCode);
  2001. Irp->IoStatus.Information = 0;
  2002. Status = STATUS_SUCCESS;
  2003. };
  2004. break;
  2005. }
  2006. #endif
  2007. //******************************
  2008. default: // bad IOCTL request
  2009. {
  2010. MyKdPrint(D_Ioctl,("Err1O"))
  2011. ExtTrace1(Extension,D_Ioctl," UnHandle IoCtl:%d",
  2012. IrpSp->Parameters.DeviceIoControl.IoControlCode);
  2013. Status = STATUS_INVALID_PARAMETER;
  2014. break;
  2015. }
  2016. }
  2017. Irp->IoStatus.Status = Status;
  2018. if (Status != STATUS_SUCCESS)
  2019. {
  2020. MyKdPrint(D_Ioctl, (" Bad Status:%xH on IOCTL:%xH",
  2021. Status, IrpSp->Parameters.DeviceIoControl.IoControlCode));
  2022. ExtTrace2(Extension, D_Ioctl, " Bad Status:%xH on IOCTL:%xH",
  2023. Status, IrpSp->Parameters.DeviceIoControl.IoControlCode);
  2024. switch (Status)
  2025. {
  2026. case STATUS_BUFFER_TOO_SMALL:
  2027. MyKdPrint(D_Ioctl,(" Err, Buf Too Small!"));
  2028. ExtTrace(Extension,D_Ioctl," Err, Buf Too Small!");
  2029. break;
  2030. case STATUS_INVALID_PARAMETER:
  2031. MyKdPrint(D_Ioctl,(" Err, Bad Parm!"));
  2032. ExtTrace(Extension,D_Ioctl," Err, Bad Parm!");
  2033. break;
  2034. default:
  2035. break;
  2036. }
  2037. }
  2038. SerialCompleteRequest(Extension, Irp, 0);
  2039. return Status;
  2040. }
  2041. /*--------------------------------------------------------------------------
  2042. FindDevExt -
  2043. Purpose: To scan through my Dev objects and return a device object ext
  2044. Return: PSERIAL_DEVICE_EXTENSION
  2045. |--------------------------------------------------------------------------*/
  2046. PSERIAL_DEVICE_EXTENSION FindDevExt(IN PCHAR PortName)
  2047. {
  2048. PSERIAL_DEVICE_EXTENSION extension;
  2049. PSERIAL_DEVICE_EXTENSION board_ext;
  2050. int Dev;
  2051. char *pn;
  2052. char *dev_pn;
  2053. int done;
  2054. Dev =0;
  2055. board_ext = Driver.board_ext;
  2056. while (board_ext)
  2057. {
  2058. extension = board_ext->port_ext;
  2059. while (extension)
  2060. {
  2061. pn = PortName;
  2062. dev_pn = extension->SymbolicLinkName;
  2063. done = 0;
  2064. while ((*dev_pn != 0) && (*pn != 0) && (done == 0))
  2065. {
  2066. if (*dev_pn != *pn)
  2067. done = 1; // no match, try next
  2068. ++dev_pn;
  2069. ++pn;
  2070. }
  2071. if ((*dev_pn == 0) && (*pn == 0))
  2072. return (extension); // found it, return ext.
  2073. ++Dev;
  2074. extension = extension->port_ext; // next in chain
  2075. } // while port extension
  2076. board_ext = board_ext->board_ext;
  2077. } // while board extension
  2078. return NULL;
  2079. }
  2080. /*--------------------------------------------------------------------------
  2081. ProgramBaudRate -
  2082. Purpose: Configure channel for desired baud rate
  2083. Return: STATUS_SUCCESS: if baud rate was configured
  2084. STATUS_INVALID_PARAMETER: if baud rate cannot be configured
  2085. |--------------------------------------------------------------------------*/
  2086. NTSTATUS
  2087. ProgramBaudRate(
  2088. IN PSERIAL_DEVICE_EXTENSION Extension,
  2089. IN ULONG DesiredBaudRate
  2090. )
  2091. {
  2092. ULONG InBaud = DesiredBaudRate;
  2093. //---- handle baud mapping
  2094. if (Extension->port_config->LockBaud != 0)
  2095. DesiredBaudRate = Extension->port_config->LockBaud;
  2096. MyKdPrint(D_Ioctl,("[DesiredBaud %d]",DesiredBaudRate))
  2097. if (DesiredBaudRate == 56000) DesiredBaudRate = 57600;
  2098. else if (DesiredBaudRate == 128000) DesiredBaudRate = 115200;
  2099. else if (DesiredBaudRate == 256000) DesiredBaudRate = 230400;
  2100. #ifdef S_VS
  2101. if(PortSetBaudRate(Extension->Port,DesiredBaudRate,FALSE,
  2102. Extension->board_ext->config->ClkRate,
  2103. Extension->board_ext->config->ClkPrescaler))
  2104. return(STATUS_INVALID_PARAMETER);
  2105. #else
  2106. if(sSetBaudRate(Extension->ChP,DesiredBaudRate,FALSE))
  2107. return(STATUS_INVALID_PARAMETER);
  2108. #endif
  2109. Extension->BaudRate = InBaud;
  2110. #ifdef S_VS
  2111. PortSetBaudRate(Extension->Port,DesiredBaudRate, TRUE,
  2112. Extension->board_ext->config->ClkRate,
  2113. Extension->board_ext->config->ClkPrescaler);
  2114. #else
  2115. sSetBaudRate(Extension->ChP,DesiredBaudRate,TRUE);
  2116. #endif
  2117. return (STATUS_SUCCESS);
  2118. }
  2119. /*--------------------------------------------------------------------------
  2120. ProgramLineControl
  2121. Purpose: Configure channels line control (data bits, stop bits, parity)
  2122. Return: STATUS_SUCCESS: if line control was programmed as desired
  2123. STATUS_INVALID_PARAMETER: if line control setting was invalid
  2124. |--------------------------------------------------------------------------*/
  2125. NTSTATUS
  2126. ProgramLineControl(
  2127. IN PSERIAL_DEVICE_EXTENSION Extension,
  2128. IN PSERIAL_LINE_CONTROL Lc
  2129. )
  2130. {
  2131. switch (Lc->WordLength)
  2132. {
  2133. case 7:
  2134. ExtTrace(Extension,D_Ioctl, "7-bits");
  2135. #ifdef S_VS
  2136. pSetData7(Extension->Port);
  2137. #else
  2138. sSetData7(Extension->ChP);
  2139. sSetRxMask(Extension->ChP,0x7f);
  2140. #endif
  2141. Extension->LineCtl.WordLength = Lc->WordLength;
  2142. break;
  2143. case 8:
  2144. ExtTrace(Extension,D_Ioctl, "8-bits");
  2145. #ifdef S_VS
  2146. pSetData8(Extension->Port);
  2147. #else
  2148. sSetData8(Extension->ChP);
  2149. sSetRxMask(Extension->ChP,0xff);
  2150. #endif
  2151. Extension->LineCtl.WordLength = Lc->WordLength;
  2152. break;
  2153. case 5:
  2154. ExtTrace(Extension,D_Ioctl, "Err WL5");
  2155. return(STATUS_INVALID_PARAMETER);
  2156. case 6:
  2157. ExtTrace(Extension,D_Ioctl, "Err WL6");
  2158. return(STATUS_INVALID_PARAMETER);
  2159. default:
  2160. ExtTrace(Extension,D_Ioctl, "Err WL?");
  2161. return(STATUS_INVALID_PARAMETER);
  2162. }
  2163. switch (Lc->Parity)
  2164. {
  2165. case NO_PARITY:
  2166. ExtTrace(Extension,D_Ioctl, "No-Par.");
  2167. #ifdef S_VS
  2168. pDisParity(Extension->Port);
  2169. #else
  2170. sDisParity(Extension->ChP);
  2171. #endif
  2172. Extension->LineCtl.Parity = Lc->Parity;
  2173. break;
  2174. case EVEN_PARITY:
  2175. ExtTrace(Extension,D_Ioctl, "Ev-Par.");
  2176. #ifdef S_VS
  2177. pSetEvenParity(Extension->Port);
  2178. #else
  2179. sEnParity(Extension->ChP);
  2180. sSetEvenParity(Extension->ChP);
  2181. #endif
  2182. Extension->LineCtl.Parity = Lc->Parity;
  2183. break;
  2184. case ODD_PARITY:
  2185. ExtTrace(Extension,D_Ioctl, "Odd-Par.");
  2186. #ifdef S_VS
  2187. pSetOddParity(Extension->Port);
  2188. #else
  2189. sEnParity(Extension->ChP);
  2190. sSetOddParity(Extension->ChP);
  2191. #endif
  2192. Extension->LineCtl.Parity = Lc->Parity;
  2193. break;
  2194. case MARK_PARITY:
  2195. ExtTrace(Extension,D_Ioctl, "Err PM");
  2196. return(STATUS_INVALID_PARAMETER);
  2197. case SPACE_PARITY:
  2198. ExtTrace(Extension,D_Ioctl, "Err PS");
  2199. return(STATUS_INVALID_PARAMETER);
  2200. default:
  2201. ExtTrace(Extension,D_Ioctl, "Err P?");
  2202. return(STATUS_INVALID_PARAMETER);
  2203. } // end switch parity...
  2204. switch (Lc->StopBits)
  2205. {
  2206. case STOP_BIT_1:
  2207. ExtTrace(Extension,D_Ioctl, "1-StopB");
  2208. #ifdef S_VS
  2209. pSetStop1(Extension->Port);
  2210. #else
  2211. sSetStop1(Extension->ChP);
  2212. #endif
  2213. Extension->LineCtl.StopBits = Lc->StopBits;
  2214. break;
  2215. case STOP_BITS_1_5:
  2216. ExtTrace(Extension,D_Ioctl, "Err S1.5");
  2217. return(STATUS_INVALID_PARAMETER);
  2218. case STOP_BITS_2:
  2219. if (Extension->port_config->Map2StopsTo1)
  2220. {
  2221. ExtTrace(Extension,D_Ioctl, "2to1-StopB");
  2222. #ifdef S_VS
  2223. pSetStop1(Extension->Port);
  2224. #else
  2225. sSetStop1(Extension->ChP);
  2226. #endif
  2227. }
  2228. else
  2229. {
  2230. ExtTrace(Extension,D_Ioctl, "2-StopB");
  2231. #ifdef S_VS
  2232. pSetStop2(Extension->Port);
  2233. #else
  2234. sSetStop2(Extension->ChP);
  2235. #endif
  2236. }
  2237. Extension->LineCtl.StopBits = Lc->StopBits;
  2238. break;
  2239. }
  2240. return (STATUS_SUCCESS);
  2241. }
  2242. /*--------------------------------------------------------------------
  2243. SerialSetHandFlow -
  2244. Note: This is somewhat redundant to ForceExtensionSettings() in openclos.c.
  2245. |-------------------------------------------------------------------*/
  2246. void SerialSetHandFlow(PSERIAL_DEVICE_EXTENSION Extension,
  2247. SERIAL_HANDFLOW *HandFlow)
  2248. {
  2249. //////////////////////////////////////////////
  2250. // All invalid parameters have been dealt with.
  2251. // Now, program the settings.
  2252. //////////////
  2253. // DTR control
  2254. if ((Extension->HandFlow.ControlHandShake & SERIAL_DTR_MASK) !=
  2255. (HandFlow->ControlHandShake & SERIAL_DTR_MASK))
  2256. {
  2257. Extension->RXHolding &= ~SERIAL_RX_DSR;
  2258. if ( (HandFlow->ControlHandShake & SERIAL_DTR_MASK) ==
  2259. SERIAL_DTR_CONTROL )
  2260. {
  2261. #ifdef S_VS
  2262. pSetDTR(Extension->Port);
  2263. #else
  2264. sSetDTR(Extension->ChP);
  2265. #endif
  2266. Extension->DTRRTSStatus |= SERIAL_DTR_STATE;
  2267. }
  2268. else if ( (HandFlow->ControlHandShake & SERIAL_DTR_MASK) ==
  2269. SERIAL_DTR_HANDSHAKE )
  2270. {
  2271. #ifdef S_VS
  2272. pEnDTRFlowCtl(Extension->Port);
  2273. Extension->DTRRTSStatus |= SERIAL_DTR_STATE;
  2274. #else
  2275. if( (sGetRxCnt(Extension->ChP) >= RX_HIWATER) ||
  2276. (!(Extension->DevStatus & COM_RXFLOW_ON))
  2277. )
  2278. {
  2279. // drop DTR
  2280. Extension->DevStatus &= ~COM_RXFLOW_ON;
  2281. sClrDTR(Extension->ChP);
  2282. Extension->DTRRTSStatus &= ~SERIAL_DTR_STATE;
  2283. Extension->RXHolding |= SERIAL_RX_DSR;
  2284. }
  2285. else
  2286. {
  2287. // DTR should be on
  2288. sSetDTR(Extension->ChP);
  2289. Extension->DTRRTSStatus |= SERIAL_DTR_STATE;
  2290. }
  2291. #endif
  2292. }
  2293. else
  2294. {
  2295. #ifdef S_VS
  2296. pClrDTR(Extension->Port);
  2297. #else
  2298. sClrDTR(Extension->ChP);
  2299. #endif
  2300. Extension->DTRRTSStatus &= ~SERIAL_DTR_STATE;
  2301. }
  2302. }
  2303. //////////////
  2304. // RTS control
  2305. if ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) !=
  2306. (HandFlow->FlowReplace & SERIAL_RTS_MASK))
  2307. {
  2308. Extension->Option &= ~OPTION_RS485_SOFTWARE_TOGGLE;
  2309. #ifdef S_VS
  2310. pDisRTSFlowCtl(Extension->Port);
  2311. #else
  2312. sDisRTSFlowCtl(Extension->ChP); // add V2.8.001(2-19-96)
  2313. #endif
  2314. switch(HandFlow->FlowReplace & SERIAL_RTS_MASK)
  2315. {
  2316. case SERIAL_RTS_CONTROL: // RTS Should be asserted while open
  2317. #ifdef S_VS
  2318. pSetRTS(Extension->Port);
  2319. #else
  2320. sSetRTS(Extension->ChP);
  2321. #endif
  2322. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  2323. break;
  2324. case SERIAL_RTS_HANDSHAKE: // RTS hardware input flow control
  2325. #ifdef S_VS
  2326. pEnRTSFlowCtl(Extension->Port);
  2327. #else
  2328. sEnRTSFlowCtl(Extension->ChP);
  2329. #endif
  2330. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  2331. break;
  2332. case SERIAL_TRANSMIT_TOGGLE: // RTS transmit toggle enabled
  2333. if (Extension->Option & OPTION_RS485_HIGH_ACTIVE)
  2334. { // normal case, emulate standard operation
  2335. Extension->Option |= OPTION_RS485_SOFTWARE_TOGGLE;
  2336. Extension->DTRRTSStatus &= ~SERIAL_RTS_STATE;
  2337. #ifdef S_VS
  2338. pEnRTSToggleHigh(Extension->Port);
  2339. #else
  2340. sClrRTS(Extension->ChP);
  2341. #endif
  2342. }
  2343. else
  2344. { // hardware reverse case
  2345. #ifdef S_VS
  2346. pEnRTSToggleLow(Extension->Port);
  2347. #else
  2348. sEnRTSToggle(Extension->ChP);
  2349. #endif
  2350. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  2351. }
  2352. break;
  2353. default:
  2354. #ifdef S_VS
  2355. pClrRTS(Extension->Port);
  2356. #else
  2357. sClrRTS(Extension->ChP);
  2358. #endif
  2359. Extension->DTRRTSStatus &= ~SERIAL_RTS_STATE;
  2360. break;
  2361. }
  2362. }
  2363. if (Extension->Option & OPTION_RS485_OVERRIDE) // 485 override
  2364. {
  2365. if (Extension->Option & OPTION_RS485_HIGH_ACTIVE)
  2366. { // normal case, emulate standard operation
  2367. Extension->Option |= OPTION_RS485_SOFTWARE_TOGGLE;
  2368. Extension->DTRRTSStatus &= ~SERIAL_RTS_STATE;
  2369. #ifdef S_VS
  2370. pEnRTSToggleHigh(Extension->Port);
  2371. #else
  2372. sClrRTS(Extension->ChP);
  2373. #endif
  2374. }
  2375. else
  2376. { // hardware reverse case
  2377. #ifdef S_VS
  2378. pEnRTSToggleLow(Extension->Port);
  2379. #else
  2380. sEnRTSToggle(Extension->ChP);
  2381. #endif
  2382. Extension->DTRRTSStatus |= SERIAL_RTS_STATE;
  2383. }
  2384. }
  2385. ///////////////////////////////
  2386. // Software output flow control
  2387. if ((Extension->HandFlow.FlowReplace & SERIAL_AUTO_TRANSMIT) !=
  2388. (HandFlow->FlowReplace & SERIAL_AUTO_TRANSMIT))
  2389. {
  2390. if (HandFlow->FlowReplace & SERIAL_AUTO_TRANSMIT)
  2391. {
  2392. #ifdef S_VS
  2393. pEnTxSoftFlowCtl(Extension->Port);
  2394. #else
  2395. sEnTxSoftFlowCtl(Extension->ChP);
  2396. #endif
  2397. }
  2398. else
  2399. {
  2400. #ifdef S_VS
  2401. pDisTxSoftFlowCtl(Extension->Port);
  2402. #else
  2403. if (Extension->TXHolding & ST_XOFF_FAKE)
  2404. {
  2405. Extension->TXHolding &= ~ST_XOFF_FAKE;
  2406. if ((Extension->TXHolding &
  2407. (SERIAL_TX_DCD | SERIAL_TX_DSR | ST_XOFF_FAKE)) == 0)
  2408. sEnTransmit(Extension->ChP); // Start up the transmitter
  2409. sDisRxCompare2(Extension->ChP);
  2410. }
  2411. sDisTxSoftFlowCtl(Extension->ChP);
  2412. sClrTxXOFF(Extension->ChP);
  2413. #endif
  2414. Extension->TXHolding &= ~SERIAL_TX_XOFF;
  2415. }
  2416. }
  2417. ///////////////////////////////////////////////////////////////
  2418. // SERIAL_AUTO_RECEIVE checked only because it may be necessary
  2419. // to send an XON if we were using s/w input flow control
  2420. // Did the setting change?
  2421. if ((Extension->HandFlow.FlowReplace & SERIAL_AUTO_RECEIVE) !=
  2422. (HandFlow->FlowReplace & SERIAL_AUTO_RECEIVE))
  2423. {
  2424. #ifdef S_VS
  2425. if (HandFlow->FlowReplace & SERIAL_AUTO_RECEIVE)
  2426. {
  2427. pEnRxSoftFlowCtl(Extension->Port);
  2428. }
  2429. else
  2430. {
  2431. pDisRxSoftFlowCtl(Extension->Port);
  2432. }
  2433. #endif
  2434. // Are we turning AUTO_REC.. off?
  2435. if(!(HandFlow->FlowReplace & SERIAL_AUTO_RECEIVE))
  2436. {
  2437. // Is the remote flowed off?
  2438. if(!(Extension->DevStatus & COM_RXFLOW_ON))
  2439. {
  2440. // send XON
  2441. Extension->DevStatus |= COM_RXFLOW_ON;
  2442. #ifdef S_RK
  2443. sWriteTxPrioByte(Extension->ChP,
  2444. Extension->SpecialChars.XonChar);
  2445. #endif
  2446. }
  2447. }
  2448. }
  2449. /////////////////////////////////////////////////////////
  2450. // No need to program the Rocket for following:
  2451. // SERIAL_BREAK_CHAR
  2452. // Replace Break error (NULL) with SpecialChars.BreakChar
  2453. // SERIAL_ERROR_CHAR
  2454. // Replace Parity and Framing with SpecialChars.ErrorChar
  2455. ///////////////////////////////////
  2456. // CTS hardware output flow control
  2457. if ((Extension->HandFlow.ControlHandShake & SERIAL_CTS_HANDSHAKE) !=
  2458. (HandFlow->ControlHandShake & SERIAL_CTS_HANDSHAKE))
  2459. {
  2460. if (HandFlow->ControlHandShake & SERIAL_CTS_HANDSHAKE)
  2461. {
  2462. #ifdef S_VS
  2463. pEnCTSFlowCtl(Extension->Port);
  2464. #else
  2465. sEnCTSFlowCtl(Extension->ChP);
  2466. #endif
  2467. if (!(Extension->ModemStatus & SERIAL_CTS_STATE))
  2468. Extension->TXHolding |= SERIAL_TX_CTS; // clear holding
  2469. }
  2470. else
  2471. {
  2472. #ifdef S_VS
  2473. pDisCTSFlowCtl(Extension->Port);
  2474. #else
  2475. sDisCTSFlowCtl(Extension->ChP);
  2476. #endif
  2477. Extension->TXHolding &= ~SERIAL_TX_CTS; // clear holding
  2478. }
  2479. }
  2480. ///////////////////////////////////
  2481. // DSR hardware output flow control
  2482. #ifdef S_VS
  2483. if ((Extension->HandFlow.ControlHandShake & SERIAL_DSR_HANDSHAKE) !=
  2484. (HandFlow->ControlHandShake & SERIAL_DSR_HANDSHAKE))
  2485. {
  2486. if (HandFlow->ControlHandShake & SERIAL_DSR_HANDSHAKE)
  2487. {
  2488. pEnDSRFlowCtl(Extension->Port);
  2489. if (!(Extension->ModemStatus & SERIAL_DSR_STATE))
  2490. Extension->TXHolding |= SERIAL_TX_DSR;
  2491. }
  2492. else
  2493. {
  2494. pDisDSRFlowCtl(Extension->Port);
  2495. Extension->TXHolding &= ~SERIAL_TX_DSR;
  2496. }
  2497. }
  2498. #endif
  2499. #ifdef S_VS
  2500. ///////////////////////////////////
  2501. // DCD hardware output flow control
  2502. if ((Extension->HandFlow.ControlHandShake & SERIAL_DCD_HANDSHAKE) !=
  2503. (HandFlow->ControlHandShake & SERIAL_DCD_HANDSHAKE))
  2504. {
  2505. if (HandFlow->ControlHandShake & SERIAL_DCD_HANDSHAKE)
  2506. {
  2507. pEnCDFlowCtl(Extension->Port);
  2508. if (!(Extension->ModemStatus & SERIAL_DCD_STATE))
  2509. Extension->TXHolding |= SERIAL_TX_DCD;
  2510. }
  2511. else
  2512. {
  2513. pDisCDFlowCtl(Extension->Port);
  2514. Extension->TXHolding &= ~SERIAL_TX_DCD;
  2515. }
  2516. }
  2517. #endif
  2518. /////////////////
  2519. // Null stripping
  2520. if (HandFlow->FlowReplace & SERIAL_NULL_STRIPPING)
  2521. {
  2522. #ifdef S_VS
  2523. pEnNullStrip(Extension->Port);
  2524. #else
  2525. sEnRxIgnore0(Extension->ChP,0);
  2526. #endif
  2527. }
  2528. else
  2529. {
  2530. #ifdef S_VS
  2531. pDisNullStrip(Extension->Port);
  2532. #else
  2533. sDisRxCompare0(Extension->ChP);
  2534. #endif
  2535. }
  2536. Extension->HandFlow.FlowReplace = HandFlow->FlowReplace;
  2537. Extension->HandFlow.ControlHandShake = HandFlow->ControlHandShake;
  2538. #ifdef S_RK
  2539. // update this because it handles flow-control and holding update
  2540. SetExtensionModemStatus(Extension);
  2541. #endif
  2542. }
  2543. #ifdef NT50
  2544. /*--------------------------------------------------------------------
  2545. SerialInternalIoControl -
  2546. |-------------------------------------------------------------------*/
  2547. NTSTATUS
  2548. SerialInternalIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  2549. {
  2550. NTSTATUS Status = STATUS_SUCCESS;
  2551. PIO_STACK_LOCATION IrpSp;
  2552. PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
  2553. KIRQL OldIrql;
  2554. BOOLEAN acceptingIRPs;
  2555. acceptingIRPs = SerialIRPPrologue(Extension);
  2556. if (acceptingIRPs == FALSE) {
  2557. MyKdPrint(D_Ioctl,("Ioctl:no irps aceepted\n"))
  2558. Irp->IoStatus.Information = 0;
  2559. Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
  2560. SerialCompleteRequest(Extension, Irp, IO_NO_INCREMENT);
  2561. return STATUS_NO_SUCH_DEVICE;
  2562. }
  2563. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  2564. Irp->IoStatus.Information = 0L;
  2565. MyKdPrint(D_Ioctl,("SerialIntIoControl: %x\n",
  2566. IrpSp->Parameters.DeviceIoControl.IoControlCode))
  2567. // Make sure we aren't aborting due to error (ERROR_ABORT)
  2568. if (Extension->ErrorWord)
  2569. {
  2570. if (Extension->DeviceType == DEV_PORT)
  2571. {
  2572. if (SerialCompleteIfError(DeviceObject, Irp) != STATUS_SUCCESS)
  2573. {
  2574. {ExtTrace(Extension,D_Ioctl,"ErrSet!");}
  2575. return STATUS_CANCELLED;
  2576. }
  2577. }
  2578. }
  2579. if (Extension->DeviceType == DEV_BOARD)
  2580. {
  2581. ExtTrace2 (Extension, D_Ioctl, " Bad Status:%xH on IIOCTL:%xH",
  2582. Status, IrpSp->Parameters.DeviceIoControl.IoControlCode);
  2583. Status = STATUS_INVALID_DEVICE_REQUEST;
  2584. SerialCompleteRequest (Extension, Irp, 0);
  2585. return Status;
  2586. };
  2587. switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
  2588. {
  2589. #if 0
  2590. case IOCTL_SERIAL_INTERNAL_DO_WAIT_WAKE:
  2591. // Send a wait-wake IRP
  2592. Status = SerialSendWaitWake(Extension);
  2593. break;
  2594. case IOCTL_SERIAL_INTERNAL_CANCEL_WAIT_WAKE:
  2595. if (Extension->PendingWakeIrp != NULL) {
  2596. IoCancelIrp(Extension->PendingWakeIrp);
  2597. }
  2598. break;
  2599. #endif
  2600. case IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS:
  2601. case IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS:
  2602. {
  2603. SERIAL_BASIC_SETTINGS basic;
  2604. PSERIAL_BASIC_SETTINGS pBasic;
  2605. //SHORT AppropriateDivisor;
  2606. //SERIAL_IOCTL_SYNC S;
  2607. if (IrpSp->Parameters.DeviceIoControl.IoControlCode ==
  2608. IOCTL_SERIAL_INTERNAL_BASIC_SETTINGS)
  2609. {
  2610. MyKdPrint(D_Ioctl,("[Set Internal Settings]\n"))
  2611. ExtTrace(Extension,D_Ioctl,"Set Int Settings");
  2612. // Check the buffer size
  2613. if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
  2614. sizeof(SERIAL_BASIC_SETTINGS))
  2615. {
  2616. Status = STATUS_BUFFER_TOO_SMALL;
  2617. break;
  2618. }
  2619. //
  2620. // Everything is 0 -- timeouts and flow control. If
  2621. // We add additional features, this zero memory method
  2622. // may not work.
  2623. //
  2624. RtlZeroMemory(&basic, sizeof(SERIAL_BASIC_SETTINGS));
  2625. Irp->IoStatus.Information = sizeof(SERIAL_BASIC_SETTINGS);
  2626. pBasic = (PSERIAL_BASIC_SETTINGS)Irp->AssociatedIrp.SystemBuffer;
  2627. //
  2628. // Save off the old settings
  2629. //
  2630. RtlCopyMemory(&pBasic->Timeouts, &Extension->Timeouts,
  2631. sizeof(SERIAL_TIMEOUTS));
  2632. RtlCopyMemory(&pBasic->HandFlow, &Extension->HandFlow,
  2633. sizeof(SERIAL_HANDFLOW));
  2634. //
  2635. // Point to our new settings
  2636. //
  2637. pBasic = &basic;
  2638. }
  2639. else //restoring settings
  2640. {
  2641. MyKdPrint(D_Ioctl,("[Restore Internal Settings]\n"))
  2642. ExtTrace(Extension,D_Ioctl,"Reset Int Settings");
  2643. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength
  2644. < sizeof(SERIAL_BASIC_SETTINGS))
  2645. {
  2646. Status = STATUS_BUFFER_TOO_SMALL;
  2647. break;
  2648. }
  2649. pBasic = (PSERIAL_BASIC_SETTINGS)Irp->AssociatedIrp.SystemBuffer;
  2650. }
  2651. KeAcquireSpinLock(&Extension->ControlLock, &OldIrql);
  2652. //
  2653. // Set the timeouts
  2654. //
  2655. RtlCopyMemory(&Extension->Timeouts, &pBasic->Timeouts,
  2656. sizeof(SERIAL_TIMEOUTS));
  2657. //
  2658. // Set flowcontrol
  2659. //
  2660. //S.Extension = Extension;
  2661. //S.Data = &pBasic->HandFlow;
  2662. SerialSetHandFlow(Extension, &pBasic->HandFlow);
  2663. //KeSynchronizeExecution(Extension->Interrupt, SerialSetHandFlow, &S);
  2664. KeReleaseSpinLock(&Extension->ControlLock, OldIrql);
  2665. }
  2666. break;
  2667. default:
  2668. Status = STATUS_INVALID_PARAMETER;
  2669. break;
  2670. }
  2671. Irp->IoStatus.Status = Status;
  2672. if (Status != STATUS_SUCCESS)
  2673. {
  2674. ExtTrace2(Extension, D_Ioctl, " Bad Status:%xH on IIOCTL:%xH",
  2675. Status, IrpSp->Parameters.DeviceIoControl.IoControlCode);
  2676. }
  2677. SerialCompleteRequest(Extension, Irp, 0);
  2678. return Status;
  2679. }
  2680. #endif
  2681. #ifdef S_VS
  2682. #define RESET_STATS 1
  2683. /*--------------------------------------------------------------------
  2684. find_ext_mac_match
  2685. |-------------------------------------------------------------------*/
  2686. static PSERIAL_DEVICE_EXTENSION find_ext_mac_match(unsigned char *mac_addr)
  2687. {
  2688. PSERIAL_DEVICE_EXTENSION ext;
  2689. ext = Driver.board_ext;
  2690. while (ext != NULL)
  2691. {
  2692. if (mac_match(mac_addr, ext->hd->dest_addr))
  2693. {
  2694. //MyKdPrint(D_Ioctl,("Found ext:%x\n", ext))
  2695. return ext;
  2696. }
  2697. ext = ext->board_ext; // next one
  2698. }
  2699. return NULL;
  2700. }
  2701. /*--------------------------------------------------------------------
  2702. ProbeNic - determine status associated nic card.
  2703. |-------------------------------------------------------------------*/
  2704. static int ProbeNic(unsigned char *pPtr, int availableLength)
  2705. {
  2706. int nic_index;
  2707. int stat;
  2708. PROBE_NIC_STRUCT *pn;
  2709. Nic *nic;
  2710. int flag;
  2711. pn = (PROBE_NIC_STRUCT *) pPtr;
  2712. nic_index = (int) pPtr[0]; // they passed in an index to which nic card
  2713. flag = (int) pPtr[1]; // they passed in a flag too
  2714. stat = 0;
  2715. if (nic_index >= VS1000_MAX_NICS)
  2716. {
  2717. MyKdPrint(D_Error,("Err PD1F\n"))
  2718. stat = 1; // err
  2719. }
  2720. if (Driver.nics == NULL)
  2721. {
  2722. MyKdPrint(D_Error,("Err PD1G\n"))
  2723. stat = 2; // err
  2724. }
  2725. if (Driver.nics[nic_index].NICHandle == NULL)
  2726. {
  2727. MyKdPrint(D_Error,("Err PD1H\n"))
  2728. stat = 3; // err
  2729. }
  2730. if (stat != 0)
  2731. {
  2732. pn->struct_size = 0;
  2733. return sizeof(PROBE_NIC_STRUCT);
  2734. }
  2735. pn->struct_size = sizeof(PROBE_NIC_STRUCT);
  2736. nic = &Driver.nics[nic_index];
  2737. #if 0
  2738. if (flag & RESET_STATS) {
  2739. nic->pkt_sent = 0;
  2740. nic->pkt_rcvd_ours = 0;
  2741. nic->pkt_rcvd_not_ours = 0;
  2742. }
  2743. #endif
  2744. // copy over the data
  2745. memcpy(pn->NicName, nic->NicName, 60);
  2746. pn->NicName[59] = 0; // ensure null terminated
  2747. memcpy(pn->address, nic->address, 6);
  2748. pn->Open = nic->Open;
  2749. pn->pkt_sent = nic->pkt_sent;
  2750. pn->pkt_rcvd_ours = nic->pkt_rcvd_ours;
  2751. pn->pkt_rcvd_not_ours = nic->pkt_rcvd_not_ours;
  2752. return sizeof(PROBE_NIC_STRUCT);
  2753. }
  2754. /*--------------------------------------------------------------------
  2755. ProbeDevices - determine status associated with the hex MAC address at pPtr;
  2756. find associated Comtrol devices...
  2757. |-------------------------------------------------------------------*/
  2758. static int ProbeDevices(unsigned char *pPtr, int availableLength)
  2759. {
  2760. Nic *nic;
  2761. PortMan *pm;
  2762. Hdlc *hd;
  2763. unsigned char mac_address[6];
  2764. int flag;
  2765. int stat,i;
  2766. PSERIAL_DEVICE_EXTENSION ext;
  2767. PROBE_DEVICE_STRUCT *pr = (PROBE_DEVICE_STRUCT *) pPtr;
  2768. memcpy(mac_address,pPtr,sizeof(mac_address));
  2769. flag = pPtr[sizeof(mac_address)];
  2770. // find the active device with the matching address
  2771. ext = find_ext_mac_match(mac_address);
  2772. stat = 0;
  2773. if (ext == NULL)
  2774. {
  2775. MyKdPrint(D_Error,("No found mac:%x %x %x %x %x %x\n",
  2776. mac_address[0],mac_address[1],mac_address[2],
  2777. mac_address[3],mac_address[4],mac_address[5]))
  2778. stat = 1;
  2779. }
  2780. if (ext != NULL)
  2781. {
  2782. pm = ext->pm;
  2783. hd = ext->hd;
  2784. if ((pm == NULL) || (hd == NULL))
  2785. {
  2786. MyKdPrint(D_Error,("No pm or hd\n"))
  2787. stat = 2;
  2788. }
  2789. }
  2790. if (stat != 0)
  2791. {
  2792. pr->struct_size = 0;
  2793. MyKdPrint(D_Error,("ProbeErr1\n"))
  2794. return sizeof(PROBE_DEVICE_STRUCT);
  2795. }
  2796. pr->struct_size = sizeof(PROBE_DEVICE_STRUCT);
  2797. #if 0
  2798. if (flag & RESET_STATS) {
  2799. pm->good_loads = 0;
  2800. pm->total_loads = 0;
  2801. hd->iframes_sent = 0;
  2802. hd->ctlframes_sent = 0;
  2803. hd->rawframes_sent = 0;
  2804. hd->iframes_resent = 0;
  2805. hd->frames_rcvd = 0;
  2806. hd->iframes_outofseq = 0;
  2807. }
  2808. #endif
  2809. // give back a nic_index to use as a handle
  2810. pr->nic_index = 0; // default
  2811. for (i=0; i<VS1000_MAX_NICS; i++)
  2812. {
  2813. if ((hd->nic == &Driver.nics[i]) && (hd->nic != NULL))
  2814. pr->nic_index = i;
  2815. }
  2816. pr->num_ports = pm->num_ports;
  2817. pr->total_loads = pm->total_loads;
  2818. pr->good_loads = pm->good_loads;
  2819. pr->backup_server = pm->backup_server;
  2820. memcpy(pr->dest_addr, hd->dest_addr, 6);
  2821. pr->state = pm->state;
  2822. pr->iframes_sent = hd->iframes_sent;
  2823. pr->rawframes_sent = hd->rawframes_sent;
  2824. pr->ctlframes_sent = hd->ctlframes_sent;
  2825. pr->iframes_resent = hd->iframes_resent;
  2826. pr->iframes_outofseq = hd->iframes_outofseq;
  2827. pr->frames_rcvd = hd->frames_rcvd;
  2828. return sizeof(PROBE_DEVICE_STRUCT);
  2829. }
  2830. #endif