static void __serial_check_fds(SERIAL_DEVICE* serial) { IRP* irp; IRP* prev; SERIAL_TTY* tty; uint32 result = 0; memset(&serial->tv, 0, sizeof(struct timeval)); tty = serial->tty; /* scan every pending */ irp = list_peek(serial->pending_irps); while (irp) { DEBUG_SVC("MajorFunction %u", irp->MajorFunction); switch (irp->MajorFunction) { case IRP_MJ_READ: if (FD_ISSET(tty->fd, &serial->read_fds)) { irp->IoStatus = STATUS_SUCCESS; serial_process_irp_read(serial, irp); } break; case IRP_MJ_WRITE: if (FD_ISSET(tty->fd, &serial->write_fds)) { irp->IoStatus = STATUS_SUCCESS; serial_process_irp_write(serial, irp); } break; case IRP_MJ_DEVICE_CONTROL: if (serial_tty_get_event(tty, &result)) { DEBUG_SVC("got event result %u", result); irp->IoStatus = STATUS_SUCCESS; stream_write_uint32(irp->output, result); irp->Complete(irp); } break; default: DEBUG_SVC("no request found"); break; } prev = irp; irp = (IRP*)list_next(serial->pending_irps, irp); if (prev->IoStatus == STATUS_SUCCESS) { list_remove(serial->pending_irps, prev); wait_obj_set(serial->in_event); } } }
static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32 abort_io, UINT32 io_status) { UINT32 major; IRP* irp = NULL; SERIAL_TTY* tty; DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); tty = serial->tty; if(!tty) { DEBUG_WARN("tty = %p", tty); return; } switch (abort_io) { case SERIAL_ABORT_IO_NONE: major = 0; break; case SERIAL_ABORT_IO_READ: major = IRP_MJ_READ; break; case SERIAL_ABORT_IO_WRITE: major = IRP_MJ_WRITE; break; default: DEBUG_SVC("unexpected abort_io code %d", abort_io); return; } irp = (IRP*) list_peek(serial->pending_irps); while (irp) { if (irp->FileId != file_id || irp->MajorFunction != major) { irp = (IRP*) list_next(serial->pending_irps, irp); continue; } /* Process a SINGLE FileId and MajorFunction */ list_remove(serial->pending_irps, irp); irp->IoStatus = io_status; Stream_Write_UINT32(irp->output, 0); irp->Complete(irp); break; } DEBUG_SVC("[out] pending size %d", list_size(serial->pending_irps)); }
static void serial_check_for_events(SERIAL_DEVICE* serial) { IRP* irp = NULL; IRP* prev; UINT32 result = 0; SERIAL_TTY* tty; tty = serial->tty; if(!tty) { DEBUG_WARN("tty = %p", tty); return; } DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); irp = (IRP*) list_peek(serial->pending_irps); while (irp) { prev = NULL; if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) { if (serial_tty_get_event(tty, &result)) { DEBUG_SVC("got event result %u", result); irp->IoStatus = STATUS_SUCCESS; Stream_Write_UINT32(irp->output, result); irp->Complete(irp); prev = irp; irp = (IRP*) list_next(serial->pending_irps, irp); list_remove(serial->pending_irps, prev); } } if (!prev) irp = (IRP*) list_next(serial->pending_irps, irp); } DEBUG_SVC("[out] pending size %d", list_size(serial->pending_irps)); }
static void __serial_check_fds(SERIAL_DEVICE* serial) { IRP* irp; IRP* prev; SERIAL_TTY* tty; UINT32 result = 0; BOOL irp_completed = FALSE; ZeroMemory(&serial->tv, sizeof(struct timeval)); tty = serial->tty; if(!tty) { DEBUG_WARN("tty = %p", tty); return; } /* scan every pending */ irp = list_peek(serial->pending_irps); while (irp) { DEBUG_SVC("MajorFunction %u", irp->MajorFunction); switch (irp->MajorFunction) { case IRP_MJ_READ: if (FD_ISSET(tty->fd, &serial->read_fds)) { irp->IoStatus = STATUS_SUCCESS; serial_process_irp_read(serial, irp); irp_completed = TRUE; } break; case IRP_MJ_WRITE: if (FD_ISSET(tty->fd, &serial->write_fds)) { irp->IoStatus = STATUS_SUCCESS; serial_process_irp_write(serial, irp); irp_completed = TRUE; } break; case IRP_MJ_DEVICE_CONTROL: if (serial_tty_get_event(tty, &result)) { DEBUG_SVC("got event result %u", result); irp->IoStatus = STATUS_SUCCESS; Stream_Write_UINT32(irp->output, result); irp->Complete(irp); irp_completed = TRUE; } break; default: DEBUG_SVC("no request found"); break; } prev = irp; irp = (IRP*) list_next(serial->pending_irps, irp); if (irp_completed || (prev->IoStatus == STATUS_SUCCESS)) list_remove(serial->pending_irps, prev); } }