Пример #1
0
static void rx_urb_complete(struct urb *urb)
{
    struct zd_usb *usb;
    struct zd_usb_rx *rx;
    const u8 *buffer;
    unsigned int length;

    switch (urb->status) {
    case 0:
        break;
    case -ESHUTDOWN:
    case -EINVAL:
    case -ENODEV:
    case -ENOENT:
    case -ECONNRESET:
    case -EPIPE:
        return;
    default:
        dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
        goto resubmit;
    }

    buffer = urb->transfer_buffer;
    length = urb->actual_length;
    usb = urb->context;
    rx = &usb->rx;

    if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
        /* If there is an old first fragment, we don't care. */
        dev_dbg_f(urb_dev(urb), "*** first fragment ***\n");
        ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment));
        spin_lock(&rx->lock);
        memcpy(rx->fragment, buffer, length);
        rx->fragment_length = length;
        spin_unlock(&rx->lock);
        goto resubmit;
    }

    spin_lock(&rx->lock);
    if (rx->fragment_length > 0) {
        /* We are on a second fragment, we believe */
        ZD_ASSERT(length + rx->fragment_length <=
                  ARRAY_SIZE(rx->fragment));
        dev_dbg_f(urb_dev(urb), "*** second fragment ***\n");
        memcpy(rx->fragment+rx->fragment_length, buffer, length);
        handle_rx_packet(usb, rx->fragment,
                         rx->fragment_length + length);
        rx->fragment_length = 0;
        spin_unlock(&rx->lock);
    } else {
        spin_unlock(&rx->lock);
        handle_rx_packet(usb, buffer, length);
    }

resubmit:
    usb_submit_urb(urb, GFP_ATOMIC);
}
Пример #2
0
static gboolean
read_one (GstPluginLoader * l)
{
  guint64 magic;
  guint32 to_read, packet_len, tag;
  guint8 *in;
  gint res;

  to_read = HEADER_SIZE;
  in = l->rx_buf;
  do {
    res = read (l->fd_r.fd, in, to_read);
    if (G_UNLIKELY (res < 0)) {
      if (errno == EAGAIN || errno == EINTR)
        continue;
      GST_LOG ("Failed reading packet header");
      return FALSE;
    }
    to_read -= res;
    in += res;
  } while (to_read > 0);

  magic = GST_READ_UINT32_BE (l->rx_buf + 8);
  if (magic != HEADER_MAGIC) {
    GST_WARNING
        ("Invalid packet (bad magic number) received from plugin scanner subprocess");
    return FALSE;
  }

  packet_len = GST_READ_UINT32_BE (l->rx_buf + 4);
  if (packet_len + HEADER_SIZE > BUF_MAX_SIZE) {
    GST_WARNING
        ("Received excessively large packet for plugin scanner subprocess");
    return FALSE;
  }
  tag = GST_READ_UINT24_BE (l->rx_buf + 1);

  if (packet_len > 0) {
    if (packet_len + HEADER_SIZE >= l->rx_buf_size) {
      GST_LOG ("Expanding rx buf from %d to %d",
          l->rx_buf_size, packet_len + HEADER_SIZE + BUF_GROW_EXTRA);
      l->rx_buf_size = packet_len + HEADER_SIZE + BUF_GROW_EXTRA;
      l->rx_buf = g_realloc (l->rx_buf, l->rx_buf_size);
    }

    in = l->rx_buf + HEADER_SIZE;
    to_read = packet_len;
    do {
      res = read (l->fd_r.fd, in, to_read);
      if (G_UNLIKELY (res < 0)) {
        if (errno == EAGAIN || errno == EINTR)
          continue;
        GST_ERROR ("Packet payload read failed");
        return FALSE;
      }
      to_read -= res;
      in += res;
    } while (to_read > 0);
  } else {
    GST_LOG ("No payload to read for 0 length packet type %d tag %u",
        l->rx_buf[0], tag);
  }

  return handle_rx_packet (l, l->rx_buf[0], tag,
      l->rx_buf + HEADER_SIZE, packet_len);
}