diff options
Diffstat (limited to 'drivers/usb/usbip')
-rw-r--r-- | drivers/usb/usbip/usbip_event.c | 5 | ||||
-rw-r--r-- | drivers/usb/usbip/usbip_protocol.txt | 358 | ||||
-rw-r--r-- | drivers/usb/usbip/vhci_hcd.c | 88 | ||||
-rw-r--r-- | drivers/usb/usbip/vhci_rx.c | 30 | ||||
-rw-r--r-- | drivers/usb/usbip/vhci_sysfs.c | 19 | ||||
-rw-r--r-- | drivers/usb/usbip/vhci_tx.c | 14 |
6 files changed, 91 insertions, 423 deletions
diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c index 64933b993..2580a32bc 100644 --- a/drivers/usb/usbip/usbip_event.c +++ b/drivers/usb/usbip/usbip_event.c @@ -117,11 +117,12 @@ EXPORT_SYMBOL_GPL(usbip_event_add); int usbip_event_happened(struct usbip_device *ud) { int happened = 0; + unsigned long flags; - spin_lock(&ud->lock); + spin_lock_irqsave(&ud->lock, flags); if (ud->event != 0) happened = 1; - spin_unlock(&ud->lock); + spin_unlock_irqrestore(&ud->lock, flags); return happened; } diff --git a/drivers/usb/usbip/usbip_protocol.txt b/drivers/usb/usbip/usbip_protocol.txt deleted file mode 100644 index 16b6fe272..000000000 --- a/drivers/usb/usbip/usbip_protocol.txt +++ /dev/null @@ -1,358 +0,0 @@ -PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! -28 Jun 2011 - -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. - -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. - - virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) - | | - | OP_REQ_DEVLIST | - | ----------------------------------------------> | - | | - | OP_REP_DEVLIST | - | <---------------------------------------------- | - | | - -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. - - virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) - | | - | OP_REQ_IMPORT | - | ----------------------------------------------> | - | | - | OP_REP_IMPORT | - | <---------------------------------------------- | - | | - | | - | USBIP_CMD_SUBMIT(seqnum = n) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = n) | - | <---------------------------------------------- | - | . | - | : | - | | - | USBIP_CMD_SUBMIT(seqnum = m) | - | ----------------------------------------------> | - | | - | USBIP_CMD_SUBMIT(seqnum = m+1) | - | ----------------------------------------------> | - | | - | USBIP_CMD_SUBMIT(seqnum = m+2) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = m) | - | <---------------------------------------------- | - | | - | USBIP_CMD_SUBMIT(seqnum = m+3) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = m+1) | - | <---------------------------------------------- | - | | - | USBIP_CMD_SUBMIT(seqnum = m+4) | - | ----------------------------------------------> | - | | - | USBIP_RET_SUBMIT(seqnum = m+2) | - | <---------------------------------------------- | - | . | - | : | - | | - | USBIP_CMD_UNLINK | - | ----------------------------------------------> | - | | - | USBIP_RET_UNLINK | - | <---------------------------------------------- | - | | - -The fields are in network (big endian) byte order meaning that the most significant -byte (MSB) is stored at the lowest address. - - -OP_REQ_DEVLIST: Retrieve the list of exported USB devices. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB - | | | devices. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 - -OP_REP_DEVLIST: Reply with the list of exported USB devices. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0. ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: 0 for OK ------------+--------+------------+--------------------------------------------------- - 8 | 4 | n | Number of exported devices: 0 means no exported - | | | devices. ------------+--------+------------+--------------------------------------------------- - 0x0C | | | From now on the exported n devices are described, - | | | if any. If no devices are exported the message - | | | ends with the previous "number of exported - | | | devices" field. ------------+--------+------------+--------------------------------------------------- - | 256 | | path: Path of the device on the host exporting the - | | | USB device, string closed with zero byte, e.g. - | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" - | | | The unused bytes shall be filled with zero - | | | bytes. ------------+--------+------------+--------------------------------------------------- - 0x10C | 32 | | busid: Bus ID of the exported device, string - | | | closed with zero byte, e.g. "3-2". The unused - | | | bytes shall be filled with zero bytes. ------------+--------+------------+--------------------------------------------------- - 0x12C | 4 | | busnum ------------+--------+------------+--------------------------------------------------- - 0x130 | 4 | | devnum ------------+--------+------------+--------------------------------------------------- - 0x134 | 4 | | speed ------------+--------+------------+--------------------------------------------------- - 0x138 | 2 | | idVendor ------------+--------+------------+--------------------------------------------------- - 0x13A | 2 | | idProduct ------------+--------+------------+--------------------------------------------------- - 0x13C | 2 | | bcdDevice ------------+--------+------------+--------------------------------------------------- - 0x13E | 1 | | bDeviceClass ------------+--------+------------+--------------------------------------------------- - 0x13F | 1 | | bDeviceSubClass ------------+--------+------------+--------------------------------------------------- - 0x140 | 1 | | bDeviceProtocol ------------+--------+------------+--------------------------------------------------- - 0x141 | 1 | | bConfigurationValue ------------+--------+------------+--------------------------------------------------- - 0x142 | 1 | | bNumConfigurations ------------+--------+------------+--------------------------------------------------- - 0x143 | 1 | | bNumInterfaces ------------+--------+------------+--------------------------------------------------- - 0x144 | | m_0 | From now on each interface is described, all - | | | together bNumInterfaces times, with the - | | | the following 4 fields: ------------+--------+------------+--------------------------------------------------- - | 1 | | bInterfaceClass ------------+--------+------------+--------------------------------------------------- - 0x145 | 1 | | bInterfaceSubClass ------------+--------+------------+--------------------------------------------------- - 0x146 | 1 | | bInterfaceProtocol ------------+--------+------------+--------------------------------------------------- - 0x147 | 1 | | padding byte for alignment, shall be set to zero ------------+--------+------------+--------------------------------------------------- - 0xC + | | | The second exported USB device starts at i=1 - i*0x138 + | | | with the busid field. - m_(i-1)*4 | | | - -OP_REQ_IMPORT: Request to import (attach) a remote USB device. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x8003 | Command code: import a remote USB device. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 ------------+--------+------------+--------------------------------------------------- - 8 | 32 | | busid: the busid of the exported device on the - | | | remote host. The possible values are taken - | | | from the message field OP_REP_DEVLIST.busid. - | | | A string closed with zero, the unused bytes - | | | shall be filled with zeros. ------------+--------+------------+--------------------------------------------------- - -OP_REP_IMPORT: Reply to import (attach) a remote USB device. - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 ------------+--------+------------+--------------------------------------------------- - 2 | 2 | 0x0003 | Reply code: Reply to import. ------------+--------+------------+--------------------------------------------------- - 4 | 4 | 0x00000000 | Status: 0 for OK - | | | 1 for error ------------+--------+------------+--------------------------------------------------- - 8 | | | From now on comes the details of the imported - | | | device, if the previous status field was OK (0), - | | | otherwise the reply ends with the status field. ------------+--------+------------+--------------------------------------------------- - | 256 | | path: Path of the device on the host exporting the - | | | USB device, string closed with zero byte, e.g. - | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" - | | | The unused bytes shall be filled with zero - | | | bytes. ------------+--------+------------+--------------------------------------------------- - 0x108 | 32 | | busid: Bus ID of the exported device, string - | | | closed with zero byte, e.g. "3-2". The unused - | | | bytes shall be filled with zero bytes. ------------+--------+------------+--------------------------------------------------- - 0x128 | 4 | | busnum ------------+--------+------------+--------------------------------------------------- - 0x12C | 4 | | devnum ------------+--------+------------+--------------------------------------------------- - 0x130 | 4 | | speed ------------+--------+------------+--------------------------------------------------- - 0x134 | 2 | | idVendor ------------+--------+------------+--------------------------------------------------- - 0x136 | 2 | | idProduct ------------+--------+------------+--------------------------------------------------- - 0x138 | 2 | | bcdDevice ------------+--------+------------+--------------------------------------------------- - 0x139 | 1 | | bDeviceClass ------------+--------+------------+--------------------------------------------------- - 0x13A | 1 | | bDeviceSubClass ------------+--------+------------+--------------------------------------------------- - 0x13B | 1 | | bDeviceProtocol ------------+--------+------------+--------------------------------------------------- - 0x13C | 1 | | bConfigurationValue ------------+--------+------------+--------------------------------------------------- - 0x13D | 1 | | bNumConfigurations ------------+--------+------------+--------------------------------------------------- - 0x13E | 1 | | bNumInterfaces - -USBIP_CMD_SUBMIT: Submit an URB - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000001 | command: Submit an URB ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: the sequence number of the URB to submit ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number, possible values are: 0...15 ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | transfer_flags: possible values depend on the - | | | URB transfer type, see below ------------+--------+------------+--------------------------------------------------- - 0x18 | 4 | | transfer_buffer_length ------------+--------+------------+--------------------------------------------------- - 0x1C | 4 | | start_frame: specify the selected frame to - | | | transmit an ISO frame, ignored if URB_ISO_ASAP - | | | is specified at transfer_flags ------------+--------+------------+--------------------------------------------------- - 0x20 | 4 | | number_of_packets: number of ISO packets ------------+--------+------------+--------------------------------------------------- - 0x24 | 4 | | interval: maximum time for the request on the - | | | server-side host controller ------------+--------+------------+--------------------------------------------------- - 0x28 | 8 | | setup: data bytes for USB setup, filled with - | | | zeros if not used ------------+--------+------------+--------------------------------------------------- - 0x30 | | | URB data. For ISO transfers the padding between - | | | each ISO packets is not transmitted. - - - Allowed transfer_flags | value | control | interrupt | bulk | isochronous - -------------------------+------------+---------+-----------+----------+------------- - URB_SHORT_NOT_OK | 0x00000001 | only in | only in | only in | no - URB_ISO_ASAP | 0x00000002 | no | no | no | yes - URB_NO_TRANSFER_DMA_MAP | 0x00000004 | yes | yes | yes | yes - URB_NO_FSBR | 0x00000020 | yes | no | no | no - URB_ZERO_PACKET | 0x00000040 | no | no | only out | no - URB_NO_INTERRUPT | 0x00000080 | yes | yes | yes | yes - URB_FREE_BUFFER | 0x00000100 | yes | yes | yes | yes - URB_DIR_MASK | 0x00000200 | yes | yes | yes | yes - - -USBIP_RET_SUBMIT: Reply for submitting an URB - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000003 | command ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: URB sequence number ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | status: zero for successful URB transaction, - | | | otherwise some kind of error happened. ------------+--------+------------+--------------------------------------------------- - 0x18 | 4 | n | actual_length: number of URB data bytes ------------+--------+------------+--------------------------------------------------- - 0x1C | 4 | | start_frame: for an ISO frame the actually - | | | selected frame for transmit. ------------+--------+------------+--------------------------------------------------- - 0x20 | 4 | | number_of_packets ------------+--------+------------+--------------------------------------------------- - 0x24 | 4 | | error_count ------------+--------+------------+--------------------------------------------------- - 0x28 | 8 | | setup: data bytes for USB setup, filled with - | | | zeros if not used ------------+--------+------------+--------------------------------------------------- - 0x30 | n | | URB data bytes. For ISO transfers the padding - | | | between each ISO packets is not transmitted. - -USBIP_CMD_UNLINK: Unlink an URB - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000002 | command: URB unlink command ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: URB sequence number to unlink: FIXME: is this so? ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number: zero ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | seqnum: the URB sequence number given previously - | | | at USBIP_CMD_SUBMIT.seqnum field ------------+--------+------------+--------------------------------------------------- - 0x30 | n | | URB data bytes. For ISO transfers the padding - | | | between each ISO packets is not transmitted. - -USBIP_RET_UNLINK: Reply for URB unlink - - Offset | Length | Value | Description ------------+--------+------------+--------------------------------------------------- - 0 | 4 | 0x00000004 | command: reply for the URB unlink command ------------+--------+------------+--------------------------------------------------- - 4 | 4 | | seqnum: the unlinked URB sequence number ------------+--------+------------+--------------------------------------------------- - 8 | 4 | | devid ------------+--------+------------+--------------------------------------------------- - 0xC | 4 | | direction: 0: USBIP_DIR_OUT - | | | 1: USBIP_DIR_IN ------------+--------+------------+--------------------------------------------------- - 0x10 | 4 | | ep: endpoint number ------------+--------+------------+--------------------------------------------------- - 0x14 | 4 | | status: This is the value contained in the - | | | urb->status in the URB completition handler. - | | | FIXME: a better explanation needed. ------------+--------+------------+--------------------------------------------------- - 0x30 | n | | URB data bytes. For ISO transfers the padding - | | | between each ISO packets is not transmitted. diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 7fbe19d52..fca511059 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -121,9 +121,11 @@ static void dump_port_status_diff(u32 prev_status, u32 new_status) void rh_port_connect(int rhport, enum usb_device_speed speed) { + unsigned long flags; + usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION | (1 << USB_PORT_FEAT_C_CONNECTION); @@ -139,22 +141,24 @@ void rh_port_connect(int rhport, enum usb_device_speed speed) break; } - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); } static void rh_port_disconnect(int rhport) { + unsigned long flags; + usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION; the_controller->port_status[rhport] |= (1 << USB_PORT_FEAT_C_CONNECTION); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); } @@ -182,13 +186,14 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) int retval; int rhport; int changed = 0; + unsigned long flags; retval = DIV_ROUND_UP(VHCI_NPORTS + 1, 8); memset(buf, 0, retval); vhci = hcd_to_vhci(hcd); - spin_lock(&vhci->lock); + spin_lock_irqsave(&vhci->lock, flags); if (!HCD_HW_ACCESSIBLE(hcd)) { usbip_dbg_vhci_rh("hw accessible flag not on?\n"); goto done; @@ -209,7 +214,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf) usb_hcd_resume_root_hub(hcd); done: - spin_unlock(&vhci->lock); + spin_unlock_irqrestore(&vhci->lock, flags); return changed ? retval : 0; } @@ -231,6 +236,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, struct vhci_hcd *dum; int retval = 0; int rhport; + unsigned long flags; u32 prev_port_status[VHCI_NPORTS]; @@ -249,7 +255,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, dum = hcd_to_vhci(hcd); - spin_lock(&dum->lock); + spin_lock_irqsave(&dum->lock, flags); /* store old status and compare now and old later */ if (usbip_dbg_flag_vhci_rh) { @@ -403,7 +409,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, } usbip_dbg_vhci_rh(" bye\n"); - spin_unlock(&dum->lock); + spin_unlock_irqrestore(&dum->lock, flags); return retval; } @@ -426,6 +432,7 @@ static void vhci_tx_urb(struct urb *urb) { struct vhci_device *vdev = get_vdev(urb->dev); struct vhci_priv *priv; + unsigned long flags; if (!vdev) { pr_err("could not get virtual device"); @@ -438,7 +445,7 @@ static void vhci_tx_urb(struct urb *urb) return; } - spin_lock(&vdev->priv_lock); + spin_lock_irqsave(&vdev->priv_lock, flags); priv->seqnum = atomic_inc_return(&the_controller->seqnum); if (priv->seqnum == 0xffff) @@ -452,7 +459,7 @@ static void vhci_tx_urb(struct urb *urb) list_add_tail(&priv->list, &vdev->priv_tx); wake_up(&vdev->waitq_tx); - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); } static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, @@ -461,6 +468,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, struct device *dev = &urb->dev->dev; int ret = 0; struct vhci_device *vdev; + unsigned long flags; usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", hcd, urb, mem_flags); @@ -468,11 +476,11 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, /* patch to usb_sg_init() is in 2.5.60 */ BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); if (urb->status != -EINPROGRESS) { dev_err(dev, "URB already unlinked!, status %d\n", urb->status); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); return urb->status; } @@ -484,7 +492,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, vdev->ud.status == VDEV_ST_ERROR) { dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport); spin_unlock(&vdev->ud.lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); return -ENODEV; } spin_unlock(&vdev->ud.lock); @@ -557,14 +565,14 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, out: vhci_tx_urb(urb); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); return 0; no_need_xmit: usb_hcd_unlink_urb_from_ep(hcd, urb); no_need_unlink: - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); if (!ret) usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); @@ -621,16 +629,17 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { struct vhci_priv *priv; struct vhci_device *vdev; + unsigned long flags; pr_info("dequeue a urb %p\n", urb); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); priv = urb->hcpriv; if (!priv) { /* URB was never linked! or will be soon given back by * vhci_rx. */ - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); return -EIDRM; } @@ -639,7 +648,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ret = usb_hcd_check_unlink_urb(hcd, urb, status); if (ret) { - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); return ret; } } @@ -667,10 +676,10 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) usb_hcd_unlink_urb_from_ep(hcd, urb); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); } else { /* tcp connection is alive */ @@ -682,7 +691,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); if (!unlink) { spin_unlock(&vdev->priv_lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); return -ENOMEM; } @@ -703,7 +712,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) spin_unlock(&vdev->priv_lock); } - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usbip_dbg_vhci_hc("leave\n"); return 0; @@ -712,8 +721,9 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) static void vhci_device_unlink_cleanup(struct vhci_device *vdev) { struct vhci_unlink *unlink, *tmp; + unsigned long flags; - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); spin_lock(&vdev->priv_lock); list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { @@ -747,19 +757,19 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) list_del(&unlink->list); spin_unlock(&vdev->priv_lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); spin_lock(&vdev->priv_lock); kfree(unlink); } spin_unlock(&vdev->priv_lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); } /* @@ -826,8 +836,9 @@ static void vhci_shutdown_connection(struct usbip_device *ud) static void vhci_device_reset(struct usbip_device *ud) { struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); + unsigned long flags; - spin_lock(&ud->lock); + spin_lock_irqsave(&ud->lock, flags); vdev->speed = 0; vdev->devid = 0; @@ -841,14 +852,16 @@ static void vhci_device_reset(struct usbip_device *ud) } ud->status = VDEV_ST_NULL; - spin_unlock(&ud->lock); + spin_unlock_irqrestore(&ud->lock, flags); } static void vhci_device_unusable(struct usbip_device *ud) { - spin_lock(&ud->lock); + unsigned long flags; + + spin_lock_irqsave(&ud->lock, flags); ud->status = VDEV_ST_ERROR; - spin_unlock(&ud->lock); + spin_unlock_irqrestore(&ud->lock, flags); } static void vhci_device_init(struct vhci_device *vdev) @@ -938,12 +951,13 @@ static int vhci_get_frame_number(struct usb_hcd *hcd) static int vhci_bus_suspend(struct usb_hcd *hcd) { struct vhci_hcd *vhci = hcd_to_vhci(hcd); + unsigned long flags; dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); - spin_lock(&vhci->lock); + spin_lock_irqsave(&vhci->lock, flags); hcd->state = HC_STATE_SUSPENDED; - spin_unlock(&vhci->lock); + spin_unlock_irqrestore(&vhci->lock, flags); return 0; } @@ -952,15 +966,16 @@ static int vhci_bus_resume(struct usb_hcd *hcd) { struct vhci_hcd *vhci = hcd_to_vhci(hcd); int rc = 0; + unsigned long flags; dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); - spin_lock(&vhci->lock); + spin_lock_irqsave(&vhci->lock, flags); if (!HCD_HW_ACCESSIBLE(hcd)) rc = -ESHUTDOWN; else hcd->state = HC_STATE_RUNNING; - spin_unlock(&vhci->lock); + spin_unlock_irqrestore(&vhci->lock, flags); return rc; } @@ -1058,17 +1073,18 @@ static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state) int rhport = 0; int connected = 0; int ret = 0; + unsigned long flags; hcd = platform_get_drvdata(pdev); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); for (rhport = 0; rhport < VHCI_NPORTS; rhport++) if (the_controller->port_status[rhport] & USB_PORT_STAT_CONNECTION) connected += 1; - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); if (connected > 0) { dev_info(&pdev->dev, diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c index 00e4a5430..d656e0edc 100644 --- a/drivers/usb/usbip/vhci_rx.c +++ b/drivers/usb/usbip/vhci_rx.c @@ -72,10 +72,11 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, { struct usbip_device *ud = &vdev->ud; struct urb *urb; + unsigned long flags; - spin_lock(&vdev->priv_lock); + spin_lock_irqsave(&vdev->priv_lock, flags); urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); if (!urb) { pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); @@ -104,9 +105,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, usbip_dbg_vhci_rx("now giveback urb %p\n", urb); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); @@ -117,8 +118,9 @@ static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev, struct usbip_header *pdu) { struct vhci_unlink *unlink, *tmp; + unsigned long flags; - spin_lock(&vdev->priv_lock); + spin_lock_irqsave(&vdev->priv_lock, flags); list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) { pr_info("unlink->seqnum %lu\n", unlink->seqnum); @@ -127,12 +129,12 @@ static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev, unlink->seqnum); list_del(&unlink->list); - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); return unlink; } } - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); return NULL; } @@ -142,6 +144,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, { struct vhci_unlink *unlink; struct urb *urb; + unsigned long flags; usbip_dump_header(pdu); @@ -152,9 +155,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, return; } - spin_lock(&vdev->priv_lock); + spin_lock_irqsave(&vdev->priv_lock, flags); urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); if (!urb) { /* @@ -171,9 +174,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, urb->status = pdu->u.ret_unlink.status; pr_info("urb->status %d\n", urb->status); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); @@ -185,10 +188,11 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, static int vhci_priv_tx_empty(struct vhci_device *vdev) { int empty = 0; + unsigned long flags; - spin_lock(&vdev->priv_lock); + spin_lock_irqsave(&vdev->priv_lock, flags); empty = list_empty(&vdev->priv_rx); - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); return empty; } diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 211f43f67..5b5462eb1 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -32,10 +32,11 @@ static ssize_t status_show(struct device *dev, struct device_attribute *attr, { char *s = out; int i = 0; + unsigned long flags; BUG_ON(!the_controller || !out); - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); /* * output example: @@ -70,7 +71,7 @@ static ssize_t status_show(struct device *dev, struct device_attribute *attr, spin_unlock(&vdev->ud.lock); } - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); return out - s; } @@ -80,11 +81,12 @@ static DEVICE_ATTR_RO(status); static int vhci_port_disconnect(__u32 rhport) { struct vhci_device *vdev; + unsigned long flags; usbip_dbg_vhci_sysfs("enter\n"); /* lock */ - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); vdev = port_to_vdev(rhport); @@ -94,14 +96,14 @@ static int vhci_port_disconnect(__u32 rhport) /* unlock */ spin_unlock(&vdev->ud.lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); return -EINVAL; } /* unlock */ spin_unlock(&vdev->ud.lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); @@ -177,6 +179,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, int sockfd = 0; __u32 rhport = 0, devid = 0, speed = 0; int err; + unsigned long flags; /* * @rhport: port number of vhci_hcd @@ -202,14 +205,14 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, /* now need lock until setting vdev status as used */ /* begin a lock */ - spin_lock(&the_controller->lock); + spin_lock_irqsave(&the_controller->lock, flags); vdev = port_to_vdev(rhport); spin_lock(&vdev->ud.lock); if (vdev->ud.status != VDEV_ST_NULL) { /* end of the lock */ spin_unlock(&vdev->ud.lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); sockfd_put(socket); @@ -227,7 +230,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, vdev->ud.status = VDEV_ST_NOTASSIGNED; spin_unlock(&vdev->ud.lock); - spin_unlock(&the_controller->lock); + spin_unlock_irqrestore(&the_controller->lock, flags); /* end the lock */ vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); diff --git a/drivers/usb/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c index 409fd99f3..3e7878fe2 100644 --- a/drivers/usb/usbip/vhci_tx.c +++ b/drivers/usb/usbip/vhci_tx.c @@ -47,16 +47,17 @@ static void setup_cmd_submit_pdu(struct usbip_header *pdup, struct urb *urb) static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev) { struct vhci_priv *priv, *tmp; + unsigned long flags; - spin_lock(&vdev->priv_lock); + spin_lock_irqsave(&vdev->priv_lock, flags); list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) { list_move_tail(&priv->list, &vdev->priv_rx); - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); return priv; } - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); return NULL; } @@ -136,16 +137,17 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev) { struct vhci_unlink *unlink, *tmp; + unsigned long flags; - spin_lock(&vdev->priv_lock); + spin_lock_irqsave(&vdev->priv_lock, flags); list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { list_move_tail(&unlink->list, &vdev->unlink_rx); - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); return unlink; } - spin_unlock(&vdev->priv_lock); + spin_unlock_irqrestore(&vdev->priv_lock, flags); return NULL; } |