Changeset 4db49344 in mainline for uspace/lib/usbhost
- Timestamp:
- 2018-01-23T21:52:28Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3dd80f8
- Parents:
- a6afb4c
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-01-23 20:49:35)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-01-23 21:52:28)
- Location:
- uspace/lib/usbhost
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/include/usb/host/endpoint.h
ra6afb4c r4db49344 53 53 typedef struct usb_transfer_batch usb_transfer_batch_t; 54 54 55 /** Host controller side endpoint structure. */ 55 /** 56 * Host controller side endpoint structure. 57 * 58 * This structure, though reference-counted, is very fragile. It is responsible 59 * for synchronizing transfer batch scheduling and completion. 60 * 61 * To avoid situations, in which two locks must be obtained to schedule/finish 62 * a transfer, the endpoint inherits a lock from the outside. Because the 63 * concrete instance of mutex can be unknown at the time of initialization, 64 * the HC shall pass the right lock at the time of onlining the endpoint. 65 * 66 * The fields used for scheduling (online, active_batch) are to be used only 67 * under that guard and by functions designed for this purpose. The driver can 68 * also completely avoid using this mechanism, in which case it is on its own in 69 * question of transfer aborting. 70 * 71 * Relevant information can be found in the documentation of HelenOS xHCI 72 * project. 73 */ 56 74 typedef struct endpoint { 57 75 /** USB device */ … … 59 77 /** Reference count. */ 60 78 atomic_t refcnt; 61 /** Reserved bandwidth. */ 62 size_t bandwidth; 63 /** The currently active transfer batch. Write using methods, read under guard. */ 79 80 /** An inherited guard */ 81 fibril_mutex_t *guard; 82 /** Whether it's allowed to schedule on this endpoint */ 83 bool online; 84 /** The currently active transfer batch. */ 64 85 usb_transfer_batch_t *active_batch; 65 /** Protects resources and active status changes. */66 fibril_mutex_t guard;67 86 /** Signals change of active status. */ 68 87 fibril_condvar_t avail; 69 88 70 /** Enpoint number */ 89 /** Reserved bandwidth. Needed for USB2 bus. */ 90 size_t bandwidth; 91 /** Endpoint number */ 71 92 usb_endpoint_t endpoint; 72 93 /** Communication direction. */ … … 79 100 /** Maximum size of one transfer */ 80 101 size_t max_transfer_size; 81 /** Number of packats that can be sent in one service interval (not necessarily uframe) */ 102 /** 103 * Number of packets that can be sent in one service interval 104 * (not necessarily uframe, despite its name) 105 */ 82 106 unsigned packets_per_uframe; 83 107 … … 90 114 extern void endpoint_del_ref(endpoint_t *); 91 115 116 extern void endpoint_set_online(endpoint_t *, fibril_mutex_t *); 117 extern void endpoint_set_offline_locked(endpoint_t *); 118 92 119 extern void endpoint_wait_timeout_locked(endpoint_t *ep, suseconds_t); 93 extern voidendpoint_activate_locked(endpoint_t *, usb_transfer_batch_t *);120 extern int endpoint_activate_locked(endpoint_t *, usb_transfer_batch_t *); 94 121 extern void endpoint_deactivate_locked(endpoint_t *); 95 122 -
uspace/lib/usbhost/src/endpoint.c
ra6afb4c r4db49344 61 61 62 62 atomic_set(&ep->refcnt, 0); 63 fibril_mutex_initialize(&ep->guard);64 63 fibril_condvar_initialize(&ep->avail); 65 64 … … 122 121 123 122 /** 124 * Wait until the endpoint have no transfer scheduled. 123 * Mark the endpoint as online. Supply a guard to be used for this endpoint 124 * synchronization. 125 */ 126 void endpoint_set_online(endpoint_t *ep, fibril_mutex_t *guard) 127 { 128 ep->guard = guard; 129 ep->online = true; 130 } 131 132 /** 133 * Mark the endpoint as offline. All other fibrils waiting to activate this 134 * endpoint will be interrupted. 135 */ 136 void endpoint_set_offline_locked(endpoint_t *ep) 137 { 138 assert(ep); 139 assert(fibril_mutex_is_locked(ep->guard)); 140 141 ep->online = false; 142 fibril_condvar_broadcast(&ep->avail); 143 } 144 145 /** 146 * Wait until a transfer finishes. Can be used even when the endpoint is 147 * offline (and is interrupted by the endpoint going offline). 125 148 */ 126 149 void endpoint_wait_timeout_locked(endpoint_t *ep, suseconds_t timeout) 127 150 { 128 assert( fibril_mutex_is_locked(&ep->guard));129 130 if (ep->active_batch != NULL) 131 fibril_condvar_wait_timeout(&ep->avail, &ep->guard, timeout);132 133 while (timeout == 0 && ep->active_batch != NULL) 134 fibril_condvar_wait_timeout(&ep->avail, &ep->guard, timeout);151 assert(ep); 152 assert(fibril_mutex_is_locked(ep->guard)); 153 154 if (ep->active_batch == NULL) 155 return; 156 157 fibril_condvar_wait_timeout(&ep->avail, ep->guard, timeout); 135 158 } 136 159 … … 140 163 * 141 164 * Call only under endpoint guard. After you activate the endpoint and release 142 * the guard, you must assume that particular transfer is already finished/aborted. 143 * 144 * @param ep endpoint_t structure. 145 * @param batch Transfer batch this endpoint is bocked by. 146 */ 147 void endpoint_activate_locked(endpoint_t *ep, usb_transfer_batch_t *batch) 165 * the guard, you must assume that particular transfer is already 166 * finished/aborted. 167 * 168 * Activation and deactivation is not done by the library to maximize 169 * performance. The HC might want to prepare some memory buffers prior to 170 * interfering with other world. 171 * 172 * @param batch Transfer batch this endpoint is blocked by. 173 */ 174 int endpoint_activate_locked(endpoint_t *ep, usb_transfer_batch_t *batch) 148 175 { 149 176 assert(ep); 150 177 assert(batch); 151 178 assert(batch->ep == ep); 152 153 endpoint_wait_timeout_locked(ep, 0); 179 assert(ep->guard); 180 assert(fibril_mutex_is_locked(ep->guard)); 181 182 while (ep->online && ep->active_batch != NULL) 183 fibril_condvar_wait(&ep->avail, ep->guard); 184 185 if (!ep->online) 186 return EINTR; 187 188 assert(ep->active_batch == NULL); 154 189 ep->active_batch = batch; 190 return EOK; 155 191 } 156 192 157 193 /** 158 194 * Mark the endpoint as inactive and allow access for further fibrils. 159 *160 * @param ep endpoint_t structure.161 195 */ 162 196 void endpoint_deactivate_locked(endpoint_t *ep) 163 197 { 164 198 assert(ep); 165 assert(fibril_mutex_is_locked(&ep->guard)); 199 assert(fibril_mutex_is_locked(ep->guard)); 200 166 201 ep->active_batch = NULL; 167 202 fibril_condvar_signal(&ep->avail);
Note:
See TracChangeset
for help on using the changeset viewer.