@@ -162,7 +162,7 @@ static inline void qtd_remove_1st_from_qhd (ehci_qhd_t *p_qhd);
162
162
static void qtd_init (ehci_qtd_t * qtd , void const * buffer , uint16_t total_bytes );
163
163
164
164
static inline void list_insert (ehci_link_t * current , ehci_link_t * new , uint8_t new_type );
165
- static inline ehci_link_t * list_next (ehci_link_t * p_link_pointer );
165
+ static inline ehci_link_t * list_next (ehci_link_t const * p_link );
166
166
167
167
TU_ATTR_WEAK void hcd_dcache_clean (void * addr , uint32_t data_size ) {
168
168
(void ) addr ;
@@ -237,24 +237,22 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport)
237
237
return (tusb_speed_t ) ehci_data .regs -> portsc_bm .nxp_port_speed ; // NXP specific port speed
238
238
}
239
239
240
- static void list_remove_qhd_by_addr (ehci_link_t * list_head , uint8_t dev_addr )
241
- {
242
- for (ehci_link_t * prev = list_head ;
243
- !prev -> terminate && (tu_align32 (prev -> address ) != (uint32_t ) list_head ) && prev != NULL ;
244
- prev = list_next (prev ) )
245
- {
246
- // TODO check type for ISO iTD and siTD
247
- // TODO Suppress cast-align warning
248
- #pragma GCC diagnostic push
249
- #pragma GCC diagnostic ignored "-Wcast-align"
250
- ehci_qhd_t * qhd = (ehci_qhd_t * ) list_next (prev );
251
- #pragma GCC diagnostic pop
252
- if ( qhd -> dev_addr == dev_addr )
253
- {
240
+ static void list_remove_qhd_by_daddr (ehci_link_t * list_head , uint8_t dev_addr ) {
241
+ ehci_link_t * prev = list_head ;
242
+
243
+ while (prev && !prev -> terminate ) {
244
+ ehci_qhd_t * qhd = (ehci_qhd_t * ) (uintptr_t ) list_next (prev );
245
+
246
+ // done if loop back to head
247
+ if ( (uintptr_t ) qhd == (uintptr_t ) list_head ) {
248
+ break ;
249
+ }
250
+
251
+ if ( qhd -> dev_addr == dev_addr ) {
254
252
// TODO deactivate all TD, wait for QHD to inactive before removal
255
253
prev -> address = qhd -> next .address ;
256
254
257
- // EHCI 4.8.2 link the removed qhd to async head (which always reachable by Host Controller)
255
+ // EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller)
258
256
qhd -> next .address = ((uint32_t ) list_head ) | (EHCI_QTYPE_QHD << 1 );
259
257
260
258
if ( qhd -> int_smask )
@@ -267,6 +265,11 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr)
267
265
// mark as removing, will completely re-usable when async advance isr occurs
268
266
qhd -> removing = 1 ;
269
267
}
268
+
269
+ hcd_dcache_clean (qhd , sizeof (ehci_qhd_t ));
270
+ hcd_dcache_clean (prev , sizeof (ehci_qhd_t ));
271
+ }else {
272
+ prev = list_next (prev );
270
273
}
271
274
}
272
275
}
@@ -275,15 +278,16 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr)
275
278
void hcd_device_close (uint8_t rhport , uint8_t dev_addr )
276
279
{
277
280
// skip dev0
278
- if (dev_addr == 0 ) return ;
281
+ if (dev_addr == 0 ) {
282
+ return ;
283
+ }
279
284
280
285
// Remove from async list
281
- list_remove_qhd_by_addr ( (ehci_link_t * ) qhd_async_head (rhport ), dev_addr );
286
+ list_remove_qhd_by_daddr ( (ehci_link_t * ) qhd_async_head (rhport ), dev_addr );
282
287
283
288
// Remove from all interval period list
284
- for (uint8_t i = 0 ; i < TU_ARRAY_SIZE (ehci_data .period_head_arr ); i ++ )
285
- {
286
- list_remove_qhd_by_addr ( (ehci_link_t * ) & ehci_data .period_head_arr [i ], dev_addr );
289
+ for (uint8_t i = 0 ; i < TU_ARRAY_SIZE (ehci_data .period_head_arr ); i ++ ) {
290
+ list_remove_qhd_by_daddr ((ehci_link_t * ) & ehci_data .period_head_arr [i ], dev_addr );
287
291
}
288
292
289
293
// Async doorbell (EHCI 4.8.2 for operational details)
@@ -990,9 +994,9 @@ static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t n
990
994
current -> address = ((uint32_t ) new ) | (new_type << 1 );
991
995
}
992
996
993
- static inline ehci_link_t * list_next (ehci_link_t * p_link_pointer )
997
+ static inline ehci_link_t * list_next (ehci_link_t const * p_link )
994
998
{
995
- return (ehci_link_t * ) tu_align32 (p_link_pointer -> address );
999
+ return (ehci_link_t * ) tu_align32 (p_link -> address );
996
1000
}
997
1001
998
1002
#endif
0 commit comments