|
1 /* Cypress West Bridge API source file (cyasstorage.c) |
|
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 /* |
|
23 * Storage Design |
|
24 * |
|
25 * The storage module is fairly straight forward once the DMA and LOWLEVEL modules |
|
26 * have been designed. The storage module simple takes requests from the user, queues the |
|
27 * associated DMA requests for action, and then sends the low level requests to the |
|
28 * West Bridge firmware. |
|
29 * |
|
30 */ |
|
31 |
|
32 #include "cyashal.h" |
|
33 #include "cyasstorage.h" |
|
34 #include "cyaserr.h" |
|
35 #include "cyasdevice.h" |
|
36 #include "cyaslowlevel.h" |
|
37 #include "cyasdma.h" |
|
38 #include "cyasregs.h" |
|
39 |
|
40 /* Map a pre-V1.2 media type to the V1.2+ bus number */ |
|
41 CyAsReturnStatus_t |
|
42 CyAnMapBusFromMediaType(CyAsDevice *dev_p, CyAsMediaType type, CyAsBusNumber_t *bus) |
|
43 { |
|
44 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
45 uint8_t code = (uint8_t)(1 << type) ; |
|
46 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
47 return CY_AS_ERROR_INVALID_HANDLE ; |
|
48 |
|
49 if (!CyAsDeviceIsConfigured(dev_p)) |
|
50 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
51 |
|
52 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
53 return CY_AS_ERROR_NO_FIRMWARE ; |
|
54 |
|
55 |
|
56 if (dev_p->media_supported[0] & code) |
|
57 { |
|
58 if (dev_p->media_supported[1] & code) |
|
59 { |
|
60 /* |
|
61 * This media type could be supported on multiple buses. So, report |
|
62 * an address resolution error. |
|
63 */ |
|
64 ret = CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR ; |
|
65 } |
|
66 else |
|
67 *bus = 0 ; |
|
68 } |
|
69 else |
|
70 { |
|
71 if (dev_p->media_supported[1] & code) |
|
72 *bus = 1 ; |
|
73 else |
|
74 ret = CY_AS_ERROR_NO_SUCH_MEDIA ; |
|
75 } |
|
76 |
|
77 return ret ; |
|
78 } |
|
79 |
|
80 static uint16_t |
|
81 CreateAddress(CyAsBusNumber_t bus, uint32_t device, uint8_t unit) |
|
82 { |
|
83 CyAsHalAssert(bus >= 0 && bus < CY_AS_MAX_BUSES) ; |
|
84 CyAsHalAssert(device < 16) ; |
|
85 |
|
86 return (uint16_t)(((uint8_t)bus << 12) | (device << 8) | unit) ; |
|
87 } |
|
88 |
|
89 CyAsMediaType |
|
90 CyAsStorageGetMediaFromAddress(uint16_t v) |
|
91 { |
|
92 CyAsMediaType media = CyAsMediaMaxMediaValue ; |
|
93 |
|
94 switch(v & 0xFF) |
|
95 { |
|
96 case 0x00: |
|
97 break; |
|
98 case 0x01: |
|
99 media = CyAsMediaNand ; |
|
100 break ; |
|
101 case 0x02: |
|
102 media = CyAsMediaSDFlash ; |
|
103 break ; |
|
104 case 0x04: |
|
105 media = CyAsMediaMMCFlash ; |
|
106 break ; |
|
107 case 0x08: |
|
108 media = CyAsMediaCEATA ; |
|
109 break ; |
|
110 case 0x10: |
|
111 media = CyAsMediaSDIO ; |
|
112 break ; |
|
113 default: |
|
114 CyAsHalAssert(0) ; |
|
115 break ; |
|
116 } |
|
117 |
|
118 return media ; |
|
119 } |
|
120 |
|
121 CyAsBusNumber_t |
|
122 CyAsStorageGetBusFromAddress(uint16_t v) |
|
123 { |
|
124 CyAsBusNumber_t bus = (CyAsBusNumber_t)((v >> 12) & 0x0f) ; |
|
125 CyAsHalAssert(bus >= 0 && bus < CY_AS_MAX_BUSES) ; |
|
126 return bus ; |
|
127 } |
|
128 |
|
129 uint32_t |
|
130 CyAsStorageGetDeviceFromAddress(uint16_t v) |
|
131 { |
|
132 return (uint32_t)((v >> 8) & 0x0f) ; |
|
133 } |
|
134 |
|
135 static uint8_t |
|
136 GetUnitFromAddress(uint16_t v) |
|
137 { |
|
138 return (uint8_t)(v & 0xff) ; |
|
139 } |
|
140 |
|
141 static CyAsReturnStatus_t |
|
142 CyAsMapBadAddr(uint16_t val) |
|
143 { |
|
144 CyAsReturnStatus_t ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
145 |
|
146 switch(val) |
|
147 { |
|
148 case 0: |
|
149 ret = CY_AS_ERROR_NO_SUCH_BUS ; |
|
150 break ; |
|
151 case 1: |
|
152 ret = CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
153 break ; |
|
154 case 2: |
|
155 ret = CY_AS_ERROR_NO_SUCH_UNIT ; |
|
156 break ; |
|
157 case 3: |
|
158 ret = CY_AS_ERROR_INVALID_BLOCK ; |
|
159 break ; |
|
160 } |
|
161 |
|
162 return ret ; |
|
163 } |
|
164 |
|
165 static void |
|
166 MyStorageRequestCallback(CyAsDevice *dev_p, uint8_t context, CyAsLLRequestResponse *req_p, |
|
167 CyAsLLRequestResponse *resp_p, CyAsReturnStatus_t ret) |
|
168 { |
|
169 uint16_t val ; |
|
170 uint16_t addr ; |
|
171 CyAsBusNumber_t bus; |
|
172 uint32_t device; |
|
173 CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ; |
|
174 CyAsDmaEndPoint *ep_p = NULL ; |
|
175 |
|
176 (void)resp_p ; |
|
177 (void)context ; |
|
178 (void)ret ; |
|
179 |
|
180 switch(CyAsLLRequestResponse_GetCode(req_p)) |
|
181 { |
|
182 case CY_RQT_MEDIA_CHANGED: |
|
183 CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ; |
|
184 |
|
185 /* Media has either been inserted or removed */ |
|
186 addr = CyAsLLRequestResponse_GetWord(req_p, 0) ; |
|
187 |
|
188 bus = CyAsStorageGetBusFromAddress(addr); |
|
189 device = CyAsStorageGetDeviceFromAddress(addr); |
|
190 |
|
191 /* Clear the entry for this device to force re-query later */ |
|
192 CyAsHalMemSet(&(dev_p->storage_device_info[bus][device]), 0, |
|
193 sizeof(dev_p->storage_device_info[bus][device])) ; |
|
194 |
|
195 val = CyAsLLRequestResponse_GetWord(req_p, 1) ; |
|
196 if (dev_p->storage_event_cb_ms) |
|
197 { |
|
198 if (val == 1) |
|
199 dev_p->storage_event_cb_ms(h, bus, device, CyAsStorageRemoved, 0) ; |
|
200 else |
|
201 dev_p->storage_event_cb_ms(h, bus, device, CyAsStorageInserted, 0) ; |
|
202 } |
|
203 else if (dev_p->storage_event_cb) |
|
204 { |
|
205 if (val == 1) |
|
206 dev_p->storage_event_cb(h, (CyAsMediaType)bus, CyAsStorageRemoved, 0) ; /*nxz*/ |
|
207 else |
|
208 dev_p->storage_event_cb(h, (CyAsMediaType)bus, CyAsStorageInserted, 0) ; /*nxz*/ |
|
209 } |
|
210 |
|
211 break ; |
|
212 |
|
213 case CY_RQT_ANTIOCH_CLAIM: |
|
214 CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ; |
|
215 if (dev_p->storage_event_cb || dev_p->storage_event_cb_ms) |
|
216 { |
|
217 val = CyAsLLRequestResponse_GetWord(req_p, 0) ; |
|
218 if (dev_p->storage_event_cb_ms) |
|
219 { |
|
220 if (val & 0x0100) |
|
221 dev_p->storage_event_cb_ms(h, 0, 0, CyAsStorageAntioch, 0) ; |
|
222 if (val & 0x0200) |
|
223 dev_p->storage_event_cb_ms(h, 1, 0, CyAsStorageAntioch, 0) ; |
|
224 } |
|
225 else |
|
226 { |
|
227 if (val & 0x01) |
|
228 dev_p->storage_event_cb(h, CyAsMediaNand, CyAsStorageAntioch, 0) ; |
|
229 if (val & 0x02) |
|
230 dev_p->storage_event_cb(h, CyAsMediaSDFlash, CyAsStorageAntioch, 0) ; |
|
231 if (val & 0x04) |
|
232 dev_p->storage_event_cb(h, CyAsMediaMMCFlash, CyAsStorageAntioch, 0) ; |
|
233 if (val & 0x08) |
|
234 dev_p->storage_event_cb(h, CyAsMediaCEATA, CyAsStorageAntioch, 0) ; |
|
235 } |
|
236 } |
|
237 break ; |
|
238 |
|
239 case CY_RQT_ANTIOCH_RELEASE: |
|
240 CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ; |
|
241 val = CyAsLLRequestResponse_GetWord(req_p, 0) ; |
|
242 if (dev_p->storage_event_cb_ms) |
|
243 { |
|
244 if (val & 0x0100) |
|
245 dev_p->storage_event_cb_ms(h, 0, 0, CyAsStorageProcessor, 0) ; |
|
246 if (val & 0x0200) |
|
247 dev_p->storage_event_cb_ms(h, 1, 0, CyAsStorageProcessor, 0) ; |
|
248 } |
|
249 else if (dev_p->storage_event_cb) |
|
250 { |
|
251 if (val & 0x01) |
|
252 dev_p->storage_event_cb(h, CyAsMediaNand, CyAsStorageProcessor, 0) ; |
|
253 if (val & 0x02) |
|
254 dev_p->storage_event_cb(h, CyAsMediaSDFlash, CyAsStorageProcessor, 0) ; |
|
255 if (val & 0x04) |
|
256 dev_p->storage_event_cb(h, CyAsMediaMMCFlash, CyAsStorageProcessor, 0) ; |
|
257 if (val & 0x08) |
|
258 dev_p->storage_event_cb(h, CyAsMediaCEATA, CyAsStorageProcessor, 0) ; |
|
259 } |
|
260 break ; |
|
261 |
|
262 |
|
263 case CY_RQT_SDIO_INTR: |
|
264 CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ; |
|
265 val = CyAsLLRequestResponse_GetWord(req_p, 0) ; |
|
266 if (dev_p->storage_event_cb_ms) |
|
267 { |
|
268 if (val & 0x0100) |
|
269 dev_p->storage_event_cb_ms(h, 1, 0, CyAsSdioInterrupt, 0) ; |
|
270 else |
|
271 dev_p->storage_event_cb_ms(h, 0, 0, CyAsSdioInterrupt, 0) ; |
|
272 |
|
273 } |
|
274 else if (dev_p->storage_event_cb) |
|
275 { |
|
276 dev_p->storage_event_cb(h, CyAsMediaSDIO, CyAsSdioInterrupt, 0) ; |
|
277 } |
|
278 break; |
|
279 |
|
280 case CY_RQT_P2S_DMA_START: |
|
281 /* Do the DMA setup for the waiting operation. This event is used only in |
|
282 * the MTP mode firmware. */ |
|
283 CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ; |
|
284 if (dev_p->storage_oper == CyAsOpRead) |
|
285 { |
|
286 ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_READ_ENDPOINT) ; |
|
287 CyAsDmaEndPointSetStopped(ep_p) ; |
|
288 CyAsDmaKickStart(dev_p, CY_AS_P2S_READ_ENDPOINT) ; |
|
289 } |
|
290 else |
|
291 { |
|
292 ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ; |
|
293 CyAsDmaEndPointSetStopped(ep_p) ; |
|
294 CyAsDmaKickStart(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ; |
|
295 } |
|
296 break ; |
|
297 |
|
298 default: |
|
299 CyAsHalPrintMessage("Invalid request received on storage context\n") ; |
|
300 val = req_p->box0 ; |
|
301 CyAsLLSendDataResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_RESP_INVALID_REQUEST, sizeof(val), &val) ; |
|
302 break ; |
|
303 } |
|
304 } |
|
305 |
|
306 static CyAsReturnStatus_t |
|
307 IsStorageActive(CyAsDevice *dev_p) |
|
308 { |
|
309 if (!CyAsDeviceIsConfigured(dev_p)) |
|
310 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
311 |
|
312 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
313 return CY_AS_ERROR_NO_FIRMWARE ; |
|
314 |
|
315 if (dev_p->storage_count == 0) |
|
316 return CY_AS_ERROR_NOT_RUNNING ; |
|
317 |
|
318 if (CyAsDeviceIsInSuspendMode(dev_p)) |
|
319 return CY_AS_ERROR_IN_SUSPEND ; |
|
320 |
|
321 return CY_AS_ERROR_SUCCESS ; |
|
322 } |
|
323 |
|
324 static void |
|
325 CyAsStorageFuncCallback(CyAsDevice *dev_p, |
|
326 uint8_t context, |
|
327 CyAsLLRequestResponse *rqt, |
|
328 CyAsLLRequestResponse *resp, |
|
329 CyAsReturnStatus_t ret) ; |
|
330 |
|
331 static CyAsReturnStatus_t |
|
332 MyHandleResponseNoData(CyAsDevice* dev_p, |
|
333 CyAsLLRequestResponse *req_p, |
|
334 CyAsLLRequestResponse *reply_p) |
|
335 { |
|
336 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
337 |
|
338 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
339 { |
|
340 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
341 goto destroy ; |
|
342 } |
|
343 |
|
344 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
345 |
|
346 destroy : |
|
347 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
348 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
349 |
|
350 return ret ; |
|
351 } |
|
352 |
|
353 static CyAsReturnStatus_t |
|
354 MyHandleResponseStorageStart(CyAsDevice* dev_p, |
|
355 CyAsLLRequestResponse *req_p, |
|
356 CyAsLLRequestResponse *reply_p, |
|
357 CyAsReturnStatus_t ret) |
|
358 { |
|
359 if (ret != CY_AS_ERROR_SUCCESS) |
|
360 goto destroy ; |
|
361 |
|
362 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
363 { |
|
364 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
365 goto destroy ; |
|
366 } |
|
367 |
|
368 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
369 if (dev_p->storage_count > 0 && ret == CY_AS_ERROR_ALREADY_RUNNING) |
|
370 ret = CY_AS_ERROR_SUCCESS ; |
|
371 |
|
372 ret = CyAsDmaEnableEndPoint(dev_p, CY_AS_P2S_WRITE_ENDPOINT, CyTrue, CyAsDirectionIn) ; |
|
373 if (ret != CY_AS_ERROR_SUCCESS) |
|
374 goto destroy ; |
|
375 |
|
376 ret = CyAsDmaSetMaxDmaSize(dev_p, CY_AS_P2S_WRITE_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ; |
|
377 if (ret != CY_AS_ERROR_SUCCESS) |
|
378 goto destroy ; |
|
379 |
|
380 ret = CyAsDmaEnableEndPoint(dev_p, CY_AS_P2S_READ_ENDPOINT, CyTrue, CyAsDirectionOut) ; |
|
381 if (ret != CY_AS_ERROR_SUCCESS) |
|
382 goto destroy ; |
|
383 |
|
384 ret = CyAsDmaSetMaxDmaSize(dev_p, CY_AS_P2S_READ_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ; |
|
385 if (ret != CY_AS_ERROR_SUCCESS) |
|
386 goto destroy ; |
|
387 |
|
388 CyAsLLRegisterRequestCallback(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, MyStorageRequestCallback) ; |
|
389 |
|
390 /* Create the request/response used for storage reads and writes. */ |
|
391 dev_p->storage_rw_req_p = CyAsLLCreateRequest(dev_p, 0, CY_RQT_STORAGE_RQT_CONTEXT, 5) ; |
|
392 if (dev_p->storage_rw_req_p == 0) |
|
393 { |
|
394 ret = CY_AS_ERROR_OUT_OF_MEMORY; |
|
395 goto destroy; |
|
396 } |
|
397 |
|
398 dev_p->storage_rw_resp_p = CyAsLLCreateResponse(dev_p, 5) ; |
|
399 if (dev_p->storage_rw_resp_p == 0) |
|
400 { |
|
401 CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ; |
|
402 ret = CY_AS_ERROR_OUT_OF_MEMORY ; |
|
403 } |
|
404 |
|
405 destroy : |
|
406 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
407 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
408 |
|
409 /* Increment the storage count only if the above functionality succeeds.*/ |
|
410 if (ret == CY_AS_ERROR_SUCCESS) |
|
411 { |
|
412 if (dev_p->storage_count == 0) |
|
413 { |
|
414 CyAsHalMemSet(dev_p->storage_device_info, 0, sizeof(dev_p->storage_device_info)) ; |
|
415 dev_p->is_storage_only_mode = CyFalse ; |
|
416 } |
|
417 |
|
418 dev_p->storage_count++ ; |
|
419 } |
|
420 |
|
421 CyAsDeviceClearSSSPending(dev_p) ; |
|
422 |
|
423 return ret ; |
|
424 } |
|
425 |
|
426 CyAsReturnStatus_t |
|
427 CyAsStorageStart(CyAsDeviceHandle handle, |
|
428 CyAsFunctionCallback cb, |
|
429 uint32_t client) |
|
430 { |
|
431 CyAsLLRequestResponse *req_p, *reply_p ; |
|
432 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
433 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
434 |
|
435 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
436 return CY_AS_ERROR_INVALID_HANDLE ; |
|
437 |
|
438 if (!CyAsDeviceIsConfigured(dev_p)) |
|
439 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
440 |
|
441 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
442 return CY_AS_ERROR_NO_FIRMWARE ; |
|
443 |
|
444 if (CyAsDeviceIsInSuspendMode(dev_p)) |
|
445 return CY_AS_ERROR_IN_SUSPEND ; |
|
446 |
|
447 if(CyAsDeviceIsSSSPending(dev_p)) |
|
448 return CY_AS_ERROR_STARTSTOP_PENDING ; |
|
449 |
|
450 CyAsDeviceSetSSSPending(dev_p) ; |
|
451 |
|
452 if (dev_p->storage_count == 0) |
|
453 { |
|
454 /* Create the request to send to the West Bridge device */ |
|
455 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_START_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
456 if (req_p == 0) |
|
457 { |
|
458 CyAsDeviceClearSSSPending(dev_p) ; |
|
459 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
460 } |
|
461 |
|
462 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
463 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
464 if (reply_p == 0) |
|
465 { |
|
466 CyAsDeviceClearSSSPending(dev_p) ; |
|
467 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
468 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
469 } |
|
470 |
|
471 if(cb == 0) |
|
472 { |
|
473 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
474 if (ret != CY_AS_ERROR_SUCCESS) |
|
475 goto destroy ; |
|
476 |
|
477 return MyHandleResponseStorageStart(dev_p, req_p, reply_p, ret) ; |
|
478 } |
|
479 else |
|
480 { |
|
481 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_START, |
|
482 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
483 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
484 |
|
485 if (ret != CY_AS_ERROR_SUCCESS) |
|
486 goto destroy ; |
|
487 |
|
488 /* The request and response are freed as part of the FuncCallback */ |
|
489 return ret ; |
|
490 } |
|
491 |
|
492 destroy: |
|
493 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
494 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
495 } |
|
496 else |
|
497 { |
|
498 dev_p->storage_count++ ; |
|
499 if (cb) |
|
500 cb(handle, ret, client, CY_FUNCT_CB_STOR_START, 0) ; |
|
501 } |
|
502 |
|
503 CyAsDeviceClearSSSPending(dev_p) ; |
|
504 |
|
505 return ret ; |
|
506 } |
|
507 |
|
508 |
|
509 static CyAsReturnStatus_t |
|
510 MyHandleResponseStorageStop(CyAsDevice* dev_p, |
|
511 CyAsLLRequestResponse *req_p, |
|
512 CyAsLLRequestResponse *reply_p, |
|
513 CyAsReturnStatus_t ret) |
|
514 { |
|
515 if (ret != CY_AS_ERROR_SUCCESS) |
|
516 goto destroy ; |
|
517 |
|
518 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
519 { |
|
520 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
521 goto destroy ; |
|
522 } |
|
523 |
|
524 destroy : |
|
525 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
526 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
527 |
|
528 if (ret == CY_AS_ERROR_SUCCESS) |
|
529 { |
|
530 CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ; |
|
531 CyAsLLDestroyResponse(dev_p, dev_p->storage_rw_resp_p) ; |
|
532 dev_p->storage_count-- ; |
|
533 } |
|
534 |
|
535 CyAsDeviceClearSSSPending(dev_p) ; |
|
536 |
|
537 return ret ; |
|
538 } |
|
539 CyAsReturnStatus_t |
|
540 CyAsStorageStop(CyAsDeviceHandle handle, |
|
541 CyAsFunctionCallback cb, |
|
542 uint32_t client) |
|
543 { |
|
544 CyAsLLRequestResponse *req_p , *reply_p ; |
|
545 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
546 |
|
547 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
548 |
|
549 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
550 return CY_AS_ERROR_INVALID_HANDLE ; |
|
551 |
|
552 ret = IsStorageActive(dev_p) ; |
|
553 if (ret != CY_AS_ERROR_SUCCESS) |
|
554 return ret ; |
|
555 |
|
556 if (CyAsDeviceIsStorageAsyncPending(dev_p)) |
|
557 return CY_AS_ERROR_ASYNC_PENDING ; |
|
558 |
|
559 if(CyAsDeviceIsSSSPending(dev_p)) |
|
560 return CY_AS_ERROR_STARTSTOP_PENDING ; |
|
561 |
|
562 CyAsDeviceSetSSSPending(dev_p) ; |
|
563 |
|
564 if (dev_p->storage_count == 1) |
|
565 { |
|
566 |
|
567 /* Create the request to send to the West Bridge device */ |
|
568 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_STOP_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 0) ; |
|
569 if (req_p == 0) |
|
570 { |
|
571 CyAsDeviceClearSSSPending(dev_p) ; |
|
572 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
573 } |
|
574 |
|
575 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
576 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
577 if (reply_p == 0) |
|
578 { |
|
579 CyAsDeviceClearSSSPending(dev_p) ; |
|
580 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
581 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
582 } |
|
583 |
|
584 if(cb == 0) |
|
585 { |
|
586 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
587 if (ret != CY_AS_ERROR_SUCCESS) |
|
588 goto destroy ; |
|
589 |
|
590 return MyHandleResponseStorageStop(dev_p, req_p, reply_p, ret) ; |
|
591 } |
|
592 else |
|
593 { |
|
594 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_STOP, |
|
595 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
596 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
597 |
|
598 if (ret != CY_AS_ERROR_SUCCESS) |
|
599 goto destroy ; |
|
600 |
|
601 /* The request and response are freed as part of the MiscFuncCallback */ |
|
602 return ret ; |
|
603 } |
|
604 |
|
605 destroy: |
|
606 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
607 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
608 } |
|
609 else if(dev_p->storage_count > 1) |
|
610 { |
|
611 dev_p->storage_count-- ; |
|
612 if (cb) |
|
613 cb(handle, ret, client, CY_FUNCT_CB_STOR_STOP, 0) ; |
|
614 } |
|
615 |
|
616 CyAsDeviceClearSSSPending(dev_p) ; |
|
617 |
|
618 return ret ; |
|
619 } |
|
620 |
|
621 CyAsReturnStatus_t |
|
622 CyAsStorageRegisterCallback(CyAsDeviceHandle handle, CyAsStorageEventCallback callback) |
|
623 { |
|
624 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
625 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
626 return CY_AS_ERROR_INVALID_HANDLE ; |
|
627 |
|
628 if (!CyAsDeviceIsConfigured(dev_p)) |
|
629 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
630 |
|
631 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
632 return CY_AS_ERROR_NO_FIRMWARE ; |
|
633 |
|
634 if (dev_p->storage_count == 0) |
|
635 return CY_AS_ERROR_NOT_RUNNING ; |
|
636 |
|
637 dev_p->storage_event_cb = NULL ; |
|
638 dev_p->storage_event_cb_ms = callback ; |
|
639 |
|
640 return CY_AS_ERROR_SUCCESS ; |
|
641 } |
|
642 |
|
643 |
|
644 |
|
645 static CyAsReturnStatus_t |
|
646 MyHandleResponseStorageClaim(CyAsDevice* dev_p, |
|
647 CyAsLLRequestResponse *req_p, |
|
648 CyAsLLRequestResponse *reply_p) |
|
649 { |
|
650 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
651 |
|
652 if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS) |
|
653 { |
|
654 ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ; |
|
655 goto destroy ; |
|
656 } |
|
657 |
|
658 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_MEDIA_CLAIMED_RELEASED) |
|
659 { |
|
660 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
661 goto destroy ; |
|
662 } |
|
663 |
|
664 /* The response must be about the address I am trying to claim or the firmware is broken */ |
|
665 if ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) != |
|
666 CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))) || |
|
667 (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) != |
|
668 CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)))) |
|
669 { |
|
670 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
671 goto destroy ; |
|
672 } |
|
673 |
|
674 if (CyAsLLRequestResponse_GetWord(reply_p, 1) != 1) |
|
675 ret = CY_AS_ERROR_NOT_ACQUIRED ; |
|
676 |
|
677 destroy : |
|
678 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
679 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
680 |
|
681 return ret ; |
|
682 } |
|
683 |
|
684 static CyAsReturnStatus_t |
|
685 MyStorageClaim(CyAsDevice *dev_p, |
|
686 void* data, |
|
687 CyAsBusNumber_t bus, |
|
688 uint32_t device, |
|
689 uint16_t req_flags, |
|
690 CyAsFunctionCallback cb, |
|
691 uint32_t client) |
|
692 { |
|
693 CyAsLLRequestResponse *req_p , *reply_p ; |
|
694 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
695 |
|
696 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
697 return CY_AS_ERROR_INVALID_HANDLE ; |
|
698 |
|
699 ret = IsStorageActive(dev_p) ; |
|
700 if (ret != CY_AS_ERROR_SUCCESS) |
|
701 return ret ; |
|
702 |
|
703 if(dev_p->mtp_count > 0) |
|
704 return CY_AS_ERROR_NOT_VALID_IN_MTP ; |
|
705 |
|
706 /* Create the request to send to the West Bridge device */ |
|
707 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CLAIM_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
708 if (req_p == 0) |
|
709 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
710 |
|
711 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ; |
|
712 |
|
713 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
714 reply_p = CyAsLLCreateResponse(dev_p, 4) ; |
|
715 if (reply_p == 0) |
|
716 { |
|
717 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
718 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
719 } |
|
720 |
|
721 if(cb == 0) |
|
722 { |
|
723 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
724 if (ret != CY_AS_ERROR_SUCCESS) |
|
725 goto destroy ; |
|
726 |
|
727 return MyHandleResponseStorageClaim(dev_p, req_p, reply_p) ; |
|
728 } |
|
729 else |
|
730 { |
|
731 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_CLAIM, |
|
732 data, dev_p->func_cbs_stor, req_flags, |
|
733 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
734 |
|
735 if (ret != CY_AS_ERROR_SUCCESS) |
|
736 goto destroy ; |
|
737 |
|
738 /* The request and response are freed as part of the MiscFuncCallback */ |
|
739 return ret ; |
|
740 } |
|
741 |
|
742 destroy: |
|
743 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
744 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
745 |
|
746 return ret ; |
|
747 } |
|
748 |
|
749 CyAsReturnStatus_t |
|
750 CyAsStorageClaim(CyAsDeviceHandle handle, |
|
751 CyAsBusNumber_t bus, |
|
752 uint32_t device, |
|
753 CyAsFunctionCallback cb, |
|
754 uint32_t client) |
|
755 { |
|
756 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
757 |
|
758 if (bus < 0 || bus >= CY_AS_MAX_BUSES) |
|
759 return CY_AS_ERROR_NO_SUCH_BUS ; |
|
760 |
|
761 return MyStorageClaim(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client) ; |
|
762 } |
|
763 |
|
764 static CyAsReturnStatus_t |
|
765 MyHandleResponseStorageRelease(CyAsDevice* dev_p, |
|
766 CyAsLLRequestResponse *req_p, |
|
767 CyAsLLRequestResponse *reply_p) |
|
768 { |
|
769 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
770 |
|
771 if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS) |
|
772 { |
|
773 ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ; |
|
774 goto destroy ; |
|
775 } |
|
776 |
|
777 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_MEDIA_CLAIMED_RELEASED) |
|
778 { |
|
779 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
780 goto destroy ; |
|
781 } |
|
782 |
|
783 /* The response must be about the address I am trying to release or the firmware is broken */ |
|
784 if ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) != |
|
785 CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))) || |
|
786 (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) != |
|
787 CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)))) |
|
788 { |
|
789 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
790 goto destroy ; |
|
791 } |
|
792 |
|
793 |
|
794 if (CyAsLLRequestResponse_GetWord(reply_p, 1) != 0) |
|
795 ret = CY_AS_ERROR_NOT_RELEASED ; |
|
796 |
|
797 destroy : |
|
798 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
799 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
800 |
|
801 return ret ; |
|
802 } |
|
803 |
|
804 static CyAsReturnStatus_t |
|
805 MyStorageRelease(CyAsDevice* dev_p, |
|
806 void* data, |
|
807 CyAsBusNumber_t bus, |
|
808 uint32_t device, |
|
809 uint16_t req_flags, |
|
810 CyAsFunctionCallback cb, |
|
811 uint32_t client) |
|
812 { |
|
813 CyAsLLRequestResponse *req_p , *reply_p ; |
|
814 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
815 |
|
816 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
817 return CY_AS_ERROR_INVALID_HANDLE ; |
|
818 |
|
819 ret = IsStorageActive(dev_p) ; |
|
820 if (ret != CY_AS_ERROR_SUCCESS) |
|
821 return ret ; |
|
822 |
|
823 if(dev_p->mtp_count > 0) |
|
824 return CY_AS_ERROR_NOT_VALID_IN_MTP ; |
|
825 |
|
826 /* Create the request to send to the West Bridge device */ |
|
827 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_RELEASE_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
828 if (req_p == 0) |
|
829 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
830 |
|
831 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ; |
|
832 |
|
833 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
834 reply_p = CyAsLLCreateResponse(dev_p, 4) ; |
|
835 if (reply_p == 0) |
|
836 { |
|
837 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
838 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
839 } |
|
840 |
|
841 if(cb == 0) |
|
842 { |
|
843 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
844 if (ret != CY_AS_ERROR_SUCCESS) |
|
845 goto destroy ; |
|
846 |
|
847 return MyHandleResponseStorageRelease(dev_p, req_p, reply_p) ; |
|
848 } |
|
849 else |
|
850 { |
|
851 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_RELEASE, |
|
852 data, dev_p->func_cbs_stor, req_flags, |
|
853 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
854 |
|
855 if (ret != CY_AS_ERROR_SUCCESS) |
|
856 goto destroy ; |
|
857 |
|
858 /* The request and response are freed as part of the MiscFuncCallback */ |
|
859 return ret ; |
|
860 } |
|
861 |
|
862 destroy: |
|
863 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
864 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
865 |
|
866 return ret ; |
|
867 } |
|
868 |
|
869 CyAsReturnStatus_t |
|
870 CyAsStorageRelease(CyAsDeviceHandle handle, |
|
871 CyAsBusNumber_t bus, |
|
872 uint32_t device, |
|
873 CyAsFunctionCallback cb, |
|
874 uint32_t client) |
|
875 { |
|
876 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
877 |
|
878 if (bus < 0 || bus >= CY_AS_MAX_BUSES) |
|
879 return CY_AS_ERROR_NO_SUCH_BUS ; |
|
880 |
|
881 return MyStorageRelease(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client) ; |
|
882 } |
|
883 |
|
884 static CyAsReturnStatus_t |
|
885 MyHandleResponseStorageQueryBus(CyAsDevice* dev_p, |
|
886 CyAsLLRequestResponse *req_p, |
|
887 CyAsLLRequestResponse *reply_p, |
|
888 uint32_t* count) |
|
889 { |
|
890 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
891 uint8_t code = CyAsLLRequestResponse_GetCode(reply_p) ; |
|
892 uint16_t v ; |
|
893 |
|
894 if (code == CY_RESP_NO_SUCH_ADDRESS) |
|
895 { |
|
896 ret = CY_AS_ERROR_NO_SUCH_BUS ; |
|
897 goto destroy ; |
|
898 } |
|
899 |
|
900 if (code != CY_RESP_BUS_DESCRIPTOR) |
|
901 { |
|
902 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
903 goto destroy ; |
|
904 } |
|
905 |
|
906 /* |
|
907 * Verify that the response corresponds to the bus that was queried. |
|
908 */ |
|
909 if (CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) != |
|
910 CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))) |
|
911 { |
|
912 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
913 goto destroy ; |
|
914 } |
|
915 |
|
916 v = CyAsLLRequestResponse_GetWord(reply_p, 1) ; |
|
917 if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) |
|
918 { |
|
919 /* |
|
920 * This request is only for the count of devices on the bus. There |
|
921 * is no need to check the media type. |
|
922 */ |
|
923 if (v) |
|
924 *count = 1 ; |
|
925 else |
|
926 *count = 0 ; |
|
927 } |
|
928 else |
|
929 { |
|
930 /* |
|
931 * This request is for the count of devices of a particular type. We need |
|
932 * to check whether the media type found matches the queried type. |
|
933 */ |
|
934 CyAsMediaType queried = (CyAsMediaType)CyAsLLRequestResponse_GetWord(req_p, 1) ; |
|
935 CyAsMediaType found = CyAsStorageGetMediaFromAddress(v) ; |
|
936 |
|
937 if (queried == found) |
|
938 *count = 1 ; |
|
939 else |
|
940 *count = 0 ; |
|
941 } |
|
942 |
|
943 destroy : |
|
944 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
945 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
946 |
|
947 return ret ; |
|
948 } |
|
949 |
|
950 CyAsReturnStatus_t |
|
951 MyStorageQueryBus(CyAsDevice *dev_p, |
|
952 CyAsBusNumber_t bus, |
|
953 CyAsMediaType type, |
|
954 uint16_t req_flags, |
|
955 uint32_t *count, |
|
956 CyAsFunctionCallback cb, |
|
957 uint32_t client) |
|
958 { |
|
959 CyAsReturnStatus_t ret ; |
|
960 CyAsLLRequestResponse *req_p, *reply_p ; |
|
961 CyAsFunctCBType cbType = CY_FUNCT_CB_STOR_QUERYBUS ; |
|
962 |
|
963 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
964 return CY_AS_ERROR_INVALID_HANDLE ; |
|
965 |
|
966 ret = IsStorageActive(dev_p) ; |
|
967 if (ret != CY_AS_ERROR_SUCCESS) |
|
968 return ret ; |
|
969 |
|
970 /* Create the request to send to the Antioch device */ |
|
971 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_BUS, CY_RQT_STORAGE_RQT_CONTEXT, 2) ; |
|
972 if (req_p == 0) |
|
973 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
974 |
|
975 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, 0, 0)) ; |
|
976 CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)type) ; |
|
977 |
|
978 /* Reserve space for the reply, the reply data will not exceed two words. */ |
|
979 reply_p = CyAsLLCreateResponse(dev_p, 2) ; |
|
980 if (reply_p == 0) |
|
981 { |
|
982 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
983 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
984 } |
|
985 |
|
986 if(cb == 0) |
|
987 { |
|
988 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
989 if (ret != CY_AS_ERROR_SUCCESS) |
|
990 goto destroy ; |
|
991 |
|
992 req_p->flags |= req_flags; |
|
993 return MyHandleResponseStorageQueryBus(dev_p, req_p, reply_p, count) ; |
|
994 } |
|
995 else |
|
996 { |
|
997 if (req_flags == CY_AS_REQUEST_RESPONSE_EX) |
|
998 cbType = CY_FUNCT_CB_STOR_QUERYMEDIA ; |
|
999 |
|
1000 ret = CyAsMiscSendRequest(dev_p, cb, client, cbType, |
|
1001 count, dev_p->func_cbs_stor, req_flags, |
|
1002 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
1003 |
|
1004 if (ret != CY_AS_ERROR_SUCCESS) |
|
1005 goto destroy ; |
|
1006 |
|
1007 /* The request and response are freed as part of the MiscFuncCallback */ |
|
1008 return ret ; |
|
1009 } |
|
1010 |
|
1011 destroy: |
|
1012 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1013 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1014 |
|
1015 return ret ; |
|
1016 } |
|
1017 |
|
1018 CyAsReturnStatus_t |
|
1019 CyAsStorageQueryBus(CyAsDeviceHandle handle, |
|
1020 CyAsBusNumber_t bus, |
|
1021 uint32_t *count, |
|
1022 CyAsFunctionCallback cb, |
|
1023 uint32_t client) |
|
1024 { |
|
1025 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1026 |
|
1027 return MyStorageQueryBus(dev_p, bus, CyAsMediaMaxMediaValue, CY_AS_REQUEST_RESPONSE_MS, |
|
1028 count, cb, client) ; |
|
1029 } |
|
1030 |
|
1031 CyAsReturnStatus_t |
|
1032 CyAsStorageQueryMedia(CyAsDeviceHandle handle, |
|
1033 CyAsMediaType type, |
|
1034 uint32_t *count, |
|
1035 CyAsFunctionCallback cb, |
|
1036 uint32_t client) |
|
1037 { |
|
1038 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1039 CyAsBusNumber_t bus ; |
|
1040 |
|
1041 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1042 |
|
1043 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
1044 return CY_AS_ERROR_INVALID_HANDLE ; |
|
1045 |
|
1046 ret = IsStorageActive(dev_p) ; |
|
1047 if (ret != CY_AS_ERROR_SUCCESS) |
|
1048 return ret ; |
|
1049 |
|
1050 ret = CyAnMapBusFromMediaType(dev_p, type, &bus) ; |
|
1051 if (ret != CY_AS_ERROR_SUCCESS) |
|
1052 return ret ; |
|
1053 |
|
1054 return MyStorageQueryBus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX, |
|
1055 count, cb, client) ; |
|
1056 } |
|
1057 |
|
1058 static CyAsReturnStatus_t |
|
1059 MyHandleResponseStorageQueryDevice(CyAsDevice* dev_p, |
|
1060 CyAsLLRequestResponse *req_p, |
|
1061 CyAsLLRequestResponse *reply_p, |
|
1062 void* data_p) |
|
1063 { |
|
1064 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1065 uint16_t v ; |
|
1066 CyAsBusNumber_t bus ; |
|
1067 CyAsMediaType type ; |
|
1068 uint32_t device ; |
|
1069 CyBool removable ; |
|
1070 CyBool writeable ; |
|
1071 CyBool locked ; |
|
1072 uint16_t block_size ; |
|
1073 uint32_t number_units ; |
|
1074 uint32_t number_eus ; |
|
1075 |
|
1076 if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS) |
|
1077 { |
|
1078 ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ; |
|
1079 goto destroy ; |
|
1080 } |
|
1081 |
|
1082 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_DEVICE_DESCRIPTOR) |
|
1083 { |
|
1084 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1085 goto destroy ; |
|
1086 } |
|
1087 |
|
1088 /* Unpack the response */ |
|
1089 v = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
1090 type = CyAsStorageGetMediaFromAddress(v) ; |
|
1091 bus = CyAsStorageGetBusFromAddress(v) ; |
|
1092 device = CyAsStorageGetDeviceFromAddress(v) ; |
|
1093 |
|
1094 block_size = CyAsLLRequestResponse_GetWord(reply_p, 1) ; |
|
1095 |
|
1096 v = CyAsLLRequestResponse_GetWord(reply_p, 2) ; |
|
1097 removable = (v & 0x8000) ? CyTrue : CyFalse ; |
|
1098 writeable = (v & 0x0100) ? CyTrue : CyFalse ; |
|
1099 locked = (v & 0x0200) ? CyTrue : CyFalse ; |
|
1100 number_units = (v & 0xff) ; |
|
1101 |
|
1102 number_eus = (CyAsLLRequestResponse_GetWord(reply_p, 3) << 16) | CyAsLLRequestResponse_GetWord(reply_p, 4) ; |
|
1103 |
|
1104 /* Store the results based on the version of originating function */ |
|
1105 if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) |
|
1106 { |
|
1107 CyAsStorageQueryDeviceData *store_p = (CyAsStorageQueryDeviceData*)data_p ; |
|
1108 |
|
1109 /* Make sure the response is about the address we asked about - if not, firmware error */ |
|
1110 if ((bus != store_p->bus) || (device != store_p->device)) |
|
1111 { |
|
1112 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1113 goto destroy ; |
|
1114 } |
|
1115 |
|
1116 store_p->desc_p.type = type ; |
|
1117 store_p->desc_p.removable = removable ; |
|
1118 store_p->desc_p.writeable = writeable ; |
|
1119 store_p->desc_p.block_size = block_size ; |
|
1120 store_p->desc_p.number_units = number_units ; |
|
1121 store_p->desc_p.locked = locked ; |
|
1122 store_p->desc_p.erase_unit_size = number_eus ; |
|
1123 dev_p->storage_device_info[bus][device] = store_p->desc_p ; |
|
1124 } |
|
1125 else |
|
1126 { |
|
1127 CyAsStorageQueryDeviceData_dep *store_p = (CyAsStorageQueryDeviceData_dep*)data_p ; |
|
1128 |
|
1129 /* Make sure the response is about the address we asked about - if not, firmware error */ |
|
1130 if ((type != store_p->type) || (device != store_p->device)) |
|
1131 { |
|
1132 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1133 goto destroy ; |
|
1134 } |
|
1135 |
|
1136 store_p->desc_p.type = type ; |
|
1137 store_p->desc_p.removable = removable ; |
|
1138 store_p->desc_p.writeable = writeable ; |
|
1139 store_p->desc_p.block_size = block_size ; |
|
1140 store_p->desc_p.number_units = number_units ; |
|
1141 store_p->desc_p.locked = locked ; |
|
1142 store_p->desc_p.erase_unit_size = number_eus ; |
|
1143 dev_p->storage_device_info[bus][device] = store_p->desc_p ; |
|
1144 } |
|
1145 |
|
1146 destroy : |
|
1147 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1148 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1149 |
|
1150 return ret ; |
|
1151 } |
|
1152 |
|
1153 static CyAsReturnStatus_t |
|
1154 MyStorageQueryDevice(CyAsDevice *dev_p, |
|
1155 void* data_p, |
|
1156 uint16_t req_flags, |
|
1157 CyAsBusNumber_t bus, |
|
1158 uint32_t device, |
|
1159 CyAsFunctionCallback cb, |
|
1160 uint32_t client) |
|
1161 { |
|
1162 CyAsLLRequestResponse *req_p , *reply_p ; |
|
1163 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1164 |
|
1165 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
1166 return CY_AS_ERROR_INVALID_HANDLE ; |
|
1167 |
|
1168 ret = IsStorageActive(dev_p) ; |
|
1169 if (ret != CY_AS_ERROR_SUCCESS) |
|
1170 return ret ; |
|
1171 |
|
1172 /* Create the request to send to the Antioch device */ |
|
1173 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
1174 if (req_p == 0) |
|
1175 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1176 |
|
1177 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ; |
|
1178 |
|
1179 /* Reserve space for the reply, the reply data will not exceed five words. */ |
|
1180 reply_p = CyAsLLCreateResponse(dev_p, 5) ; |
|
1181 if (reply_p == 0) |
|
1182 { |
|
1183 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1184 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1185 } |
|
1186 |
|
1187 if(cb == 0) |
|
1188 { |
|
1189 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
1190 if (ret != CY_AS_ERROR_SUCCESS) |
|
1191 goto destroy ; |
|
1192 |
|
1193 req_p->flags |= req_flags; |
|
1194 return MyHandleResponseStorageQueryDevice(dev_p, req_p, reply_p, data_p) ; |
|
1195 } |
|
1196 else |
|
1197 { |
|
1198 |
|
1199 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_QUERYDEVICE, |
|
1200 data_p, dev_p->func_cbs_stor, req_flags, |
|
1201 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
1202 |
|
1203 if (ret != CY_AS_ERROR_SUCCESS) |
|
1204 goto destroy ; |
|
1205 |
|
1206 /* The request and response are freed as part of the MiscFuncCallback */ |
|
1207 return ret ; |
|
1208 } |
|
1209 |
|
1210 destroy: |
|
1211 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1212 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1213 |
|
1214 return ret ; |
|
1215 } |
|
1216 |
|
1217 CyAsReturnStatus_t |
|
1218 CyAsStorageQueryDevice(CyAsDeviceHandle handle, |
|
1219 CyAsStorageQueryDeviceData* data_p, |
|
1220 CyAsFunctionCallback cb, |
|
1221 uint32_t client) |
|
1222 { |
|
1223 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1224 return MyStorageQueryDevice(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, data_p->bus, |
|
1225 data_p->device, cb, client) ; |
|
1226 } |
|
1227 |
|
1228 static CyAsReturnStatus_t |
|
1229 MyHandleResponseStorageQueryUnit(CyAsDevice* dev_p, |
|
1230 CyAsLLRequestResponse *req_p, |
|
1231 CyAsLLRequestResponse *reply_p, |
|
1232 void* data_p) |
|
1233 { |
|
1234 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1235 CyAsBusNumber_t bus ; |
|
1236 uint32_t device ; |
|
1237 uint32_t unit ; |
|
1238 CyAsMediaType type ; |
|
1239 uint16_t block_size ; |
|
1240 uint32_t start_block ; |
|
1241 uint32_t unit_size ; |
|
1242 uint16_t v ; |
|
1243 |
|
1244 if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS) |
|
1245 { |
|
1246 ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ; |
|
1247 goto destroy ; |
|
1248 } |
|
1249 |
|
1250 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_UNIT_DESCRIPTOR) |
|
1251 { |
|
1252 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1253 goto destroy ; |
|
1254 } |
|
1255 |
|
1256 /* Unpack the response */ |
|
1257 v = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
1258 bus = CyAsStorageGetBusFromAddress(v) ; |
|
1259 device = CyAsStorageGetDeviceFromAddress(v) ; |
|
1260 unit = GetUnitFromAddress(v) ; |
|
1261 |
|
1262 type = CyAsStorageGetMediaFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 1)); |
|
1263 |
|
1264 block_size = CyAsLLRequestResponse_GetWord(reply_p, 2) ; |
|
1265 start_block = CyAsLLRequestResponse_GetWord(reply_p, 3) | (CyAsLLRequestResponse_GetWord(reply_p, 4) << 16) ; |
|
1266 unit_size = CyAsLLRequestResponse_GetWord(reply_p, 5) | (CyAsLLRequestResponse_GetWord(reply_p, 6) << 16) ; |
|
1267 |
|
1268 /* Store the results based on the version of originating function */ |
|
1269 if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) |
|
1270 { |
|
1271 CyAsStorageQueryUnitData *store_p = (CyAsStorageQueryUnitData*)data_p ; |
|
1272 |
|
1273 /* Make sure the response is about the address we asked about - if not, firmware error */ |
|
1274 if (bus != store_p->bus || device != store_p->device || unit != store_p->unit) |
|
1275 { |
|
1276 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1277 goto destroy ; |
|
1278 } |
|
1279 |
|
1280 store_p->desc_p.type = type ; |
|
1281 store_p->desc_p.block_size = block_size ; |
|
1282 store_p->desc_p.start_block = start_block ; |
|
1283 store_p->desc_p.unit_size = unit_size ; |
|
1284 } |
|
1285 else |
|
1286 { |
|
1287 CyAsStorageQueryUnitData_dep *store_p = (CyAsStorageQueryUnitData_dep*)data_p ; |
|
1288 |
|
1289 /* Make sure the response is about the media type we asked about - if not, firmware error */ |
|
1290 if ((type != store_p->type) || (device != store_p->device) || (unit != store_p->unit) ) { |
|
1291 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1292 goto destroy ; |
|
1293 } |
|
1294 |
|
1295 store_p->desc_p.type = type ; |
|
1296 store_p->desc_p.block_size = block_size ; |
|
1297 store_p->desc_p.start_block = start_block ; |
|
1298 store_p->desc_p.unit_size = unit_size ; |
|
1299 } |
|
1300 |
|
1301 dev_p->storage_device_info[bus][device].type = type ; |
|
1302 dev_p->storage_device_info[bus][device].block_size = block_size ; |
|
1303 |
|
1304 destroy : |
|
1305 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1306 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1307 |
|
1308 return ret ; |
|
1309 } |
|
1310 |
|
1311 static CyAsReturnStatus_t |
|
1312 MyStorageQueryUnit(CyAsDevice *dev_p, |
|
1313 void* data_p, |
|
1314 uint16_t req_flags, |
|
1315 CyAsBusNumber_t bus, |
|
1316 uint32_t device, |
|
1317 uint32_t unit, |
|
1318 CyAsFunctionCallback cb, |
|
1319 uint32_t client) |
|
1320 { |
|
1321 CyAsLLRequestResponse *req_p , *reply_p ; |
|
1322 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1323 |
|
1324 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
1325 return CY_AS_ERROR_INVALID_HANDLE ; |
|
1326 |
|
1327 ret = IsStorageActive(dev_p) ; |
|
1328 if (ret != CY_AS_ERROR_SUCCESS) |
|
1329 return ret ; |
|
1330 |
|
1331 /* Create the request to send to the West Bridge device */ |
|
1332 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_UNIT, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
1333 if (req_p == 0) |
|
1334 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1335 |
|
1336 if (device > 255) |
|
1337 return CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
1338 |
|
1339 if (unit > 255) |
|
1340 return CY_AS_ERROR_NO_SUCH_UNIT ; |
|
1341 |
|
1342 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, (uint8_t)unit)) ; |
|
1343 |
|
1344 /* Reserve space for the reply, the reply data will be of seven words. */ |
|
1345 reply_p = CyAsLLCreateResponse(dev_p, 7) ; |
|
1346 if (reply_p == 0) |
|
1347 { |
|
1348 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1349 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1350 } |
|
1351 |
|
1352 if(cb == 0) |
|
1353 { |
|
1354 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
1355 if (ret != CY_AS_ERROR_SUCCESS) |
|
1356 goto destroy ; |
|
1357 |
|
1358 req_p->flags |= req_flags ; |
|
1359 return MyHandleResponseStorageQueryUnit(dev_p, req_p, reply_p, data_p) ; |
|
1360 } |
|
1361 else |
|
1362 { |
|
1363 |
|
1364 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_QUERYUNIT, |
|
1365 data_p, dev_p->func_cbs_stor, req_flags, |
|
1366 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
1367 |
|
1368 if (ret != CY_AS_ERROR_SUCCESS) |
|
1369 goto destroy ; |
|
1370 |
|
1371 /* The request and response are freed as part of the MiscFuncCallback */ |
|
1372 return ret ; |
|
1373 } |
|
1374 |
|
1375 destroy: |
|
1376 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1377 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1378 |
|
1379 return ret ; |
|
1380 } |
|
1381 |
|
1382 CyAsReturnStatus_t |
|
1383 CyAsStorageQueryUnit(CyAsDeviceHandle handle, |
|
1384 CyAsStorageQueryUnitData* data_p, |
|
1385 CyAsFunctionCallback cb, |
|
1386 uint32_t client) |
|
1387 { |
|
1388 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1389 return MyStorageQueryUnit(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, data_p->bus, |
|
1390 data_p->device, data_p->unit, cb, client) ; |
|
1391 } |
|
1392 |
|
1393 |
|
1394 static CyAsReturnStatus_t |
|
1395 CyAsGetBlockSize(CyAsDevice *dev_p, |
|
1396 CyAsBusNumber_t bus, |
|
1397 uint32_t device, |
|
1398 CyAsFunctionCallback cb) |
|
1399 { |
|
1400 CyAsLLRequestResponse *req_p , *reply_p ; |
|
1401 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1402 |
|
1403 /* Create the request to send to the West Bridge device */ |
|
1404 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
1405 if (req_p == 0) |
|
1406 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1407 |
|
1408 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ; |
|
1409 |
|
1410 reply_p = CyAsLLCreateResponse(dev_p, 4) ; |
|
1411 if (reply_p == 0) |
|
1412 { |
|
1413 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1414 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1415 } |
|
1416 |
|
1417 if(cb == 0) |
|
1418 { |
|
1419 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
1420 if (ret != CY_AS_ERROR_SUCCESS) |
|
1421 goto destroy ; |
|
1422 |
|
1423 if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS) |
|
1424 { |
|
1425 ret = CY_AS_ERROR_NO_SUCH_BUS ; |
|
1426 goto destroy ; |
|
1427 } |
|
1428 |
|
1429 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_DEVICE_DESCRIPTOR) |
|
1430 { |
|
1431 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1432 goto destroy ; |
|
1433 } |
|
1434 |
|
1435 /* Make sure the response is about the media type we asked about - if not, firmware error */ |
|
1436 if ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)) != bus) || |
|
1437 (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)) != device) ) |
|
1438 { |
|
1439 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1440 goto destroy ; |
|
1441 } |
|
1442 |
|
1443 |
|
1444 dev_p->storage_device_info[bus][device].block_size = CyAsLLRequestResponse_GetWord(reply_p, 1) ; |
|
1445 } |
|
1446 else |
|
1447 ret = CY_AS_ERROR_INVALID_REQUEST ; |
|
1448 |
|
1449 destroy: |
|
1450 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1451 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1452 |
|
1453 return ret ; |
|
1454 } |
|
1455 |
|
1456 CyAsReturnStatus_t |
|
1457 MyStorageDeviceControl( |
|
1458 CyAsDevice *dev_p, |
|
1459 CyAsBusNumber_t bus, |
|
1460 uint32_t device, |
|
1461 CyBool card_detect_en, |
|
1462 CyBool write_prot_en, |
|
1463 CyAsStorageCardDetect config_detect, |
|
1464 CyAsFunctionCallback cb, |
|
1465 uint32_t client) |
|
1466 { |
|
1467 CyAsLLRequestResponse *req_p , *reply_p ; |
|
1468 CyAsReturnStatus_t ret ; |
|
1469 CyBool use_gpio = CyFalse ; |
|
1470 |
|
1471 (void)device ; |
|
1472 |
|
1473 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
1474 return CY_AS_ERROR_INVALID_HANDLE ; |
|
1475 |
|
1476 if (!CyAsDeviceIsConfigured(dev_p)) |
|
1477 return CY_AS_ERROR_NOT_CONFIGURED ; |
|
1478 |
|
1479 if (!CyAsDeviceIsFirmwareLoaded(dev_p)) |
|
1480 return CY_AS_ERROR_NO_FIRMWARE ; |
|
1481 |
|
1482 if (CyAsDeviceIsInSuspendMode(dev_p)) |
|
1483 return CY_AS_ERROR_IN_SUSPEND ; |
|
1484 |
|
1485 if (bus < 0 || bus >= CY_AS_MAX_BUSES) |
|
1486 return CY_AS_ERROR_NO_SUCH_BUS ; |
|
1487 |
|
1488 if (device >= CY_AS_MAX_STORAGE_DEVICES) |
|
1489 return CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
1490 |
|
1491 /* If SD is not supported on the specified bus, then return ERROR */ |
|
1492 if((dev_p->media_supported[bus] ==0 ) || (dev_p->media_supported[bus] &(1<<CyAsMediaNand))) |
|
1493 return CY_AS_ERROR_NOT_SUPPORTED; |
|
1494 |
|
1495 if(config_detect == CyAsStorageDetect_GPIO) |
|
1496 use_gpio = CyTrue ; |
|
1497 else if(config_detect == CyAsStorageDetect_SDAT_3) |
|
1498 use_gpio = CyFalse ; |
|
1499 else |
|
1500 return CY_AS_ERROR_INVALID_PARAMETER ; |
|
1501 |
|
1502 /* Create the request to send to the West Bridge device */ |
|
1503 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SD_INTERFACE_CONTROL, CY_RQT_STORAGE_RQT_CONTEXT, 2) ; |
|
1504 if (req_p == 0) |
|
1505 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1506 |
|
1507 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ; |
|
1508 CyAsLLRequestResponse_SetWord(req_p, 1, (((uint16_t)card_detect_en << 8) | ((uint16_t)use_gpio << 1) | (uint16_t)write_prot_en)) ; |
|
1509 |
|
1510 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
1511 if (reply_p == 0) |
|
1512 { |
|
1513 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1514 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
1515 } |
|
1516 |
|
1517 if(cb == 0) |
|
1518 { |
|
1519 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
1520 if (ret != CY_AS_ERROR_SUCCESS) |
|
1521 goto destroy ; |
|
1522 |
|
1523 if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE) |
|
1524 { |
|
1525 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1526 goto destroy ; |
|
1527 } |
|
1528 |
|
1529 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
1530 } |
|
1531 else |
|
1532 { |
|
1533 |
|
1534 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_DEVICECONTROL, |
|
1535 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
1536 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
1537 |
|
1538 if (ret != CY_AS_ERROR_SUCCESS) |
|
1539 goto destroy ; |
|
1540 |
|
1541 /* The request and response are freed as part of the MiscFuncCallback */ |
|
1542 return ret ; |
|
1543 } |
|
1544 destroy: |
|
1545 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
1546 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
1547 |
|
1548 return ret ; |
|
1549 } |
|
1550 |
|
1551 CyAsReturnStatus_t |
|
1552 CyAsStorageDeviceControl(CyAsDeviceHandle handle, |
|
1553 CyAsBusNumber_t bus, |
|
1554 uint32_t device, |
|
1555 CyBool card_detect_en, |
|
1556 CyBool write_prot_en, |
|
1557 CyAsStorageCardDetect config_detect, |
|
1558 CyAsFunctionCallback cb, |
|
1559 uint32_t client) |
|
1560 { |
|
1561 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1562 |
|
1563 return MyStorageDeviceControl(dev_p, bus, device, card_detect_en, write_prot_en, config_detect, cb, client); |
|
1564 } |
|
1565 |
|
1566 static void |
|
1567 CyAsAsyncStorageCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t ret) |
|
1568 { |
|
1569 CyAsStorageCallback_dep cb ; |
|
1570 CyAsStorageCallback cb_ms ; |
|
1571 |
|
1572 (void)size ; |
|
1573 (void)buf_p ; |
|
1574 (void)ep ; |
|
1575 |
|
1576 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
1577 |
|
1578 /* |
|
1579 * If the LL request callback has already been called, the user |
|
1580 * callback has to be called from here. |
|
1581 */ |
|
1582 if (!dev_p->storage_wait) |
|
1583 { |
|
1584 CyAsHalAssert(dev_p->storage_cb != NULL || dev_p->storage_cb_ms != NULL) ; |
|
1585 cb = dev_p->storage_cb ; |
|
1586 cb_ms = dev_p->storage_cb_ms ; |
|
1587 |
|
1588 dev_p->storage_cb = 0 ; |
|
1589 dev_p->storage_cb_ms = 0 ; |
|
1590 |
|
1591 if (ret == CY_AS_ERROR_SUCCESS) |
|
1592 ret = dev_p->storage_error ; |
|
1593 |
|
1594 if (cb_ms) |
|
1595 { |
|
1596 cb_ms((CyAsDeviceHandle)dev_p, dev_p->storage_bus_index, dev_p->storage_device_index, |
|
1597 dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ; |
|
1598 } |
|
1599 else |
|
1600 { |
|
1601 cb((CyAsDeviceHandle)dev_p, |
|
1602 dev_p->storage_device_info[dev_p->storage_bus_index][dev_p->storage_device_index].type, |
|
1603 dev_p->storage_device_index, dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ; |
|
1604 } |
|
1605 } |
|
1606 else |
|
1607 dev_p->storage_error = ret ; |
|
1608 } |
|
1609 |
|
1610 static void |
|
1611 CyAsAsyncStorageReplyCallback( |
|
1612 CyAsDevice *dev_p, |
|
1613 uint8_t context, |
|
1614 CyAsLLRequestResponse *rqt, |
|
1615 CyAsLLRequestResponse *resp, |
|
1616 CyAsReturnStatus_t ret) |
|
1617 { |
|
1618 CyAsStorageCallback_dep cb ; |
|
1619 CyAsStorageCallback cb_ms ; |
|
1620 uint8_t reqtype ; |
|
1621 (void)rqt ; |
|
1622 (void)context ; |
|
1623 |
|
1624 reqtype = CyAsLLRequestResponse_GetCode(rqt) ; |
|
1625 |
|
1626 if (ret == CY_AS_ERROR_SUCCESS) |
|
1627 { |
|
1628 if (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_ANTIOCH_DEFERRED_ERROR) |
|
1629 { |
|
1630 ret = CyAsLLRequestResponse_GetWord(resp, 0) & 0x00FF ; |
|
1631 } |
|
1632 else if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE) |
|
1633 { |
|
1634 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1635 } |
|
1636 } |
|
1637 |
|
1638 if (ret != CY_AS_ERROR_SUCCESS) |
|
1639 { |
|
1640 if(reqtype == CY_RQT_READ_BLOCK) |
|
1641 CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ; |
|
1642 else |
|
1643 CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ; |
|
1644 } |
|
1645 |
|
1646 dev_p->storage_wait = CyFalse ; |
|
1647 |
|
1648 /* |
|
1649 * If the DMA callback has already been called, the user callback |
|
1650 * has to be called from here. |
|
1651 */ |
|
1652 if (!CyAsDeviceIsStorageAsyncPending(dev_p)) |
|
1653 { |
|
1654 CyAsHalAssert(dev_p->storage_cb != NULL || dev_p->storage_cb_ms != NULL) ; |
|
1655 cb = dev_p->storage_cb ; |
|
1656 cb_ms = dev_p->storage_cb_ms ; |
|
1657 |
|
1658 dev_p->storage_cb = 0 ; |
|
1659 dev_p->storage_cb_ms = 0 ; |
|
1660 |
|
1661 if (ret == CY_AS_ERROR_SUCCESS) |
|
1662 ret = dev_p->storage_error ; |
|
1663 |
|
1664 if (cb_ms) |
|
1665 { |
|
1666 cb_ms((CyAsDeviceHandle)dev_p, dev_p->storage_bus_index, dev_p->storage_device_index, |
|
1667 dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ; |
|
1668 } |
|
1669 else |
|
1670 { |
|
1671 cb((CyAsDeviceHandle)dev_p, |
|
1672 dev_p->storage_device_info[dev_p->storage_bus_index][dev_p->storage_device_index].type, |
|
1673 dev_p->storage_device_index, dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ; |
|
1674 } |
|
1675 } |
|
1676 else |
|
1677 dev_p->storage_error = ret ; |
|
1678 } |
|
1679 |
|
1680 static CyAsReturnStatus_t |
|
1681 CyAsStorageAsyncOper(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, uint8_t reqtype, uint16_t req_flags, |
|
1682 CyAsBusNumber_t bus, uint32_t device, uint32_t unit, |
|
1683 uint32_t block, void *data_p, uint16_t num_blocks, |
|
1684 CyAsStorageCallback_dep callback, CyAsStorageCallback callback_ms) |
|
1685 { |
|
1686 uint32_t mask ; |
|
1687 CyAsLLRequestResponse *req_p , *reply_p ; |
|
1688 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1689 |
|
1690 ret = IsStorageActive(dev_p) ; |
|
1691 if (ret != CY_AS_ERROR_SUCCESS) |
|
1692 return ret ; |
|
1693 |
|
1694 if (bus < 0 || bus >= CY_AS_MAX_BUSES) |
|
1695 return CY_AS_ERROR_NO_SUCH_BUS ; |
|
1696 |
|
1697 if (device >= CY_AS_MAX_STORAGE_DEVICES) |
|
1698 return CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
1699 |
|
1700 if (unit > 255) |
|
1701 return CY_AS_ERROR_NO_SUCH_UNIT ; |
|
1702 |
|
1703 /* We are supposed to return sucess if the number of |
|
1704 * blocks is zero |
|
1705 */ |
|
1706 if (num_blocks == 0) |
|
1707 { |
|
1708 if (callback_ms) |
|
1709 callback_ms((CyAsDeviceHandle)dev_p, bus, device, unit, block, |
|
1710 ((reqtype == CY_RQT_WRITE_BLOCK) ? CyAsOpWrite : CyAsOpRead), |
|
1711 CY_AS_ERROR_SUCCESS) ; |
|
1712 else |
|
1713 callback((CyAsDeviceHandle)dev_p, dev_p->storage_device_info[bus][device].type, |
|
1714 device, unit, block, ((reqtype == CY_RQT_WRITE_BLOCK) ? CyAsOpWrite : CyAsOpRead), |
|
1715 CY_AS_ERROR_SUCCESS) ; |
|
1716 |
|
1717 return CY_AS_ERROR_SUCCESS ; |
|
1718 } |
|
1719 |
|
1720 if (dev_p->storage_device_info[bus][device].block_size == 0) |
|
1721 return CY_AS_ERROR_QUERY_DEVICE_NEEDED ; |
|
1722 |
|
1723 /* |
|
1724 * Since async operations can be triggered by interrupt code, we must |
|
1725 * insure that we do not get multiple async operations going at one time and |
|
1726 * protect this test and set operation from interrupts. |
|
1727 * Also need to check for pending Async MTP writes |
|
1728 */ |
|
1729 mask = CyAsHalDisableInterrupts() ; |
|
1730 if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait) || (CyAsDeviceIsUsbAsyncPending(dev_p, 6))) |
|
1731 { |
|
1732 CyAsHalEnableInterrupts(mask) ; |
|
1733 return CY_AS_ERROR_ASYNC_PENDING ; |
|
1734 } |
|
1735 |
|
1736 CyAsDeviceSetStorageAsyncPending(dev_p) ; |
|
1737 CyAsHalEnableInterrupts(mask) ; |
|
1738 |
|
1739 /* |
|
1740 * Storage information about the currently outstanding request |
|
1741 */ |
|
1742 dev_p->storage_cb = callback ; |
|
1743 dev_p->storage_cb_ms = callback_ms ; |
|
1744 dev_p->storage_bus_index = bus ; |
|
1745 dev_p->storage_device_index = device ; |
|
1746 dev_p->storage_unit = unit ; |
|
1747 dev_p->storage_block_addr = block ; |
|
1748 |
|
1749 /* Initialise the request to send to the West Bridge. */ |
|
1750 req_p = dev_p->storage_rw_req_p ; |
|
1751 CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5) ; |
|
1752 |
|
1753 /* Initialise the space for reply from the West Bridge. */ |
|
1754 reply_p = dev_p->storage_rw_resp_p ; |
|
1755 CyAsLLInitResponse(reply_p, 5) ; |
|
1756 |
|
1757 /* Remember which version of the API originated the request */ |
|
1758 req_p->flags |= req_flags ; |
|
1759 |
|
1760 /* Setup the DMA request and adjust the storage operation if we are reading */ |
|
1761 if (reqtype == CY_RQT_READ_BLOCK) |
|
1762 { |
|
1763 ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, |
|
1764 CyFalse, CyTrue, CyAsAsyncStorageCallback) ; |
|
1765 dev_p->storage_oper = CyAsOpRead ; |
|
1766 } |
|
1767 else if (reqtype == CY_RQT_WRITE_BLOCK) |
|
1768 { |
|
1769 ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, |
|
1770 CyFalse, CyFalse, CyAsAsyncStorageCallback) ; |
|
1771 dev_p->storage_oper = CyAsOpWrite ; |
|
1772 } |
|
1773 if (ret != CY_AS_ERROR_SUCCESS) |
|
1774 { |
|
1775 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
1776 return ret ; |
|
1777 } |
|
1778 |
|
1779 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, (uint8_t)unit)) ; |
|
1780 CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((block >> 16) & 0xffff)) ; |
|
1781 CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(block & 0xffff)) ; |
|
1782 CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_blocks >> 8) & 0x00ff)) ; |
|
1783 CyAsLLRequestResponse_SetWord(req_p, 4, (uint16_t)((num_blocks << 8) & 0xff00)) ; |
|
1784 |
|
1785 /* Set the burst mode flag. */ |
|
1786 if (dev_p->is_storage_only_mode) |
|
1787 req_p->data[4] |= 0x0001; |
|
1788 |
|
1789 /* Send the request and wait for completion of storage request */ |
|
1790 dev_p->storage_wait = CyTrue ; |
|
1791 ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsAsyncStorageReplyCallback) ; |
|
1792 if (ret != CY_AS_ERROR_SUCCESS) |
|
1793 { |
|
1794 CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ; |
|
1795 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
1796 } |
|
1797 |
|
1798 return ret ; |
|
1799 } |
|
1800 |
|
1801 static void |
|
1802 CyAsSyncStorageCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err) |
|
1803 { |
|
1804 (void)ep ; |
|
1805 (void)buf_p ; |
|
1806 (void)size ; |
|
1807 |
|
1808 dev_p->storage_error = err ; |
|
1809 } |
|
1810 |
|
1811 static void |
|
1812 CyAsSyncStorageReplyCallback( |
|
1813 CyAsDevice *dev_p, |
|
1814 uint8_t context, |
|
1815 CyAsLLRequestResponse *rqt, |
|
1816 CyAsLLRequestResponse *resp, |
|
1817 CyAsReturnStatus_t ret) |
|
1818 { |
|
1819 uint8_t reqtype ; |
|
1820 (void)rqt ; |
|
1821 |
|
1822 reqtype = CyAsLLRequestResponse_GetCode(rqt) ; |
|
1823 |
|
1824 if (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_ANTIOCH_DEFERRED_ERROR) |
|
1825 { |
|
1826 ret = CyAsLLRequestResponse_GetWord(resp, 0) & 0x00FF ; |
|
1827 |
|
1828 if (ret != CY_AS_ERROR_SUCCESS) |
|
1829 { |
|
1830 if(reqtype == CY_RQT_READ_BLOCK) |
|
1831 CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ; |
|
1832 else |
|
1833 CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ; |
|
1834 } |
|
1835 } |
|
1836 else if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE) |
|
1837 { |
|
1838 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
1839 } |
|
1840 |
|
1841 dev_p->storage_wait = CyFalse ; |
|
1842 dev_p->storage_error = ret ; |
|
1843 |
|
1844 /* Wake any threads/processes that are waiting on the read/write completion. */ |
|
1845 CyAsHalWake (&dev_p->context[context]->channel) ; |
|
1846 } |
|
1847 |
|
1848 static CyAsReturnStatus_t |
|
1849 CyAsStorageSyncOper(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, uint8_t reqtype, CyAsBusNumber_t bus, uint32_t device, |
|
1850 uint32_t unit, uint32_t block, void *data_p, uint16_t num_blocks) |
|
1851 { |
|
1852 CyAsLLRequestResponse *req_p , *reply_p ; |
|
1853 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
1854 CyAsContext *ctxt_p ; |
|
1855 uint32_t loopcount = 200 ; |
|
1856 |
|
1857 ret = IsStorageActive(dev_p) ; |
|
1858 if (ret != CY_AS_ERROR_SUCCESS) |
|
1859 return ret ; |
|
1860 |
|
1861 if (bus < 0 || bus >= CY_AS_MAX_BUSES) |
|
1862 return CY_AS_ERROR_NO_SUCH_BUS ; |
|
1863 |
|
1864 if (device >= CY_AS_MAX_STORAGE_DEVICES) |
|
1865 return CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
1866 |
|
1867 if (unit > 255) |
|
1868 return CY_AS_ERROR_NO_SUCH_UNIT ; |
|
1869 |
|
1870 if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait)) |
|
1871 return CY_AS_ERROR_ASYNC_PENDING ; |
|
1872 |
|
1873 /* Also need to check for pending Async MTP writes */ |
|
1874 if(CyAsDeviceIsUsbAsyncPending(dev_p, 6)) |
|
1875 return CY_AS_ERROR_ASYNC_PENDING ; |
|
1876 |
|
1877 /* We are supposed to return sucess if the number of |
|
1878 * blocks is zero |
|
1879 */ |
|
1880 if (num_blocks == 0) |
|
1881 return CY_AS_ERROR_SUCCESS ; |
|
1882 |
|
1883 if (dev_p->storage_device_info[bus][device].block_size == 0) |
|
1884 { |
|
1885 /* |
|
1886 * Normally, a given device has been queried via the query device call before a |
|
1887 * read request is issued. Therefore, this normally will not be run. |
|
1888 */ |
|
1889 ret = CyAsGetBlockSize(dev_p, bus, device, 0) ; |
|
1890 if (ret != CY_AS_ERROR_SUCCESS) |
|
1891 return ret ; |
|
1892 } |
|
1893 |
|
1894 /* Initialise the request to send to the West Bridge. */ |
|
1895 req_p = dev_p->storage_rw_req_p ; |
|
1896 CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5) ; |
|
1897 |
|
1898 /* Initialise the space for reply from the West Bridge. */ |
|
1899 reply_p = dev_p->storage_rw_resp_p ; |
|
1900 CyAsLLInitResponse(reply_p, 5) ; |
|
1901 |
|
1902 /* Setup the DMA request */ |
|
1903 if (reqtype == CY_RQT_READ_BLOCK) |
|
1904 { |
|
1905 ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, CyFalse, |
|
1906 CyTrue, CyAsSyncStorageCallback) ; |
|
1907 dev_p->storage_oper = CyAsOpRead ; |
|
1908 } |
|
1909 else if (reqtype == CY_RQT_WRITE_BLOCK) |
|
1910 { |
|
1911 ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, CyFalse, |
|
1912 CyFalse, CyAsSyncStorageCallback) ; |
|
1913 dev_p->storage_oper = CyAsOpWrite ; |
|
1914 } |
|
1915 if (ret != CY_AS_ERROR_SUCCESS) |
|
1916 { |
|
1917 return ret ; |
|
1918 } |
|
1919 |
|
1920 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, (uint8_t)unit)) ; |
|
1921 CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((block >> 16) & 0xffff)) ; |
|
1922 CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(block & 0xffff)) ; |
|
1923 CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_blocks >> 8) & 0x00ff)) ; |
|
1924 CyAsLLRequestResponse_SetWord(req_p, 4, (uint16_t)((num_blocks << 8) & 0xff00)) ; |
|
1925 |
|
1926 /* Set the burst mode flag. */ |
|
1927 if (dev_p->is_storage_only_mode) |
|
1928 req_p->data[4] |= 0x0001; |
|
1929 |
|
1930 /* Send the request and wait for completion of storage request */ |
|
1931 dev_p->storage_wait = CyTrue ; |
|
1932 ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSyncStorageReplyCallback) ; |
|
1933 if (ret != CY_AS_ERROR_SUCCESS) |
|
1934 { |
|
1935 CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ; |
|
1936 } |
|
1937 else |
|
1938 { |
|
1939 /* Setup the DMA request */ |
|
1940 ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ; |
|
1941 ret = CyAsDmaDrainQueue(dev_p, ep, CyFalse) ; |
|
1942 |
|
1943 while (loopcount-- > 0) |
|
1944 { |
|
1945 if (dev_p->storage_wait == CyFalse) |
|
1946 break ; |
|
1947 CyAsHalSleepOn(&ctxt_p->channel, 10) ; |
|
1948 } |
|
1949 |
|
1950 if (dev_p->storage_wait == CyTrue) |
|
1951 { |
|
1952 dev_p->storage_wait = CyFalse ; |
|
1953 CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ; |
|
1954 ret = CY_AS_ERROR_TIMEOUT ; |
|
1955 } |
|
1956 |
|
1957 if (ret == CY_AS_ERROR_SUCCESS) |
|
1958 ret = dev_p->storage_error ; |
|
1959 } |
|
1960 |
|
1961 return ret ; |
|
1962 } |
|
1963 |
|
1964 CyAsReturnStatus_t |
|
1965 CyAsStorageRead(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, uint32_t block, |
|
1966 void *data_p, uint16_t num_blocks) |
|
1967 { |
|
1968 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1969 |
|
1970 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
1971 return CY_AS_ERROR_INVALID_HANDLE ; |
|
1972 |
|
1973 return CyAsStorageSyncOper(dev_p, dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK, bus, device, |
|
1974 unit, block, data_p, num_blocks) ; |
|
1975 } |
|
1976 |
|
1977 CyAsReturnStatus_t |
|
1978 CyAsStorageWrite(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, uint32_t block, |
|
1979 void *data_p, uint16_t num_blocks) |
|
1980 { |
|
1981 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1982 |
|
1983 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
1984 return CY_AS_ERROR_INVALID_HANDLE ; |
|
1985 |
|
1986 if(dev_p->mtp_turbo_active) |
|
1987 return CY_AS_ERROR_NOT_VALID_DURING_MTP ; |
|
1988 |
|
1989 return CyAsStorageSyncOper(dev_p, dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK, bus, device, |
|
1990 unit, block, data_p, num_blocks) ; |
|
1991 } |
|
1992 |
|
1993 |
|
1994 CyAsReturnStatus_t |
|
1995 CyAsStorageReadAsync(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, |
|
1996 uint32_t block, void *data_p, uint16_t num_blocks, CyAsStorageCallback callback) |
|
1997 { |
|
1998 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
1999 |
|
2000 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2001 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2002 |
|
2003 if (callback == 0) |
|
2004 return CY_AS_ERROR_NULL_CALLBACK ; |
|
2005 |
|
2006 return CyAsStorageAsyncOper(dev_p, dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK, |
|
2007 CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block, data_p, num_blocks, NULL, callback); |
|
2008 } |
|
2009 |
|
2010 CyAsReturnStatus_t |
|
2011 CyAsStorageWriteAsync(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, |
|
2012 uint32_t block, void *data_p, uint16_t num_blocks, CyAsStorageCallback callback) |
|
2013 { |
|
2014 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2015 |
|
2016 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2017 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2018 |
|
2019 if (callback == 0) |
|
2020 return CY_AS_ERROR_NULL_CALLBACK ; |
|
2021 |
|
2022 if(dev_p->mtp_turbo_active) |
|
2023 return CY_AS_ERROR_NOT_VALID_DURING_MTP ; |
|
2024 |
|
2025 return CyAsStorageAsyncOper(dev_p, dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK, |
|
2026 CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block, data_p, num_blocks, NULL, callback); |
|
2027 } |
|
2028 |
|
2029 |
|
2030 static void |
|
2031 MyStorageCancelCallback ( |
|
2032 CyAsDevice *dev_p, |
|
2033 uint8_t context, |
|
2034 CyAsLLRequestResponse *rqt, |
|
2035 CyAsLLRequestResponse *resp, |
|
2036 CyAsReturnStatus_t stat) |
|
2037 { |
|
2038 (void)context ; |
|
2039 (void)stat ; |
|
2040 |
|
2041 /* Nothing to do here, except free up the request and response structures. */ |
|
2042 CyAsLLDestroyResponse(dev_p, resp) ; |
|
2043 CyAsLLDestroyRequest(dev_p, rqt) ; |
|
2044 } |
|
2045 |
|
2046 |
|
2047 CyAsReturnStatus_t |
|
2048 CyAsStorageCancelAsync(CyAsDeviceHandle handle) |
|
2049 { |
|
2050 CyAsReturnStatus_t ret ; |
|
2051 CyAsLLRequestResponse *req_p , *reply_p ; |
|
2052 |
|
2053 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2054 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2055 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2056 |
|
2057 ret = IsStorageActive(dev_p) ; |
|
2058 if (ret != CY_AS_ERROR_SUCCESS) |
|
2059 return ret ; |
|
2060 |
|
2061 if (!CyAsDeviceIsStorageAsyncPending(dev_p)) |
|
2062 return CY_AS_ERROR_ASYNC_NOT_PENDING ; |
|
2063 |
|
2064 /* |
|
2065 * Create and send a mailbox request to firmware asking it to abort processing |
|
2066 * of the current P2S operation. The rest of the cancel processing will be |
|
2067 * driven through the callbacks for the read/write call. |
|
2068 */ |
|
2069 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ABORT_P2S_XFER, CY_RQT_GENERAL_RQT_CONTEXT, 1) ; |
|
2070 if (req_p == 0) |
|
2071 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2072 |
|
2073 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
2074 if (reply_p == 0) |
|
2075 { |
|
2076 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2077 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2078 } |
|
2079 |
|
2080 ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MyStorageCancelCallback) ; |
|
2081 if (ret) |
|
2082 { |
|
2083 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2084 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2085 } |
|
2086 |
|
2087 return CY_AS_ERROR_SUCCESS ; |
|
2088 } |
|
2089 |
|
2090 /* |
|
2091 * This function does all the API side clean-up associated with |
|
2092 * CyAsStorageStop, without any communication with the firmware. |
|
2093 */ |
|
2094 void CyAsStorageCleanup(CyAsDevice *dev_p) |
|
2095 { |
|
2096 if (dev_p->storage_count) |
|
2097 { |
|
2098 CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ; |
|
2099 CyAsLLDestroyResponse(dev_p, dev_p->storage_rw_resp_p) ; |
|
2100 dev_p->storage_count = 0 ; |
|
2101 CyAsDeviceClearScsiMessages(dev_p) ; |
|
2102 CyAsHalMemSet(dev_p->storage_device_info, 0, sizeof(dev_p->storage_device_info)) ; |
|
2103 |
|
2104 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
2105 dev_p->storage_cb = 0 ; |
|
2106 dev_p->storage_cb_ms = 0 ; |
|
2107 dev_p->storage_wait = CyFalse ; |
|
2108 } |
|
2109 } |
|
2110 |
|
2111 static CyAsReturnStatus_t |
|
2112 MyHandleResponseSDRegRead( |
|
2113 CyAsDevice *dev_p, |
|
2114 CyAsLLRequestResponse *req_p, |
|
2115 CyAsLLRequestResponse *reply_p, |
|
2116 CyAsStorageSDRegReadData *info) |
|
2117 { |
|
2118 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2119 uint8_t resp_type, i ; |
|
2120 uint16_t resp_len ; |
|
2121 uint8_t length = info->length ; |
|
2122 uint8_t *data_p = info->buf_p ; |
|
2123 |
|
2124 resp_type = CyAsLLRequestResponse_GetCode(reply_p) ; |
|
2125 if (resp_type == CY_RESP_SD_REGISTER_DATA) |
|
2126 { |
|
2127 uint16_t *resp_p = reply_p->data + 1 ; |
|
2128 uint16_t temp ; |
|
2129 |
|
2130 resp_len = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
2131 CyAsHalAssert(resp_len >= length) ; |
|
2132 |
|
2133 /* |
|
2134 * Copy the values into the output buffer after doing the |
|
2135 * necessary bit shifting. The bit shifting is required because |
|
2136 * the data comes out of the West Bridge with a 6 bit offset. |
|
2137 */ |
|
2138 i = 0 ; |
|
2139 while (length) |
|
2140 { |
|
2141 temp = ((resp_p[i] << 6) | (resp_p[i + 1] >> 10)) ; |
|
2142 i++ ; |
|
2143 |
|
2144 *data_p++ = (uint8_t)(temp >> 8) ; |
|
2145 length-- ; |
|
2146 |
|
2147 if (length) |
|
2148 { |
|
2149 *data_p++ = (uint8_t)(temp & 0xFF) ; |
|
2150 length-- ; |
|
2151 } |
|
2152 } |
|
2153 } |
|
2154 else |
|
2155 { |
|
2156 if (resp_type == CY_RESP_SUCCESS_FAILURE) |
|
2157 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
2158 else |
|
2159 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
2160 } |
|
2161 |
|
2162 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2163 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2164 |
|
2165 return ret ; |
|
2166 } |
|
2167 |
|
2168 CyAsReturnStatus_t |
|
2169 CyAsStorageSDRegisterRead( |
|
2170 CyAsDeviceHandle handle, |
|
2171 CyAsBusNumber_t bus, |
|
2172 uint8_t device, |
|
2173 CyAsSDCardRegType regType, |
|
2174 CyAsStorageSDRegReadData *data_p, |
|
2175 CyAsFunctionCallback cb, |
|
2176 uint32_t client) |
|
2177 { |
|
2178 CyAsLLRequestResponse *req_p , *reply_p ; |
|
2179 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2180 uint8_t length ; |
|
2181 |
|
2182 /* |
|
2183 * Sanity checks required before sending the request to the |
|
2184 * firmware. |
|
2185 */ |
|
2186 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2187 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2188 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2189 |
|
2190 ret = IsStorageActive(dev_p) ; |
|
2191 if (ret != CY_AS_ERROR_SUCCESS) |
|
2192 return ret ; |
|
2193 |
|
2194 if (device >= CY_AS_MAX_STORAGE_DEVICES) |
|
2195 return CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
2196 |
|
2197 if (regType > CyAsSDReg_CSD) |
|
2198 return CY_AS_ERROR_INVALID_PARAMETER ; |
|
2199 |
|
2200 /* If SD/MMC media is not supported on the addressed bus, return error. */ |
|
2201 if ((dev_p->media_supported[bus] & (1 << CyAsMediaSDFlash)) == 0) |
|
2202 return CY_AS_ERROR_INVALID_PARAMETER ; |
|
2203 |
|
2204 /* |
|
2205 * Find the amount of data to be returned. This will be the minimum of |
|
2206 * the actual data length, and the length requested. |
|
2207 */ |
|
2208 switch (regType) |
|
2209 { |
|
2210 case CyAsSDReg_OCR: |
|
2211 length = CY_AS_SD_REG_OCR_LENGTH ; |
|
2212 break ; |
|
2213 |
|
2214 case CyAsSDReg_CID: |
|
2215 length = CY_AS_SD_REG_CID_LENGTH ; |
|
2216 break ; |
|
2217 |
|
2218 case CyAsSDReg_CSD: |
|
2219 length = CY_AS_SD_REG_CSD_LENGTH ; |
|
2220 break ; |
|
2221 |
|
2222 default: |
|
2223 length = 0 ; |
|
2224 CyAsHalAssert(0) ; |
|
2225 } |
|
2226 |
|
2227 if (length < data_p->length) |
|
2228 data_p->length = length ; |
|
2229 length = data_p->length ; |
|
2230 |
|
2231 /* Create the request to send to the West Bridge device */ |
|
2232 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SD_REGISTER_READ, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
2233 if (req_p == 0) |
|
2234 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2235 |
|
2236 CyAsLLRequestResponse_SetWord(req_p, 0, (CreateAddress(bus, device, 0) | (uint16_t)regType)) ; |
|
2237 |
|
2238 reply_p = CyAsLLCreateResponse(dev_p, CY_AS_SD_REG_MAX_RESP_LENGTH) ; |
|
2239 if (reply_p == 0) |
|
2240 { |
|
2241 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2242 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2243 } |
|
2244 |
|
2245 if (cb == 0) |
|
2246 { |
|
2247 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
2248 if (ret != CY_AS_ERROR_SUCCESS) |
|
2249 goto destroy ; |
|
2250 |
|
2251 return MyHandleResponseSDRegRead(dev_p, req_p, reply_p, data_p) ; |
|
2252 } |
|
2253 else |
|
2254 { |
|
2255 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_SDREGISTERREAD, |
|
2256 data_p, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
2257 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
2258 |
|
2259 if (ret != CY_AS_ERROR_SUCCESS) |
|
2260 goto destroy ; |
|
2261 |
|
2262 /* The request and response are freed as part of the MiscFuncCallback */ |
|
2263 return ret ; |
|
2264 } |
|
2265 |
|
2266 destroy: |
|
2267 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2268 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2269 |
|
2270 return ret ; |
|
2271 } |
|
2272 |
|
2273 CyAsReturnStatus_t |
|
2274 CyAsStorageCreatePPartition( |
|
2275 CyAsDeviceHandle handle, /* Handle to the device of interest */ |
|
2276 CyAsBusNumber_t bus, |
|
2277 uint32_t device, |
|
2278 uint32_t size, /* of P-port only partition in blocks */ |
|
2279 CyAsFunctionCallback cb, |
|
2280 uint32_t client) |
|
2281 { |
|
2282 CyAsLLRequestResponse *req_p, *reply_p ; |
|
2283 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2284 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2285 |
|
2286 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2287 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2288 |
|
2289 ret = IsStorageActive(dev_p) ; |
|
2290 if (ret != CY_AS_ERROR_SUCCESS) |
|
2291 return ret ; |
|
2292 |
|
2293 /* Partitions cannot be created or deleted while the USB stack is active. */ |
|
2294 if (dev_p->usb_count) |
|
2295 return CY_AS_ERROR_USB_RUNNING ; |
|
2296 |
|
2297 /* Create the request to send to the West Bridge device */ |
|
2298 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_PARTITION_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 3) ; |
|
2299 if (req_p == 0) |
|
2300 { |
|
2301 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2302 } |
|
2303 |
|
2304 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
2305 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
2306 if (reply_p == 0) |
|
2307 { |
|
2308 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2309 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2310 } |
|
2311 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00) ); |
|
2312 CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((size >> 16) & 0xffff)) ; |
|
2313 CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(size & 0xffff)) ; |
|
2314 |
|
2315 if(cb == 0) |
|
2316 { |
|
2317 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
2318 if (ret != CY_AS_ERROR_SUCCESS) |
|
2319 goto destroy ; |
|
2320 |
|
2321 return MyHandleResponseNoData(dev_p, req_p, reply_p) ; |
|
2322 } |
|
2323 else |
|
2324 { |
|
2325 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_PARTITION, |
|
2326 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
2327 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
2328 |
|
2329 if (ret != CY_AS_ERROR_SUCCESS) |
|
2330 goto destroy ; |
|
2331 |
|
2332 /* The request and response are freed as part of the FuncCallback */ |
|
2333 return ret ; |
|
2334 |
|
2335 } |
|
2336 |
|
2337 destroy: |
|
2338 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2339 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2340 |
|
2341 return ret ; |
|
2342 } |
|
2343 |
|
2344 CyAsReturnStatus_t |
|
2345 CyAsStorageRemovePPartition( |
|
2346 CyAsDeviceHandle handle, |
|
2347 CyAsBusNumber_t bus, |
|
2348 uint32_t device, |
|
2349 CyAsFunctionCallback cb, |
|
2350 uint32_t client) |
|
2351 { |
|
2352 CyAsLLRequestResponse *req_p, *reply_p ; |
|
2353 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2354 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2355 |
|
2356 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2357 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2358 |
|
2359 ret = IsStorageActive(dev_p) ; |
|
2360 if (ret != CY_AS_ERROR_SUCCESS) |
|
2361 return ret ; |
|
2362 |
|
2363 /* Partitions cannot be created or deleted while the USB stack is active. */ |
|
2364 if (dev_p->usb_count) |
|
2365 return CY_AS_ERROR_USB_RUNNING ; |
|
2366 |
|
2367 /* Create the request to send to the West Bridge device */ |
|
2368 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_PARTITION_ERASE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
2369 if (req_p == 0) |
|
2370 { |
|
2371 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2372 } |
|
2373 |
|
2374 /* Reserve space for the reply, the reply data will not exceed one word */ |
|
2375 reply_p = CyAsLLCreateResponse(dev_p, 1) ; |
|
2376 if (reply_p == 0) |
|
2377 { |
|
2378 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2379 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2380 } |
|
2381 |
|
2382 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00) ); |
|
2383 |
|
2384 if(cb == 0) |
|
2385 { |
|
2386 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
2387 if (ret != CY_AS_ERROR_SUCCESS) |
|
2388 goto destroy ; |
|
2389 |
|
2390 return MyHandleResponseNoData(dev_p, req_p, reply_p) ; |
|
2391 } |
|
2392 else |
|
2393 { |
|
2394 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_NODATA, |
|
2395 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
2396 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
2397 |
|
2398 if (ret != CY_AS_ERROR_SUCCESS) |
|
2399 goto destroy ; |
|
2400 |
|
2401 /* The request and response are freed as part of the FuncCallback */ |
|
2402 return ret ; |
|
2403 |
|
2404 } |
|
2405 |
|
2406 destroy: |
|
2407 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2408 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2409 |
|
2410 return ret ; |
|
2411 } |
|
2412 |
|
2413 static CyAsReturnStatus_t |
|
2414 MyHandleResponseGetTransferAmount(CyAsDevice* dev_p, |
|
2415 CyAsLLRequestResponse *req_p, |
|
2416 CyAsLLRequestResponse *reply_p, |
|
2417 CyAsMSCProgressData *data) |
|
2418 { |
|
2419 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2420 uint8_t code = CyAsLLRequestResponse_GetCode(reply_p) ; |
|
2421 uint16_t v1, v2 ; |
|
2422 |
|
2423 if (code != CY_RESP_TRANSFER_COUNT) |
|
2424 { |
|
2425 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
2426 goto destroy ; |
|
2427 } |
|
2428 |
|
2429 v1 = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
2430 v2 = CyAsLLRequestResponse_GetWord(reply_p, 1) ; |
|
2431 data->wr_count = (uint32_t)((v1 << 16) | v2) ; |
|
2432 |
|
2433 v1 = CyAsLLRequestResponse_GetWord(reply_p, 2) ; |
|
2434 v2 = CyAsLLRequestResponse_GetWord(reply_p, 3) ; |
|
2435 data->rd_count = (uint32_t)((v1 << 16) | v2) ; |
|
2436 |
|
2437 destroy : |
|
2438 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2439 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2440 |
|
2441 return ret ; |
|
2442 } |
|
2443 |
|
2444 CyAsReturnStatus_t |
|
2445 CyAsStorageGetTransferAmount( |
|
2446 CyAsDeviceHandle handle, |
|
2447 CyAsBusNumber_t bus, |
|
2448 uint32_t device, |
|
2449 CyAsMSCProgressData *data_p, |
|
2450 CyAsFunctionCallback cb, |
|
2451 uint32_t client |
|
2452 ) |
|
2453 { |
|
2454 CyAsLLRequestResponse *req_p, *reply_p ; |
|
2455 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2456 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2457 |
|
2458 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2459 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2460 |
|
2461 ret = IsStorageActive(dev_p) ; |
|
2462 if (ret != CY_AS_ERROR_SUCCESS) |
|
2463 return ret ; |
|
2464 |
|
2465 /* Check if the firmware image supports this feature. */ |
|
2466 if ((dev_p->media_supported[0]) && (dev_p->media_supported[0] == (1 << CyAsMediaNand))) |
|
2467 return CY_AS_ERROR_NOT_SUPPORTED ; |
|
2468 |
|
2469 /* Create the request to send to the West Bridge device */ |
|
2470 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_GET_TRANSFER_AMOUNT, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
2471 if (req_p == 0) |
|
2472 { |
|
2473 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2474 } |
|
2475 |
|
2476 /* Reserve space for the reply, the reply data will not exceed four words. */ |
|
2477 reply_p = CyAsLLCreateResponse(dev_p, 4) ; |
|
2478 if (reply_p == 0) |
|
2479 { |
|
2480 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2481 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2482 } |
|
2483 |
|
2484 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00)); |
|
2485 |
|
2486 if(cb == 0) |
|
2487 { |
|
2488 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
2489 if (ret != CY_AS_ERROR_SUCCESS) |
|
2490 goto destroy ; |
|
2491 |
|
2492 return MyHandleResponseGetTransferAmount(dev_p, req_p, reply_p, data_p) ; |
|
2493 } |
|
2494 else |
|
2495 { |
|
2496 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_GETTRANSFERAMOUNT, |
|
2497 (void *)data_p, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
2498 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
2499 |
|
2500 if (ret != CY_AS_ERROR_SUCCESS) |
|
2501 goto destroy ; |
|
2502 |
|
2503 /* The request and response are freed as part of the FuncCallback */ |
|
2504 return ret ; |
|
2505 } |
|
2506 |
|
2507 destroy: |
|
2508 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2509 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2510 |
|
2511 return ret ; |
|
2512 |
|
2513 } |
|
2514 |
|
2515 CyAsReturnStatus_t |
|
2516 CyAsStorageErase( |
|
2517 CyAsDeviceHandle handle, |
|
2518 CyAsBusNumber_t bus, |
|
2519 uint32_t device, |
|
2520 uint32_t erase_unit, |
|
2521 uint16_t num_erase_units, |
|
2522 CyAsFunctionCallback cb, |
|
2523 uint32_t client |
|
2524 ) |
|
2525 { |
|
2526 CyAsLLRequestResponse *req_p, *reply_p ; |
|
2527 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2528 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2529 |
|
2530 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2531 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2532 |
|
2533 ret = IsStorageActive(dev_p) ; |
|
2534 if (ret != CY_AS_ERROR_SUCCESS) |
|
2535 return ret ; |
|
2536 |
|
2537 if (bus < 0 || bus >= CY_AS_MAX_BUSES) |
|
2538 return CY_AS_ERROR_NO_SUCH_BUS ; |
|
2539 |
|
2540 if (device >= CY_AS_MAX_STORAGE_DEVICES) |
|
2541 return CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
2542 |
|
2543 if (dev_p->storage_device_info[bus][device].block_size == 0) |
|
2544 return CY_AS_ERROR_QUERY_DEVICE_NEEDED ; |
|
2545 |
|
2546 /* If SD is not supported on the specified bus, then return ERROR */ |
|
2547 if(dev_p->storage_device_info[bus][device].type != CyAsMediaSDFlash) |
|
2548 return CY_AS_ERROR_NOT_SUPPORTED; |
|
2549 |
|
2550 if (num_erase_units == 0) |
|
2551 return CY_AS_ERROR_SUCCESS ; |
|
2552 |
|
2553 /* Create the request to send to the West Bridge device */ |
|
2554 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ERASE, CY_RQT_STORAGE_RQT_CONTEXT, 5) ; |
|
2555 if (req_p == 0) |
|
2556 { |
|
2557 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2558 } |
|
2559 |
|
2560 /* Reserve space for the reply, the reply data will not exceed four words. */ |
|
2561 reply_p = CyAsLLCreateResponse(dev_p, 4) ; |
|
2562 if (reply_p == 0) |
|
2563 { |
|
2564 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2565 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2566 } |
|
2567 |
|
2568 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00)); |
|
2569 CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((erase_unit >> 16) & 0xffff)) ; |
|
2570 CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(erase_unit & 0xffff)) ; |
|
2571 CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_erase_units >> 8) & 0x00ff)) ; |
|
2572 CyAsLLRequestResponse_SetWord(req_p, 4, (uint16_t)((num_erase_units << 8) & 0xff00)) ; |
|
2573 |
|
2574 if(cb == 0) |
|
2575 { |
|
2576 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
2577 if (ret != CY_AS_ERROR_SUCCESS) |
|
2578 goto destroy ; |
|
2579 |
|
2580 ret = MyHandleResponseNoData(dev_p, req_p, reply_p) ; |
|
2581 |
|
2582 /* If error = "invalid response", this (very likely) means that we are not using the SD-only firmware module |
|
2583 which is the only one supporting StorageErase. In this case force a "non supported" error code */ |
|
2584 if (ret == CY_AS_ERROR_INVALID_RESPONSE) |
|
2585 ret = CY_AS_ERROR_NOT_SUPPORTED; |
|
2586 |
|
2587 return ret ; |
|
2588 } |
|
2589 else |
|
2590 { |
|
2591 ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_ERASE, |
|
2592 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, |
|
2593 req_p, reply_p, CyAsStorageFuncCallback) ; |
|
2594 |
|
2595 if (ret != CY_AS_ERROR_SUCCESS) |
|
2596 goto destroy ; |
|
2597 |
|
2598 /* The request and response are freed as part of the FuncCallback */ |
|
2599 return ret ; |
|
2600 } |
|
2601 |
|
2602 destroy: |
|
2603 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2604 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2605 |
|
2606 return ret ; |
|
2607 } |
|
2608 |
|
2609 static void |
|
2610 CyAsStorageFuncCallback(CyAsDevice *dev_p, |
|
2611 uint8_t context, |
|
2612 CyAsLLRequestResponse *rqt, |
|
2613 CyAsLLRequestResponse *resp, |
|
2614 CyAsReturnStatus_t stat) |
|
2615 { |
|
2616 CyAsFuncCBNode* node = (CyAsFuncCBNode*)dev_p->func_cbs_stor->head_p ; |
|
2617 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2618 |
|
2619 CyBool exRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX) == CY_AS_REQUEST_RESPONSE_EX ; |
|
2620 CyBool msRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS) == CY_AS_REQUEST_RESPONSE_MS ; |
|
2621 uint8_t code ; |
|
2622 uint8_t cntxt ; |
|
2623 |
|
2624 CyAsHalAssert(exRequest || msRequest) ; |
|
2625 CyAsHalAssert(dev_p->func_cbs_stor->count != 0) ; |
|
2626 CyAsHalAssert(dev_p->func_cbs_stor->type == CYAS_FUNC_CB) ; |
|
2627 (void) exRequest; |
|
2628 (void) msRequest; |
|
2629 |
|
2630 (void)context ; |
|
2631 |
|
2632 cntxt = CyAsLLRequestResponse_GetContext(rqt) ; |
|
2633 CyAsHalAssert(cntxt == CY_RQT_STORAGE_RQT_CONTEXT) ; |
|
2634 |
|
2635 code = CyAsLLRequestResponse_GetCode(rqt) ; |
|
2636 switch(code) |
|
2637 { |
|
2638 case CY_RQT_START_STORAGE: |
|
2639 ret = MyHandleResponseStorageStart(dev_p, rqt, resp, stat) ; |
|
2640 break ; |
|
2641 case CY_RQT_STOP_STORAGE: |
|
2642 ret = MyHandleResponseStorageStop(dev_p, rqt, resp, stat) ; |
|
2643 break ; |
|
2644 case CY_RQT_CLAIM_STORAGE: |
|
2645 ret = MyHandleResponseStorageClaim(dev_p, rqt, resp) ; |
|
2646 break ; |
|
2647 case CY_RQT_RELEASE_STORAGE: |
|
2648 ret = MyHandleResponseStorageRelease(dev_p, rqt, resp) ; |
|
2649 break ; |
|
2650 case CY_RQT_QUERY_MEDIA: |
|
2651 CyAsHalAssert(CyFalse) ; /* Not used any more. */ |
|
2652 break ; |
|
2653 case CY_RQT_QUERY_BUS: |
|
2654 CyAsHalAssert(node->data != 0) ; |
|
2655 ret = MyHandleResponseStorageQueryBus(dev_p, rqt, resp, (uint32_t*)node->data) ; |
|
2656 break ; |
|
2657 case CY_RQT_QUERY_DEVICE: |
|
2658 CyAsHalAssert(node->data != 0) ; |
|
2659 ret = MyHandleResponseStorageQueryDevice(dev_p, rqt, resp, node->data) ; |
|
2660 break ; |
|
2661 case CY_RQT_QUERY_UNIT: |
|
2662 CyAsHalAssert(node->data != 0) ; |
|
2663 ret = MyHandleResponseStorageQueryUnit(dev_p, rqt, resp, node->data) ; |
|
2664 break ; |
|
2665 case CY_RQT_SD_INTERFACE_CONTROL: |
|
2666 ret = MyHandleResponseNoData(dev_p, rqt, resp) ; |
|
2667 break ; |
|
2668 case CY_RQT_SD_REGISTER_READ: |
|
2669 CyAsHalAssert(node->data != 0) ; |
|
2670 ret = MyHandleResponseSDRegRead(dev_p, rqt, resp, (CyAsStorageSDRegReadData *)node->data) ; |
|
2671 break ; |
|
2672 case CY_RQT_PARTITION_STORAGE: |
|
2673 ret = MyHandleResponseNoData(dev_p, rqt, resp); |
|
2674 break ; |
|
2675 case CY_RQT_PARTITION_ERASE: |
|
2676 ret = MyHandleResponseNoData(dev_p, rqt, resp) ; |
|
2677 break ; |
|
2678 case CY_RQT_GET_TRANSFER_AMOUNT: |
|
2679 CyAsHalAssert(node->data != 0) ; |
|
2680 ret = MyHandleResponseGetTransferAmount(dev_p, rqt, resp, (CyAsMSCProgressData *)node->data) ; |
|
2681 break ; |
|
2682 case CY_RQT_ERASE: |
|
2683 ret = MyHandleResponseNoData(dev_p, rqt, resp) ; |
|
2684 |
|
2685 /* If error = "invalid response", this (very likely) means that we are not using the SD-only firmware module |
|
2686 which is the only one supporting StorageErase. In this case force a "non supported" error code */ |
|
2687 if (ret == CY_AS_ERROR_INVALID_RESPONSE) |
|
2688 ret = CY_AS_ERROR_NOT_SUPPORTED; |
|
2689 |
|
2690 break ; |
|
2691 |
|
2692 default: |
|
2693 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
2694 CyAsHalAssert(CyFalse) ; |
|
2695 break ; |
|
2696 } |
|
2697 |
|
2698 /* |
|
2699 * If the low level layer returns a direct error, use the corresponding error code. |
|
2700 * If not, use the error code based on the response from firmware. |
|
2701 */ |
|
2702 if (stat == CY_AS_ERROR_SUCCESS) |
|
2703 stat = ret ; |
|
2704 |
|
2705 /* Call the user callback, if there is one */ |
|
2706 if (node->cb_p) |
|
2707 node->cb_p((CyAsDeviceHandle)dev_p, stat, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ; |
|
2708 CyAsRemoveCBNode(dev_p->func_cbs_stor) ; |
|
2709 } |
|
2710 |
|
2711 |
|
2712 static void |
|
2713 CyAsSdioSyncReplyCallback( |
|
2714 CyAsDevice *dev_p, |
|
2715 uint8_t context, |
|
2716 CyAsLLRequestResponse *rqt, |
|
2717 CyAsLLRequestResponse *resp, |
|
2718 CyAsReturnStatus_t ret) |
|
2719 { |
|
2720 (void)rqt ; |
|
2721 |
|
2722 if ((CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_GET_TUPLE )|| |
|
2723 (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_EXT)) |
|
2724 { |
|
2725 ret = CyAsLLRequestResponse_GetWord(resp, 0) ; |
|
2726 if ((ret & 0x00FF) != CY_AS_ERROR_SUCCESS) |
|
2727 { |
|
2728 if(CyAsLLRequestResponse_GetCode(rqt) == CY_RQT_SDIO_READ_EXTENDED) |
|
2729 CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ; |
|
2730 else |
|
2731 CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ; |
|
2732 } |
|
2733 } |
|
2734 else |
|
2735 { |
|
2736 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
2737 } |
|
2738 |
|
2739 dev_p->storage_rw_resp_p=resp; |
|
2740 dev_p->storage_wait = CyFalse ; |
|
2741 if(((ret & 0x00FF) == CY_AS_ERROR_IO_ABORTED) || ((ret & 0x00FF) == CY_AS_ERROR_IO_SUSPENDED)) |
|
2742 dev_p->storage_error = (ret & 0x00FF); |
|
2743 else |
|
2744 dev_p->storage_error = (ret & 0x00FF)? CY_AS_ERROR_INVALID_RESPONSE : CY_AS_ERROR_SUCCESS ; |
|
2745 |
|
2746 /* Wake any threads/processes that are waiting on the read/write completion. */ |
|
2747 CyAsHalWake (&dev_p->context[context]->channel); |
|
2748 } |
|
2749 |
|
2750 CyAsReturnStatus_t |
|
2751 CyAsSdioDeviceCheck( |
|
2752 CyAsDevice* dev_p, |
|
2753 CyAsBusNumber_t bus, |
|
2754 uint32_t device) |
|
2755 { |
|
2756 if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) |
|
2757 return CY_AS_ERROR_INVALID_HANDLE ; |
|
2758 |
|
2759 if (bus < 0 || bus >= CY_AS_MAX_BUSES) |
|
2760 return CY_AS_ERROR_NO_SUCH_BUS ; |
|
2761 |
|
2762 if (device >= CY_AS_MAX_STORAGE_DEVICES) |
|
2763 return CY_AS_ERROR_NO_SUCH_DEVICE ; |
|
2764 |
|
2765 if (!CyAsDeviceIsAstoriaDev(dev_p)) |
|
2766 return CY_AS_ERROR_NOT_SUPPORTED ; |
|
2767 |
|
2768 return (IsStorageActive(dev_p)) ; |
|
2769 } |
|
2770 |
|
2771 CyAsReturnStatus_t |
|
2772 CyAsSdioDirectIo( |
|
2773 CyAsDeviceHandle handle, |
|
2774 CyAsBusNumber_t bus, |
|
2775 uint32_t device, |
|
2776 uint8_t nFunctionNo, |
|
2777 uint32_t address, |
|
2778 uint8_t miscBuf, |
|
2779 uint16_t argument, |
|
2780 uint8_t isWrite, |
|
2781 uint8_t * data_p ) |
|
2782 { |
|
2783 CyAsLLRequestResponse *req_p , *reply_p ; |
|
2784 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2785 uint16_t resp_data; |
|
2786 |
|
2787 /* |
|
2788 * Sanity checks required before sending the request to the |
|
2789 * firmware. |
|
2790 */ |
|
2791 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2792 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
2793 if( ret != CY_AS_ERROR_SUCCESS ) |
|
2794 return ret; |
|
2795 |
|
2796 |
|
2797 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
2798 return CY_AS_ERROR_INVALID_FUNCTION; |
|
2799 if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo)) |
|
2800 return CY_AS_ERROR_FUNCTION_SUSPENDED; |
|
2801 |
|
2802 req_p = CyAsLLCreateRequest(dev_p, (isWrite==CyTrue)?CY_RQT_SDIO_WRITE_DIRECT:CY_RQT_SDIO_READ_DIRECT, |
|
2803 CY_RQT_STORAGE_RQT_CONTEXT, 3) ; |
|
2804 if (req_p == 0) |
|
2805 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2806 |
|
2807 /*Setting up request*/ |
|
2808 |
|
2809 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ; |
|
2810 /* D1 */ |
|
2811 if(isWrite==CyTrue) |
|
2812 { |
|
2813 CyAsLLRequestResponse_SetWord(req_p, 1, ((argument<<8)|0x0080|(nFunctionNo<<4)| |
|
2814 ((miscBuf&CY_SDIO_RAW)<<3)|((miscBuf&CY_SDIO_REARM_INT)>>5)|(uint16_t)(address>>15))); |
|
2815 } |
|
2816 else |
|
2817 { |
|
2818 CyAsLLRequestResponse_SetWord(req_p, 1, (nFunctionNo<<4)|((miscBuf&CY_SDIO_REARM_INT)>>5)| |
|
2819 (uint16_t)(address>>15)); |
|
2820 } |
|
2821 /* D2 */ |
|
2822 CyAsLLRequestResponse_SetWord(req_p, 2, ((uint16_t)((address&0x00007fff)<<1))) ; |
|
2823 |
|
2824 /*Create response*/ |
|
2825 reply_p = CyAsLLCreateResponse(dev_p, 2) ; |
|
2826 |
|
2827 if (reply_p == 0) |
|
2828 { |
|
2829 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2830 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
2831 } |
|
2832 |
|
2833 /*Sending the request*/ |
|
2834 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
2835 if (ret != CY_AS_ERROR_SUCCESS) |
|
2836 goto destroy ; |
|
2837 |
|
2838 /*Check reply type*/ |
|
2839 if ( CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_SDIO_DIRECT) |
|
2840 { |
|
2841 resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
2842 if(resp_data>>8) |
|
2843 { |
|
2844 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
2845 } |
|
2846 else if (data_p!=0) |
|
2847 *(uint8_t*)(data_p)=(uint8_t)(resp_data&0x00ff); |
|
2848 } |
|
2849 else |
|
2850 { |
|
2851 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
2852 } |
|
2853 |
|
2854 destroy: |
|
2855 if(req_p!=0) |
|
2856 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
2857 if(reply_p!=0) |
|
2858 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
2859 return ret ; |
|
2860 } |
|
2861 |
|
2862 |
|
2863 CyAsReturnStatus_t |
|
2864 CyAsSdioDirectRead( |
|
2865 CyAsDeviceHandle handle, |
|
2866 CyAsBusNumber_t bus, |
|
2867 uint32_t device, |
|
2868 uint8_t nFunctionNo, |
|
2869 uint32_t address, |
|
2870 uint8_t miscBuf, |
|
2871 uint8_t * data_p) |
|
2872 { |
|
2873 return (CyAsSdioDirectIo(handle,bus,device, nFunctionNo, address, miscBuf, 0x00, CyFalse, data_p)); |
|
2874 } |
|
2875 |
|
2876 CyAsReturnStatus_t |
|
2877 CyAsSdioDirectWrite( |
|
2878 CyAsDeviceHandle handle, |
|
2879 CyAsBusNumber_t bus, |
|
2880 uint32_t device, |
|
2881 uint8_t nFunctionNo, |
|
2882 uint32_t address, |
|
2883 uint8_t miscBuf, |
|
2884 uint16_t argument, |
|
2885 uint8_t * data_p) |
|
2886 { |
|
2887 return (CyAsSdioDirectIo(handle,bus,device, nFunctionNo, address, miscBuf, argument, CyTrue, data_p)); |
|
2888 } |
|
2889 |
|
2890 /*Cmd53 IO*/ |
|
2891 CyAsReturnStatus_t |
|
2892 CyAsSdioExtendedIO( |
|
2893 CyAsDeviceHandle handle, |
|
2894 CyAsBusNumber_t bus, |
|
2895 uint32_t device, |
|
2896 uint8_t nFunctionNo, |
|
2897 uint32_t address, |
|
2898 uint8_t miscBuf, |
|
2899 uint16_t argument, |
|
2900 uint8_t isWrite, |
|
2901 uint8_t * data_p , |
|
2902 uint8_t isResume) |
|
2903 { |
|
2904 CyAsLLRequestResponse *req_p , *reply_p ; |
|
2905 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
2906 uint8_t resp_type; |
|
2907 uint8_t reqtype; |
|
2908 uint16_t resp_data; |
|
2909 CyAsContext *ctxt_p ; |
|
2910 uint32_t dmasize,loopcount = 200; |
|
2911 CyAsEndPointNumber_t ep; |
|
2912 |
|
2913 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
2914 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
2915 if( ret != CY_AS_ERROR_SUCCESS ) |
|
2916 return ret; |
|
2917 |
|
2918 |
|
2919 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
2920 return CY_AS_ERROR_INVALID_FUNCTION; |
|
2921 if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo)) |
|
2922 return CY_AS_ERROR_FUNCTION_SUSPENDED; |
|
2923 |
|
2924 |
|
2925 if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait)) |
|
2926 return CY_AS_ERROR_ASYNC_PENDING ; |
|
2927 |
|
2928 /* Request for 0 bytes of blocks is returned as a success*/ |
|
2929 if(argument == 0) |
|
2930 return CY_AS_ERROR_SUCCESS; |
|
2931 |
|
2932 /* Initialise the request to send to the West Bridge device. */ |
|
2933 if(isWrite == CyTrue) |
|
2934 { |
|
2935 reqtype =CY_RQT_SDIO_WRITE_EXTENDED; |
|
2936 ep=dev_p->storage_write_endpoint; |
|
2937 } |
|
2938 else |
|
2939 { |
|
2940 reqtype=CY_RQT_SDIO_READ_EXTENDED; |
|
2941 ep=dev_p->storage_read_endpoint; |
|
2942 } |
|
2943 |
|
2944 req_p = dev_p->storage_rw_req_p ; |
|
2945 CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3) ; |
|
2946 |
|
2947 /* Initialise the space for reply from the Antioch. */ |
|
2948 reply_p = dev_p->storage_rw_resp_p ; |
|
2949 CyAsLLInitResponse(reply_p, 2) ; |
|
2950 |
|
2951 /* Setup the DMA request */ |
|
2952 if(!(miscBuf&CY_SDIO_BLOCKMODE)) |
|
2953 { |
|
2954 if(argument > dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize) |
|
2955 return CY_AS_ERROR_INVALID_BLOCKSIZE; |
|
2956 |
|
2957 } |
|
2958 else |
|
2959 { |
|
2960 if( argument > 511) |
|
2961 { |
|
2962 return CY_AS_ERROR_INVALID_BLOCKSIZE; |
|
2963 } |
|
2964 } |
|
2965 |
|
2966 if(argument == 512) |
|
2967 argument =0; |
|
2968 |
|
2969 dmasize=((miscBuf&CY_SDIO_BLOCKMODE) !=0)? dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize*argument:argument; |
|
2970 |
|
2971 ret = CyAsDmaQueueRequest(dev_p, ep, (void*)(data_p), dmasize, CyFalse, |
|
2972 (isWrite & CyTrue)?CyFalse:CyTrue, CyAsSyncStorageCallback) ; |
|
2973 |
|
2974 if (ret != CY_AS_ERROR_SUCCESS) |
|
2975 { |
|
2976 return ret ; |
|
2977 } |
|
2978 |
|
2979 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo|((isResume)?0x80:0x00) )) ; |
|
2980 CyAsLLRequestResponse_SetWord(req_p, 1, ((uint16_t)nFunctionNo)<<12| |
|
2981 ((uint16_t)(miscBuf&(CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))<<9| |
|
2982 (uint16_t)(address>>7)|((isWrite==CyTrue)?0x8000:0x0000 )) ; |
|
2983 CyAsLLRequestResponse_SetWord(req_p, 2, ((uint16_t)(address&0x0000ffff)<<9) | argument) ; |
|
2984 |
|
2985 |
|
2986 /* Send the request and wait for completion of storage request */ |
|
2987 dev_p->storage_wait = CyTrue ; |
|
2988 ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioSyncReplyCallback) ; |
|
2989 |
|
2990 if (ret != CY_AS_ERROR_SUCCESS) |
|
2991 { |
|
2992 CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ; |
|
2993 } |
|
2994 else |
|
2995 { |
|
2996 /* Setup the DMA request */ |
|
2997 ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ; |
|
2998 ret = CyAsDmaDrainQueue(dev_p, ep, CyTrue) ; |
|
2999 |
|
3000 while (loopcount-- > 0) |
|
3001 { |
|
3002 if (dev_p->storage_wait == CyFalse) |
|
3003 break; |
|
3004 CyAsHalSleepOn(&ctxt_p->channel, 10) ; |
|
3005 } |
|
3006 if (dev_p->storage_wait == CyTrue) |
|
3007 { |
|
3008 dev_p->storage_wait = CyFalse ; |
|
3009 CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ; |
|
3010 dev_p->storage_error = CY_AS_ERROR_TIMEOUT ; |
|
3011 } |
|
3012 |
|
3013 ret=dev_p->storage_error; |
|
3014 |
|
3015 if (ret != CY_AS_ERROR_SUCCESS) |
|
3016 { |
|
3017 return ret ; |
|
3018 } |
|
3019 |
|
3020 |
|
3021 resp_type = CyAsLLRequestResponse_GetCode(dev_p->storage_rw_resp_p) ; |
|
3022 if (resp_type == CY_RESP_SDIO_EXT) |
|
3023 { |
|
3024 resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0)&0x00ff ; |
|
3025 if(resp_data) |
|
3026 { |
|
3027 ret = CY_AS_ERROR_INVALID_REQUEST ; |
|
3028 } |
|
3029 |
|
3030 } |
|
3031 else |
|
3032 { |
|
3033 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
3034 } |
|
3035 } |
|
3036 return ret; |
|
3037 |
|
3038 } |
|
3039 |
|
3040 static void |
|
3041 CyAsSdioAsyncReplyCallback( |
|
3042 CyAsDevice* dev_p, |
|
3043 uint8_t context, |
|
3044 CyAsLLRequestResponse* rqt, |
|
3045 CyAsLLRequestResponse* resp, |
|
3046 CyAsReturnStatus_t ret ) |
|
3047 { |
|
3048 CyAsStorageCallback cb_ms ; |
|
3049 uint8_t reqtype ; |
|
3050 uint32_t pendingblocks; |
|
3051 (void)rqt ; |
|
3052 (void)context ; |
|
3053 |
|
3054 pendingblocks = 0; |
|
3055 reqtype = CyAsLLRequestResponse_GetCode(rqt) ; |
|
3056 if (ret == CY_AS_ERROR_SUCCESS) |
|
3057 { |
|
3058 if ((CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SUCCESS_FAILURE) || |
|
3059 (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_EXT)) |
|
3060 { |
|
3061 ret = CyAsLLRequestResponse_GetWord(resp, 0) ; |
|
3062 ret &= 0x00FF ; |
|
3063 } |
|
3064 else |
|
3065 { |
|
3066 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
3067 } |
|
3068 } |
|
3069 |
|
3070 if (ret != CY_AS_ERROR_SUCCESS) |
|
3071 { |
|
3072 if(reqtype == CY_RQT_SDIO_READ_EXTENDED) |
|
3073 CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ; |
|
3074 else |
|
3075 CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ; |
|
3076 |
|
3077 dev_p->storage_error = ret; |
|
3078 } |
|
3079 |
|
3080 |
|
3081 |
|
3082 dev_p->storage_wait = CyFalse ; |
|
3083 |
|
3084 /* |
|
3085 * If the DMA callback has already been called, the user callback |
|
3086 * has to be called from here. |
|
3087 */ |
|
3088 if (!CyAsDeviceIsStorageAsyncPending(dev_p)) |
|
3089 { |
|
3090 CyAsHalAssert(dev_p->storage_cb_ms != NULL) ; |
|
3091 cb_ms = dev_p->storage_cb_ms ; |
|
3092 |
|
3093 dev_p->storage_cb = 0 ; |
|
3094 dev_p->storage_cb_ms = 0 ; |
|
3095 |
|
3096 if ((ret == CY_AS_ERROR_SUCCESS) || (ret == CY_AS_ERROR_IO_ABORTED) || (ret == CY_AS_ERROR_IO_SUSPENDED)) |
|
3097 { |
|
3098 ret = dev_p->storage_error ; |
|
3099 pendingblocks = ((uint32_t)CyAsLLRequestResponse_GetWord(resp, 1))<<16; |
|
3100 } |
|
3101 else |
|
3102 ret = CY_AS_ERROR_INVALID_RESPONSE; |
|
3103 |
|
3104 cb_ms((CyAsDeviceHandle)dev_p, dev_p->storage_bus_index, dev_p->storage_device_index, |
|
3105 (dev_p->storage_unit | pendingblocks), dev_p->storage_block_addr, dev_p->storage_oper, ret) ; |
|
3106 } |
|
3107 else |
|
3108 dev_p->storage_error = ret ; |
|
3109 } |
|
3110 |
|
3111 |
|
3112 CyAsReturnStatus_t |
|
3113 CyAsSdioExtendedIOAsync( |
|
3114 CyAsDeviceHandle handle, |
|
3115 CyAsBusNumber_t bus, |
|
3116 uint32_t device, |
|
3117 uint8_t nFunctionNo, |
|
3118 uint32_t address, |
|
3119 uint8_t miscBuf, |
|
3120 uint16_t argument, |
|
3121 uint8_t isWrite, |
|
3122 uint8_t * data_p, |
|
3123 CyAsStorageCallback callback ) |
|
3124 { |
|
3125 |
|
3126 uint32_t mask ; |
|
3127 uint32_t dmasize; |
|
3128 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3129 uint8_t reqtype; |
|
3130 CyAsEndPointNumber_t ep; |
|
3131 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
3132 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3133 |
|
3134 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3135 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3136 return ret; |
|
3137 |
|
3138 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3139 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3140 if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo)) |
|
3141 return CY_AS_ERROR_FUNCTION_SUSPENDED; |
|
3142 |
|
3143 if (callback == 0) |
|
3144 return CY_AS_ERROR_NULL_CALLBACK ; |
|
3145 |
|
3146 /* We are supposed to return sucess if the number of |
|
3147 * blocks is zero |
|
3148 */ |
|
3149 if(((miscBuf&CY_SDIO_BLOCKMODE)!=0)&&(argument==0)) |
|
3150 { |
|
3151 callback(handle, bus, device,nFunctionNo,address,((isWrite) ? CyAsOpWrite : CyAsOpRead), CY_AS_ERROR_SUCCESS) ; |
|
3152 return CY_AS_ERROR_SUCCESS ; |
|
3153 } |
|
3154 |
|
3155 |
|
3156 /* |
|
3157 * Since async operations can be triggered by interrupt code, we must |
|
3158 * insure that we do not get multiple async operations going at one time and |
|
3159 * protect this test and set operation from interrupts. |
|
3160 */ |
|
3161 mask = CyAsHalDisableInterrupts() ; |
|
3162 if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait)) |
|
3163 { |
|
3164 CyAsHalEnableInterrupts(mask) ; |
|
3165 return CY_AS_ERROR_ASYNC_PENDING ; |
|
3166 } |
|
3167 CyAsDeviceSetStorageAsyncPending(dev_p) ; |
|
3168 CyAsHalEnableInterrupts(mask) ; |
|
3169 |
|
3170 |
|
3171 /* |
|
3172 * Storage information about the currently outstanding request |
|
3173 */ |
|
3174 dev_p->storage_cb_ms = callback ; |
|
3175 dev_p->storage_bus_index = bus ; |
|
3176 dev_p->storage_device_index = device ; |
|
3177 dev_p->storage_unit = nFunctionNo ; |
|
3178 dev_p->storage_block_addr = address ; |
|
3179 |
|
3180 if(isWrite == CyTrue) |
|
3181 { |
|
3182 reqtype =CY_RQT_SDIO_WRITE_EXTENDED; |
|
3183 ep=dev_p->storage_write_endpoint; |
|
3184 } |
|
3185 else |
|
3186 { |
|
3187 reqtype=CY_RQT_SDIO_READ_EXTENDED; |
|
3188 ep=dev_p->storage_read_endpoint; |
|
3189 } |
|
3190 |
|
3191 /* Initialise the request to send to the West Bridge. */ |
|
3192 req_p = dev_p->storage_rw_req_p ; |
|
3193 CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3) ; |
|
3194 |
|
3195 /* Initialise the space for reply from the West Bridge. */ |
|
3196 reply_p = dev_p->storage_rw_resp_p ; |
|
3197 CyAsLLInitResponse(reply_p, 2) ; |
|
3198 |
|
3199 if(!(miscBuf&CY_SDIO_BLOCKMODE)) |
|
3200 { |
|
3201 if(argument > dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize) |
|
3202 return CY_AS_ERROR_INVALID_BLOCKSIZE; |
|
3203 |
|
3204 } |
|
3205 else |
|
3206 { |
|
3207 if( argument > 511) |
|
3208 { |
|
3209 return CY_AS_ERROR_INVALID_BLOCKSIZE; |
|
3210 } |
|
3211 } |
|
3212 |
|
3213 if(argument == 512) |
|
3214 argument =0; |
|
3215 dmasize=((miscBuf&CY_SDIO_BLOCKMODE) !=0)? dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize*argument:argument; |
|
3216 |
|
3217 /* Setup the DMA request and adjust the storage operation if we are reading */ |
|
3218 if (reqtype == CY_RQT_SDIO_READ_EXTENDED) |
|
3219 { |
|
3220 ret = CyAsDmaQueueRequest(dev_p, ep, (void*)data_p,dmasize , CyFalse, CyTrue,CyAsAsyncStorageCallback) ; |
|
3221 dev_p->storage_oper = CyAsOpRead ; |
|
3222 } |
|
3223 else if (reqtype == CY_RQT_SDIO_WRITE_EXTENDED) |
|
3224 { |
|
3225 ret = CyAsDmaQueueRequest(dev_p, ep, (void*)data_p, dmasize, CyFalse, CyFalse,CyAsAsyncStorageCallback) ; |
|
3226 dev_p->storage_oper = CyAsOpWrite ; |
|
3227 } |
|
3228 if (ret != CY_AS_ERROR_SUCCESS) |
|
3229 { |
|
3230 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
3231 return ret ; |
|
3232 } |
|
3233 |
|
3234 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ; |
|
3235 CyAsLLRequestResponse_SetWord(req_p, 1, ((uint16_t)nFunctionNo)<<12| |
|
3236 ((uint16_t)(miscBuf&(CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))<<9| |
|
3237 (uint16_t)(address>>7)|((isWrite==CyTrue)?0x8000:0x0000 )) ; |
|
3238 CyAsLLRequestResponse_SetWord(req_p, 2, ((uint16_t)(address&0x0000ffff)<<9) | argument) ; |
|
3239 |
|
3240 |
|
3241 /* Send the request and wait for completion of storage request */ |
|
3242 dev_p->storage_wait = CyTrue ; |
|
3243 ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioAsyncReplyCallback) ; |
|
3244 if (ret != CY_AS_ERROR_SUCCESS) |
|
3245 { |
|
3246 CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ; |
|
3247 CyAsDeviceClearStorageAsyncPending(dev_p) ; |
|
3248 } |
|
3249 else |
|
3250 { |
|
3251 CyAsDmaKickStart(dev_p, ep) ; |
|
3252 } |
|
3253 |
|
3254 return ret ; |
|
3255 } |
|
3256 |
|
3257 /* CMD53 Extended Read*/ |
|
3258 CyAsReturnStatus_t |
|
3259 CyAsSdioExtendedRead( |
|
3260 CyAsDeviceHandle handle, |
|
3261 CyAsBusNumber_t bus, |
|
3262 uint32_t device, |
|
3263 uint8_t nFunctionNo, |
|
3264 uint32_t address, |
|
3265 uint8_t miscBuf, |
|
3266 uint16_t argument, |
|
3267 uint8_t * data_p, |
|
3268 CyAsSdioCallback callback ) |
|
3269 { |
|
3270 if (callback==0) |
|
3271 return CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyFalse,data_p,0); |
|
3272 |
|
3273 return CyAsSdioExtendedIOAsync(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyFalse,data_p,callback); |
|
3274 } |
|
3275 |
|
3276 /* CMD53 Extended Write*/ |
|
3277 CyAsReturnStatus_t |
|
3278 CyAsSdioExtendedWrite( |
|
3279 CyAsDeviceHandle handle, |
|
3280 CyAsBusNumber_t bus, |
|
3281 uint32_t device, |
|
3282 uint8_t nFunctionNo, |
|
3283 uint32_t address, |
|
3284 uint8_t miscBuf, |
|
3285 uint16_t argument, |
|
3286 uint8_t * data_p, |
|
3287 CyAsSdioCallback callback ) |
|
3288 { |
|
3289 if (callback==0) |
|
3290 return CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyTrue,data_p,0); |
|
3291 |
|
3292 return CyAsSdioExtendedIOAsync(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyTrue,data_p,callback); |
|
3293 } |
|
3294 |
|
3295 |
|
3296 /* Read the CIS info tuples for the given function and Tuple ID*/ |
|
3297 CyAsReturnStatus_t |
|
3298 CyAsSdioGetCISInfo( |
|
3299 CyAsDeviceHandle handle, |
|
3300 CyAsBusNumber_t bus, |
|
3301 uint32_t device, |
|
3302 uint8_t nFunctionNo, |
|
3303 uint16_t tupleId, |
|
3304 uint8_t * data_p ) |
|
3305 { |
|
3306 |
|
3307 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3308 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
3309 uint16_t resp_data; |
|
3310 CyAsContext *ctxt_p ; |
|
3311 uint32_t loopcount = 200; |
|
3312 |
|
3313 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3314 |
|
3315 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3316 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3317 return ret; |
|
3318 |
|
3319 if(!( CyAsSdioCheckFunctionInitialized(handle,bus,0) )) |
|
3320 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3321 |
|
3322 if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait)) |
|
3323 return CY_AS_ERROR_ASYNC_PENDING ; |
|
3324 |
|
3325 |
|
3326 /* Initialise the request to send to the Antioch. */ |
|
3327 req_p = dev_p->storage_rw_req_p ; |
|
3328 CyAsLLInitRequest(req_p, CY_RQT_SDIO_GET_TUPLE, CY_RQT_STORAGE_RQT_CONTEXT, 2) ; |
|
3329 |
|
3330 /* Initialise the space for reply from the Antioch. */ |
|
3331 reply_p = dev_p->storage_rw_resp_p ; |
|
3332 CyAsLLInitResponse(reply_p, 3) ; |
|
3333 |
|
3334 /* Setup the DMA request */ |
|
3335 ret = CyAsDmaQueueRequest(dev_p, dev_p->storage_read_endpoint, data_p+1, 255, CyFalse, CyTrue, |
|
3336 CyAsSyncStorageCallback) ; |
|
3337 |
|
3338 if (ret != CY_AS_ERROR_SUCCESS) |
|
3339 { |
|
3340 return ret ; |
|
3341 } |
|
3342 |
|
3343 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ; |
|
3344 |
|
3345 /* Set tuple id to fetch. */ |
|
3346 CyAsLLRequestResponse_SetWord(req_p, 1, tupleId<<8) ; |
|
3347 |
|
3348 /* Send the request and wait for completion of storage request */ |
|
3349 dev_p->storage_wait = CyTrue ; |
|
3350 ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioSyncReplyCallback) ; |
|
3351 |
|
3352 |
|
3353 if (ret != CY_AS_ERROR_SUCCESS) |
|
3354 { |
|
3355 CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, CY_AS_ERROR_CANCELED) ; |
|
3356 } |
|
3357 else |
|
3358 { |
|
3359 /* Setup the DMA request */ |
|
3360 ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ; |
|
3361 ret = CyAsDmaDrainQueue(dev_p, dev_p->storage_read_endpoint, CyTrue) ; |
|
3362 |
|
3363 while (loopcount-- > 0) |
|
3364 { |
|
3365 if (dev_p->storage_wait == CyFalse) |
|
3366 break; |
|
3367 CyAsHalSleepOn(&ctxt_p->channel, 10) ; |
|
3368 } |
|
3369 |
|
3370 if (dev_p->storage_wait == CyTrue) |
|
3371 { |
|
3372 dev_p->storage_wait = CyFalse ; |
|
3373 CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ; |
|
3374 return CY_AS_ERROR_TIMEOUT ; |
|
3375 } |
|
3376 ret = dev_p->storage_error ; |
|
3377 |
|
3378 if (ret != CY_AS_ERROR_SUCCESS) |
|
3379 { |
|
3380 return ret ; |
|
3381 } |
|
3382 |
|
3383 if ( CyAsLLRequestResponse_GetCode(dev_p->storage_rw_resp_p) == CY_RESP_SDIO_GET_TUPLE) |
|
3384 { |
|
3385 resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
3386 if(resp_data) |
|
3387 { |
|
3388 ret = CY_AS_ERROR_INVALID_REQUEST ; |
|
3389 } |
|
3390 else if (data_p!=0) |
|
3391 *(uint8_t*)data_p=(uint8_t)(CyAsLLRequestResponse_GetWord(reply_p, 0)&0x00ff); |
|
3392 } |
|
3393 else |
|
3394 { |
|
3395 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
3396 } |
|
3397 } |
|
3398 return ret; |
|
3399 } |
|
3400 |
|
3401 /*Query Device*/ |
|
3402 CyAsReturnStatus_t |
|
3403 CyAsSdioQueryCard( |
|
3404 CyAsDeviceHandle handle, |
|
3405 CyAsBusNumber_t bus, |
|
3406 uint32_t device, |
|
3407 CyAsSDIOCard* data_p ) |
|
3408 { |
|
3409 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3410 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
3411 |
|
3412 uint8_t resp_type; |
|
3413 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3414 |
|
3415 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3416 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3417 return ret; |
|
3418 |
|
3419 /* Allocating memory to the SDIO device structure in dev_p */ |
|
3420 |
|
3421 CyAsHalMemSet(& dev_p->sdiocard[bus],0,sizeof(CyAsSDIODevice)); |
|
3422 |
|
3423 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_QUERY_CARD, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
3424 if (req_p == 0) |
|
3425 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3426 |
|
3427 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0 )) ; |
|
3428 |
|
3429 reply_p = CyAsLLCreateResponse(dev_p, 5) ; |
|
3430 if (reply_p == 0) |
|
3431 { |
|
3432 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3433 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3434 } |
|
3435 |
|
3436 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
3437 |
|
3438 if (ret != CY_AS_ERROR_SUCCESS) |
|
3439 goto destroy ; |
|
3440 |
|
3441 resp_type = CyAsLLRequestResponse_GetCode(reply_p); |
|
3442 if ( resp_type == CY_RESP_SDIO_QUERY_CARD) |
|
3443 { |
|
3444 dev_p->sdiocard[bus].card.num_functions = (uint8_t)((reply_p->data[0]&0xff00)>>8); |
|
3445 dev_p->sdiocard[bus].card.memory_present = (uint8_t)reply_p->data[0]&0x0001; |
|
3446 dev_p->sdiocard[bus].card.manufacturer_Id = reply_p->data[1]; |
|
3447 dev_p->sdiocard[bus].card.manufacturer_info = reply_p->data[2]; |
|
3448 dev_p->sdiocard[bus].card.blocksize = reply_p->data[3]; |
|
3449 dev_p->sdiocard[bus].card.maxblocksize = reply_p->data[3]; |
|
3450 dev_p->sdiocard[bus].card.card_capability = (uint8_t)((reply_p->data[4]&0xff00)>>8); |
|
3451 dev_p->sdiocard[bus].card.sdio_version = (uint8_t)(reply_p->data[4]&0x00ff); |
|
3452 dev_p->sdiocard[bus].function_init_map = 0x01; |
|
3453 data_p->num_functions = dev_p->sdiocard[bus].card.num_functions; |
|
3454 data_p->memory_present = dev_p->sdiocard[bus].card.memory_present; |
|
3455 data_p->manufacturer_Id = dev_p->sdiocard[bus].card.manufacturer_Id; |
|
3456 data_p->manufacturer_info = dev_p->sdiocard[bus].card.manufacturer_info; |
|
3457 data_p->blocksize = dev_p->sdiocard[bus].card.blocksize; |
|
3458 data_p->maxblocksize = dev_p->sdiocard[bus].card.maxblocksize; |
|
3459 data_p->card_capability = dev_p->sdiocard[bus].card.card_capability; |
|
3460 data_p->sdio_version = dev_p->sdiocard[bus].card.sdio_version; |
|
3461 } |
|
3462 else |
|
3463 { |
|
3464 if (resp_type == CY_RESP_SUCCESS_FAILURE) |
|
3465 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
3466 else |
|
3467 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
3468 } |
|
3469 destroy: |
|
3470 if(req_p!=0) |
|
3471 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3472 if(reply_p!=0) |
|
3473 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
3474 return ret ; |
|
3475 } |
|
3476 |
|
3477 /*Reset SDIO card. */ |
|
3478 CyAsReturnStatus_t |
|
3479 CyAsSdioResetCard( |
|
3480 CyAsDeviceHandle handle, |
|
3481 CyAsBusNumber_t bus, |
|
3482 uint32_t device ) |
|
3483 { |
|
3484 |
|
3485 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3486 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
3487 uint8_t resp_type; |
|
3488 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3489 |
|
3490 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3491 |
|
3492 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3493 return ret; |
|
3494 |
|
3495 if(dev_p->sdiocard != 0) |
|
3496 { |
|
3497 dev_p->sdiocard[bus].function_init_map=0; |
|
3498 dev_p->sdiocard[bus].function_suspended_map = 0; |
|
3499 } |
|
3500 |
|
3501 |
|
3502 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_RESET_DEV, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
3503 |
|
3504 if (req_p == 0) |
|
3505 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3506 |
|
3507 /*Setup mailbox */ |
|
3508 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0) ) ; |
|
3509 |
|
3510 reply_p = CyAsLLCreateResponse(dev_p, 2) ; |
|
3511 if (reply_p == 0) |
|
3512 { |
|
3513 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3514 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3515 } |
|
3516 |
|
3517 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
3518 |
|
3519 |
|
3520 if (ret != CY_AS_ERROR_SUCCESS) |
|
3521 goto destroy ; |
|
3522 |
|
3523 |
|
3524 resp_type = CyAsLLRequestResponse_GetCode(reply_p) ; |
|
3525 |
|
3526 |
|
3527 if (resp_type == CY_RESP_SUCCESS_FAILURE) |
|
3528 { |
|
3529 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
3530 if(ret == CY_AS_ERROR_SUCCESS) |
|
3531 { |
|
3532 ret = CyAsSdioQueryCard(handle,bus,device,0); |
|
3533 } |
|
3534 } |
|
3535 else |
|
3536 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
3537 |
|
3538 destroy: |
|
3539 if(req_p!=0) |
|
3540 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3541 if(reply_p!=0) |
|
3542 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
3543 return ret ; |
|
3544 } |
|
3545 |
|
3546 /* Initialise an IO function*/ |
|
3547 CyAsReturnStatus_t |
|
3548 CyAsSdioInitFunction( |
|
3549 CyAsDeviceHandle handle, |
|
3550 CyAsBusNumber_t bus, |
|
3551 uint32_t device, |
|
3552 uint8_t nFunctionNo, |
|
3553 uint8_t miscBuf ) |
|
3554 { |
|
3555 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3556 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
3557 uint8_t resp_type; |
|
3558 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3559 |
|
3560 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3561 |
|
3562 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3563 return ret; |
|
3564 |
|
3565 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,0))) |
|
3566 return CY_AS_ERROR_NOT_RUNNING; |
|
3567 |
|
3568 if((CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3569 { |
|
3570 if(miscBuf&CY_SDIO_FORCE_INIT) |
|
3571 dev_p->sdiocard[bus].function_init_map&=(~(1<<nFunctionNo)); |
|
3572 else |
|
3573 return CY_AS_ERROR_ALREADY_RUNNING; |
|
3574 } |
|
3575 |
|
3576 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_INIT_FUNCTION, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
3577 if (req_p == 0) |
|
3578 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3579 |
|
3580 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ; |
|
3581 |
|
3582 reply_p = CyAsLLCreateResponse(dev_p, 5) ; |
|
3583 if (reply_p == 0) |
|
3584 { |
|
3585 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3586 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3587 } |
|
3588 |
|
3589 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
3590 |
|
3591 if (ret != CY_AS_ERROR_SUCCESS) |
|
3592 goto destroy ; |
|
3593 |
|
3594 resp_type = CyAsLLRequestResponse_GetCode(reply_p) ; |
|
3595 |
|
3596 if (resp_type == CY_RESP_SDIO_INIT_FUNCTION) |
|
3597 { |
|
3598 |
|
3599 dev_p->sdiocard[bus].function[nFunctionNo-1].function_code = (uint8_t)((reply_p->data[0]&0xff00)>>8); |
|
3600 dev_p->sdiocard[bus].function[nFunctionNo-1].extended_func_code = (uint8_t)reply_p->data[0]&0x00ff; |
|
3601 dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize = reply_p->data[1]; |
|
3602 dev_p->sdiocard[bus].function[nFunctionNo-1].maxblocksize = reply_p->data[1]; |
|
3603 dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn = (uint32_t)(reply_p->data[2])<<16; |
|
3604 dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn |=(uint32_t)(reply_p->data[3]); |
|
3605 dev_p->sdiocard[bus].function[nFunctionNo-1].csa_bits = (uint8_t)((reply_p->data[4]&0xff00)>>8); |
|
3606 dev_p->sdiocard[bus].function[nFunctionNo-1].wakeup_support = (uint8_t)(reply_p->data[4]&0x0001); |
|
3607 dev_p->sdiocard[bus].function_init_map |= (1<<nFunctionNo); |
|
3608 CyAsSdioClearFunctionSuspended(handle,bus,nFunctionNo); |
|
3609 |
|
3610 } |
|
3611 else |
|
3612 { |
|
3613 if (resp_type == CY_RESP_SUCCESS_FAILURE) |
|
3614 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
3615 else |
|
3616 ret = CY_AS_ERROR_INVALID_FUNCTION ; |
|
3617 } |
|
3618 |
|
3619 destroy: |
|
3620 if(req_p!=0) |
|
3621 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3622 if(reply_p!=0) |
|
3623 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
3624 return ret ; |
|
3625 } |
|
3626 |
|
3627 /*Query individual functions. */ |
|
3628 CyAsReturnStatus_t |
|
3629 CyAsSdioQueryFunction( |
|
3630 CyAsDeviceHandle handle, |
|
3631 CyAsBusNumber_t bus, |
|
3632 uint32_t device, |
|
3633 uint8_t nFunctionNo, |
|
3634 CyAsSDIOFunc* data_p ) |
|
3635 { |
|
3636 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3637 CyAsReturnStatus_t ret; |
|
3638 |
|
3639 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3640 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3641 return ret; |
|
3642 |
|
3643 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3644 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3645 |
|
3646 data_p->blocksize = dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize; |
|
3647 data_p->card_psn = dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn; |
|
3648 data_p->csa_bits = dev_p->sdiocard[bus].function[nFunctionNo-1].csa_bits; |
|
3649 data_p->extended_func_code = dev_p->sdiocard[bus].function[nFunctionNo-1].extended_func_code; |
|
3650 data_p->function_code = dev_p->sdiocard[bus].function[nFunctionNo-1].function_code; |
|
3651 data_p->maxblocksize = dev_p->sdiocard[bus].function[nFunctionNo-1].maxblocksize; |
|
3652 data_p->wakeup_support = dev_p->sdiocard[bus].function[nFunctionNo-1].wakeup_support; |
|
3653 |
|
3654 |
|
3655 return CY_AS_ERROR_SUCCESS; |
|
3656 } |
|
3657 |
|
3658 /* Abort the Current Extended IO Operation*/ |
|
3659 CyAsReturnStatus_t |
|
3660 CyAsSdioAbortFunction( |
|
3661 CyAsDeviceHandle handle, |
|
3662 CyAsBusNumber_t bus, |
|
3663 uint32_t device, |
|
3664 uint8_t nFunctionNo) |
|
3665 { |
|
3666 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3667 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
3668 uint8_t resp_type; |
|
3669 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3670 |
|
3671 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3672 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3673 return ret; |
|
3674 |
|
3675 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3676 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3677 |
|
3678 if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait)) |
|
3679 { |
|
3680 if(!(CyAsSdioGetCardCapability(handle,bus) & CY_SDIO_SDC )) |
|
3681 { |
|
3682 return CY_AS_ERROR_INVALID_COMMAND; |
|
3683 } |
|
3684 } |
|
3685 |
|
3686 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_ABORT_IO, CY_RQT_GENERAL_RQT_CONTEXT, 1) ; |
|
3687 |
|
3688 if (req_p == 0) |
|
3689 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3690 |
|
3691 /*Setup mailbox */ |
|
3692 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ; |
|
3693 |
|
3694 reply_p = CyAsLLCreateResponse(dev_p, 2) ; |
|
3695 if (reply_p == 0) |
|
3696 { |
|
3697 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3698 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3699 } |
|
3700 |
|
3701 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
3702 if (ret != CY_AS_ERROR_SUCCESS) |
|
3703 goto destroy ; |
|
3704 |
|
3705 resp_type = CyAsLLRequestResponse_GetCode(reply_p) ; |
|
3706 |
|
3707 if (resp_type == CY_RESP_SUCCESS_FAILURE) |
|
3708 ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
3709 else |
|
3710 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
3711 |
|
3712 |
|
3713 destroy: |
|
3714 if(req_p!=0) |
|
3715 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3716 if(reply_p!=0) |
|
3717 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
3718 return ret ; |
|
3719 } |
|
3720 |
|
3721 /* Suspend IO to current function*/ |
|
3722 CyAsReturnStatus_t |
|
3723 CyAsSdioSuspend( |
|
3724 CyAsDeviceHandle handle, |
|
3725 CyAsBusNumber_t bus, |
|
3726 uint32_t device, |
|
3727 uint8_t nFunctionNo) |
|
3728 { |
|
3729 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3730 CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ; |
|
3731 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3732 |
|
3733 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3734 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3735 return ret; |
|
3736 |
|
3737 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3738 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3739 if(!(CyAsSdioCheckSupportBusSuspend(handle,bus))) |
|
3740 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3741 if(!(CyAsSdioGetCardCapability(handle,bus) & CY_SDIO_SDC)) |
|
3742 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3743 if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo)) |
|
3744 return CY_AS_ERROR_FUNCTION_SUSPENDED; |
|
3745 |
|
3746 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_SUSPEND, CY_RQT_GENERAL_RQT_CONTEXT, 1) ; |
|
3747 if (req_p == 0) |
|
3748 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3749 |
|
3750 /*Setup mailbox */ |
|
3751 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ; |
|
3752 |
|
3753 reply_p = CyAsLLCreateResponse(dev_p, 2) ; |
|
3754 if (reply_p == 0) |
|
3755 { |
|
3756 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3757 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3758 } |
|
3759 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
3760 |
|
3761 if (ret == CY_AS_ERROR_SUCCESS) |
|
3762 { |
|
3763 ret = CyAsLLRequestResponse_GetCode(reply_p) ; |
|
3764 CyAsSdioSetFunctionSuspended(handle,bus,nFunctionNo); |
|
3765 } |
|
3766 |
|
3767 if(req_p!=0) |
|
3768 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3769 if(reply_p!=0) |
|
3770 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
3771 |
|
3772 return ret ; |
|
3773 } |
|
3774 |
|
3775 /*Resume suspended function*/ |
|
3776 CyAsReturnStatus_t |
|
3777 CyAsSdioResume( |
|
3778 CyAsDeviceHandle handle, |
|
3779 CyAsBusNumber_t bus, |
|
3780 uint32_t device, |
|
3781 uint8_t nFunctionNo, |
|
3782 CyAsOperType op, |
|
3783 uint8_t miscBuf, |
|
3784 uint16_t pendingblockcount, |
|
3785 uint8_t *data_p |
|
3786 ) |
|
3787 { |
|
3788 CyAsLLRequestResponse *req_p , *reply_p ; |
|
3789 CyAsReturnStatus_t resp_data, ret = CY_AS_ERROR_SUCCESS ; |
|
3790 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3791 |
|
3792 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3793 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3794 return ret; |
|
3795 |
|
3796 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3797 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3798 |
|
3799 /* If suspend resume is not supported return */ |
|
3800 if(!(CyAsSdioCheckSupportBusSuspend(handle,bus))) |
|
3801 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3802 |
|
3803 /* if the function is not suspended return. */ |
|
3804 if(!(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))) |
|
3805 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3806 |
|
3807 req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_RESUME, CY_RQT_STORAGE_RQT_CONTEXT, 1) ; |
|
3808 if (req_p == 0) |
|
3809 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3810 |
|
3811 /*Setup mailbox */ |
|
3812 CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ; |
|
3813 |
|
3814 reply_p = CyAsLLCreateResponse(dev_p, 2) ; |
|
3815 if (reply_p == 0) |
|
3816 { |
|
3817 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3818 return CY_AS_ERROR_OUT_OF_MEMORY ; |
|
3819 } |
|
3820 ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ; |
|
3821 |
|
3822 if (ret != CY_AS_ERROR_SUCCESS) |
|
3823 goto destroy ; |
|
3824 |
|
3825 |
|
3826 if ( CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_SDIO_RESUME) |
|
3827 { |
|
3828 resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ; |
|
3829 if(resp_data & 0x00ff) |
|
3830 { |
|
3831 /* Send extended read request to resume the read. */ |
|
3832 if(op == CyAsOpRead) |
|
3833 { |
|
3834 ret = CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,0,miscBuf,pendingblockcount,CyFalse,data_p,1); |
|
3835 } |
|
3836 else |
|
3837 { |
|
3838 ret = CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,0,miscBuf,pendingblockcount,CyTrue,data_p,1); |
|
3839 } |
|
3840 } |
|
3841 else |
|
3842 { |
|
3843 ret= CY_AS_ERROR_SUCCESS; |
|
3844 } |
|
3845 |
|
3846 } |
|
3847 else |
|
3848 { |
|
3849 ret = CY_AS_ERROR_INVALID_RESPONSE ; |
|
3850 } |
|
3851 |
|
3852 destroy: |
|
3853 CyAsSdioClearFunctionSuspended(handle,bus,nFunctionNo); |
|
3854 if(req_p!=0) |
|
3855 CyAsLLDestroyRequest(dev_p, req_p) ; |
|
3856 if(reply_p!=0) |
|
3857 CyAsLLDestroyResponse(dev_p, reply_p) ; |
|
3858 return ret ; |
|
3859 |
|
3860 } |
|
3861 |
|
3862 /*Set function blocksize. Size cannot exceed max block size for the function*/ |
|
3863 CyAsReturnStatus_t |
|
3864 CyAsSdioSetBlocksize( |
|
3865 CyAsDeviceHandle handle, |
|
3866 CyAsBusNumber_t bus, |
|
3867 uint32_t device, |
|
3868 uint8_t nFunctionNo, |
|
3869 uint16_t blocksize) |
|
3870 { |
|
3871 CyAsReturnStatus_t ret; |
|
3872 CyAsDevice *dev_p = (CyAsDevice *)handle ; |
|
3873 ret = CyAsSdioDeviceCheck(dev_p,bus,device); |
|
3874 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3875 return ret; |
|
3876 |
|
3877 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3878 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3879 if( nFunctionNo == 0) |
|
3880 { |
|
3881 if ( blocksize > CyAsSdioGetCardMaxBlocksize(handle,bus)) |
|
3882 return CY_AS_ERROR_INVALID_BLOCKSIZE; |
|
3883 else if (blocksize == CyAsSdioGetCardBlocksize(handle,bus)) |
|
3884 return CY_AS_ERROR_SUCCESS; |
|
3885 } |
|
3886 else |
|
3887 { |
|
3888 if ( blocksize > CyAsSdioGetFunctionMaxBlocksize(handle,bus,nFunctionNo)) |
|
3889 return CY_AS_ERROR_INVALID_BLOCKSIZE; |
|
3890 else if (blocksize == CyAsSdioGetFunctionBlocksize(handle,bus,nFunctionNo)) |
|
3891 return CY_AS_ERROR_SUCCESS; |
|
3892 } |
|
3893 |
|
3894 ret = CyAsSdioDirectWrite(handle,bus,device,0,(uint16_t)(nFunctionNo<<8)|0x10,0,blocksize&0x00ff,0); |
|
3895 if(ret != CY_AS_ERROR_SUCCESS ) |
|
3896 return ret; |
|
3897 ret = CyAsSdioDirectWrite(handle,bus,device,0,(uint16_t)(nFunctionNo<<8)|0x11,0,(blocksize&0xff00)>>8,0); |
|
3898 if (ret != CY_AS_ERROR_SUCCESS ) |
|
3899 return ret; |
|
3900 |
|
3901 if(nFunctionNo ==0) |
|
3902 CyAsSdioSetCardBlockSize(handle,bus,blocksize); |
|
3903 else |
|
3904 CyAsSdioSetFunctionBlockSize(handle,bus,nFunctionNo,blocksize); |
|
3905 return ret; |
|
3906 } |
|
3907 |
|
3908 /* Deinitialize an SDIO function*/ |
|
3909 CyAsReturnStatus_t |
|
3910 CyAsSdioDeInitFunction( |
|
3911 CyAsDeviceHandle handle, |
|
3912 CyAsBusNumber_t bus, |
|
3913 uint32_t device, |
|
3914 uint8_t nFunctionNo) |
|
3915 { |
|
3916 CyAsReturnStatus_t ret; |
|
3917 uint8_t temp; |
|
3918 |
|
3919 if(nFunctionNo == 0) |
|
3920 return CY_AS_ERROR_INVALID_FUNCTION; |
|
3921 |
|
3922 ret = CyAsSdioDeviceCheck((CyAsDevice*)handle,bus,device); |
|
3923 if( ret != CY_AS_ERROR_SUCCESS ) |
|
3924 return ret; |
|
3925 |
|
3926 if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo))) |
|
3927 return CY_AS_ERROR_SUCCESS; |
|
3928 |
|
3929 temp =(uint8_t)(((CyAsDevice*)handle)->sdiocard[bus].function_init_map & (~(1<<nFunctionNo))); |
|
3930 CyAsSdioDirectWrite(handle,bus,device,0,0x02,0,temp,0); |
|
3931 ((CyAsDevice*)handle)->sdiocard[bus].function_init_map &= (~(1<<nFunctionNo)); |
|
3932 |
|
3933 return CY_AS_ERROR_SUCCESS; |
|
3934 } |
|
3935 |
|
3936 /* This includes the implementation of the deprecated functions for backward |
|
3937 * compatibility |
|
3938 */ |
|
3939 #include "cyasstorage_dep_impl.h" |
|
3940 |
|
3941 /*[]*/ |