|
1 /* Cypress West Bridge API header file (cyasmtp.h) |
|
2 ## =========================== |
|
3 ## |
|
4 ## Copyright Cypress Semiconductor Corporation, 2006-2009, |
|
5 ## All Rights Reserved |
|
6 ## UNPUBLISHED, LICENSED SOFTWARE. |
|
7 ## |
|
8 ## CONFIDENTIAL AND PROPRIETARY INFORMATION |
|
9 ## WHICH IS THE PROPERTY OF CYPRESS. |
|
10 ## |
|
11 ## Use of this file is governed |
|
12 ## by the license agreement included in the file |
|
13 ## |
|
14 ## <install>/license/license.txt |
|
15 ## |
|
16 ## where <install> is the Cypress software |
|
17 ## installation root directory path. |
|
18 ## |
|
19 ## =========================== |
|
20 */ |
|
21 |
|
22 #include "cyashal.h" |
|
23 #include "cyasmtp.h" |
|
24 #include "cyaserr.h" |
|
25 #include "cyasdma.h" |
|
26 #include "cyaslowlevel.h" |
|
27 |
|
28 static void |
|
29 CyAsMTPFuncCallback(CyAsDevice *dev_p, |
|
30 uint8_t context, |
|
31 CyAsLLRequestResponse *rqt, |
|
32 CyAsLLRequestResponse *resp, |
|
33 CyAsReturnStatus_t stat) ; |
|
34 |
|
35 static CyAsReturnStatus_t |
|
36 IsMTPActive(CyAsDevice *dev_p) |
|
37 { |
|
38 if (!CyAsDeviceIsConfigured(dev_p)) |
|
39 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
40 |
|
41 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
42 return CY_AS_ERROR_NO_FIRMWARE ; |
|
43 |
|
44 if (dev_p->mtp_count == 0) |
|
45 return CY_AS_ERROR_NOT_RUNNING ; |
|
46 |
|
47 if (CyAsDeviceIsInSuspendMode(dev_p)) |
|
48 return CY_AS_ERROR_IN_SUSPEND ; |
|
49 |
|
50 return CY_AS_ERROR_SUCCESS ; |
|
51 } |
|
52 |
|
53 static void |
|
54 MyMtpRequestCallback(CyAsDevice *dev_p, |
|
55 uint8_t context, |
|
56 CyAsLLRequestResponse *req_p, |
|
57 CyAsLLRequestResponse *resp_p, |
|
58 CyAsReturnStatus_t ret) |
|
59 { |
|
60 uint16_t val, ev, status ; |
|
61 uint16_t mtp_datalen = 0 ; |
|
62 uint32_t bytecount_l, bytecount_h ; |
|
63 CyAsMTPSendObjectCompleteData sendObjData ; |
|
64 CyAsMTPGetObjectCompleteData getObjData ; |
|
65 CyAsDmaEndPoint *ep_p ; |
|
66 |
|
67 uint8_t code = CyAsLLRequestResponse_GetCode(req_p) ; |
|
68 |
|
69 (void)resp_p ; |
|
70 (void)context ; |
|
71 (void)ret ; |
|
72 |
|
73 switch(code) |
|
74 { |
|
75 case CY_RQT_MTP_EVENT: |
|
76 val = CyAsLLRequestResponse_GetWord(req_p, 0) ; |
|
77 status = (val >> 8) & 0xFF ; /* MSB indicates status of read/write */ |
|
78 ev = val & 0xFF ; /* event type */ |
|
79 switch(ev) |
|
80 { |
|
81 case 0: /* SendObject Complete */ |
|
82 { |
|
83 bytecount_l = CyAsLLRequestResponse_GetWord(req_p, 1) ; |
|
84 bytecount_h = CyAsLLRequestResponse_GetWord(req_p, 2) ; |
|
85 sendObjData.byte_count = (bytecount_h << 16) | bytecount_l ; |
|
86 |
|
87 sendObjData.status = status ; |
|
88 |
|
89 /* use the byte count again */ |
|
90 bytecount_l = CyAsLLRequestResponse_GetWord(req_p, 3) ; |
|
91 bytecount_h = CyAsLLRequestResponse_GetWord(req_p, 4) ; |
|
92 sendObjData.transaction_id = (bytecount_h << 16) | bytecount_l ; |
|
93 |
|
94 dev_p->mtp_turbo_active = CyFalse ; |
|
95 |
|
96 if (dev_p->mtp_event_cb) |
|
97 dev_p->mtp_event_cb((CyAsDeviceHandle)dev_p, CyAsMTPSendObjectComplete, |
|
98 &sendObjData) ; |
|
99 } |
|
100 break ; |
|
101 |
|
102 case 1: /* GetObject Complete */ |
|
103 { |
|
104 bytecount_l = CyAsLLRequestResponse_GetWord(req_p, 1) ; |
|
105 bytecount_h = CyAsLLRequestResponse_GetWord(req_p, 2) ; |
|
106 |
|
107 getObjData.byte_count = (bytecount_h << 16) | bytecount_l ; |
|
108 getObjData.status = status ; |
|
109 |
|
110 dev_p->mtp_turbo_active = CyFalse ; |
|
111 |
|
112 if (dev_p->mtp_event_cb) |
|
113 dev_p->mtp_event_cb((CyAsDeviceHandle)dev_p, CyAsMTPGetObjectComplete, |
|
114 &getObjData); |
|
115 } |
|
116 break ; |
|
117 |
|
118 case 2: /* BlockTable Needed */ |
|
119 { |
|
120 if (dev_p->mtp_event_cb) |
|
121 dev_p->mtp_event_cb((CyAsDeviceHandle)dev_p, CyAsMTPBlockTableNeeded, 0); |
|
122 } |
|
123 break ; |
|
124 default: |
|
125 CyAsHalPrintMessage("Invalid event type\n") ; |
|
126 CyAsLLSendDataResponse(dev_p, CY_RQT_TUR_RQT_CONTEXT, CY_RESP_MTP_INVALID_EVENT, sizeof(ev), &ev) ; |
|
127 break ; |
|
128 } |
|
129 break ; |
|
130 |
|
131 case CY_RQT_TURBO_CMD_FROM_HOST: |
|
132 { |
|
133 mtp_datalen = CyAsLLRequestResponse_GetWord(req_p, 1) ; |
|
134 |
|
135 /* Get the endpoint pointer based on the endpoint number */ |
|
136 ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_READ_ENDPOINT) ; |
|
137 |
|
138 /* The event should arrive only after the DMA operation has been queued. */ |
|
139 CyAsHalAssert(ep_p->queue_p != 0) ; |
|
140 |
|
141 /* Put the len in ep data information in dmaqueue and kick start the queue */ |
|
142 CyAsHalAssert(ep_p->queue_p->size >= mtp_datalen) ; |
|
143 |
|
144 if (mtp_datalen == 0) |
|
145 { |
|
146 CyAsDmaCompletedCallback(dev_p->tag, CY_AS_MTP_READ_ENDPOINT, 0, CY_AS_ERROR_SUCCESS) ; |
|
147 } |
|
148 else |
|
149 { |
|
150 ep_p->maxhwdata = mtp_datalen ; |
|
151 |
|
152 /* |
|
153 * Make sure that the DMA status for this EP is not running, so that |
|
154 * the call to CyAsDmaKickStart gets this transfer going. |
|
155 * Note: In MTP mode, we never leave a DMA transfer of greater than one |
|
156 * packet running. So, it is okay to override the status here and start |
|
157 * the next packet transfer. |
|
158 */ |
|
159 CyAsDmaEndPointSetStopped(ep_p) ; |
|
160 |
|
161 /* Kick start the queue if it is not running */ |
|
162 CyAsDmaKickStart(dev_p, CY_AS_MTP_READ_ENDPOINT) ; |
|
163 } |
|
164 } |
|
165 break ; |
|
166 |
|
167 case CY_RQT_TURBO_START_WRITE_DMA: |
|
168 { |
|
169 /* |
|
170 * Now that the firmware is ready to receive the next packet of data, start |
|
171 * the corresponding DMA transfer. First, ensure that a DMA operation is still |
|
172 * pending in the queue for the write endpoint. |
|
173 */ |
|
174 CyAsLLSendStatusResponse(dev_p, CY_RQT_TUR_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ; |
|
175 |
|
176 ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_WRITE_ENDPOINT) ; |
|
177 CyAsHalAssert (ep_p->queue_p != 0) ; |
|
178 |
|
179 CyAsDmaEndPointSetStopped(ep_p) ; |
|
180 CyAsDmaKickStart(dev_p, CY_AS_MTP_WRITE_ENDPOINT) ; |
|
181 } |
|
182 break ; |
|
183 |
|
184 default: |
|
185 CyAsHalPrintMessage("Invalid request received on TUR context\n") ; |
|
186 val = req_p->box0 ; |
|
187 CyAsLLSendDataResponse(dev_p, CY_RQT_TUR_RQT_CONTEXT, CY_RESP_INVALID_REQUEST, sizeof(val), &val) ; |
|
188 break ; |
|
189 } |
|
190 } |
|
191 |
|
192 static CyAsReturnStatus_t |
|
193 MyHandleResponseNoData(CyAsDevice* dev_p, |
|
194 CyAsLLRequestResponse *req_p, |
|
195 CyAsLLRequestResponse *reply_p) |
|
196 { |
|
197 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
198 |
|
199 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
200 { |
|
201 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
202 goto destroy ; |
|
203 } |
|
204 |
|
205 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
206 |
|
207 destroy : |
|
208 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
209 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
210 |
|
211 return ret ; |
|
212 } |
|
213 |
|
214 static CyAsReturnStatus_t |
|
215 MyHandleResponseMTPStart(CyAsDevice* dev_p, |
|
216 CyAsLLRequestResponse *req_p, |
|
217 CyAsLLRequestResponse *reply_p, |
|
218 CyAsReturnStatus_t ret) |
|
219 { |
|
220 if (ret != CY_AS_ERROR_SUCCESS) |
|
221 goto destroy ; |
|
222 |
|
223 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
224 { |
|
225 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
226 goto destroy ; |
|
227 } |
|
228 |
|
229 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
230 if (ret != CY_AS_ERROR_SUCCESS) |
|
231 goto destroy ; |
|
232 |
|
233 dev_p->mtp_count++ ; |
|
234 |
|
235 CyAsDmaEnableEndPoint(dev_p, CY_AS_MTP_READ_ENDPOINT, CyTrue, CyAsDirectionOut) ; |
|
236 dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].enabled = CyTrue ; |
|
237 dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].dir = CyAsUsbOut ; |
|
238 dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].type = CyAsUsbBulk ; |
|
239 |
|
240 CyAsDmaEnableEndPoint(dev_p, CY_AS_MTP_WRITE_ENDPOINT, CyTrue, CyAsDirectionIn) ; |
|
241 dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].enabled = CyTrue ; |
|
242 dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].dir = CyAsUsbIn ; |
|
243 dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].type = CyAsUsbBulk ; |
|
244 |
|
245 CyAsDmaSetMaxDmaSize(dev_p, 0x02, 0x0200) ; /* Packet size is 512 bytes */ |
|
246 CyAsDmaSetMaxDmaSize(dev_p, 0x06, 0x40) ; /* Packet size is 64 bytes until a switch to high speed happens. */ |
|
247 |
|
248 destroy : |
|
249 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
250 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
251 |
|
252 if (ret != CY_AS_ERROR_SUCCESS) |
|
253 CyAsLLRegisterRequestCallback(dev_p, CY_RQT_TUR_RQT_CONTEXT, 0) ; |
|
254 |
|
255 CyAsDeviceClearMSSPending(dev_p) ; |
|
256 |
|
257 return ret ; |
|
258 } |
|
259 |
|
260 |
|
261 CyAsReturnStatus_t |
|
262 CyAsMTPStart(CyAsDeviceHandle handle, |
|
263 CyAsMTPEventCallback eventCB, |
|
264 CyAsFunctionCallback cb, |
|
265 uint32_t client |
|
266 ) |
|
267 { |
|
268 CyAsLLRequestResponse *req_p, *reply_p ; |
|
269 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
270 CyAsDevice* dev_p ; |
|
271 |
|
272 dev_p = (CyAsDevice *)handle ; |
|
273 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
274 return CY_AS_ERROR_INVALID_HANDLE ; |
|
275 |
|
276 if (!CyAsDeviceIsConfigured(dev_p)) |
|
277 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
278 |
|
279 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
280 return CY_AS_ERROR_NO_FIRMWARE ; |
|
281 |
|
282 if (CyAsDeviceIsInSuspendMode(dev_p)) |
|
283 return CY_AS_ERROR_IN_SUSPEND ; |
|
284 |
|
285 if (CyAsDeviceIsInCallback(dev_p)) |
|
286 return CY_AS_ERROR_INVALID_IN_CALLBACK ; |
|
287 |
|
288 if(CyAsDeviceIsMSSPending(dev_p)) |
|
289 return CY_AS_ERROR_STARTSTOP_PENDING ; |
|
290 |
|
291 if (dev_p->storage_count == 0) |
|
292 return CY_AS_ERROR_NOT_RUNNING ; |
|
293 |
|
294 if (dev_p->usb_count == 0) |
|
295 return CY_AS_ERROR_NOT_RUNNING ; |
|
296 |
|
297 if (dev_p->is_mtp_firmware == 0) |
|
298 return CY_AS_ERROR_NOT_SUPPORTED ; |
|
299 |
|
300 CyAsDeviceSetMSSPending(dev_p) ; |
|
301 |
|
302 if (dev_p->mtp_count == 0) |
|
303 { |
|
304 |
|
305 dev_p->mtp_event_cb = eventCB ; |
|
306 /* |
|
307 * We register here becuase the start request may cause events to occur before the |
|
308 * response to the start request. |
|
309 */ |
|
310 CyAsLLRegisterRequestCallback(dev_p, CY_RQT_TUR_RQT_CONTEXT, MyMtpRequestCallback) ; |
|
311 |
|
312 /* Create the request to send to the West Bridge device */ |
|
313 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_START_MTP, CY_RQT_TUR_RQT_CONTEXT, 0) ; |
|
314 if (req_p == 0) |
|
315 { |
|
316 CyAsDeviceClearMSSPending(dev_p) ; |
|
317 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
318 } |
|
319 |
|
320 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
321 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
322 if (reply_p == 0) |
|
323 { |
|
324 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
325 CyAsDeviceClearMSSPending(dev_p) ; |
|
326 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
327 } |
|
328 |
|
329 if(cb == 0) |
|
330 { |
|
331 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
332 if (ret != CY_AS_ERROR_SUCCESS) |
|
333 goto destroy ; |
|
334 |
|
335 return MyHandleResponseMTPStart(dev_p, req_p, reply_p, ret) ; |
|
336 } |
|
337 else |
|
338 { |
|
339 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_START, |
|
340 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, |
|
341 CyAsMTPFuncCallback) ; |
|
342 |
|
343 if (ret != CY_AS_ERROR_SUCCESS) |
|
344 goto destroy ; |
|
345 |
|
346 return ret ; |
|
347 } |
|
348 |
|
349 destroy: |
|
350 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
351 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
352 } |
|
353 else |
|
354 { |
|
355 dev_p->mtp_count++ ; |
|
356 if (cb) |
|
357 cb(handle, ret, client, CY_FUNCT_CB_MTP_START, 0) ; |
|
358 } |
|
359 |
|
360 CyAsDeviceClearMSSPending(dev_p) ; |
|
361 |
|
362 return ret ; |
|
363 } |
|
364 |
|
365 static CyAsReturnStatus_t |
|
366 MyHandleResponseMTPStop(CyAsDevice* dev_p, |
|
367 CyAsLLRequestResponse *req_p, |
|
368 CyAsLLRequestResponse *reply_p, |
|
369 CyAsReturnStatus_t ret) |
|
370 { |
|
371 if (ret != CY_AS_ERROR_SUCCESS) |
|
372 goto destroy ; |
|
373 |
|
374 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
375 { |
|
376 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
377 goto destroy ; |
|
378 } |
|
379 |
|
380 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
381 if (ret != CY_AS_ERROR_SUCCESS) |
|
382 goto destroy ; |
|
383 |
|
384 /* |
|
385 * We sucessfully shutdown the stack, so decrement to make the count |
|
386 * zero. |
|
387 */ |
|
388 dev_p->mtp_count-- ; |
|
389 |
|
390 destroy : |
|
391 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
392 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
393 |
|
394 if (ret != CY_AS_ERROR_SUCCESS) |
|
395 CyAsLLRegisterRequestCallback(dev_p, CY_RQT_TUR_RQT_CONTEXT, 0) ; |
|
396 |
|
397 CyAsDeviceClearMSSPending(dev_p) ; |
|
398 |
|
399 return ret ; |
|
400 } |
|
401 |
|
402 CyAsReturnStatus_t |
|
403 CyAsMTPStop(CyAsDeviceHandle handle, |
|
404 CyAsFunctionCallback cb, |
|
405 uint32_t client |
|
406 ) |
|
407 { |
|
408 CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ; |
|
409 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
410 |
|
411 CyAsDevice*dev_p ; |
|
412 |
|
413 CyAsLogDebugMessage(6, "CyAsMTPStop called") ; |
|
414 |
|
415 dev_p = (CyAsDevice *)handle ; |
|
416 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
417 return CY_AS_ERROR_INVALID_HANDLE ; |
|
418 |
|
419 ret = IsMTPActive(dev_p) ; |
|
420 if (ret != CY_AS_ERROR_SUCCESS) |
|
421 return ret ; |
|
422 |
|
423 if (CyAsDeviceIsInCallback(dev_p)) |
|
424 return CY_AS_ERROR_INVALID_IN_CALLBACK ; |
|
425 |
|
426 if(CyAsDeviceIsMSSPending(dev_p)) |
|
427 return CY_AS_ERROR_STARTSTOP_PENDING ; |
|
428 |
|
429 CyAsDeviceSetMSSPending(dev_p) ; |
|
430 |
|
431 if (dev_p->mtp_count == 1) |
|
432 { |
|
433 /* Create the request to send to the West Bridge device */ |
|
434 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_STOP_MTP, CY_RQT_TUR_RQT_CONTEXT, 0) ; |
|
435 if (req_p == 0) |
|
436 { |
|
437 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
438 goto destroy ; |
|
439 } |
|
440 |
|
441 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
442 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
443 if (reply_p == 0) |
|
444 { |
|
445 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
446 goto destroy ; |
|
447 } |
|
448 |
|
449 if(cb == 0) |
|
450 { |
|
451 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
452 if (ret != CY_AS_ERROR_SUCCESS) |
|
453 goto destroy ; |
|
454 |
|
455 return MyHandleResponseMTPStop(dev_p, req_p, reply_p, ret) ; |
|
456 } |
|
457 else |
|
458 { |
|
459 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_STOP, |
|
460 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, |
|
461 CyAsMTPFuncCallback) ; |
|
462 |
|
463 if (ret != CY_AS_ERROR_SUCCESS) |
|
464 goto destroy ; |
|
465 |
|
466 return ret ; |
|
467 } |
|
468 |
|
469 destroy: |
|
470 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
471 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
472 } |
|
473 else if (dev_p->mtp_count > 1) |
|
474 { |
|
475 |
|
476 dev_p->mtp_count-- ; |
|
477 |
|
478 if (cb) |
|
479 cb(handle, ret, client, CY_FUNCT_CB_MTP_STOP, 0) ; |
|
480 } |
|
481 |
|
482 CyAsDeviceClearMSSPending(dev_p) ; |
|
483 |
|
484 return ret ; |
|
485 } |
|
486 |
|
487 static void |
|
488 MtpWriteCallback( |
|
489 CyAsDevice *dev_p, |
|
490 uint8_t context, |
|
491 CyAsLLRequestResponse *rqt, |
|
492 CyAsLLRequestResponse *resp, |
|
493 CyAsReturnStatus_t ret) |
|
494 { |
|
495 CyAsHalAssert(context == CY_RQT_TUR_RQT_CONTEXT) ; |
|
496 |
|
497 if (ret == CY_AS_ERROR_SUCCESS) |
|
498 { |
|
499 if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE) |
|
500 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
501 else |
|
502 ret = CyAsLLRequestResponse_GetWord(resp, 0) ; |
|
503 } |
|
504 |
|
505 if (ret != CY_AS_ERROR_SUCCESS) |
|
506 { |
|
507 /* Firmware failed the request. Cancel the DMA transfer. */ |
|
508 CyAsDmaCancel(dev_p, 0x04, CY_AS_ERROR_CANCELED) ; |
|
509 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
510 } |
|
511 |
|
512 CyAsLLDestroyResponse(dev_p, resp) ; |
|
513 CyAsLLDestroyRequest(dev_p, rqt) ; |
|
514 } |
|
515 |
|
516 static void |
|
517 AsyncWriteRequestCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err) |
|
518 { |
|
519 CyAsDeviceHandle h ; |
|
520 CyAsFunctionCallback cb ; |
|
521 |
|
522 (void)size ; |
|
523 (void)buf_p ; |
|
524 (void)ep ; |
|
525 |
|
526 |
|
527 CyAsLogDebugMessage(6, "AsyncWriteRequestCallback called") ; |
|
528 |
|
529 h = (CyAsDeviceHandle)dev_p ; |
|
530 |
|
531 cb = dev_p->mtp_cb ; |
|
532 dev_p->mtp_cb = 0 ; |
|
533 |
|
534 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
535 |
|
536 if (cb) |
|
537 cb(h, err, dev_p->mtp_client, dev_p->mtp_op, 0) ; |
|
538 |
|
539 } |
|
540 |
|
541 static void |
|
542 SyncMTPCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err) |
|
543 { |
|
544 (void)ep ; |
|
545 (void)buf_p ; |
|
546 (void)size ; |
|
547 |
|
548 dev_p->mtp_error = err ; |
|
549 } |
|
550 |
|
551 static CyAsReturnStatus_t |
|
552 CyAsMTPOperation(CyAsDevice *dev_p, |
|
553 CyAsMTPBlockTable* blk_table, |
|
554 uint32_t num_bytes, |
|
555 uint32_t transaction_id, |
|
556 CyAsFunctionCallback cb, |
|
557 uint32_t client, |
|
558 uint8_t rqttype |
|
559 ) |
|
560 { |
|
561 CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ; |
|
562 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
563 uint32_t mask = 0 ; |
|
564 CyAsFunctCBType mtp_cb_op = (CyAsFunctCBType)0 ; |
|
565 uint16_t size = 2 ; |
|
566 |
|
567 if(dev_p->mtp_count == 0) |
|
568 return CY_AS_ERROR_NOT_RUNNING ; |
|
569 |
|
570 if (rqttype == CY_RQT_INIT_SEND_OBJECT) |
|
571 { |
|
572 mtp_cb_op = CY_FUNCT_CB_MTP_INIT_SEND_OBJECT ; |
|
573 dev_p->mtp_turbo_active = CyTrue ; |
|
574 } |
|
575 else if (rqttype == CY_RQT_INIT_GET_OBJECT) |
|
576 { |
|
577 mtp_cb_op = CY_FUNCT_CB_MTP_INIT_GET_OBJECT ; |
|
578 dev_p->mtp_turbo_active = CyTrue ; |
|
579 } |
|
580 else |
|
581 mtp_cb_op = CY_FUNCT_CB_MTP_SEND_BLOCK_TABLE ; |
|
582 |
|
583 ret = IsMTPActive(dev_p) ; |
|
584 if (ret != CY_AS_ERROR_SUCCESS) |
|
585 return ret ; |
|
586 |
|
587 if (CY_RQT_INIT_GET_OBJECT == rqttype) |
|
588 { |
|
589 size = 4 ; |
|
590 } |
|
591 /* Create the request to send to the West Bridge device */ |
|
592 req_p = CyAsLLCreateRequest(dev_p, rqttype, CY_RQT_TUR_RQT_CONTEXT, size) ; |
|
593 if (req_p == 0) |
|
594 { |
|
595 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
596 goto destroy ; |
|
597 } |
|
598 |
|
599 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
600 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
601 if (reply_p == 0) |
|
602 { |
|
603 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
604 goto destroy ; |
|
605 } |
|
606 |
|
607 CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)(num_bytes & 0xFFFF)) ; |
|
608 CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((num_bytes >> 16) & 0xFFFF)) ; |
|
609 |
|
610 /* If it is GET_OBJECT, send transaction id as well */ |
|
611 if (CY_RQT_INIT_GET_OBJECT == rqttype) |
|
612 { |
|
613 CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(transaction_id & 0xFFFF)) ; |
|
614 CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((transaction_id >> 16) & 0xFFFF)) ; |
|
615 } |
|
616 |
|
617 if(cb == 0) |
|
618 { |
|
619 /* Queue the DMA request for block table write */ |
|
620 ret = CyAsDmaQueueRequest(dev_p, 4, blk_table, sizeof(CyAsMTPBlockTable), CyFalse, CyFalse, SyncMTPCallback) ; |
|
621 |
|
622 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
623 if (ret != CY_AS_ERROR_SUCCESS) |
|
624 { |
|
625 CyAsDmaCancel(dev_p, 4, CY_AS_ERROR_CANCELED) ; |
|
626 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
627 |
|
628 goto destroy ; |
|
629 } |
|
630 |
|
631 ret = CyAsDmaDrainQueue(dev_p, 4, CyTrue) ; |
|
632 if (ret != CY_AS_ERROR_SUCCESS) |
|
633 goto destroy ; |
|
634 |
|
635 ret = dev_p->mtp_error ; |
|
636 goto destroy ; |
|
637 } |
|
638 else |
|
639 { |
|
640 #if 0 |
|
641 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_INIT_SEND_OBJECT, |
|
642 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, |
|
643 CyAsMTPFuncCallback) ; |
|
644 |
|
645 if (ret != CY_AS_ERROR_SUCCESS) |
|
646 goto destroy ; |
|
647 #endif |
|
648 |
|
649 /* Protection from interrupt driven code */ |
|
650 /* since we are using storage EP4 check if any storage activity is pending */ |
|
651 mask = CyAsHalDisableInterrupts() ; |
|
652 if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait)) |
|
653 { |
|
654 CyAsHalEnableInterrupts(mask) ; |
|
655 return CY_AS_ERROR_ASYNC_PENDING ; |
|
656 } |
|
657 CyAsDeviceSetStorageAsyncPending(dev_p) ; |
|
658 CyAsHalEnableInterrupts(mask) ; |
|
659 |
|
660 dev_p->mtp_cb = cb ; |
|
661 dev_p->mtp_client = client ; |
|
662 dev_p->mtp_op = mtp_cb_op ; |
|
663 |
|
664 ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MtpWriteCallback) ; |
|
665 if (ret != CY_AS_ERROR_SUCCESS) |
|
666 goto destroy ; |
|
667 |
|
668 ret = CyAsDmaQueueRequest(dev_p, 4, blk_table, sizeof(CyAsMTPBlockTable), CyFalse, CyFalse, AsyncWriteRequestCallback) ; |
|
669 if (ret != CY_AS_ERROR_SUCCESS) |
|
670 return ret ; |
|
671 |
|
672 /* Kick start the queue if it is not running */ |
|
673 CyAsDmaKickStart(dev_p, 4) ; |
|
674 |
|
675 return CY_AS_ERROR_SUCCESS ; |
|
676 } |
|
677 |
|
678 destroy: |
|
679 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
680 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
681 |
|
682 return ret ; |
|
683 } |
|
684 |
|
685 CyAsReturnStatus_t |
|
686 CyAsMTPInitSendObject(CyAsDeviceHandle handle, |
|
687 CyAsMTPBlockTable* blk_table, |
|
688 uint32_t num_bytes, |
|
689 CyAsFunctionCallback cb, |
|
690 uint32_t client |
|
691 ) |
|
692 { |
|
693 CyAsDevice* dev_p ; |
|
694 dev_p = (CyAsDevice *)handle ; |
|
695 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
696 return CY_AS_ERROR_INVALID_HANDLE ; |
|
697 |
|
698 return CyAsMTPOperation(dev_p, blk_table, num_bytes, 0, cb, client, CY_RQT_INIT_SEND_OBJECT) ; |
|
699 |
|
700 } |
|
701 |
|
702 CyAsReturnStatus_t |
|
703 CyAsMTPInitGetObject(CyAsDeviceHandle handle, |
|
704 CyAsMTPBlockTable* blk_table, |
|
705 uint32_t num_bytes, |
|
706 uint32_t transaction_id, |
|
707 CyAsFunctionCallback cb, |
|
708 uint32_t client |
|
709 ) |
|
710 { |
|
711 CyAsDevice* dev_p ; |
|
712 dev_p = (CyAsDevice *)handle ; |
|
713 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
714 return CY_AS_ERROR_INVALID_HANDLE ; |
|
715 |
|
716 return CyAsMTPOperation(dev_p, blk_table, num_bytes, transaction_id, cb, client, CY_RQT_INIT_GET_OBJECT) ; |
|
717 |
|
718 } |
|
719 |
|
720 static CyAsReturnStatus_t |
|
721 MyHandleResponseCancelSendObject(CyAsDevice* dev_p, |
|
722 CyAsLLRequestResponse *req_p, |
|
723 CyAsLLRequestResponse *reply_p, |
|
724 CyAsReturnStatus_t ret) |
|
725 { |
|
726 if (ret != CY_AS_ERROR_SUCCESS) |
|
727 goto destroy ; |
|
728 |
|
729 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
730 { |
|
731 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
732 goto destroy ; |
|
733 } |
|
734 |
|
735 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
736 if (ret != CY_AS_ERROR_SUCCESS) |
|
737 goto destroy ; |
|
738 |
|
739 |
|
740 destroy : |
|
741 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
742 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
743 |
|
744 return ret ; |
|
745 } |
|
746 |
|
747 CyAsReturnStatus_t |
|
748 CyAsMTPCancelSendObject(CyAsDeviceHandle handle, |
|
749 CyAsFunctionCallback cb, |
|
750 uint32_t client |
|
751 ) |
|
752 { |
|
753 CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ; |
|
754 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
755 CyAsDevice*dev_p ; |
|
756 |
|
757 dev_p = (CyAsDevice *)handle ; |
|
758 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
759 return CY_AS_ERROR_INVALID_HANDLE ; |
|
760 |
|
761 if(dev_p->mtp_count == 0) |
|
762 return CY_AS_ERROR_NOT_RUNNING ; |
|
763 |
|
764 /* Create the request to send to the West Bridge device */ |
|
765 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CANCEL_SEND_OBJECT, CY_RQT_TUR_RQT_CONTEXT, 0) ; |
|
766 if (req_p == 0) |
|
767 { |
|
768 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
769 goto destroy ; |
|
770 } |
|
771 |
|
772 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
773 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
774 if (reply_p == 0) |
|
775 { |
|
776 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
777 goto destroy ; |
|
778 } |
|
779 |
|
780 if(cb == 0) |
|
781 { |
|
782 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
783 if (ret != CY_AS_ERROR_SUCCESS) |
|
784 goto destroy ; |
|
785 |
|
786 return MyHandleResponseCancelSendObject(dev_p, req_p, reply_p, ret) ; |
|
787 } |
|
788 else |
|
789 { |
|
790 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_CANCEL_SEND_OBJECT, |
|
791 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, |
|
792 CyAsMTPFuncCallback) ; |
|
793 |
|
794 if (ret != CY_AS_ERROR_SUCCESS) |
|
795 goto destroy ; |
|
796 |
|
797 return ret ; |
|
798 } |
|
799 |
|
800 destroy : |
|
801 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
802 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
803 |
|
804 return ret ; |
|
805 } |
|
806 |
|
807 static CyAsReturnStatus_t |
|
808 MyHandleResponseCancelGetObject(CyAsDevice* dev_p, |
|
809 CyAsLLRequestResponse *req_p, |
|
810 CyAsLLRequestResponse *reply_p, |
|
811 CyAsReturnStatus_t ret) |
|
812 { |
|
813 if (ret != CY_AS_ERROR_SUCCESS) |
|
814 goto destroy ; |
|
815 |
|
816 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
817 { |
|
818 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
819 goto destroy ; |
|
820 } |
|
821 |
|
822 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
823 if (ret != CY_AS_ERROR_SUCCESS) |
|
824 goto destroy ; |
|
825 |
|
826 |
|
827 destroy : |
|
828 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
829 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
830 |
|
831 return ret ; |
|
832 } |
|
833 |
|
834 CyAsReturnStatus_t |
|
835 CyAsMTPCancelGetObject(CyAsDeviceHandle handle, |
|
836 CyAsFunctionCallback cb, |
|
837 uint32_t client |
|
838 ) |
|
839 { |
|
840 CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ; |
|
841 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
842 CyAsDevice*dev_p ; |
|
843 |
|
844 dev_p = (CyAsDevice *)handle ; |
|
845 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
846 return CY_AS_ERROR_INVALID_HANDLE ; |
|
847 |
|
848 if(dev_p->mtp_count == 0) |
|
849 return CY_AS_ERROR_NOT_RUNNING ; |
|
850 |
|
851 /* Create the request to send to the West Bridge device */ |
|
852 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CANCEL_GET_OBJECT, CY_RQT_TUR_RQT_CONTEXT, 0) ; |
|
853 if (req_p == 0) |
|
854 { |
|
855 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
856 goto destroy ; |
|
857 } |
|
858 |
|
859 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
860 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
861 if (reply_p == 0) |
|
862 { |
|
863 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
864 goto destroy ; |
|
865 } |
|
866 |
|
867 if(cb == 0) |
|
868 { |
|
869 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
870 if (ret != CY_AS_ERROR_SUCCESS) |
|
871 goto destroy ; |
|
872 |
|
873 return MyHandleResponseCancelGetObject(dev_p, req_p, reply_p, ret) ; |
|
874 } |
|
875 else |
|
876 { |
|
877 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_CANCEL_GET_OBJECT, |
|
878 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, |
|
879 CyAsMTPFuncCallback) ; |
|
880 |
|
881 if (ret != CY_AS_ERROR_SUCCESS) |
|
882 goto destroy ; |
|
883 |
|
884 return ret ; |
|
885 } |
|
886 |
|
887 destroy: |
|
888 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
889 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
890 |
|
891 return ret ; |
|
892 } |
|
893 |
|
894 CyAsReturnStatus_t |
|
895 CyAsMTPSendBlockTable(CyAsDeviceHandle handle, |
|
896 CyAsMTPBlockTable* blk_table, |
|
897 CyAsFunctionCallback cb, |
|
898 uint32_t client |
|
899 ) |
|
900 { |
|
901 CyAsDevice* dev_p ; |
|
902 dev_p = (CyAsDevice *)handle ; |
|
903 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
904 return CY_AS_ERROR_INVALID_HANDLE ; |
|
905 |
|
906 return CyAsMTPOperation(dev_p, blk_table, 0, 0, cb, client, CY_RQT_SEND_BLOCK_TABLE) ; |
|
907 } |
|
908 |
|
909 static void |
|
910 CyAsMTPFuncCallback(CyAsDevice *dev_p, |
|
911 uint8_t context, |
|
912 CyAsLLRequestResponse *rqt, |
|
913 CyAsLLRequestResponse *resp, |
|
914 CyAsReturnStatus_t stat) |
|
915 { |
|
916 CyAsFuncCBNode* node = (CyAsFuncCBNode*)dev_p->func_cbs_mtp->head_p ; |
|
917 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
918 uint8_t code ; |
|
919 CyBool delay_callback = CyFalse ; |
|
920 |
|
921 CyAsHalAssert(dev_p->func_cbs_mtp->count != 0) ; |
|
922 CyAsHalAssert(dev_p->func_cbs_mtp->type == CYAS_FUNC_CB) ; |
|
923 |
|
924 (void)context ; |
|
925 |
|
926 /* The Handlers are responsible for Deleting the rqt and resp when |
|
927 * they are finished |
|
928 */ |
|
929 code = CyAsLLRequestResponse_GetCode(rqt) ; |
|
930 switch(code) |
|
931 { |
|
932 case CY_RQT_START_MTP: |
|
933 ret = MyHandleResponseMTPStart(dev_p, rqt, resp, stat) ; |
|
934 break ; |
|
935 case CY_RQT_STOP_MTP: |
|
936 ret = MyHandleResponseMTPStop(dev_p, rqt, resp, stat) ; |
|
937 break ; |
|
938 #if 0 |
|
939 case CY_RQT_INIT_SEND_OBJECT: |
|
940 ret = MyHandleResponseInitSendObject(dev_p, rqt, resp, stat, CyTrue) ; |
|
941 delay_callback = CyTrue ; |
|
942 break ; |
|
943 #endif |
|
944 case CY_RQT_CANCEL_SEND_OBJECT: |
|
945 ret = MyHandleResponseCancelSendObject(dev_p, rqt, resp, stat) ; |
|
946 break ; |
|
947 #if 0 |
|
948 case CY_RQT_INIT_GET_OBJECT: |
|
949 ret = MyHandleResponseInitGetObject(dev_p, rqt, resp, stat, CyTrue) ; |
|
950 delay_callback = CyTrue ; |
|
951 break ; |
|
952 #endif |
|
953 case CY_RQT_CANCEL_GET_OBJECT: |
|
954 ret = MyHandleResponseCancelGetObject(dev_p, rqt, resp, stat) ; |
|
955 break ; |
|
956 #if 0 |
|
957 case CY_RQT_SEND_BLOCK_TABLE: |
|
958 ret = MyHandleResponseSendBlockTable(dev_p, rqt, resp, stat, CyTrue) ; |
|
959 delay_callback = CyTrue ; |
|
960 break ; |
|
961 #endif |
|
962 case CY_RQT_ENABLE_USB_PATH: |
|
963 ret = MyHandleResponseNoData(dev_p, rqt, resp) ; |
|
964 if (ret == CY_AS_ERROR_SUCCESS) |
|
965 dev_p->is_storage_only_mode = CyFalse ; |
|
966 break ; |
|
967 default: |
|
968 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
969 CyAsHalAssert(CyFalse) ; |
|
970 break ; |
|
971 } |
|
972 |
|
973 /* |
|
974 * If the low level layer returns a direct error, use the corresponding error code. |
|
975 * If not, use the error code based on the response from firmware. |
|
976 */ |
|
977 if (stat == CY_AS_ERROR_SUCCESS) |
|
978 stat = ret ; |
|
979 |
|
980 if(!delay_callback) |
|
981 { |
|
982 node->cb_p((CyAsDeviceHandle)dev_p, stat, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ; |
|
983 CyAsRemoveCBNode(dev_p->func_cbs_mtp) ; |
|
984 } |
|
985 } |
|
986 |
|
987 CyAsReturnStatus_t |
|
988 CyAsMTPStorageOnlyStart(CyAsDeviceHandle handle) |
|
989 { |
|
990 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
991 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
992 return CY_AS_ERROR_INVALID_HANDLE ; |
|
993 |
|
994 if (!CyAsDeviceIsConfigured(dev_p)) |
|
995 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
996 |
|
997 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
998 return CY_AS_ERROR_NO_FIRMWARE ; |
|
999 |
|
1000 if (dev_p->storage_count == 0) |
|
1001 return CY_AS_ERROR_NOT_RUNNING ; |
|
1002 |
|
1003 dev_p->is_storage_only_mode = CyTrue ; |
|
1004 return CY_AS_ERROR_SUCCESS ; |
|
1005 } |
|
1006 |
|
1007 CyAsReturnStatus_t |
|
1008 CyAsMTPStorageOnlyStop(CyAsDeviceHandle handle, |
|
1009 CyAsFunctionCallback cb, |
|
1010 uint32_t client) |
|
1011 { |
|
1012 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1013 CyAsLLRequestResponse *req_p, *reply_p ; |
|
1014 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1015 |
|
1016 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
1017 return CY_AS_ERROR_INVALID_HANDLE ; |
|
1018 |
|
1019 if (!CyAsDeviceIsConfigured(dev_p)) |
|
1020 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
1021 |
|
1022 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
1023 return CY_AS_ERROR_NO_FIRMWARE ; |
|
1024 |
|
1025 if (dev_p->storage_count == 0) |
|
1026 return CY_AS_ERROR_NOT_RUNNING ; |
|
1027 |
|
1028 if (dev_p->is_storage_only_mode == CyFalse) |
|
1029 return CY_AS_ERROR_SUCCESS ; |
|
1030 |
|
1031 if (CyAsDeviceIsInCallback(dev_p)) |
|
1032 return CY_AS_ERROR_INVALID_IN_CALLBACK ; |
|
1033 |
|
1034 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ENABLE_USB_PATH, CY_RQT_TUR_RQT_CONTEXT, 1) ; |
|
1035 if (req_p == 0) |
|
1036 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1037 |
|
1038 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
1039 if (reply_p == 0) |
|
1040 { |
|
1041 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1042 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1043 } |
|
1044 |
|
1045 if(cb == 0) |
|
1046 { |
|
1047 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
1048 if (ret != CY_AS_ERROR_SUCCESS) |
|
1049 goto destroy ; |
|
1050 |
|
1051 ret = MyHandleResponseNoData(dev_p, req_p, reply_p) ; |
|
1052 if (ret == CY_AS_ERROR_SUCCESS) |
|
1053 dev_p->is_storage_only_mode = CyFalse ; |
|
1054 return ret ; |
|
1055 } |
|
1056 else |
|
1057 { |
|
1058 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_STOP_STORAGE_ONLY, |
|
1059 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, |
|
1060 CyAsMTPFuncCallback) ; |
|
1061 |
|
1062 if (ret != CY_AS_ERROR_SUCCESS) |
|
1063 goto destroy ; |
|
1064 |
|
1065 return ret ; |
|
1066 } |
|
1067 |
|
1068 destroy: |
|
1069 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1070 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1071 |
|
1072 return ret ; |
|
1073 } |