void usbip_stop_threads(struct usbip_device *ud) { /* kill threads related to this sdev, if v.c. exists */ if (ud->tcp_rx.thread != NULL) { send_sig(SIGKILL, ud->tcp_rx.thread, 1); wait_for_completion(&ud->tcp_rx.thread_done); usbip_udbg("rx_thread for ud %p has finished\n", ud); } if (ud->tcp_tx.thread != NULL) { send_sig(SIGKILL, ud->tcp_tx.thread, 1); wait_for_completion(&ud->tcp_tx.thread_done); usbip_udbg("tx_thread for ud %p has finished\n", ud); } }
static void stop_tx_thread(struct usbip_device *ud) { if (ud->tcp_tx.thread != NULL) { send_sig(SIGKILL, ud->tcp_tx.thread, 1); wait_for_completion(&ud->tcp_tx.thread_done); usbip_udbg("tx_thread for ud %p has finished\n", ud); } }
static ssize_t store_match_busid(struct device_driver *dev, const char *buf, size_t count) { int len; char busid[BUSID_SIZE]; if (count < 5) return -EINVAL; /* strnlen() does not include \0 */ len = strnlen(buf + 4, BUSID_SIZE); /* busid needs to include \0 termination */ if (!(len < BUSID_SIZE)) return -EINVAL; strncpy(busid, buf + 4, BUSID_SIZE); if (!strncmp(buf, "add ", 4)) { if (add_match_busid(busid) < 0) return -ENOMEM; else { usbip_udbg("add busid %s\n", busid); return count; } } else if (!strncmp(buf, "del ", 4)) { if (del_match_busid(busid) < 0) return -ENODEV; else { usbip_udbg("del busid %s\n", busid); return count; } } else return -EINVAL; }
void usbip_dump_header(struct usbip_header *pdu) { usbip_udbg("BASE: cmd %u seq %u devid %u dir %u ep %u\n", pdu->base.command, pdu->base.seqnum, pdu->base.devid, pdu->base.direction, pdu->base.ep); switch (pdu->base.command) { case USBIP_CMD_SUBMIT: usbip_udbg("CMD_SUBMIT: " "x_flags %u x_len %u sf %u #p %u iv %u\n", pdu->u.cmd_submit.transfer_flags, pdu->u.cmd_submit.transfer_buffer_length, pdu->u.cmd_submit.start_frame, pdu->u.cmd_submit.number_of_packets, pdu->u.cmd_submit.interval); break; case USBIP_CMD_UNLINK: usbip_udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum); break; case USBIP_RET_SUBMIT: usbip_udbg("RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n", pdu->u.ret_submit.status, pdu->u.ret_submit.actual_length, pdu->u.ret_submit.start_frame, pdu->u.ret_submit.number_of_packets, pdu->u.ret_submit.error_count); case USBIP_RET_UNLINK: usbip_udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status); break; default: /* NOT REACHED */ usbip_udbg("UNKNOWN\n"); } }
/* Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */ int usbip_xmit(int send, struct socket *sock, char *buf, int size, int msg_flags) { int result; struct msghdr msg; struct kvec iov; int total = 0; /* for blocks of if (usbip_dbg_flag_xmit) */ char *bp = buf; int osize = size; usbip_dbg_xmit("enter\n"); if (!sock || !buf || !size) { printk(KERN_ERR "%s: invalid arg, sock %p buff %p size %d\n", __func__, sock, buf, size); return -EINVAL; } if (usbip_dbg_flag_xmit) { if (send) { if (!in_interrupt()) printk(KERN_DEBUG "%-10s:", current->comm); else printk(KERN_DEBUG "interrupt :"); printk(KERN_DEBUG "%s: sending... , sock %p, buf %p, " "size %d, msg_flags %d\n", __func__, sock, buf, size, msg_flags); usbip_dump_buffer(buf, size); } } do { sock->sk->sk_allocation = GFP_NOIO; iov.iov_base = buf; iov.iov_len = size; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_namelen = 0; msg.msg_flags = msg_flags | MSG_NOSIGNAL; if (send) result = kernel_sendmsg(sock, &msg, &iov, 1, size); else result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL); if (result <= 0) { usbip_udbg("usbip_xmit: %s sock %p buf %p size %u ret " "%d total %d\n", send ? "send" : "receive", sock, buf, size, result, total); goto err; } size -= result; buf += result; total += result; } while (size > 0); if (usbip_dbg_flag_xmit) { if (!send) { if (!in_interrupt()) printk(KERN_DEBUG "%-10s:", current->comm); else printk(KERN_DEBUG "interrupt :"); printk(KERN_DEBUG "usbip_xmit: receiving....\n"); usbip_dump_buffer(bp, osize); printk(KERN_DEBUG "usbip_xmit: received, osize %d ret " "%d size %d total %d\n", osize, result, size, total); } if (send) printk(KERN_DEBUG "usbip_xmit: send, total %d\n", total); } return total; err: return result; }