Beispiel #1
0
/* queue an irp to the device */
static obj_handle_t queue_irp( struct device_file *file, struct irp_call *irp,
                               const async_data_t *async_data, int blocking )
{
    obj_handle_t handle = 0;

    if (blocking && !(handle = alloc_handle( current->process, irp, SYNCHRONIZE, 0 ))) return 0;

    if (!(irp->async = fd_queue_async( file->fd, async_data, ASYNC_TYPE_WAIT )))
    {
        if (handle) close_handle( current->process, handle );
        return 0;
    }
    irp->user_arg = async_data->arg;
    add_irp_to_queue( file, irp, current );
    set_error( STATUS_PENDING );
    return handle;
}
Beispiel #2
0
static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
                                  int blocking, const void *data, data_size_t size )
{
    struct device *device = get_fd_user( fd );
    struct ioctl_call *ioctl;
    obj_handle_t handle;

    if (!device->manager)  /* it has been deleted */
    {
        set_error( STATUS_FILE_DELETED );
        return 0;
    }

    if (!(ioctl = create_ioctl( device, code, data, size, get_reply_max_size() )))
        return 0;

    ioctl->thread   = (struct thread *)grab_object( current );
    ioctl->user_arg = async_data->arg;

    if (!(handle = alloc_handle( current->process, ioctl, SYNCHRONIZE, 0 )))
    {
        release_object( ioctl );
        return 0;
    }

    if (!(ioctl->async = fd_queue_async( device->fd, async_data, ASYNC_TYPE_WAIT )))
    {
        close_handle( current->process, handle );
        release_object( ioctl );
        return 0;
    }
    list_add_tail( &device->requests, &ioctl->dev_entry );
    list_add_tail( &device->manager->requests, &ioctl->mgr_entry );
    if (list_head( &device->manager->requests ) == &ioctl->mgr_entry)  /* first one */
        wake_up( &device->manager->obj, 0 );
    /* don't release ioctl since it is now queued in the device */
    set_error( STATUS_PENDING );
    return handle;
}