@@ -748,6 +748,56 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
}
EXPORT_SYMBOL_GPL(usbip_recv_xbuff);
+int usbip_prepare_threads(struct usbip_thread_info *uti,
+ struct usbip_device *ud, int sockfd,
+ int (*tx_fn)(void *data), const char *tx_name,
+ int (*rx_fn)(void *data), const char *rx_name)
+{
+ int err;
+ struct socket *socket;
+ struct task_struct *tx;
+ struct task_struct *rx;
+
+ /* Extract socket from fd. */
+ socket = sockfd_lookup(sockfd, &err);
+ if (!socket)
+ return -EINVAL;
+ /* Create threads for this socket. */
+ rx = kthread_create(rx_fn, ud, rx_name);
+ if (IS_ERR(rx)) {
+ err = PTR_ERR(rx);
+ goto out_socket;
+ }
+ tx = kthread_create(tx_fn, ud, tx_name);
+ if (IS_ERR(tx)) {
+ err = PTR_ERR(tx);
+ goto out_rx;
+ }
+ uti->tcp_socket = socket;
+ get_task_struct(rx);
+ uti->tcp_rx = rx;
+ get_task_struct(tx);
+ uti->tcp_tx = tx;
+ return 0;
+ out_rx:
+ kthread_stop(rx);
+ out_socket:
+ sockfd_put(socket);
+ return err;
+}
+EXPORT_SYMBOL_GPL(usbip_prepare_threads);
+
+void usbip_unprepare_threads(struct usbip_thread_info *uti)
+{
+ kthread_stop_put(uti->tcp_tx);
+ uti->tcp_tx = NULL;
+ kthread_stop_put(uti->tcp_rx);
+ uti->tcp_rx = NULL;
+ sockfd_put(uti->tcp_socket);
+ uti->tcp_socket = NULL;
+}
+EXPORT_SYMBOL_GPL(usbip_unprepare_threads);
+
static int __init usbip_core_init(void)
{
return usbip_init_eh();
@@ -316,6 +316,18 @@ void usbip_header_correct_endian(struct usbip_header *pdu, int send);
struct usbip_iso_packet_descriptor*
usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
+struct usbip_thread_info {
+ struct socket *tcp_socket;
+ struct task_struct *tcp_tx;
+ struct task_struct *tcp_rx;
+};
+
+int usbip_prepare_threads(struct usbip_thread_info *uti,
+ struct usbip_device *ud, int sockfd,
+ int (*tx_fn)(void *data), const char *tx_name,
+ int (*rx_fn)(void *data), const char *rx_name);
+void usbip_unprepare_threads(struct usbip_thread_info *uti);
+
/* some members of urb must be substituted before. */
int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
void usbip_pad_iso(struct usbip_device *ud, struct urb *urb);