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); }
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); }