@@ -59,6 +59,11 @@ static int last_sel_trans_num_avail_hc_at_end = 0;
59
59
60
60
extern int g_next_sched_frame , g_np_count , g_np_sent ;
61
61
62
+ extern haint_data_t haint_saved ;
63
+ extern hcintmsk_data_t hcintmsk_saved [MAX_EPS_CHANNELS ];
64
+ extern hcint_data_t hcint_saved [MAX_EPS_CHANNELS ];
65
+ extern gintsts_data_t ginsts_saved ;
66
+
62
67
dwc_otg_hcd_t * dwc_otg_hcd_alloc_hcd (void )
63
68
{
64
69
return DWC_ALLOC (sizeof (dwc_otg_hcd_t ));
@@ -168,31 +173,43 @@ static void del_timers(dwc_otg_hcd_t * hcd)
168
173
169
174
/**
170
175
* Processes all the URBs in a single list of QHs. Completes them with
171
- * -ETIMEDOUT and frees the QTD.
176
+ * -ESHUTDOWN and frees the QTD.
172
177
*/
173
178
static void kill_urbs_in_qh_list (dwc_otg_hcd_t * hcd , dwc_list_link_t * qh_list )
174
179
{
175
- dwc_list_link_t * qh_item ;
180
+ dwc_list_link_t * qh_item , * qh_tmp ;
176
181
dwc_otg_qh_t * qh ;
177
182
dwc_otg_qtd_t * qtd , * qtd_tmp ;
178
183
179
- DWC_LIST_FOREACH (qh_item , qh_list ) {
184
+ DWC_LIST_FOREACH_SAFE (qh_item , qh_tmp , qh_list ) {
180
185
qh = DWC_LIST_ENTRY (qh_item , dwc_otg_qh_t , qh_list_entry );
181
186
DWC_CIRCLEQ_FOREACH_SAFE (qtd , qtd_tmp ,
182
187
& qh -> qtd_list , qtd_list_entry ) {
183
188
qtd = DWC_CIRCLEQ_FIRST (& qh -> qtd_list );
184
189
if (qtd -> urb != NULL ) {
185
190
hcd -> fops -> complete (hcd , qtd -> urb -> priv ,
186
- qtd -> urb , - DWC_E_TIMEOUT );
191
+ qtd -> urb , - DWC_E_SHUTDOWN );
187
192
dwc_otg_hcd_qtd_remove_and_free (hcd , qtd , qh );
188
193
}
189
194
190
195
}
196
+ if (qh -> channel ) {
197
+ /* Using hcchar.chen == 1 is not a reliable test.
198
+ * It is possible that the channel has already halted
199
+ * but not yet been through the IRQ handler.
200
+ */
201
+ dwc_otg_hc_halt (hcd -> core_if , qh -> channel ,
202
+ DWC_OTG_HC_XFER_URB_DEQUEUE );
203
+ if (microframe_schedule )
204
+ hcd -> available_host_channels ++ ;
205
+ qh -> channel = NULL ;
206
+ }
207
+ dwc_otg_hcd_qh_remove (hcd , qh );
191
208
}
192
209
}
193
210
194
211
/**
195
- * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
212
+ * Responds with an error status of ESHUTDOWN to all URBs in the non-periodic
196
213
* and periodic schedules. The QTD associated with each URB is removed from
197
214
* the schedule and freed. This function may be called when a disconnect is
198
215
* detected or when the HCD is being stopped.
@@ -278,7 +295,8 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p)
278
295
*/
279
296
dwc_otg_hcd -> flags .b .port_connect_status_change = 1 ;
280
297
dwc_otg_hcd -> flags .b .port_connect_status = 0 ;
281
-
298
+ if (fiq_fix_enable )
299
+ local_fiq_disable ();
282
300
/*
283
301
* Shutdown any transfers in process by clearing the Tx FIFO Empty
284
302
* interrupt mask and status bits and disabling subsequent host
@@ -374,8 +392,22 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p)
374
392
channel -> qh = NULL ;
375
393
}
376
394
}
395
+ if (fiq_split_enable ) {
396
+ for (i = 0 ; i < 128 ; i ++ ) {
397
+ dwc_otg_hcd -> hub_port [i ] = 0 ;
398
+ }
399
+ haint_saved .d32 = 0 ;
400
+ for (i = 0 ; i < MAX_EPS_CHANNELS ; i ++ ) {
401
+ hcint_saved [i ].d32 = 0 ;
402
+ hcintmsk_saved [i ].d32 = 0 ;
403
+ }
404
+ }
405
+
377
406
}
378
407
408
+ if (fiq_fix_enable )
409
+ local_fiq_enable ();
410
+
379
411
if (dwc_otg_hcd -> fops -> disconnect ) {
380
412
dwc_otg_hcd -> fops -> disconnect (dwc_otg_hcd );
381
413
}
0 commit comments