PS2SDK
PS2 Homebrew Libraries
td_queue.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11 #include "usbdpriv.h"
12 
13 static void checkGenTdQueue(void)
14 {
15  UsbdEndpoint_t *queueStart_tmp1;
16 
17  if ( !memPool->m_freeHcTdList )
18  {
19  return;
20  }
21  for ( queueStart_tmp1 = memPool->m_tdQueueStart; queueStart_tmp1 && queueStart_tmp1->m_inTdQueue != GENTD_QUEUE;
22  queueStart_tmp1 = queueStart_tmp1->m_busyNext )
23  {
24  }
25  if ( queueStart_tmp1 )
26  handleIoReqList(queueStart_tmp1);
27 }
28 
29 void processDoneQueue_GenTd(UsbdHcTD_t *arg)
30 {
31  u32 tdHcArea;
32  const u8 *curBufPtr;
33  const void *bufferEnd;
34  UsbdIoRequest_t **lut_ptr1;
35  u32 hcRes;
36  UsbdIoRequest_t *req_1;
37  UsbdHcED_t *ed;
38  UsbdHcTD_t *tdListPos_2;
39  UsbdHcTD_t *nextTd;
40  UsbdIoRequest_t *req_2;
41  UsbdIoRequest_t *listPos;
42  UsbdIoRequest_t *pos;
43  UsbdIoRequest_t *next_tmp1;
44  UsbdIoRequest_t *firstElem;
45  UsbdIoRequest_t *lastElem;
46 
47  lastElem = NULL;
48  firstElem = NULL;
49  tdHcArea = arg->m_hcArea;
50  curBufPtr = (u8 *)arg->m_curBufPtr;
51  bufferEnd = arg->m_bufferEnd;
52  lut_ptr1 = &memPool->m_hcTdToIoReqLUT[arg - memPool->m_hcTdBuf];
53  hcRes = tdHcArea >> 28;
54  req_1 = *lut_ptr1;
55  *lut_ptr1 = NULL;
56  if ( !req_1 )
57  {
58  return;
59  }
60  freeTd(arg);
61  if ( bufferEnd && ((tdHcArea & 0x180000) != 0) ) // dir != SETUP
62  {
63  // transfer successful when !curBufPtr
64  req_1->m_transferedBytes = curBufPtr ? (u32)(curBufPtr - (u8 *)req_1->m_destPtr) : req_1->m_length;
65  }
66  if ( req_1->m_resultCode == USB_RC_OK )
67  req_1->m_resultCode = hcRes;
68  if ( hcRes || ((tdHcArea & 0xE00000) != 0xE00000) ) // E00000: interrupts disabled
69  {
70  req_1->m_prev = NULL;
71  firstElem = req_1;
72  req_1->m_next = NULL;
73  lastElem = req_1;
74  }
75  ed = req_1->m_correspEndpoint->m_hcEd;
76  if ( hcRes && ED_HALTED(*ed) )
77  {
78  for ( tdListPos_2 = (UsbdHcTD_t *)((uiptr)ed->m_tdHead & ~0xF); tdListPos_2 && tdListPos_2 != ed->m_tdTail;
79  tdListPos_2 = nextTd )
80  {
81  UsbdIoRequest_t **lut_ptr2;
82 
83  nextTd = tdListPos_2->m_next;
84  freeTd(tdListPos_2);
85  lut_ptr2 = &memPool->m_hcTdToIoReqLUT[tdListPos_2 - memPool->m_hcTdBuf];
86  req_2 = *lut_ptr2;
87  *lut_ptr2 = NULL;
88  if ( !req_2 )
89  {
90  continue;
91  }
92  for ( listPos = firstElem; listPos && listPos != req_2; listPos = listPos->m_next )
93  {
94  }
95  if ( listPos )
96  {
97  continue;
98  }
99  req_2->m_resultCode = USB_RC_ABORTED;
100  req_2->m_prev = lastElem;
101  if ( lastElem )
102  lastElem->m_next = req_2;
103  else
104  firstElem = req_2;
105  req_2->m_next = NULL;
106  lastElem = req_2;
107  }
108  ed->m_tdHead = ed->m_tdTail;
109  }
110  for ( pos = firstElem; pos; pos = next_tmp1 )
111  {
112  pos->m_busyFlag = 0;
113  next_tmp1 = pos->m_next;
114  if ( pos->m_correspEndpoint->m_correspDevice )
115  {
116  if ( pos->m_callbackProc )
117  pos->m_callbackProc(pos);
118  }
119  else
120  {
121  freeIoRequest(pos);
122  }
123  }
124  checkGenTdQueue();
125 }
126 
127 static void checkIsoTdQueue(void)
128 {
129  UsbdEndpoint_t *queueStart_tmp1;
130 
131  if ( !memPool->m_freeHcIsoTdList )
132  {
133  return;
134  }
135  for ( queueStart_tmp1 = memPool->m_tdQueueStart; queueStart_tmp1 && queueStart_tmp1->m_inTdQueue != ISOTD_QUEUE;
136  queueStart_tmp1 = queueStart_tmp1->m_busyNext )
137  {
138  }
139  if ( queueStart_tmp1 )
140  handleIoReqList(queueStart_tmp1);
141 }
142 
143 void processDoneQueue_IsoTd(UsbdHcIsoTD_t *arg)
144 {
145  u32 hcArea;
146  unsigned int psw_tmp;
147  u32 tdHcRes;
148  unsigned int pswRes;
149  UsbdIoRequest_t **lut_ptr1;
150  int pswOfs;
151  UsbdIoRequest_t *req_1;
152  UsbdHcED_t *ed;
153  UsbdHcTD_t *tdHead;
154  UsbdHcIsoTD_t *curTd;
155  UsbdHcIsoTD_t *nextTd;
156  UsbdIoRequest_t *req_2;
157  UsbdIoRequest_t *listPos;
158  UsbdIoRequest_t *pos;
159  UsbdIoRequest_t *next_tmp1;
160  UsbdIoRequest_t *listStart;
161  UsbdIoRequest_t *listEnd;
162 
163  hcArea = arg->m_hcArea;
164  psw_tmp = arg->m_psw[0];
165  tdHcRes = hcArea >> 28;
166  pswRes = psw_tmp >> 12;
167  lut_ptr1 = &memPool->m_hcIsoTdToIoReqLUT[arg - memPool->m_hcIsoTdBuf];
168  pswOfs = psw_tmp & 0x7FF;
169  req_1 = *lut_ptr1;
170  *lut_ptr1 = NULL;
171  if ( !req_1 )
172  {
173  return;
174  }
175  if ( req_1->m_req.bNumPackets )
176  bcopy(arg->m_psw, req_1->m_req.Packets, 16);
177  freeIsoTd(arg);
178  req_1->m_transferedBytes = 0;
179  if ( req_1->m_req.bNumPackets )
180  {
181  req_1->m_resultCode = tdHcRes;
182  }
183  else
184  {
185  req_1->m_resultCode = tdHcRes | (pswRes << 4);
186  if ( tdHcRes == USB_RC_OK && (pswRes == USB_RC_OK || pswRes == USB_RC_DATAUNDER) )
187  {
188  if ( (req_1->m_correspEndpoint->m_hcEd->m_hcArea.stru.m_hcArea & HCED_DIR_MASK) == HCED_DIR_IN )
189  req_1->m_transferedBytes = pswOfs;
190  else
191  req_1->m_transferedBytes = req_1->m_length;
192  }
193  }
194  req_1->m_prev = NULL;
195  listStart = req_1;
196  req_1->m_next = NULL;
197  listEnd = req_1;
198  ed = req_1->m_correspEndpoint->m_hcEd;
199  tdHead = ed->m_tdHead;
200  if ( ED_HALTED(*ed) )
201  {
202  for ( curTd = (UsbdHcIsoTD_t *)((uiptr)tdHead & ~0xF); curTd && curTd != (UsbdHcIsoTD_t *)(ed->m_tdTail);
203  curTd = nextTd )
204  {
205  UsbdIoRequest_t **lut_ptr2;
206 
207  nextTd = curTd->m_next;
208  freeIsoTd(curTd);
209  lut_ptr2 = &memPool->m_hcIsoTdToIoReqLUT[curTd - memPool->m_hcIsoTdBuf];
210  req_2 = *lut_ptr2;
211  *lut_ptr2 = NULL;
212  if ( req_2 )
213  {
214  for ( listPos = listStart; listPos && listPos != req_2; listPos = listPos->m_next )
215  {
216  }
217  if ( listPos )
218  {
219  continue;
220  }
221  req_2->m_resultCode = USB_RC_ABORTED;
222  req_2->m_prev = listEnd;
223  if ( listEnd )
224  listEnd->m_next = req_2;
225  else
226  listStart = req_2;
227  req_2->m_next = NULL;
228  listEnd = req_2;
229  }
230  }
231  ed->m_tdHead = ed->m_tdTail;
232  }
233  for ( pos = listStart; pos; pos = next_tmp1 )
234  {
235  pos->m_busyFlag = 0;
236  next_tmp1 = pos->m_next;
237  if ( pos->m_correspEndpoint->m_correspDevice )
238  {
239  if ( pos->m_callbackProc )
240  pos->m_callbackProc(pos);
241  }
242  else
243  {
244  freeIoRequest(pos);
245  }
246  }
247  checkIsoTdQueue();
248 }
USB_RC_OK
#define USB_RC_OK
Definition: usbd.h:238
_hcIsoTd
Definition: usbdpriv.h:144
USB_RC_ABORTED
#define USB_RC_ABORTED
Definition: usbd.h:289
usbdpriv.h
_hcTd
Definition: usbdpriv.h:136
_hcEd
Definition: usbdpriv.h:165
USB_RC_DATAUNDER
#define USB_RC_DATAUNDER
Definition: usbd.h:256
_ioRequest
Definition: usbdpriv.h:82
_endpoint
Definition: usbdpriv.h:173