Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174180367
D55035.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D55035.diff
View Options
diff --git a/sys/compat/linuxkpi/common/include/linux/usb.h b/sys/compat/linuxkpi/common/include/linux/usb.h
--- a/sys/compat/linuxkpi/common/include/linux/usb.h
+++ b/sys/compat/linuxkpi/common/include/linux/usb.h
@@ -120,6 +120,8 @@
/* USB Request Block (URB). */
struct urb;
+struct usb_anchor;
+
typedef void (usb_complete_t)(struct urb *);
/*
@@ -145,6 +147,10 @@
struct usb_device *dev; /* (in) pointer to associated device */
struct usb_host_endpoint *endpoint; /* (in) pipe pointer */
struct kref kref;
+
+ struct list_head anchor_list;
+ struct usb_anchor *anchor;
+
uint8_t *setup_packet; /* (in) setup packet (control only) */
uint8_t *bsd_data_ptr;
void *transfer_buffer; /* (in) associated data buffer */
@@ -236,6 +242,41 @@
linuxkpi_usb_free_urb(urb);
}
+/* Anchor. */
+struct usb_anchor {
+ struct list_head urb_list;
+ spinlock_t lock;
+};
+
+void linuxkpi_init_usb_anchor(struct usb_anchor *);
+void linuxkpi_usb_anchor_urb(struct urb *, struct usb_anchor *);
+void linuxkpi_usb_unanchor_urb(struct urb *);
+void linuxkpi_usb_kill_anchored_urbs(struct usb_anchor *);
+
+static inline void
+init_usb_anchor(struct usb_anchor *ua)
+{
+ linuxkpi_init_usb_anchor(ua);
+}
+
+static inline void
+usb_anchor_urb(struct urb *urb, struct usb_anchor *ua)
+{
+ linuxkpi_usb_anchor_urb(urb, ua);
+}
+
+static inline void
+usb_unanchor_urb(struct urb *urb)
+{
+ linuxkpi_usb_unanchor_urb(urb);
+}
+
+static inline void
+usb_kill_anchored_urbs(struct usb_anchor *ua)
+{
+ linuxkpi_usb_kill_anchored_urbs(ua);
+}
+
/* ---------------------------------------------------------------------------- */
/* Driver related. */
diff --git a/sys/compat/linuxkpi/common/src/linuxkpi_usb.c b/sys/compat/linuxkpi/common/src/linuxkpi_usb.c
--- a/sys/compat/linuxkpi/common/src/linuxkpi_usb.c
+++ b/sys/compat/linuxkpi/common/src/linuxkpi_usb.c
@@ -156,6 +156,8 @@
urb = usbd_xfer_get_priv(xfer);
usbd_xfer_set_priv(xfer, NULL);
+ usb_unanchor_urb(urb);
+
/* Prevent complete() macro expansion, *sigh*. */
if (urb->complete != NULL)
(urb->complete)(urb);
@@ -1004,6 +1006,72 @@
urb->context = arg;
}
+/* Anchor. */
+void
+linuxkpi_init_usb_anchor(struct usb_anchor *ua)
+{
+ memset(ua, 0, sizeof(*ua));
+ spin_lock_init(&ua->lock);
+ INIT_LIST_HEAD(&ua->urb_list);
+}
+
+void
+linuxkpi_usb_anchor_urb(struct urb *urb, struct usb_anchor *ua)
+{
+ unsigned long flags;
+
+ /* Make sure the urb stays valid while on the anchor list. */
+ usb_get_urb(urb);
+
+ spin_lock_irqsave(&ua->lock, flags);
+ list_add_tail(&urb->anchor_list, &ua->urb_list);
+ urb->anchor = ua;
+ spin_unlock_irqrestore(&ua->lock, flags);
+}
+
+void
+linuxkpi_usb_unanchor_urb(struct urb *urb)
+{
+ unsigned long flags;
+ struct usb_anchor *ua;
+
+ if (urb == NULL)
+ return;
+
+ ua = urb->anchor;
+ if (ua == NULL)
+ return;
+
+ spin_lock_irqsave(&ua->lock, flags);
+ /* Re-check under lock. */
+ if (urb->anchor == NULL)
+ goto out;
+
+ urb->anchor = NULL;
+ list_del(&urb->anchor_list);
+ usb_put_urb(urb);
+out:
+ spin_unlock_irqrestore(&ua->lock, flags);
+}
+
+void
+linuxkpi_usb_kill_anchored_urbs(struct usb_anchor *ua)
+{
+ struct urb *urb;
+
+ spin_lock_irq(&ua->lock);
+ while (!list_empty(&ua->urb_list)) {
+ urb = list_entry(ua->urb_list.prev, struct urb, anchor_list);
+ usb_get_urb(urb);
+ /* We need to drop the lock. */
+ spin_unlock_irq(&ua->lock);
+ usb_kill_urb(urb);
+ usb_put_urb(urb);
+ spin_lock_irq(&ua->lock);
+ }
+ spin_unlock_irq(&ua->lock);
+}
+
/*
* usb_control_msg()
*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 2, 4:43 AM (7 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40060385
Default Alt Text
D55035.diff (3 KB)
Attached To
Mode
D55035: LinuxKPI: usb: add usb_anchor support
Attached
Detach File
Event Timeline
Log In to Comment