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