Ejemplo n.º 1
0
int DarwinController::SetMoveSpeed(unsigned char joint_ID, int move_speed){
    unsigned char speed_packet[9] = {0, };
    unsigned char params[2] = {GetLowByte(move_speed), GetHighByte(move_speed)}; 
    MakePacket(speed_packet, joint_ID, 2, WRITE, GOAL_POSITION_L, params);
    unsigned char rxpacket[MAXNUM_RXPARAM] = {0, };
    return ReadWrite(speed_packet, rxpacket);
}
Ejemplo n.º 2
0
void Settings::ReadWrite(const Settings::Action action, QObject *qobject_p,
                         const QStringList &properties, const QStringList &ignore_objects)
{
const QPointer<QObject> qo_qp(qobject_p);
    if (qo_qp) {
        const auto object_name(qobject_p->objectName());
        if (TRUE != object_name.isEmpty()) {
            if (TRUE != ignore_objects.contains(object_name)) {
                beginGroup(object_name);
                SingleObjectPropertiesReadWrite(action, qobject_p, properties);
                foreach (auto o_p, qobject_p->children()) {
                    QPointer<QObject> child_qo_qp(o_p);
                    if (child_qo_qp) {
                        const auto object_name(o_p->objectName());
                        if (TRUE != object_name.isEmpty()) {
                            if (TRUE != ignore_objects.contains(object_name)) {
                                ReadWrite(action, o_p, properties, ignore_objects);
                            }
                        }
                    }
                }
                endGroup();
            }
        }
    }
Ejemplo n.º 3
0
int DarwinController::Set_PID_Gain(unsigned char joint_ID, unsigned char P_Value, unsigned char I_Value, unsigned char D_Value){
    unsigned char PID_packet[10] = {0, };
    unsigned char params[3] = {P_Value, I_Value, D_Value};
    MakePacket(PID_packet, joint_ID, 1, WRITE, D_GAIN, params);

    unsigned char rxpacket[MAXNUM_RXPARAM] = {0, };
    return ReadWrite(PID_packet, rxpacket);
}
Ejemplo n.º 4
0
// Converts an angle given in degrees into motor ticks and sends write packet to motor 
int DarwinController::SetJointAngle(unsigned char joint_ID, int goal_angle){
    unsigned char angle_packet[9] = {0, };
    int goal_ticks = goal_angle * 11.378; // 4096/360
    unsigned char params[2] = {GetLowByte(goal_ticks), GetHighByte(goal_ticks)}; 
    MakePacket(angle_packet, joint_ID, 2, WRITE, GOAL_POSITION_L, params);
    unsigned char rxpacket[MAXNUM_RXPARAM] = {0, };
    return ReadWrite(angle_packet, rxpacket);
}
Ejemplo n.º 5
0
NTSTATUS StartIrpWrite(
    IN PC0C_IO_PORT pIoPort,
    IN PLIST_ENTRY pQueueToComplete)
{
  return ReadWrite(
      pIoPort->pIoPortRemote, FALSE,
      pIoPort, TRUE,
      pQueueToComplete);
}
Ejemplo n.º 6
0
VOID TimeoutRoutine(
    PC0C_IO_PORT pIoPort,
    IN PC0C_IRP_QUEUE pQueue)
{
  LIST_ENTRY queueToComplete;
  KIRQL oldIrql;

  InitializeListHead(&queueToComplete);

  KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql);

  if (pQueue->pCurrent) {
    PC0C_IRP_STATE pState;

    pState = GetIrpState(pQueue->pCurrent);
    HALT_UNLESS(pState);

    pState->flags |= C0C_IRP_FLAG_EXPIRED;

    switch (pState->iQueue) {
      case C0C_QUEUE_WRITE:
        ReadWrite(pIoPort->pIoPortRemote, FALSE, pIoPort, FALSE, &queueToComplete);
        break;
      case C0C_QUEUE_READ:
        ReadWrite(pIoPort, FALSE, pIoPort->pIoPortRemote, FALSE, &queueToComplete);
        break;
      case C0C_QUEUE_CLOSE:
        FdoPortIo(C0C_IO_TYPE_CLOSE_COMPLETE,
                  NULL,
                  pIoPort,
                  &pIoPort->irpQueues[C0C_QUEUE_CLOSE],
                  &queueToComplete);
        break;
    }
  }

  KeReleaseSpinLock(pIoPort->pIoLock, oldIrql);

  FdoPortCompleteQueue(&queueToComplete);
}
Ejemplo n.º 7
0
/* ReadJointAngle - sends out a single read to a joint motor
 * Return - joint angle in ticks of prompted joint
 *        - for failed read, return -99999
 */
int DarwinController::ReadJointAngle(int id){

    unsigned char rxpacket[MAXNUM_RXPARAM + 10] = {0, };
    unsigned char txpacketread[] = {0, 0, id, 0x04, 0x02, 0x24, 0x02, 0};

    FinishPacket(txpacketread);

    int result = ReadWrite(txpacketread, rxpacket);

    if(result == 0){
        printf("Failed read! \n");
        return -9999999;
    } else {
        return MakeWord((int)rxpacket[PARAMETER], (int)rxpacket[PARAMETER + 1]);

    }

}
Ejemplo n.º 8
0
/* Ping - send a ping to a specific id
 * Return - true if the ping was successful
 */
bool DarwinController::Ping(int id, int *error){
    unsigned char txpacket[MAXNUM_TXPARAM + 10] = {0, };
    unsigned char rxpacket[MAXNUM_RXPARAM + 10] = {0, };


    txpacket[ID]           = (unsigned char)id;
    txpacket[INSTRUCTION]  = 1;
    txpacket[LENGTH]       = 2;

    FinishPacket(txpacket);

    int result = ReadWrite(txpacket, rxpacket);
    if( result == 0){
        return false;
    } else {
        return true;
    }
}
Ejemplo n.º 9
0
VOID CancelRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
  LIST_ENTRY queueToComplete;
  PC0C_IO_PORT pIoPort;
  PC0C_IRP_STATE pState;
  KIRQL oldIrql;
  PC0C_IRP_QUEUE pQueue;

  IoReleaseCancelSpinLock(pIrp->CancelIrql);

  pIoPort = FDO_PORT_TO_IO_PORT(pDevObj);
  pState = GetIrpState(pIrp);
  HALT_UNLESS(pState);

  pQueue = &pIoPort->irpQueues[pState->iQueue];

  InitializeListHead(&queueToComplete);

  KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql);

  if (pState->flags & C0C_IRP_FLAG_IN_QUEUE) {
    RemoveEntryList(&pIrp->Tail.Overlay.ListEntry);
    pState->flags &= ~C0C_IRP_FLAG_IN_QUEUE;
  }

  pIrp->IoStatus.Status = STATUS_CANCELLED;
  InsertTailList(&queueToComplete, &pIrp->Tail.Overlay.ListEntry);

  if (pState->flags & C0C_IRP_FLAG_IS_CURRENT) {
    ShiftQueue(pQueue);

    if (pState->iQueue == C0C_QUEUE_WRITE)
      ReadWrite(pIoPort->pIoPortRemote, FALSE, pIoPort, FALSE, &queueToComplete);
  }

  KeReleaseSpinLock(pIoPort->pIoLock, oldIrql);

  FdoPortCompleteQueue(&queueToComplete);
}
Ejemplo n.º 10
0
Archivo: cunit.c Proyecto: asu88/SOT
/* LEER LINEAS DEL FICHERO*/
void
ReadLines(char* archivo, int fd_out){
	FILE* fd_in;
	char milinea[MAXLINEA];
	char* linea=NULL;
	int lon;
	Comando* command;
	int fp=0;
	int is_primero=1;
	//abrir el archivo
	fd_in=fopen(archivo, "r");
	if (fd_in==NULL){
		err(1, "No se puede abrir el archivo %s\n", archivo);
		//retornar error
	}
	//leer linea a linea
	while(feof(fd_in)!=1){
		linea=fgets(milinea, sizeof(milinea), fd_in);
		if(linea!=NULL && strcmp(linea, "\n")!=0){ //lineas en blanco
			lon=strlen(linea);
			//quitar \n
			if(linea[lon-1]=='\n'){
				linea[lon-1]='\0';
			}
			//		
			command=(Comando*)malloc(512*sizeof(Comando));
			fp=EjecutarLineas(linea, command, fp, fd_out, is_primero);
			free(command);	
			is_primero=0;
		}	
	}
	ReadWrite(fp, fd_out);
	close(fp);
	close(fd_out);
	//cerrar el archivo
	if(fclose(fd_in)<0){
		err(1, "No se puede cerrar el archivo %s\n", archivo);
	}	
}
Ejemplo n.º 11
0
/* ReadByte - Read a byte of data from the specified id and address
 * Return - length of successfully read packet. Return bad number if fails.
 */
int DarwinController::ReadByte(int id, int address, int *byte){
    unsigned char txpacket[MAXNUM_TXPARAM + 10] = {0, };
    unsigned char rxpacket[MAXNUM_RXPARAM + 10] = {0, };

    txpacket[ID]           = (unsigned char)id;
    txpacket[INSTRUCTION]  = READ;
    txpacket[PARAMETER]    = (unsigned char)address;
    txpacket[PARAMETER+1]  = 1;
    txpacket[LENGTH]       = 4;

    int txlength = txpacket[LENGTH] + 4;

    FinishPacket(txpacket); // don't know why i had this commented out.

    int result = ReadWrite(txpacket, rxpacket);

    if(result == txlength){ 
        *byte = (int)rxpacket[PARAMETER];
    }

    return result;
}
Ejemplo n.º 12
0
/******************************************************
 * Takes in an instruction and list of params         *
 * Params needs to be in the form:                    *
 *    {ID_1, data_1, ID_2, data_2, ...}               *
 * There can be any amount of motors and in any order *
 * Note that paramlength does not include the ID      *
 ******************************************************/
int DarwinController::SyncWrite(unsigned char* packet, unsigned char instruction, unsigned char* params, unsigned char numparams, unsigned char paramlength){
   
    unsigned char len = numparams + 7; //Last index of array (where checksum goes) 
    packet[0] = 0xFF;    // Heading
    packet[1] = 0xFF;
    packet[ID] = 0xFE;    // Broadcast ID
    packet[LENGTH] = len-3;   // Length of packet except for headings, ID, Checksum
    packet[INSTRUCTION] = 0x83;    // Sync Write
    packet[5] = instruction;  // What is happening at each motor
    packet[6] = paramlength;  // Number of bytes written to each motor

    for(unsigned char i = 0; i < numparams; i++){
        packet[7+i] = params[i];
    }

    packet[len] = CalculateChecksum(packet);

    unsigned char rxpacket[MAXNUM_RXPARAM + 10] = {0, };

    return ReadWrite(packet, rxpacket);
    //return port.WritePort(packet, len+1); /alt method

}
Ejemplo n.º 13
0
Archivo: cunit.c Proyecto: asu88/SOT
/* CREAR EL FICHERO .OUT Y SI ESO .OK*/
int
check_ok(char* file_out , char* file_ok, int fd_out){
	int success, fd_ok;
	if(ExistsFile(file_ok)){
		success=Comparate(file_out, file_ok);
		if(success){
			return 1;
		}else{
			return 0;
		}
	}else{
		//creamos el archivo .ok
		fd_out=open(file_out, O_RDONLY);
		fd_ok=CreatFile(file_ok);
		//metemos el contenido de .out en .ok
		if(fd_out>0 && fd_ok>0){
			ReadWrite(fd_out, fd_ok);			
		}else{
			return 0;
		}
	}
	close(fd_ok);
	return 1;
}
Ejemplo n.º 14
0
int main(int argc, char *argv[])
{
  int inFileBool = 0;
  int outFileBool = 0;
  int in_xtcBool = 0;
  int out_xtcBool = 0;
  int in_trrBool = 0;
  int out_trrBool = 0;
  char *rfile=NULL, *wfile=NULL;
  

  if(argc != 5)
    {
      fprintf(stderr,"Usage: %s -i inFile -o outFile\n",argv[0]);
      exit(1);
    }
  else
    {
      int ii = 1;

      while(ii < argc)
	{
	  if(strcmp(argv[ii], "-i") == 0)         // if (argv[ii] == "-i")
	    {
	      ii++;
	      inFileBool = 1;
	 
	      if(strstr(argv[ii], ".xtc") != NULL)
		{
		  in_xtcBool = 1;
		  in_trrBool = 0;
		}
	      if(strstr(argv[ii], ".trr") != NULL)
		{
		  in_trrBool = 1;
		  in_xtcBool = 0;
		}

	      rfile = argv[ii];
	    }

	  if(strcmp(argv[ii], "-o") == 0)
	    {
	      ii++;
	      outFileBool = 1;
	 
	      if(strstr(argv[ii], ".xtc") != NULL)
		{		
		  out_xtcBool = 1;
		  out_trrBool = 0;
		}
	      if(strstr(argv[ii], ".trr") != NULL)
		{
		  out_trrBool = 1;
		  out_xtcBool = 0;
		}

	      wfile = argv[ii];
	    }

	  ii++;
	}
    }

  if(!inFileBool || !outFileBool)
    {
      perror("Usage : ./ReadWrite -i inFile -o outFile");
      exit(1);
    }

  ReadWrite(rfile, wfile, in_xtcBool, out_xtcBool, in_trrBool, out_trrBool);
  

  return 0;
}
Ejemplo n.º 15
0
static int ReadMemory( addr48_ptr *addr, byte *data, int len )
{
    return( ReadWrite( DoReadMem, addr, (char *)data, len ) );
}
Ejemplo n.º 16
0
static unsigned short WriteMemory( addr48_ptr *addr, byte far *data, unsigned short len )
{
    return( ReadWrite( D32DebugWrite, addr, data, len ) );
}
Ejemplo n.º 17
0
int DarwinController::Set_D_Gain(unsigned char joint_ID, unsigned char D_Value){
    unsigned char D_packet[8] = {0, };
    MakePacket(D_packet, joint_ID, 1, WRITE, D_GAIN, &D_Value); // Pass in pointer b/c it expects a char*
    unsigned char rxpacket[MAXNUM_RXPARAM] = {0, };
    return ReadWrite(D_packet, rxpacket);
}
Ejemplo n.º 18
0
/* BulkRead - reads all motor and board information at once into rxpacket
 * Return - length of successfully read packet
 */
int DarwinController::BulkRead(unsigned char *rxpacket){

    return ReadWrite(BulkReadTxPacket, rxpacket);
}
Ejemplo n.º 19
0
NTSTATUS FdoPortIoCtl(
    IN PC0C_FDOPORT_EXTENSION pDevExt,
    IN PIRP pIrp)
{
    NTSTATUS status;
    PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    ULONG code = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
    KIRQL oldIrql;
    PC0C_IO_PORT pIoPortLocal;

    pIrp->IoStatus.Information = 0;
    pIoPortLocal = pDevExt->pIoPortLocal;

    if ((pIoPortLocal->handFlow.ControlHandShake & SERIAL_ERROR_ABORT) &&
            pIoPortLocal->errors && code != IOCTL_SERIAL_GET_COMMSTATUS)
    {
        status = STATUS_CANCELLED;
    } else {
        status = STATUS_SUCCESS;

        switch (code) {
        case IOCTL_SERIAL_SET_RTS:
        case IOCTL_SERIAL_CLR_RTS:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            switch (pIoPortLocal->handFlow.FlowReplace & SERIAL_RTS_MASK) {
            case SERIAL_RTS_HANDSHAKE:
            case SERIAL_TRANSMIT_TOGGLE:
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                status = STATUS_INVALID_PARAMETER;
                break;
            default: {
                LIST_ENTRY queueToComplete;

                InitializeListHead(&queueToComplete);

                SetModemControl(
                    pIoPortLocal,
                    code == IOCTL_SERIAL_SET_RTS ? C0C_MCR_RTS : 0,
                    C0C_MCR_RTS,
                    &queueToComplete);

                if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }

                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                FdoPortCompleteQueue(&queueToComplete);
            }
            }
            break;
        case IOCTL_SERIAL_SET_DTR:
        case IOCTL_SERIAL_CLR_DTR:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            switch (pIoPortLocal->handFlow.ControlHandShake & SERIAL_DTR_MASK) {
            case SERIAL_DTR_HANDSHAKE:
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                status = STATUS_INVALID_PARAMETER;
                break;
            default: {
                LIST_ENTRY queueToComplete;

                InitializeListHead(&queueToComplete);

                SetModemControl(
                    pIoPortLocal,
                    code == IOCTL_SERIAL_SET_DTR ? C0C_MCR_DTR : 0,
                    C0C_MCR_DTR,
                    &queueToComplete);

                if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }

                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                FdoPortCompleteQueue(&queueToComplete);
            }
            }
            break;
        case IOCTL_SERIAL_SET_MODEM_CONTROL: {
            LIST_ENTRY queueToComplete;
            UCHAR mask;
            PUCHAR pSysBuf;
            ULONG InputBufferLength;

            InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

            if (InputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;

            if (InputBufferLength >= (sizeof(ULONG) + sizeof(ULONG) + C0CE_SIGNATURE_SIZE) &&
                    RtlEqualMemory(pSysBuf + sizeof(ULONG) + sizeof(ULONG), C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE))
            {
                mask = C0C_MCR_MASK & (UCHAR)*((PULONG)pSysBuf + 1);
            } else {
                mask = C0C_MCR_MASK;
            }

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            SetModemControl(pIoPortLocal, (UCHAR)*(PULONG)pSysBuf, mask, &queueToComplete);

            if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                ReadWrite(
                    pIoPortLocal, FALSE,
                    pIoPortLocal->pIoPortRemote, FALSE,
                    &queueToComplete);
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_MODEM_CONTROL:
        case IOCTL_SERIAL_GET_DTRRTS: {
            ULONG modemControl;
            PUCHAR pSysBuf;
            ULONG OutputBufferLength;

            OutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

            if (OutputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            modemControl = pIoPortLocal->modemControl;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            pSysBuf = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;

            if (code == IOCTL_SERIAL_GET_DTRRTS) {
                modemControl &= SERIAL_DTR_STATE | SERIAL_RTS_STATE;
                pIrp->IoStatus.Information = sizeof(ULONG);
            } else {
                ULONG InputBufferLength;

                InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

                if (OutputBufferLength >= (sizeof(ULONG) + C0CE_SIGNATURE_SIZE) &&
                        InputBufferLength >= C0CE_SIGNATURE_SIZE &&
                        RtlEqualMemory(pSysBuf, C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE))
                {
                    RtlCopyMemory(pSysBuf + sizeof(PULONG), C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE);

                    if (OutputBufferLength > (sizeof(ULONG) + C0CE_SIGNATURE_SIZE)) {
                        RtlZeroMemory(pSysBuf + sizeof(ULONG) + C0CE_SIGNATURE_SIZE,
                                      OutputBufferLength - (sizeof(ULONG) + C0CE_SIGNATURE_SIZE));
                    }

                    pIrp->IoStatus.Information = OutputBufferLength;
                } else {
                    pIrp->IoStatus.Information = sizeof(ULONG);
                }

                modemControl &= C0C_MCR_MASK;
            }

            *(PULONG)pSysBuf = modemControl;

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        }
        case IOCTL_SERIAL_SET_XON: {
            LIST_ENTRY queueToComplete;

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            SetXonXoffHolding(pIoPortLocal, C0C_XCHAR_ON);

            if (pIoPortLocal->tryWrite) {
                ReadWrite(
                    pIoPortLocal, FALSE,
                    pIoPortLocal->pIoPortRemote, FALSE,
                    &queueToComplete);
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_SET_XOFF:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            SetXonXoffHolding(pIoPortLocal, C0C_XCHAR_OFF);
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        case IOCTL_SERIAL_SET_BREAK_ON: {
            LIST_ENTRY queueToComplete;

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            SetBreakHolding(pIoPortLocal, TRUE, &queueToComplete);
            UpdateTransmitToggle(pIoPortLocal, &queueToComplete);

            ReadWrite(
                pIoPortLocal, FALSE,
                pIoPortLocal->pIoPortRemote, FALSE,
                &queueToComplete);

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_SET_BREAK_OFF: {
            LIST_ENTRY queueToComplete;

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            SetBreakHolding(pIoPortLocal, FALSE, &queueToComplete);
            UpdateTransmitToggle(pIoPortLocal, &queueToComplete);

            if (pIoPortLocal->tryWrite || pIoPortLocal->pIoPortRemote->tryWrite) {
                ReadWrite(
                    pIoPortLocal, FALSE,
                    pIoPortLocal->pIoPortRemote, FALSE,
                    &queueToComplete);
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_MODEMSTATUS:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PULONG)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->modemStatus;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(ULONG);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_WAIT_MASK:
            status = FdoPortSetWaitMask(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_GET_WAIT_MASK:
            status = FdoPortGetWaitMask(pIoPortLocal, pIrp, pIrpStack);
            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_WAIT_ON_MASK:
            status = FdoPortWaitOnMask(pIoPortLocal, pIrp, pIrpStack);
#if ENABLE_TRACING
            if (status == STATUS_SUCCESS)
                TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
#endif /* ENABLE_TRACING */
            break;
        case IOCTL_SERIAL_IMMEDIATE_CHAR:
            status = FdoPortImmediateChar(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_XOFF_COUNTER:
            status = FdoPortXoffCounter(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_PURGE: {
            LIST_ENTRY queueToComplete;
            PULONG pSysBuf;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

            if (*pSysBuf & ~(
                        SERIAL_PURGE_TXABORT |
                        SERIAL_PURGE_RXABORT |
                        SERIAL_PURGE_TXCLEAR |
                        SERIAL_PURGE_RXCLEAR
                    )) {
                status = STATUS_INVALID_PARAMETER;
                break;
            }

            InitializeListHead(&queueToComplete);
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (*pSysBuf & SERIAL_PURGE_RXABORT)
                CancelQueue(&pIoPortLocal->irpQueues[C0C_QUEUE_READ], &queueToComplete);

            if (*pSysBuf & SERIAL_PURGE_TXABORT)
                CancelQueue(&pIoPortLocal->irpQueues[C0C_QUEUE_WRITE], &queueToComplete);

            if (*pSysBuf & SERIAL_PURGE_RXCLEAR) {
                PurgeBuffer(&pIoPortLocal->readBuf);
                UpdateHandFlow(pIoPortLocal, TRUE, &queueToComplete);
                if (pIoPortLocal->tryWrite || pIoPortLocal->pIoPortRemote->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);

            break;
        }
        case IOCTL_SERIAL_GET_COMMSTATUS: {
            PSERIAL_STATUS pSysBuf;
            PIRP pIrpWrite;

            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_STATUS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PSERIAL_STATUS)pIrp->AssociatedIrp.SystemBuffer;
            RtlZeroMemory(pSysBuf, sizeof(*pSysBuf));

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            pSysBuf->AmountInInQueue = (ULONG)C0C_BUFFER_BUSY(&pIoPortLocal->readBuf);

            pIrpWrite = pIoPortLocal->irpQueues[C0C_QUEUE_WRITE].pCurrent;

            if (pIrpWrite) {
                PIO_STACK_LOCATION pIrpStackWrite = IoGetCurrentIrpStackLocation(pIrpWrite);

                if (pIrpStackWrite->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
                        pIrpStackWrite->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR)
                {
                    pSysBuf->WaitForImmediate = TRUE;
                }
            }

            pSysBuf->AmountInOutQueue = pIoPortLocal->amountInWriteQueue;
            pSysBuf->HoldReasons = pIoPortLocal->writeHolding;

            if ((pIoPortLocal->handFlow.ControlHandShake & SERIAL_DSR_SENSITIVITY) &&
                    (pIoPortLocal->modemStatus & C0C_MSB_DSR) == 0)
            {
                pSysBuf->HoldReasons |= SERIAL_RX_WAITING_FOR_DSR;
            }

            if (pIoPortLocal->writeHoldingRemote & SERIAL_TX_WAITING_FOR_XON)
                pSysBuf->HoldReasons |= SERIAL_TX_WAITING_XOFF_SENT;

            pSysBuf->Errors = pIoPortLocal->errors;
            pIoPortLocal->errors = 0;

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            pIrp->IoStatus.Information = sizeof(SERIAL_STATUS);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);

            break;
        }
        case IOCTL_SERIAL_SET_HANDFLOW: {
            LIST_ENTRY queueToComplete;
            PSERIAL_HANDFLOW pSysBuf;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_HANDFLOW)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PSERIAL_HANDFLOW)pIrp->AssociatedIrp.SystemBuffer;

            if (pSysBuf->ControlHandShake & SERIAL_CONTROL_INVALID ||
                    pSysBuf->FlowReplace & SERIAL_FLOW_INVALID ||
                    (pSysBuf->ControlHandShake & SERIAL_DTR_MASK) == SERIAL_DTR_MASK ||
                    pSysBuf->XonLimit < 0 ||
                    pSysBuf->XoffLimit < 0)
            {
                status = STATUS_INVALID_PARAMETER;
                break;
            }

            InitializeListHead(&queueToComplete);
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            status = SetHandFlow(pIoPortLocal, pSysBuf, &queueToComplete);

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_HANDFLOW:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_HANDFLOW)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_HANDFLOW)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->handFlow;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIAL_HANDFLOW);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_TIMEOUTS:
            status = FdoPortSetTimeouts(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_GET_TIMEOUTS:
            status = FdoPortGetTimeouts(pIoPortLocal, pIrp, pIrpStack);
            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_CHARS: {
            PSERIAL_CHARS pSysBuf;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_CHARS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (pIoPortLocal->escapeChar &&
                    ((pIoPortLocal->escapeChar == pSysBuf->XoffChar) ||
                     (pIoPortLocal->escapeChar == pSysBuf->XonChar)))
            {
                status = STATUS_INVALID_PARAMETER;
            }

            if (status == STATUS_SUCCESS)
                pIoPortLocal->specialChars = *pSysBuf;

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_GET_CHARS:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_CHARS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->specialChars;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            pIrp->IoStatus.Information = sizeof(SERIAL_CHARS);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_LSRMST_INSERT: {
            ULONG Information;
            ULONG optsAndBits;
            UCHAR escapeChar;
            PUCHAR pSysBuf;
            ULONG InputBufferLength;
            BOOLEAN extended;

            InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

            if (InputBufferLength < sizeof(UCHAR)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            Information = 0;
            pSysBuf = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;
            escapeChar = *pSysBuf;

            if (InputBufferLength >= (sizeof(UCHAR) + C0CE_SIGNATURE_SIZE + sizeof(ULONG)) &&
                    RtlEqualMemory(pSysBuf + 1, C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE))
            {
                extended = TRUE;
                optsAndBits = *(ULONG *)(pSysBuf + 1 + C0CE_SIGNATURE_SIZE);

#define C0CE_INSERT_OPTS ( \
        C0CE_INSERT_IOCTL_GET| \
        C0CE_INSERT_IOCTL_RXCLEAR)

#define C0CE_INSERT_BITS ( \
        C0CE_INSERT_ENABLE_LSR| \
        C0CE_INSERT_ENABLE_MST| \
        C0CE_INSERT_ENABLE_RBR| \
        C0CE_INSERT_ENABLE_RLC| \
        C0CE_INSERT_ENABLE_LSR_BI)

#define C0CE_INSERT_CAPS (C0CE_INSERT_OPTS|C0CE_INSERT_BITS)

                if (optsAndBits == C0CE_INSERT_IOCTL_CAPS) {
                    optsAndBits = 0;

                    Information += C0CE_SIGNATURE_SIZE + sizeof(ULONG);

                    if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < Information) {
                        status = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }

                    RtlCopyMemory(pSysBuf, C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE);
                    *(ULONG *)(pSysBuf + C0CE_SIGNATURE_SIZE) = C0CE_INSERT_CAPS;
                } else {
                    if (optsAndBits & ~C0CE_INSERT_CAPS) {
                        status = STATUS_INVALID_PARAMETER;
                        break;
                    }

                    if (optsAndBits & C0CE_INSERT_IOCTL_GET) {
                        if (optsAndBits & (C0CE_INSERT_ENABLE_LSR|C0CE_INSERT_ENABLE_LSR_BI))
                            Information += sizeof(UCHAR)*2 + sizeof(UCHAR);
                        if (optsAndBits & C0CE_INSERT_ENABLE_MST)
                            Information += sizeof(UCHAR)*2 + sizeof(UCHAR);
                        if (optsAndBits & C0CE_INSERT_ENABLE_RBR)
                            Information += sizeof(UCHAR)*2 + sizeof(ULONG);
                        if (optsAndBits & C0CE_INSERT_ENABLE_RLC)
                            Information += sizeof(UCHAR)*2 + sizeof(UCHAR)*3;
                    }

                    if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < Information) {
                        status = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }
                }
            } else {
                extended = FALSE;
                optsAndBits = (C0CE_INSERT_ENABLE_LSR|C0CE_INSERT_ENABLE_MST);
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (escapeChar && ((escapeChar == pIoPortLocal->specialChars.XoffChar) ||
                               (escapeChar == pIoPortLocal->specialChars.XonChar) ||
                               (pIoPortLocal->handFlow.FlowReplace & SERIAL_ERROR_CHAR)))
            {
                status = STATUS_INVALID_PARAMETER;
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                break;
            }

            pIoPortLocal->insertMask = optsAndBits & C0CE_INSERT_BITS;
            pIoPortLocal->escapeChar = escapeChar;

            if (extended) {
                LIST_ENTRY queueToComplete;
                PC0C_IO_PORT pIoPortRemote;

                InitializeListHead(&queueToComplete);
                pIoPortRemote = pIoPortLocal->pIoPortRemote;

                if (optsAndBits & C0CE_INSERT_IOCTL_GET) {
                    if (optsAndBits & (C0CE_INSERT_ENABLE_LSR|C0CE_INSERT_ENABLE_LSR_BI)) {
                        UCHAR lsr = 0;

                        if (C0C_TX_BUFFER_THR_EMPTY(&pIoPortLocal->txBuf)) {
                            lsr |= 0x20;  /* transmit holding register empty */

                            if (C0C_TX_BUFFER_EMPTY(&pIoPortLocal->txBuf))
                                lsr |= 0x40;  /* transmit holding register empty and line is idle */
                        }

                        if ((optsAndBits & C0CE_INSERT_ENABLE_LSR_BI) != 0 && pIoPortLocal->rcvdBreak)
                            lsr |= 0x10;  /* break interrupt indicator */

                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = SERIAL_LSRMST_LSR_NODATA;
                        *pSysBuf++ = lsr;
                    }

                    if (optsAndBits & C0CE_INSERT_ENABLE_MST) {
                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = SERIAL_LSRMST_MST;
                        *pSysBuf++ = pIoPortLocal->modemStatus;
                    }

                    if (optsAndBits & C0CE_INSERT_ENABLE_RBR) {
                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = C0CE_INSERT_RBR;
                        *(ULONG *)pSysBuf = pIoPortRemote->baudRate.BaudRate;
                        pSysBuf += sizeof(ULONG);
                    }

                    if (optsAndBits & C0CE_INSERT_ENABLE_RLC) {
                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = C0CE_INSERT_RLC;
                        *pSysBuf++ = pIoPortRemote->lineControl.WordLength;
                        *pSysBuf++ = pIoPortRemote->lineControl.Parity;
                        *pSysBuf++ = pIoPortRemote->lineControl.StopBits;
                    }
                }

                pIrp->IoStatus.Information = Information;

                if (optsAndBits & C0CE_INSERT_IOCTL_RXCLEAR) {
                    PurgeBuffer(&pIoPortLocal->readBuf);
                    UpdateHandFlow(pIoPortLocal, TRUE, &queueToComplete);
                    if (pIoPortLocal->tryWrite || pIoPortRemote->tryWrite) {
                        ReadWrite(
                            pIoPortLocal, FALSE,
                            pIoPortRemote, FALSE,
                            &queueToComplete);
                    }
                }

                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                FdoPortCompleteQueue(&queueToComplete);

                TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
                break;
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_SET_LINE_CONTROL: {
            PSERIAL_LINE_CONTROL pLineControl;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_LINE_CONTROL)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pLineControl = (PSERIAL_LINE_CONTROL)pIrp->AssociatedIrp.SystemBuffer;

            switch (pLineControl->WordLength) {
            case 5:
            case 6:
            case 7:
            case 8:
                break;
            default:
                status = STATUS_INVALID_PARAMETER;
            }

            switch (pLineControl->Parity) {
            case NO_PARITY:
            case ODD_PARITY:
            case EVEN_PARITY:
            case MARK_PARITY:
            case SPACE_PARITY:
                break;
            default:
                status = STATUS_INVALID_PARAMETER;
            }

            switch (pLineControl->StopBits) {
            case STOP_BIT_1:
            case STOP_BITS_1_5:
            case STOP_BITS_2:
                break;
            default:
                status = STATUS_INVALID_PARAMETER;
            }

            if (status == STATUS_INVALID_PARAMETER)
                break;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            if (pIoPortLocal->lineControl.StopBits != pLineControl->StopBits ||
                    pIoPortLocal->lineControl.Parity != pLineControl->Parity ||
                    pIoPortLocal->lineControl.WordLength != pLineControl->WordLength)
            {
                PC0C_IO_PORT pIoPortRemote;

                pIoPortLocal->lineControl = *pLineControl;
                SetWriteDelay(pIoPortLocal);

                pIoPortRemote = pIoPortLocal->pIoPortRemote;

                if (pIoPortRemote->escapeChar && (pIoPortRemote->insertMask & C0CE_INSERT_ENABLE_RLC)) {
                    LIST_ENTRY queueToComplete;

                    InitializeListHead(&queueToComplete);

                    InsertRemoteLc(pIoPortRemote, &queueToComplete);

                    if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                        ReadWrite(
                            pIoPortLocal, FALSE,
                            pIoPortLocal->pIoPortRemote, FALSE,
                            &queueToComplete);
                    }

                    KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                    FdoPortCompleteQueue(&queueToComplete);
                    break;
                }
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_GET_LINE_CONTROL:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_LINE_CONTROL)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_LINE_CONTROL)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->lineControl;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_BAUD_RATE: {
            PSERIAL_BAUD_RATE pBaudRate;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_BAUD_RATE)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pBaudRate = (PSERIAL_BAUD_RATE)pIrp->AssociatedIrp.SystemBuffer;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            if (pIoPortLocal->baudRate.BaudRate != pBaudRate->BaudRate) {
                PC0C_IO_PORT pIoPortRemote;

                pIoPortLocal->baudRate = *pBaudRate;
                SetWriteDelay(pIoPortLocal);

                pIoPortRemote = pIoPortLocal->pIoPortRemote;

                if (pIoPortRemote->escapeChar && (pIoPortRemote->insertMask & C0CE_INSERT_ENABLE_RBR)) {
                    LIST_ENTRY queueToComplete;

                    InitializeListHead(&queueToComplete);

                    InsertRemoteBr(pIoPortRemote, &queueToComplete);

                    if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                        ReadWrite(
                            pIoPortLocal, FALSE,
                            pIoPortLocal->pIoPortRemote, FALSE,
                            &queueToComplete);
                    }

                    KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                    FdoPortCompleteQueue(&queueToComplete);
                    break;
                }
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_GET_BAUD_RATE:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_BAUD_RATE)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_BAUD_RATE)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->baudRate;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIAL_BAUD_RATE);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_GET_PROPERTIES: {
            ULONG size;

            status = GetCommProp(pDevExt,
                                 pIrp->AssociatedIrp.SystemBuffer,
                                 pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
                                 &size);

            if (status == STATUS_SUCCESS) {
                pIrp->IoStatus.Information = size;
                TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            }

            break;
        }
        case IOCTL_SERIAL_CONFIG_SIZE:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }
            pIrp->IoStatus.Information = sizeof(ULONG);
            *(PULONG)pIrp->AssociatedIrp.SystemBuffer = 0;
            break;
        case IOCTL_SERIAL_SET_QUEUE_SIZE: {
            PSERIAL_QUEUE_SIZE pSysBuf = (PSERIAL_QUEUE_SIZE)pIrp->AssociatedIrp.SystemBuffer;
            LIST_ENTRY queueToComplete;
            PC0C_BUFFER pReadBuf;
            PUCHAR pBase;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_QUEUE_SIZE)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pReadBuf = &pIoPortLocal->readBuf;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            if (pSysBuf->InSize <= C0C_BUFFER_SIZE(pReadBuf)) {
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                break;
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            try {
                pBase = C0C_ALLOCATE_POOL_WITH_QUOTA(NonPagedPool, pSysBuf->InSize);
            }
            except (EXCEPTION_EXECUTE_HANDLER) {
                pBase = NULL;
                status = GetExceptionCode();
            }

            if (!pBase)
                break;

            InitializeListHead(&queueToComplete);
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (SetNewBufferBase(pReadBuf, pBase, pSysBuf->InSize)) {
                pIoPortLocal->handFlow.XoffLimit = pSysBuf->InSize >> 3;
                pIoPortLocal->handFlow.XonLimit = pSysBuf->InSize >> 1;
                SetLimit(pIoPortLocal);
                UpdateHandFlow(pIoPortLocal, TRUE, &queueToComplete);
                if (pIoPortLocal->tryWrite || pIoPortLocal->pIoPortRemote->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_STATS:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIALPERF_STATS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIALPERF_STATS)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->perfStats;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIALPERF_STATS);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_CLEAR_STATS:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            RtlZeroMemory(&pIoPortLocal->perfStats, sizeof(pIoPortLocal->perfStats));
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        default:
            status = STATUS_INVALID_PARAMETER;
        }
    }
Ejemplo n.º 20
0
// is_enabled is a 0 for no torque or 1 for torque
int DarwinController::Set_Torque_Enable(unsigned char joint_ID, unsigned char is_enabled){
    unsigned char Torque_packet[8] = {0, };
    MakePacket(Torque_packet, joint_ID, 1, WRITE, TORQUE_ENABLE, &is_enabled);
    unsigned char rxpacket[MAXNUM_RXPARAM] = {0, };
    return ReadWrite(Torque_packet, rxpacket);
}
Ejemplo n.º 21
0
static int WriteMemory( addr48_ptr *addr, byte *data, int len )
{
    if( addr->segment == Regs.CS ) addr->segment = Regs.DS; // hack, ack
    return( ReadWrite( DoWriteMem, addr, (char *)data, len ) );
}
Ejemplo n.º 22
0
NTSTATUS SetHandFlow(
    PC0C_IO_PORT pIoPort,
    PSERIAL_HANDFLOW pHandFlow,
    PLIST_ENTRY pQueueToComplete)
{
  UCHAR bits, mask;
  PC0C_BUFFER pReadBuf;
  PSERIAL_HANDFLOW pNewHandFlow;
  BOOLEAN setModemStatusHolding;

  pReadBuf = &pIoPort->readBuf;

  if (pHandFlow) {
    if ((pIoPort->escapeChar && (pHandFlow->FlowReplace & SERIAL_ERROR_CHAR)) ||
        ((SIZE_T)pHandFlow->XonLimit > C0C_BUFFER_SIZE(pReadBuf)) ||
        ((SIZE_T)pHandFlow->XoffLimit > C0C_BUFFER_SIZE(pReadBuf)))
    {
      return STATUS_INVALID_PARAMETER;
    }

    pNewHandFlow = pHandFlow;
  } else {
    pNewHandFlow = &pIoPort->handFlow;
  }

  // Set local side
  if (!pHandFlow)
    pIoPort->writeHolding &= ~SERIAL_TX_WAITING_FOR_XON;

  if (pHandFlow &&
      ((pIoPort->handFlow.FlowReplace & SERIAL_AUTO_TRANSMIT) != 0) &&
      ((pHandFlow->FlowReplace & SERIAL_AUTO_TRANSMIT) == 0))
  {
    SetXonXoffHolding(pIoPort, C0C_XCHAR_ON);
  }

  if (!pHandFlow ||
      (pIoPort->handFlow.ControlHandShake & SERIAL_OUT_HANDSHAKEMASK) !=
          (pHandFlow->ControlHandShake & SERIAL_OUT_HANDSHAKEMASK))
  {
    setModemStatusHolding = TRUE;
  } else {
    setModemStatusHolding = FALSE;
  }

  // Set remote side
  bits = mask = 0;

  if (!pHandFlow ||
      (pIoPort->handFlow.FlowReplace & SERIAL_RTS_MASK) !=
          (pHandFlow->FlowReplace & SERIAL_RTS_MASK))
  {
    switch (pNewHandFlow->FlowReplace & SERIAL_RTS_MASK) {
    case 0:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_CTS;
      mask |= C0C_MCR_RTS;
      break;
    case SERIAL_RTS_CONTROL:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_CTS;
      bits |= C0C_MCR_RTS;
      mask |= C0C_MCR_RTS;
      break;
    case SERIAL_RTS_HANDSHAKE:
      if (C0C_BUFFER_BUSY(pReadBuf) > (C0C_BUFFER_SIZE(pReadBuf) - pNewHandFlow->XoffLimit)) {
        pIoPort->writeHoldingRemote |= SERIAL_TX_WAITING_FOR_CTS;
        mask |= C0C_MCR_RTS;
      }
      else
      if (pIoPort->writeHoldingRemote & SERIAL_TX_WAITING_FOR_CTS) {
        if (C0C_BUFFER_BUSY(pReadBuf) <= (SIZE_T)pNewHandFlow->XonLimit) {
          pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_CTS;
          bits |= C0C_MCR_RTS;
          mask |= C0C_MCR_RTS;
        }
      }
      else {
        bits |= C0C_MCR_RTS;
        mask |= C0C_MCR_RTS;
      }
    }
  }

  if (!pHandFlow ||
      (pIoPort->handFlow.ControlHandShake & SERIAL_DTR_MASK) !=
          (pHandFlow->ControlHandShake & SERIAL_DTR_MASK))
  {
    switch (pNewHandFlow->ControlHandShake & SERIAL_DTR_MASK) {
    case 0:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_DSR;
      mask |= C0C_MCR_DTR;
      break;
    case SERIAL_DTR_CONTROL:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_DSR;
      bits |= C0C_MCR_DTR;
      mask |= C0C_MCR_DTR;
      break;
    case SERIAL_DTR_HANDSHAKE:
      if (C0C_BUFFER_BUSY(pReadBuf) > (C0C_BUFFER_SIZE(pReadBuf) - pNewHandFlow->XoffLimit)) {
        pIoPort->writeHoldingRemote |= SERIAL_TX_WAITING_FOR_DSR;
        mask |= C0C_MCR_DTR;
      }
      else
      if (pIoPort->writeHoldingRemote & SERIAL_TX_WAITING_FOR_DSR) {
        if (C0C_BUFFER_BUSY(pReadBuf) <= (SIZE_T)pNewHandFlow->XonLimit) {
          pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_DSR;
          bits |= C0C_MCR_DTR;
          mask |= C0C_MCR_DTR;
        }
      }
      else {
        bits |= C0C_MCR_DTR;
        mask |= C0C_MCR_DTR;
      }
    }
  }

  if (!pHandFlow ||
      (pIoPort->handFlow.FlowReplace & SERIAL_AUTO_RECEIVE) !=
          (pHandFlow->FlowReplace & SERIAL_AUTO_RECEIVE))
  {
    if (pNewHandFlow->FlowReplace & SERIAL_AUTO_RECEIVE) {
      if (C0C_BUFFER_BUSY(pReadBuf) > (C0C_BUFFER_SIZE(pReadBuf) - pNewHandFlow->XoffLimit)) {
        pIoPort->writeHoldingRemote |= SERIAL_TX_WAITING_FOR_XON;
        if ((pNewHandFlow->FlowReplace & SERIAL_XOFF_CONTINUE) == 0)
          pIoPort->writeHolding |= SERIAL_TX_WAITING_FOR_XON;
        pIoPort->sendXonXoff = C0C_XCHAR_OFF;
        pIoPort->tryWrite = TRUE;
      }
    }
    else
    if (pIoPort->writeHoldingRemote & SERIAL_TX_WAITING_FOR_XON) {
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_XON;
      pIoPort->writeHolding &= ~SERIAL_TX_WAITING_FOR_XON;
      if (pIoPort->sendXonXoff != C0C_XCHAR_OFF) {
        // XOFF was sent so send XON
        pIoPort->sendXonXoff = C0C_XCHAR_ON;
        pIoPort->tryWrite = TRUE;
      } else {
        // XOFF still was not sent so cancel it
        pIoPort->sendXonXoff = 0;
      }
    }
  }

  if (pHandFlow)
    pIoPort->handFlow = *pHandFlow;

  if (setModemStatusHolding)
    SetModemStatusHolding(pIoPort);

  if (mask)
    SetModemControl(pIoPort, bits, mask, pQueueToComplete);

  UpdateTransmitToggle(pIoPort, pQueueToComplete);

  SetLimit(pIoPort->pIoPortRemote);
  SetLimit(pIoPort);

  if (pIoPort->pIoPortRemote->tryWrite) {
    ReadWrite(
        pIoPort, FALSE,
        pIoPort->pIoPortRemote, FALSE,
        pQueueToComplete);
  }

  if (pIoPort->tryWrite) {
    ReadWrite(
        pIoPort->pIoPortRemote, FALSE,
        pIoPort, FALSE,
        pQueueToComplete);
  }

  return STATUS_SUCCESS;
}