1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /** |
3 | * xhci-dbgcap.h - xHCI debug capability support |
4 | * |
5 | * Copyright (C) 2017 Intel Corporation |
6 | * |
7 | * Author: Lu Baolu <baolu.lu@linux.intel.com> |
8 | */ |
9 | #ifndef __LINUX_XHCI_DBGCAP_H |
10 | #define __LINUX_XHCI_DBGCAP_H |
11 | |
12 | #include <linux/tty.h> |
13 | #include <linux/kfifo.h> |
14 | |
15 | struct dbc_regs { |
16 | __le32 capability; |
17 | __le32 doorbell; |
18 | __le32 ersts; /* Event Ring Segment Table Size*/ |
19 | __le32 __reserved_0; /* 0c~0f reserved bits */ |
20 | __le64 erstba; /* Event Ring Segment Table Base Address */ |
21 | __le64 erdp; /* Event Ring Dequeue Pointer */ |
22 | __le32 control; |
23 | __le32 status; |
24 | __le32 portsc; /* Port status and control */ |
25 | __le32 __reserved_1; /* 2b~28 reserved bits */ |
26 | __le64 dccp; /* Debug Capability Context Pointer */ |
27 | __le32 devinfo1; /* Device Descriptor Info Register 1 */ |
28 | __le32 devinfo2; /* Device Descriptor Info Register 2 */ |
29 | }; |
30 | |
31 | struct dbc_info_context { |
32 | __le64 string0; |
33 | __le64 manufacturer; |
34 | __le64 product; |
35 | __le64 serial; |
36 | __le32 length; |
37 | __le32 __reserved_0[7]; |
38 | }; |
39 | |
40 | #define DBC_CTRL_DBC_RUN BIT(0) |
41 | #define DBC_CTRL_PORT_ENABLE BIT(1) |
42 | #define DBC_CTRL_HALT_OUT_TR BIT(2) |
43 | #define DBC_CTRL_HALT_IN_TR BIT(3) |
44 | #define DBC_CTRL_DBC_RUN_CHANGE BIT(4) |
45 | #define DBC_CTRL_DBC_ENABLE BIT(31) |
46 | #define DBC_CTRL_MAXBURST(p) (((p) >> 16) & 0xff) |
47 | #define DBC_DOOR_BELL_TARGET(p) (((p) & 0xff) << 8) |
48 | |
49 | #define DBC_MAX_PACKET 1024 |
50 | #define DBC_MAX_STRING_LENGTH 64 |
51 | #define DBC_STRING_MANUFACTURER "Linux Foundation" |
52 | #define DBC_STRING_PRODUCT "Linux USB Debug Target" |
53 | #define DBC_STRING_SERIAL "0001" |
54 | #define DBC_CONTEXT_SIZE 64 |
55 | |
56 | /* |
57 | * Port status: |
58 | */ |
59 | #define DBC_PORTSC_CONN_STATUS BIT(0) |
60 | #define DBC_PORTSC_PORT_ENABLED BIT(1) |
61 | #define DBC_PORTSC_CONN_CHANGE BIT(17) |
62 | #define DBC_PORTSC_RESET_CHANGE BIT(21) |
63 | #define DBC_PORTSC_LINK_CHANGE BIT(22) |
64 | #define DBC_PORTSC_CONFIG_CHANGE BIT(23) |
65 | |
66 | struct dbc_str_descs { |
67 | char string0[DBC_MAX_STRING_LENGTH]; |
68 | char manufacturer[DBC_MAX_STRING_LENGTH]; |
69 | char product[DBC_MAX_STRING_LENGTH]; |
70 | char serial[DBC_MAX_STRING_LENGTH]; |
71 | }; |
72 | |
73 | #define DBC_PROTOCOL 1 /* GNU Remote Debug Command */ |
74 | #define DBC_VENDOR_ID 0x1d6b /* Linux Foundation 0x1d6b */ |
75 | #define DBC_PRODUCT_ID 0x0010 /* device 0010 */ |
76 | #define DBC_DEVICE_REV 0x0010 /* 0.10 */ |
77 | |
78 | enum dbc_state { |
79 | DS_DISABLED = 0, |
80 | DS_INITIALIZED, |
81 | DS_ENABLED, |
82 | DS_CONNECTED, |
83 | DS_CONFIGURED, |
84 | DS_STALLED, |
85 | }; |
86 | |
87 | struct dbc_ep { |
88 | struct xhci_dbc *dbc; |
89 | struct list_head list_pending; |
90 | struct xhci_ring *ring; |
91 | unsigned int direction:1; |
92 | }; |
93 | |
94 | #define DBC_QUEUE_SIZE 16 |
95 | #define DBC_WRITE_BUF_SIZE 8192 |
96 | |
97 | /* |
98 | * Private structure for DbC hardware state: |
99 | */ |
100 | struct dbc_port { |
101 | struct tty_port port; |
102 | spinlock_t port_lock; /* port access */ |
103 | int minor; |
104 | |
105 | struct list_head read_pool; |
106 | struct list_head read_queue; |
107 | unsigned int n_read; |
108 | struct tasklet_struct push; |
109 | |
110 | struct list_head write_pool; |
111 | struct kfifo write_fifo; |
112 | |
113 | bool registered; |
114 | }; |
115 | |
116 | struct dbc_driver { |
117 | int (*configure)(struct xhci_dbc *dbc); |
118 | void (*disconnect)(struct xhci_dbc *dbc); |
119 | }; |
120 | |
121 | struct xhci_dbc { |
122 | spinlock_t lock; /* device access */ |
123 | struct device *dev; |
124 | struct xhci_hcd *xhci; |
125 | struct dbc_regs __iomem *regs; |
126 | struct xhci_ring *ring_evt; |
127 | struct xhci_ring *ring_in; |
128 | struct xhci_ring *ring_out; |
129 | struct xhci_erst erst; |
130 | struct xhci_container_ctx *ctx; |
131 | |
132 | struct dbc_str_descs *string; |
133 | dma_addr_t string_dma; |
134 | size_t string_size; |
135 | u16 idVendor; |
136 | u16 idProduct; |
137 | u16 bcdDevice; |
138 | u8 bInterfaceProtocol; |
139 | |
140 | enum dbc_state state; |
141 | struct delayed_work event_work; |
142 | unsigned resume_required:1; |
143 | struct dbc_ep eps[2]; |
144 | |
145 | const struct dbc_driver *driver; |
146 | void *priv; |
147 | }; |
148 | |
149 | struct dbc_request { |
150 | void *buf; |
151 | unsigned int length; |
152 | dma_addr_t dma; |
153 | void (*complete)(struct xhci_dbc *dbc, |
154 | struct dbc_request *req); |
155 | struct list_head list_pool; |
156 | int status; |
157 | unsigned int actual; |
158 | |
159 | struct xhci_dbc *dbc; |
160 | struct list_head list_pending; |
161 | dma_addr_t trb_dma; |
162 | union xhci_trb *trb; |
163 | unsigned direction:1; |
164 | }; |
165 | |
166 | #define dbc_bulkout_ctx(d) \ |
167 | ((struct xhci_ep_ctx *)((d)->ctx->bytes + DBC_CONTEXT_SIZE)) |
168 | #define dbc_bulkin_ctx(d) \ |
169 | ((struct xhci_ep_ctx *)((d)->ctx->bytes + DBC_CONTEXT_SIZE * 2)) |
170 | #define dbc_bulkout_enq(d) \ |
171 | xhci_trb_virt_to_dma((d)->ring_out->enq_seg, (d)->ring_out->enqueue) |
172 | #define dbc_bulkin_enq(d) \ |
173 | xhci_trb_virt_to_dma((d)->ring_in->enq_seg, (d)->ring_in->enqueue) |
174 | #define dbc_epctx_info2(t, p, b) \ |
175 | cpu_to_le32(EP_TYPE(t) | MAX_PACKET(p) | MAX_BURST(b)) |
176 | #define dbc_ep_dma_direction(d) \ |
177 | ((d)->direction ? DMA_FROM_DEVICE : DMA_TO_DEVICE) |
178 | |
179 | #define BULK_OUT 0 |
180 | #define BULK_IN 1 |
181 | #define EPID_OUT 2 |
182 | #define EPID_IN 3 |
183 | |
184 | enum evtreturn { |
185 | EVT_ERR = -1, |
186 | EVT_DONE, |
187 | EVT_GSER, |
188 | EVT_DISC, |
189 | }; |
190 | |
191 | static inline struct dbc_ep *get_in_ep(struct xhci_dbc *dbc) |
192 | { |
193 | return &dbc->eps[BULK_IN]; |
194 | } |
195 | |
196 | static inline struct dbc_ep *get_out_ep(struct xhci_dbc *dbc) |
197 | { |
198 | return &dbc->eps[BULK_OUT]; |
199 | } |
200 | |
201 | #ifdef CONFIG_USB_XHCI_DBGCAP |
202 | int xhci_create_dbc_dev(struct xhci_hcd *xhci); |
203 | void xhci_remove_dbc_dev(struct xhci_hcd *xhci); |
204 | int xhci_dbc_init(void); |
205 | void xhci_dbc_exit(void); |
206 | int dbc_tty_init(void); |
207 | void dbc_tty_exit(void); |
208 | int xhci_dbc_tty_probe(struct device *dev, void __iomem *res, struct xhci_hcd *xhci); |
209 | void xhci_dbc_tty_remove(struct xhci_dbc *dbc); |
210 | struct xhci_dbc *xhci_alloc_dbc(struct device *dev, void __iomem *res, |
211 | const struct dbc_driver *driver); |
212 | void xhci_dbc_remove(struct xhci_dbc *dbc); |
213 | struct dbc_request *dbc_alloc_request(struct xhci_dbc *dbc, |
214 | unsigned int direction, |
215 | gfp_t flags); |
216 | void dbc_free_request(struct dbc_request *req); |
217 | int dbc_ep_queue(struct dbc_request *req); |
218 | #ifdef CONFIG_PM |
219 | int xhci_dbc_suspend(struct xhci_hcd *xhci); |
220 | int xhci_dbc_resume(struct xhci_hcd *xhci); |
221 | #endif /* CONFIG_PM */ |
222 | #else |
223 | static inline int xhci_create_dbc_dev(struct xhci_hcd *xhci) |
224 | { |
225 | return 0; |
226 | } |
227 | |
228 | static inline void xhci_remove_dbc_dev(struct xhci_hcd *xhci) |
229 | { |
230 | } |
231 | static inline int xhci_dbc_init(void) |
232 | { |
233 | return 0; |
234 | } |
235 | static inline void xhci_dbc_exit(void) |
236 | { |
237 | } |
238 | static inline int xhci_dbc_suspend(struct xhci_hcd *xhci) |
239 | { |
240 | return 0; |
241 | } |
242 | |
243 | static inline int xhci_dbc_resume(struct xhci_hcd *xhci) |
244 | { |
245 | return 0; |
246 | } |
247 | #endif /* CONFIG_USB_XHCI_DBGCAP */ |
248 | #endif /* __LINUX_XHCI_DBGCAP_H */ |
249 | |