staticvoid usbip_dump_pipe(unsignedint p)
{ unsignedchar type = usb_pipetype(p); unsignedchar ep = usb_pipeendpoint(p); unsignedchar dev = usb_pipedevice(p); unsignedchar dir = usb_pipein(p);
dev_dbg(dev, " devnum(%d) devpath(%s) usb speed(%s)",
udev->devnum, udev->devpath, usb_speed_string(udev->speed));
pr_debug("tt hub ttport %d\n", udev->ttport);
dev_dbg(dev, " "); for (i = 0; i < 16; i++)
pr_debug(" %2u", i);
pr_debug("\n");
dev_dbg(dev, " toggle0(IN) :"); for (i = 0; i < 16; i++)
pr_debug(" %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0);
pr_debug("\n");
dev_dbg(dev, " toggle1(OUT):"); for (i = 0; i < 16; i++)
pr_debug(" %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0);
pr_debug("\n");
dev_dbg(dev, " epmaxp_in :"); for (i = 0; i < 16; i++) { if (udev->ep_in[i])
pr_debug(" %2u",
le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize));
}
pr_debug("\n");
dev_dbg(dev, " epmaxp_out :"); for (i = 0; i < 16; i++) { if (udev->ep_out[i])
pr_debug(" %2u",
le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize));
}
pr_debug("\n");
dev_dbg(dev, "parent %s, bus %s\n", dev_name(&udev->parent->dev),
udev->bus->bus_name);
/* there may be more cases to tweak the flags. */ staticunsignedint tweak_transfer_flags(unsignedint flags)
{
flags &= ~URB_NO_TRANSFER_DMA_MAP; return flags;
}
/* * USBIP driver packs URB transfer flags in PDUs that are exchanged * between Server (usbip_host) and Client (vhci_hcd). URB_* flags * are internal to kernel and could change. Where as USBIP URB flags * exchanged in PDUs are USBIP user API must not change. * * USBIP_URB* flags are exported as explicit API and client and server * do mapping from kernel flags to USBIP_URB*. Details as follows: * * Client tx path (USBIP_CMD_SUBMIT): * - Maps URB_* to USBIP_URB_* when it sends USBIP_CMD_SUBMIT packet. * * Server rx path (USBIP_CMD_SUBMIT): * - Maps USBIP_URB_* to URB_* when it receives USBIP_CMD_SUBMIT packet. * * Flags aren't included in USBIP_CMD_UNLINK and USBIP_RET_SUBMIT packets * and no special handling is needed for them in the following cases: * - Server rx path (USBIP_CMD_UNLINK) * - Client rx path & Server tx path (USBIP_RET_SUBMIT) * * Code paths: * usbip_pack_pdu() is the common routine that handles packing pdu from * urb and unpack pdu to an urb. * * usbip_pack_cmd_submit() and usbip_pack_ret_submit() handle * USBIP_CMD_SUBMIT and USBIP_RET_SUBMIT respectively. * * usbip_map_urb_to_usbip() and usbip_map_usbip_to_urb() are used * by usbip_pack_cmd_submit() and usbip_pack_ret_submit() to map * flags.
*/
/* * Some members are not still implemented in usbip. I hope this issue * will be discussed when usbip is ported to other operating systems.
*/ if (pack) { /* map after tweaking the urb flags */
spdu->transfer_flags = urb_to_usbip(tweak_transfer_flags(urb->transfer_flags));
spdu->transfer_buffer_length = urb->transfer_buffer_length;
spdu->start_frame = urb->start_frame;
spdu->number_of_packets = urb->number_of_packets;
spdu->interval = urb->interval;
} else {
urb->transfer_flags = usbip_to_urb(spdu->transfer_flags);
urb->transfer_buffer_length = spdu->transfer_buffer_length;
urb->start_frame = spdu->start_frame;
urb->number_of_packets = spdu->number_of_packets;
urb->interval = spdu->interval;
}
}
/* some members of urb must be substituted before. */ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
{ void *buff; struct usbip_iso_packet_descriptor *iso; int np = urb->number_of_packets; int size = np * sizeof(*iso); int i; int ret; int total_length = 0;
if (!usb_pipeisoc(urb->pipe)) return 0;
/* my Bluetooth dongle gets ISO URBs which are np = 0 */ if (np == 0) return 0;
buff = kzalloc(size, GFP_KERNEL); if (!buff) return -ENOMEM;
ret = usbip_recv(ud->tcp_socket, buff, size); if (ret != size) {
dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n",
ret);
kfree(buff);
iso = (struct usbip_iso_packet_descriptor *) buff; for (i = 0; i < np; i++) {
usbip_iso_packet_correct_endian(&iso[i], 0);
usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 0);
total_length += urb->iso_frame_desc[i].actual_length;
}
kfree(buff);
if (total_length != urb->actual_length) {
dev_err(&urb->dev->dev, "total length of iso packets %d not equal to actual length of buffer %d\n",
total_length, urb->actual_length);
/* * This functions restores the padding which was removed for optimizing * the bandwidth during transfer over tcp/ip * * buffer and iso packets need to be stored and be in propeper endian in urb * before calling this function
*/ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb)
{ int np = urb->number_of_packets; int i; int actualoffset = urb->actual_length;
if (!usb_pipeisoc(urb->pipe)) return;
/* if no packets or length of data is 0, then nothing to unpack */ if (np == 0 || urb->actual_length == 0) return;
/* * if actual_length is transfer_buffer_length then no padding is * present.
*/ if (urb->actual_length == urb->transfer_buffer_length) return;
/* * loop over all packets from last to first (to prevent overwriting * memory when padding) and move them into the proper place
*/ for (i = np-1; i > 0; i--) {
actualoffset -= urb->iso_frame_desc[i].actual_length;
memmove(urb->transfer_buffer + urb->iso_frame_desc[i].offset,
urb->transfer_buffer + actualoffset,
urb->iso_frame_desc[i].actual_length);
}
}
EXPORT_SYMBOL_GPL(usbip_pad_iso);
/* some members of urb must be substituted before. */ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
{ struct scatterlist *sg; int ret = 0; int recv; int size; int copy; int i;
if (ud->side == USBIP_STUB || ud->side == USBIP_VUDC) { /* the direction of urb must be OUT. */ if (usb_pipein(urb->pipe)) return 0;
size = urb->transfer_buffer_length;
} else { /* the direction of urb must be IN. */ if (usb_pipeout(urb->pipe)) return 0;
size = urb->actual_length;
}
/* no need to recv xbuff */ if (!(size > 0)) return 0;
if (size > urb->transfer_buffer_length) /* should not happen, probably malicious packet */ goto error;
if (urb->num_sgs) {
copy = size;
for_each_sg(urb->sg, sg, urb->num_sgs, i) { int recv_size;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.