Lines Matching +full:lock +full:- +full:status
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2003-2008 Takahiro Hirofuchi
15 * usbip_status shows the status of usbip-host as long as this driver is bound
22 int status; in usbip_status_show() local
26 return -ENODEV; in usbip_status_show()
29 spin_lock_irq(&sdev->ud.lock); in usbip_status_show()
30 status = sdev->ud.status; in usbip_status_show()
31 spin_unlock_irq(&sdev->ud.lock); in usbip_status_show()
33 return sysfs_emit(buf, "%d\n", status); in usbip_status_show()
39 * is used to transfer usbip requests by kernel threads. -1 is a magic number
54 return -ENODEV; in usbip_sockfd_store()
59 return -EINVAL; in usbip_sockfd_store()
61 if (sockfd != -1) { in usbip_sockfd_store()
66 mutex_lock(&sdev->ud.sysfs_lock); in usbip_sockfd_store()
67 spin_lock_irq(&sdev->ud.lock); in usbip_sockfd_store()
69 if (sdev->ud.status != SDEV_ST_AVAILABLE) { in usbip_sockfd_store()
80 if (socket->type != SOCK_STREAM) { in usbip_sockfd_store()
81 dev_err(dev, "Expecting SOCK_STREAM - found %d", in usbip_sockfd_store()
82 socket->type); in usbip_sockfd_store()
87 spin_unlock_irq(&sdev->ud.lock); in usbip_sockfd_store()
88 tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx"); in usbip_sockfd_store()
93 tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx"); in usbip_sockfd_store()
104 /* lock and update sdev->ud state */ in usbip_sockfd_store()
105 spin_lock_irq(&sdev->ud.lock); in usbip_sockfd_store()
106 sdev->ud.tcp_socket = socket; in usbip_sockfd_store()
107 sdev->ud.sockfd = sockfd; in usbip_sockfd_store()
108 sdev->ud.tcp_rx = tcp_rx; in usbip_sockfd_store()
109 sdev->ud.tcp_tx = tcp_tx; in usbip_sockfd_store()
110 sdev->ud.status = SDEV_ST_USED; in usbip_sockfd_store()
111 spin_unlock_irq(&sdev->ud.lock); in usbip_sockfd_store()
113 wake_up_process(sdev->ud.tcp_rx); in usbip_sockfd_store()
114 wake_up_process(sdev->ud.tcp_tx); in usbip_sockfd_store()
116 mutex_unlock(&sdev->ud.sysfs_lock); in usbip_sockfd_store()
121 mutex_lock(&sdev->ud.sysfs_lock); in usbip_sockfd_store()
123 spin_lock_irq(&sdev->ud.lock); in usbip_sockfd_store()
124 if (sdev->ud.status != SDEV_ST_USED) in usbip_sockfd_store()
127 spin_unlock_irq(&sdev->ud.lock); in usbip_sockfd_store()
129 usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN); in usbip_sockfd_store()
130 mutex_unlock(&sdev->ud.sysfs_lock); in usbip_sockfd_store()
138 spin_unlock_irq(&sdev->ud.lock); in usbip_sockfd_store()
140 mutex_unlock(&sdev->ud.sysfs_lock); in usbip_sockfd_store()
141 return -EINVAL; in usbip_sockfd_store()
163 if (ud->tcp_socket) { in stub_shutdown_connection()
164 dev_dbg(&sdev->udev->dev, "shutdown sockfd %d\n", ud->sockfd); in stub_shutdown_connection()
165 kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); in stub_shutdown_connection()
169 if (ud->tcp_rx) { in stub_shutdown_connection()
170 kthread_stop_put(ud->tcp_rx); in stub_shutdown_connection()
171 ud->tcp_rx = NULL; in stub_shutdown_connection()
173 if (ud->tcp_tx) { in stub_shutdown_connection()
174 kthread_stop_put(ud->tcp_tx); in stub_shutdown_connection()
175 ud->tcp_tx = NULL; in stub_shutdown_connection()
184 if (ud->tcp_socket) { in stub_shutdown_connection()
185 sockfd_put(ud->tcp_socket); in stub_shutdown_connection()
186 ud->tcp_socket = NULL; in stub_shutdown_connection()
187 ud->sockfd = -1; in stub_shutdown_connection()
198 spin_lock_irqsave(&sdev->priv_lock, flags); in stub_shutdown_connection()
199 list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) { in stub_shutdown_connection()
200 list_del(&unlink->list); in stub_shutdown_connection()
203 list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, in stub_shutdown_connection()
205 list_del(&unlink->list); in stub_shutdown_connection()
208 spin_unlock_irqrestore(&sdev->priv_lock, flags); in stub_shutdown_connection()
215 struct usb_device *udev = sdev->udev; in stub_device_reset()
218 dev_dbg(&udev->dev, "device reset"); in stub_device_reset()
222 dev_err(&udev->dev, "lock for reset\n"); in stub_device_reset()
223 spin_lock_irq(&ud->lock); in stub_device_reset()
224 ud->status = SDEV_ST_ERROR; in stub_device_reset()
225 spin_unlock_irq(&ud->lock); in stub_device_reset()
233 spin_lock_irq(&ud->lock); in stub_device_reset()
235 dev_err(&udev->dev, "device reset\n"); in stub_device_reset()
236 ud->status = SDEV_ST_ERROR; in stub_device_reset()
238 dev_info(&udev->dev, "device reset\n"); in stub_device_reset()
239 ud->status = SDEV_ST_AVAILABLE; in stub_device_reset()
241 spin_unlock_irq(&ud->lock); in stub_device_reset()
246 spin_lock_irq(&ud->lock); in stub_device_unusable()
247 ud->status = SDEV_ST_ERROR; in stub_device_unusable()
248 spin_unlock_irq(&ud->lock); in stub_device_unusable()
252 * stub_device_alloc - allocate a new stub_device struct
260 int busnum = udev->bus->busnum; in stub_device_alloc()
261 int devnum = udev->devnum; in stub_device_alloc()
263 dev_dbg(&udev->dev, "allocating stub device"); in stub_device_alloc()
270 sdev->udev = usb_get_dev(udev); in stub_device_alloc()
277 sdev->devid = (busnum << 16) | devnum; in stub_device_alloc()
278 sdev->ud.side = USBIP_STUB; in stub_device_alloc()
279 sdev->ud.status = SDEV_ST_AVAILABLE; in stub_device_alloc()
280 spin_lock_init(&sdev->ud.lock); in stub_device_alloc()
281 mutex_init(&sdev->ud.sysfs_lock); in stub_device_alloc()
282 sdev->ud.tcp_socket = NULL; in stub_device_alloc()
283 sdev->ud.sockfd = -1; in stub_device_alloc()
285 INIT_LIST_HEAD(&sdev->priv_init); in stub_device_alloc()
286 INIT_LIST_HEAD(&sdev->priv_tx); in stub_device_alloc()
287 INIT_LIST_HEAD(&sdev->priv_free); in stub_device_alloc()
288 INIT_LIST_HEAD(&sdev->unlink_free); in stub_device_alloc()
289 INIT_LIST_HEAD(&sdev->unlink_tx); in stub_device_alloc()
290 spin_lock_init(&sdev->priv_lock); in stub_device_alloc()
292 init_waitqueue_head(&sdev->tx_waitq); in stub_device_alloc()
294 sdev->ud.eh_ops.shutdown = stub_shutdown_connection; in stub_device_alloc()
295 sdev->ud.eh_ops.reset = stub_device_reset; in stub_device_alloc()
296 sdev->ud.eh_ops.unusable = stub_device_unusable; in stub_device_alloc()
298 usbip_start_eh(&sdev->ud); in stub_device_alloc()
300 dev_dbg(&udev->dev, "register new device\n"); in stub_device_alloc()
313 const char *udev_busid = dev_name(&udev->dev); in stub_probe()
318 dev_dbg(&udev->dev, "Enter probe\n"); in stub_probe()
321 * calling alloc while holding busid_table lock. in stub_probe()
325 return -ENOMEM; in stub_probe()
329 if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || in stub_probe()
330 (busid_priv->status == STUB_BUSID_OTHER)) { in stub_probe()
331 dev_info(&udev->dev, in stub_probe()
340 rc = -ENODEV; in stub_probe()
347 if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) { in stub_probe()
348 dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n", in stub_probe()
350 rc = -ENODEV; in stub_probe()
354 if (!strcmp(udev->bus->bus_name, "vhci_hcd")) { in stub_probe()
355 dev_dbg(&udev->dev, in stub_probe()
359 rc = -ENODEV; in stub_probe()
364 dev_info(&udev->dev, in stub_probe()
365 "usbip-host: register new device (bus %u dev %u)\n", in stub_probe()
366 udev->bus->busnum, udev->devnum); in stub_probe()
368 busid_priv->shutdown_busid = 0; in stub_probe()
371 dev_set_drvdata(&udev->dev, sdev); in stub_probe()
373 busid_priv->sdev = sdev; in stub_probe()
374 busid_priv->udev = udev; in stub_probe()
376 save_status = busid_priv->status; in stub_probe()
377 busid_priv->status = STUB_BUSID_ALLOC; in stub_probe()
387 rc = usb_hub_claim_port(udev->parent, udev->portnum, in stub_probe()
390 dev_dbg(&udev->dev, "unable to claim port\n"); in stub_probe()
397 dev_set_drvdata(&udev->dev, NULL); in stub_probe()
399 /* we already have busid_priv, just lock busid_lock */ in stub_probe()
400 spin_lock(&busid_priv->busid_lock); in stub_probe()
401 busid_priv->sdev = NULL; in stub_probe()
402 busid_priv->status = save_status; in stub_probe()
403 spin_unlock(&busid_priv->busid_lock); in stub_probe()
404 /* lock is released - go to free */ in stub_probe()
420 usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED); in shutdown_busid()
423 usbip_stop_eh(&busid_priv->sdev->ud); in shutdown_busid()
433 const char *udev_busid = dev_name(&udev->dev); in stub_disconnect()
437 dev_dbg(&udev->dev, "Enter disconnect\n"); in stub_disconnect()
445 sdev = dev_get_drvdata(&udev->dev); in stub_disconnect()
449 dev_err(&udev->dev, "could not get device"); in stub_disconnect()
455 dev_set_drvdata(&udev->dev, NULL); in stub_disconnect()
465 rc = usb_hub_release_port(udev->parent, udev->portnum, in stub_disconnect()
469 * device usb_hub_release_port will return -ENODEV so we can safely ignore in stub_disconnect()
472 if (rc && (rc != -ENODEV)) { in stub_disconnect()
473 dev_dbg(&udev->dev, "unable to release port (%i)\n", rc); in stub_disconnect()
481 /* we already have busid_priv, just lock busid_lock */ in stub_disconnect()
482 spin_lock(&busid_priv->busid_lock); in stub_disconnect()
483 if (!busid_priv->shutdown_busid) in stub_disconnect()
484 busid_priv->shutdown_busid = 1; in stub_disconnect()
486 spin_unlock(&busid_priv->busid_lock); in stub_disconnect()
491 usb_put_dev(sdev->udev); in stub_disconnect()
493 /* we already have busid_priv, just lock busid_lock */ in stub_disconnect()
494 spin_lock(&busid_priv->busid_lock); in stub_disconnect()
496 busid_priv->sdev = NULL; in stub_disconnect()
499 if (busid_priv->status == STUB_BUSID_ALLOC) in stub_disconnect()
500 busid_priv->status = STUB_BUSID_ADDED; in stub_disconnect()
502 spin_unlock(&busid_priv->busid_lock); in stub_disconnect()
513 dev_dbg(&udev->dev, "stub_suspend\n"); in stub_suspend()
520 dev_dbg(&udev->dev, "stub_resume\n"); in stub_resume()
528 .name = "usbip-host",