/* recv a pdu */ static void stub_rx_pdu(struct usbip_device *ud) { int ret; struct usbip_header pdu; struct stub_device *sdev = container_of(ud, struct stub_device, ud); dbg_stub_rx("Enter\n"); memset(&pdu, 0, sizeof(pdu)); /* 1. receive a pdu header */ dbg_stub_rx("before usbip_xmit\n"); ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0); dbg_stub_rx("after usbip_xmit\n"); if (ret != sizeof(pdu)) { uerr("recv a header, %d\n", ret); usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); return; } usbip_header_correct_endian(&pdu, 0); if (dbg_flag_stub_rx) usbip_dump_header(&pdu); if (!valid_request(sdev, &pdu)) { uerr("recv invalid request\n"); usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); return; } #if CLIENT > 2 sdev->heartbeat_pending = 0; #endif switch (pdu.base.command) { case USBIP_CMD_UNLINK: stub_recv_cmd_unlink(sdev, &pdu); break; case USBIP_CMD_SUBMIT: stub_recv_cmd_submit(sdev, &pdu); break; #if CLIENT > 2 // added by tf, 110530 case USBIP_HEARTBEAT_REPLY: sdev->heartbeat_pending = 0; break; // end --- added #endif default: /* NOTREACHED */ uerr("unknown pdu\n"); usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); return; } }
/* recv a pdu */ static void stub_rx_pdu(struct usbip_device *ud) { int ret; struct usbip_header pdu; struct stub_device *sdev = container_of(ud, struct stub_device, ud); dbg_stub_rx("Enter\n"); memset(&pdu, 0, sizeof(pdu)); /* 1. receive a pdu header */ ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu),0); if (ret != sizeof(pdu)) { uerr("recv a header, %d\n", ret); usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); return; } usbip_header_correct_endian(&pdu, 0); if (dbg_flag_stub_rx) usbip_dump_header(&pdu); if (!valid_request(sdev, &pdu)) { uerr("recv invalid request\n"); usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); return; } switch (pdu.base.command) { case USBIP_CMD_UNLINK: stub_recv_cmd_unlink(sdev, &pdu); break; case USBIP_CMD_SUBMIT: stub_recv_cmd_submit(sdev, &pdu); break; default: /* NOTREACHED */ uerr("unknown pdu\n"); usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); return; } }
/* 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; if (!usb_pipeisoc(urb->pipe)) return 0; buff = kzalloc(size, GFP_KERNEL); if (!buff) return -ENOMEM; ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0); if (ret != size) { uerr("recv iso_frame_descriptor, %d\n", ret); kfree(buff); if (ud->side == USBIP_STUB) usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); else usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); return -EPIPE; } for (i = 0; i < np; i++) { iso = buff + (i * sizeof(*iso)); usbip_iso_pakcet_correct_endian(iso, 0); usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0); } kfree(buff); return ret; }
/* some members of urb must be substituted before. */ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) { int ret; int size; if (ud->side == USBIP_STUB) { /* stub_rx.c */ /* the direction of urb must be OUT. */ if (usb_pipein(urb->pipe)) return 0; size = urb->transfer_buffer_length; } else { /* vhci_rx.c */ /* 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; ret = usbip_xmit(0, ud->tcp_socket, (char *)urb->transfer_buffer, size, 0); if (ret != size) { dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret); if (ud->side == USBIP_STUB) { usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); } else { usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); return -EPIPE; } } return ret; }
int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) { int ret; char *iso_frame_desc = (char *) &urb->iso_frame_desc[0]; int np = urb->number_of_packets; int size = np * sizeof(struct usb_iso_packet_descriptor); if (!usb_pipeisoc(urb->pipe)) return 0; ret = usbip_xmit(0, ud->tcp_socket, iso_frame_desc, size, 0); if (ret != size ) { uerr("recv iso_frame_descriptor, %d\n", ret); if (ud->side == USBIP_STUB) { usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); } else { usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); } return -EPIPE; } return ret; }
ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen) { return usbip_xmit(sockfd, buff, bufflen, 0); }
ssize_t usbip_send(int sockfd, void *buff, size_t bufflen) { return usbip_xmit(sockfd, buff, bufflen, 1); }
/* 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) { /* pr_info("iso np == 0\n"); */ /* usbip_dump_urb(urb); */ return 0; } buff = kzalloc(size, GFP_KERNEL); if (!buff) return -ENOMEM; ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0); if (ret != size) { dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n", ret); kfree(buff); if (ud->side == USBIP_STUB) usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); else usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); return -EPIPE; } for (i = 0; i < np; i++) { iso = buff + (i * sizeof(*iso)); usbip_iso_packet_correct_endian(iso, 0); usbip_pack_iso(iso, &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); if (ud->side == USBIP_STUB) usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); else usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); return -EPIPE; } return ret; }