Esempio n. 1
0
/* Hand over a packet to a device for processing.  Return value
   USB_RET_ASYNC indicates the processing isn't finished yet, the
   driver will call usb_packet_complete() when done processing it. */
int usb_handle_packet(USBDevice *dev, USBPacket *p)
{
    int ret;

    if (dev == NULL) {
        return USB_RET_NODEV;
    }
    assert(dev == p->ep->dev);
    assert(dev->state == USB_STATE_DEFAULT);
    usb_packet_check_state(p, USB_PACKET_SETUP);
    assert(p->ep != NULL);

    if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
        ret = usb_process_one(p);
        if (ret == USB_RET_ASYNC) {
            usb_packet_set_state(p, USB_PACKET_ASYNC);
            QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
        } else {
            p->result = ret;
            usb_packet_set_state(p, USB_PACKET_COMPLETE);
        }
    } else {
        ret = USB_RET_ASYNC;
        usb_packet_set_state(p, USB_PACKET_QUEUED);
        QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
    }
    return ret;
}
Esempio n. 2
0
/* Sends an LLCP PDU from the RE to the guest. Sending
 * means that the PDU is either generated and transmitted
 * directly or enqueued for later transmission.
 */
static int
send_pdu_from_re(ssize_t (*create)(void*, struct llcp_pdu*),
                 void* data, struct nfc_re* re)
{
    if (re->xmit_next) {
        /* it's our turn to xmit the next PDU; we do this
         * immediately and cancel the possible timer for the
         * SYMM PDU */
        struct create_nci_dta_param param =
            CREATE_NCI_DTA_PARAM_INIT(create, data, re);

        goldfish_nfc_send_dta(create_nci_dta, &param);
        re->xmit_next = 0;
        if (re->xmit_timer) {
            qemu_del_timer(re->xmit_timer);
        }
    } else {
        /* we're waiting for the host to send a SYMM PDU, so
         * we queue up PDUs for later delivery */
        struct llcp_pdu_buf* buf = llcp_alloc_pdu_buf();
        if (!buf) {
            return -1;
        }
        buf->len = create(data, (struct llcp_pdu*)buf->pdu);
        QTAILQ_INSERT_TAIL(&re->xmit_q, buf, entry);
    }
    return 0;
}
Esempio n. 3
0
File: core.c Progetto: gbraad/qemu
/* Hand over a packet to a device for processing.  Return value
   USB_RET_ASYNC indicates the processing isn't finished yet, the
   driver will call usb_packet_complete() when done processing it. */
int usb_handle_packet(USBDevice *dev, USBPacket *p)
{
    int ret;

    if (dev == NULL) {
        return USB_RET_NODEV;
    }
    assert(dev == p->ep->dev);
    assert(dev->state == USB_STATE_DEFAULT);
    usb_packet_check_state(p, USB_PACKET_SETUP);
    assert(p->ep != NULL);

    /* Submitting a new packet clears halt */
    if (p->ep->halted) {
        assert(QTAILQ_EMPTY(&p->ep->queue));
        p->ep->halted = false;
    }

    if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
        ret = usb_process_one(p);
        if (ret == USB_RET_ASYNC) {
            assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
            usb_packet_set_state(p, USB_PACKET_ASYNC);
            QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
        } else if (ret == USB_RET_ADD_TO_QUEUE) {
            usb_packet_set_state(p, USB_PACKET_QUEUED);
            QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
            ret = USB_RET_ASYNC;
        } else {
            /*
             * When pipelining is enabled usb-devices must always return async,
             * otherwise packets can complete out of order!
             */
            assert(!p->ep->pipeline || QTAILQ_EMPTY(&p->ep->queue));
            if (ret != USB_RET_NAK) {
                p->result = ret;
                usb_packet_set_state(p, USB_PACKET_COMPLETE);
            }
        }
    } else {
        ret = USB_RET_ASYNC;
        usb_packet_set_state(p, USB_PACKET_QUEUED);
        QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
    }
    return ret;
}
Esempio n. 4
0
void register_module_init(void (*fn)(void), module_init_type type)
{
    ModuleEntry *e;
    ModuleTypeList *l;

    e = g_malloc0(sizeof(*e));
    e->init = fn;

    l = find_type(type);

    QTAILQ_INSERT_TAIL(l, e, node);
}
Esempio n. 5
0
void cpu_list_add(CPUState *cpu)
{
    qemu_mutex_lock(&qemu_cpu_list_lock);
    if (cpu->cpu_index == UNASSIGNED_CPU_INDEX) {
        cpu->cpu_index = cpu_get_free_index();
        assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX);
    } else {
        assert(!cpu_index_auto_assigned);
    }
    QTAILQ_INSERT_TAIL(&cpus, cpu, node);
    qemu_mutex_unlock(&qemu_cpu_list_lock);

    finish_safe_work(cpu);
}
Esempio n. 6
0
void slirp_add_net_forward(unsigned long dest_ip, unsigned long dest_mask,
                           int dest_lport, int dest_hport,
                           unsigned long redirect_ip, int redirect_port)
{
    slirp_net_forward_init();

    struct net_forward_entry *entry = malloc(sizeof(*entry));
    if (entry == NULL) {
        DEBUG_MISC((dfd, "Unable to create new forwarding entry, malloc failed\n"));
        exit(-1);
    }

    entry->dest_ip = dest_ip;
    entry->dest_mask = dest_mask;
    entry->dest_lport = dest_lport;
    entry->dest_hport = dest_hport;
    entry->redirect_ip = redirect_ip;
    entry->redirect_port = redirect_port;

    QTAILQ_INSERT_TAIL(&net_forwards, entry, next);
}
Esempio n. 7
0
static size_t
process_ptype_cc(struct nfc_re* re, const struct llcp_pdu* llcp,
                 size_t len, uint8_t* consumed,
                 struct llcp_pdu* rsp)
{
    struct llcp_data_link* dl;

    dl = llcp_clear_data_link(re->llcp_dl[llcp->ssap] + llcp->dsap);
    assert(dl->status == LLCP_DATA_LINK_CONNECTING);
    dl->status = LLCP_DATA_LINK_CONNECTED;

    /* move DL's pending PDUs to global xmit queue */
    while (!QTAILQ_EMPTY(&dl->xmit_q)) {
        struct llcp_pdu_buf* buf = QTAILQ_FIRST(&dl->xmit_q);
        QTAILQ_REMOVE(&dl->xmit_q, buf, entry);
        QTAILQ_INSERT_TAIL(&re->xmit_q, buf, entry);
    }

    update_last_saps(re, llcp->ssap, llcp->dsap);

    *consumed = sizeof(*llcp) + 1;

    return 0;
}
Esempio n. 8
0
static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
                                         QXLRect *rect)
{
    SimpleSpiceUpdate *update;
    QXLDrawable *drawable;
    QXLImage *image;
    QXLCommand *cmd;
    int bw, bh;
    struct timespec time_space;
    pixman_image_t *dest;

    trace_qemu_spice_create_update(
           rect->left, rect->right,
           rect->top, rect->bottom);

    update   = g_malloc0(sizeof(*update));
    drawable = &update->drawable;
    image    = &update->image;
    cmd      = &update->ext.cmd;

    bw       = rect->right - rect->left;
    bh       = rect->bottom - rect->top;
    update->bitmap = g_malloc(bw * bh * 4);

    drawable->bbox            = *rect;
    drawable->clip.type       = SPICE_CLIP_TYPE_NONE;
    drawable->effect          = QXL_EFFECT_OPAQUE;
    drawable->release_info.id = (uintptr_t)(&update->ext);
    drawable->type            = QXL_DRAW_COPY;
    drawable->surfaces_dest[0] = -1;
    drawable->surfaces_dest[1] = -1;
    drawable->surfaces_dest[2] = -1;
    clock_gettime(CLOCK_MONOTONIC, &time_space);
    /* time in milliseconds from epoch. */
    drawable->mm_time = time_space.tv_sec * 1000
                      + time_space.tv_nsec / 1000 / 1000;

    drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
    drawable->u.copy.src_bitmap      = (uintptr_t)image;
    drawable->u.copy.src_area.right  = bw;
    drawable->u.copy.src_area.bottom = bh;

    QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_DEVICE, ssd->unique++);
    image->descriptor.type   = SPICE_IMAGE_TYPE_BITMAP;
    image->bitmap.flags      = QXL_BITMAP_DIRECT | QXL_BITMAP_TOP_DOWN;
    image->bitmap.stride     = bw * 4;
    image->descriptor.width  = image->bitmap.x = bw;
    image->descriptor.height = image->bitmap.y = bh;
    image->bitmap.data = (uintptr_t)(update->bitmap);
    image->bitmap.palette = 0;
    image->bitmap.format = SPICE_BITMAP_FMT_32BIT;

    dest = pixman_image_create_bits(PIXMAN_LE_x8r8g8b8, bw, bh,
                                    (void *)update->bitmap, bw * 4);
    pixman_image_composite(PIXMAN_OP_SRC, ssd->surface, NULL, ssd->mirror,
                           rect->left, rect->top, 0, 0,
                           rect->left, rect->top, bw, bh);
    pixman_image_composite(PIXMAN_OP_SRC, ssd->mirror, NULL, dest,
                           rect->left, rect->top, 0, 0,
                           0, 0, bw, bh);
    pixman_image_unref(dest);

    cmd->type = QXL_CMD_DRAW;
    cmd->data = (uintptr_t)drawable;

    QTAILQ_INSERT_TAIL(&ssd->updates, update, next);
}
Esempio n. 9
0
static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
        QXLRect *rect)
{
    SimpleSpiceUpdate *update;
    QXLDrawable *drawable;
    QXLImage *image;
    QXLCommand *cmd;
    uint8_t *src, *mirror, *dst;
    int by, bw, bh, offset, bytes;

    trace_qemu_spice_create_update(
        rect->left, rect->right,
        rect->top, rect->bottom);

    update   = qemu_mallocz(sizeof(*update));
    drawable = &update->drawable;
    image    = &update->image;
    cmd      = &update->ext.cmd;

    bw       = rect->right - rect->left;
    bh       = rect->bottom - rect->top;
    update->bitmap = qemu_malloc(bw * bh * 4);

    drawable->bbox            = *rect;
    drawable->clip.type       = SPICE_CLIP_TYPE_NONE;
    drawable->effect          = QXL_EFFECT_OPAQUE;
    drawable->release_info.id = (intptr_t)update;
    drawable->type            = QXL_DRAW_COPY;
    drawable->surfaces_dest[0] = -1;
    drawable->surfaces_dest[1] = -1;
    drawable->surfaces_dest[2] = -1;

    drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
    drawable->u.copy.src_bitmap      = (intptr_t)image;
    drawable->u.copy.src_area.right  = bw;
    drawable->u.copy.src_area.bottom = bh;

    QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_DEVICE, ssd->unique++);
    image->descriptor.type   = SPICE_IMAGE_TYPE_BITMAP;
    image->bitmap.flags      = QXL_BITMAP_DIRECT | QXL_BITMAP_TOP_DOWN;
    image->bitmap.stride     = bw * 4;
    image->descriptor.width  = image->bitmap.x = bw;
    image->descriptor.height = image->bitmap.y = bh;
    image->bitmap.data = (intptr_t)(update->bitmap);
    image->bitmap.palette = 0;
    image->bitmap.format = SPICE_BITMAP_FMT_32BIT;

    offset =
        rect->top * ds_get_linesize(ssd->ds) +
        rect->left * ds_get_bytes_per_pixel(ssd->ds);
    bytes = ds_get_bytes_per_pixel(ssd->ds) * bw;
    src = ds_get_data(ssd->ds) + offset;
    mirror = ssd->ds_mirror + offset;
    dst = update->bitmap;
    for (by = 0; by < bh; by++) {
        memcpy(mirror, src, bytes);
        qemu_pf_conv_run(ssd->conv, dst, mirror, bw);
        src += ds_get_linesize(ssd->ds);
        mirror += ds_get_linesize(ssd->ds);
        dst += image->bitmap.stride;
    }

    cmd->type = QXL_CMD_DRAW;
    cmd->data = (intptr_t)drawable;

    QTAILQ_INSERT_TAIL(&ssd->updates, update, next);
}