1 /* Cypress West Bridge API source file (cyasstorage.c)
2 ## ===========================
3 ## Copyright (C) 2010 Cypress Semiconductor
5 ## This program is free software; you can redistribute it and/or
6 ## modify it under the terms of the GNU General Public License
7 ## as published by the Free Software Foundation; either version 2
8 ## of the License, or (at your option) any later version.
10 ## This program is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ## GNU General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with this program; if not, write to the Free Software
17 ## Foundation, Inc., 51 Franklin Street, Fifth Floor
18 ## Boston, MA 02110-1301, USA.
19 ## ===========================
25 * The storage module is fairly straight forward once the
26 * DMA and LOWLEVEL modules have been designed. The
27 * storage module simple takes requests from the user, queues
28 * the associated DMA requests for action, and then sends
29 * the low level requests to the West Bridge firmware.
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"
41 /* Map a pre-V1.2 media type to the V1.2+ bus number */
43 cy_an_map_bus_from_media_type(cy_as_device *dev_p,
44 cy_as_media_type type, cy_as_bus_number_t *bus)
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;
51 if (!cy_as_device_is_configured(dev_p))
52 return CY_AS_ERROR_NOT_CONFIGURED;
54 if (!cy_as_device_is_firmware_loaded(dev_p))
55 return CY_AS_ERROR_NO_FIRMWARE;
58 if (dev_p->media_supported[0] & code) {
59 if (dev_p->media_supported[1] & code) {
61 * this media type could be supported on multiple
62 * buses. so, report an address resolution error.
64 ret = CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR;
68 if (dev_p->media_supported[1] & code)
71 ret = CY_AS_ERROR_NO_SUCH_MEDIA;
78 create_address(cy_as_bus_number_t bus, uint32_t device, uint8_t unit)
80 cy_as_hal_assert(bus >= 0 && bus < CY_AS_MAX_BUSES);
81 cy_as_hal_assert(device < 16);
83 return (uint16_t)(((uint8_t)bus << 12) | (device << 8) | unit);
87 cy_as_storage_get_media_from_address(uint16_t v)
89 cy_as_media_type media = cy_as_media_max_media_value;
95 media = cy_as_media_nand;
98 media = cy_as_media_sd_flash;
101 media = cy_as_media_mmc_flash;
104 media = cy_as_media_ce_ata;
107 media = cy_as_media_sdio;
118 cy_as_storage_get_bus_from_address(uint16_t v)
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);
126 cy_as_storage_get_device_from_address(uint16_t v)
128 return (uint32_t)((v >> 8) & 0x0f);
132 get_unit_from_address(uint16_t v)
134 return (uint8_t)(v & 0xff);
137 static cy_as_return_status_t
138 cy_as_map_bad_addr(uint16_t val)
140 cy_as_return_status_t ret = CY_AS_ERROR_INVALID_RESPONSE;
144 ret = CY_AS_ERROR_NO_SUCH_BUS;
147 ret = CY_AS_ERROR_NO_SUCH_DEVICE;
150 ret = CY_AS_ERROR_NO_SUCH_UNIT;
153 ret = CY_AS_ERROR_INVALID_BLOCK;
161 my_storage_request_callback(cy_as_device *dev_p,
163 cy_as_ll_request_response *req_p,
164 cy_as_ll_request_response *resp_p,
165 cy_as_return_status_t ret)
169 cy_as_bus_number_t bus;
171 cy_as_device_handle h = (cy_as_device_handle)dev_p;
172 cy_as_dma_end_point *ep_p = NULL;
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);
183 /* Media has either been inserted or removed */
184 addr = cy_as_ll_request_response__get_word(req_p, 0);
186 bus = cy_as_storage_get_bus_from_address(addr);
187 device = cy_as_storage_get_device_from_address(addr);
189 /* Clear the entry for this device to force re-query later */
190 cy_as_hal_mem_set(&(dev_p->storage_device_info[bus][device]), 0,
191 sizeof(dev_p->storage_device_info[bus][device]));
193 val = cy_as_ll_request_response__get_word(req_p, 1);
194 if (dev_p->storage_event_cb_ms) {
196 dev_p->storage_event_cb_ms(h, bus,
197 device, cy_as_storage_removed, 0);
199 dev_p->storage_event_cb_ms(h, bus,
200 device, cy_as_storage_inserted, 0);
201 } else if (dev_p->storage_event_cb) {
203 dev_p->storage_event_cb(h, bus,
204 cy_as_storage_removed, 0);
206 dev_p->storage_event_cb(h, bus,
207 cy_as_storage_inserted, 0);
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) {
219 dev_p->storage_event_cb_ms(h, 0, 0,
220 cy_as_storage_antioch, 0);
222 dev_p->storage_event_cb_ms(h, 1, 0,
223 cy_as_storage_antioch, 0);
226 dev_p->storage_event_cb(h,
228 cy_as_storage_antioch, 0);
230 dev_p->storage_event_cb(h,
231 cy_as_media_sd_flash,
232 cy_as_storage_antioch, 0);
234 dev_p->storage_event_cb(h,
235 cy_as_media_mmc_flash,
236 cy_as_storage_antioch, 0);
238 dev_p->storage_event_cb(h,
240 cy_as_storage_antioch, 0);
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) {
251 dev_p->storage_event_cb_ms(h, 0, 0,
252 cy_as_storage_processor, 0);
254 dev_p->storage_event_cb_ms(h, 1, 0,
255 cy_as_storage_processor, 0);
256 } else if (dev_p->storage_event_cb) {
258 dev_p->storage_event_cb(h,
260 cy_as_storage_processor, 0);
262 dev_p->storage_event_cb(h,
263 cy_as_media_sd_flash,
264 cy_as_storage_processor, 0);
266 dev_p->storage_event_cb(h,
267 cy_as_media_mmc_flash,
268 cy_as_storage_processor, 0);
270 dev_p->storage_event_cb(h,
272 cy_as_storage_processor, 0);
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) {
283 dev_p->storage_event_cb_ms(h, 1, 0,
284 cy_as_sdio_interrupt, 0);
286 dev_p->storage_event_cb_ms(h, 0, 0,
287 cy_as_sdio_interrupt, 0);
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);
295 case CY_RQT_P2S_DMA_START:
296 /* Do the DMA setup for the waiting operation. */
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);
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);
312 cy_as_hal_print_message("invalid request received "
313 "on storage context\n");
315 cy_as_ll_send_data_response(dev_p, CY_RQT_STORAGE_RQT_CONTEXT,
316 CY_RESP_INVALID_REQUEST, sizeof(val), &val);
321 static cy_as_return_status_t
322 is_storage_active(cy_as_device *dev_p)
324 if (!cy_as_device_is_configured(dev_p))
325 return CY_AS_ERROR_NOT_CONFIGURED;
327 if (!cy_as_device_is_firmware_loaded(dev_p))
328 return CY_AS_ERROR_NO_FIRMWARE;
330 if (dev_p->storage_count == 0)
331 return CY_AS_ERROR_NOT_RUNNING;
333 if (cy_as_device_is_in_suspend_mode(dev_p))
334 return CY_AS_ERROR_IN_SUSPEND;
336 return CY_AS_ERROR_SUCCESS;
340 cy_as_storage_func_callback(cy_as_device *dev_p,
342 cy_as_ll_request_response *rqt,
343 cy_as_ll_request_response *resp,
344 cy_as_return_status_t ret);
346 static cy_as_return_status_t
347 my_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)
351 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
353 if (cy_as_ll_request_response__get_code(reply_p) !=
354 CY_RESP_SUCCESS_FAILURE) {
355 ret = CY_AS_ERROR_INVALID_RESPONSE;
359 ret = cy_as_ll_request_response__get_word(reply_p, 0);
362 cy_as_ll_destroy_request(dev_p, req_p);
363 cy_as_ll_destroy_response(dev_p, reply_p);
368 static cy_as_return_status_t
369 my_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)
374 if (ret != CY_AS_ERROR_SUCCESS)
377 if (cy_as_ll_request_response__get_code(reply_p) !=
378 CY_RESP_SUCCESS_FAILURE) {
379 ret = CY_AS_ERROR_INVALID_RESPONSE;
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;
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)
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)
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)
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)
408 cy_as_ll_register_request_callback(dev_p,
409 CY_RQT_STORAGE_RQT_CONTEXT, my_storage_request_callback);
411 /* Create the request/response used for storage reads and writes. */
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;
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;
426 cy_as_ll_destroy_request(dev_p, req_p);
427 cy_as_ll_destroy_response(dev_p, reply_p);
429 /* Increment the storage count only if
430 * the above functionality succeeds.*/
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;
438 dev_p->storage_count++;
441 cy_as_device_clear_s_s_s_pending(dev_p);
446 cy_as_return_status_t
447 cy_as_storage_start(cy_as_device_handle handle,
448 cy_as_function_callback cb,
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;
455 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
456 return CY_AS_ERROR_INVALID_HANDLE;
458 if (!cy_as_device_is_configured(dev_p))
459 return CY_AS_ERROR_NOT_CONFIGURED;
461 if (!cy_as_device_is_firmware_loaded(dev_p))
462 return CY_AS_ERROR_NO_FIRMWARE;
464 if (cy_as_device_is_in_suspend_mode(dev_p))
465 return CY_AS_ERROR_IN_SUSPEND;
467 if (cy_as_device_is_s_s_s_pending(dev_p))
468 return CY_AS_ERROR_STARTSTOP_PENDING;
470 cy_as_device_set_s_s_s_pending(dev_p);
472 if (dev_p->storage_count == 0) {
473 /* Create the request to send to the West Bridge device */
474 req_p = cy_as_ll_create_request(dev_p,
475 CY_RQT_START_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1);
477 cy_as_device_clear_s_s_s_pending(dev_p);
478 return CY_AS_ERROR_OUT_OF_MEMORY;
481 /* Reserve space for the reply, the reply data
482 * will not exceed one word */
483 reply_p = cy_as_ll_create_response(dev_p, 1);
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;
491 ret = cy_as_ll_send_request_wait_reply(dev_p,
493 if (ret != CY_AS_ERROR_SUCCESS)
496 return my_handle_response_storage_start(dev_p,
497 req_p, reply_p, ret);
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);
504 if (ret != CY_AS_ERROR_SUCCESS)
507 /* The request and response are freed as
508 * part of the FuncCallback */
513 cy_as_ll_destroy_request(dev_p, req_p);
514 cy_as_ll_destroy_response(dev_p, reply_p);
516 dev_p->storage_count++;
518 cb(handle, ret, client, CY_FUNCT_CB_STOR_START, 0);
521 cy_as_device_clear_s_s_s_pending(dev_p);
527 static cy_as_return_status_t
528 my_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)
533 if (ret != CY_AS_ERROR_SUCCESS)
536 if (cy_as_ll_request_response__get_code(reply_p) !=
537 CY_RESP_SUCCESS_FAILURE) {
538 ret = CY_AS_ERROR_INVALID_RESPONSE;
543 cy_as_ll_destroy_request(dev_p, req_p);
544 cy_as_ll_destroy_response(dev_p, reply_p);
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--;
552 cy_as_device_clear_s_s_s_pending(dev_p);
556 cy_as_return_status_t
557 cy_as_storage_stop(cy_as_device_handle handle,
558 cy_as_function_callback cb,
561 cy_as_ll_request_response *req_p , *reply_p;
562 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
564 cy_as_device *dev_p = (cy_as_device *)handle;
566 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
567 return CY_AS_ERROR_INVALID_HANDLE;
569 ret = is_storage_active(dev_p);
570 if (ret != CY_AS_ERROR_SUCCESS)
573 if (cy_as_device_is_storage_async_pending(dev_p))
574 return CY_AS_ERROR_ASYNC_PENDING;
576 if (cy_as_device_is_s_s_s_pending(dev_p))
577 return CY_AS_ERROR_STARTSTOP_PENDING;
579 cy_as_device_set_s_s_s_pending(dev_p);
581 if (dev_p->storage_count == 1) {
583 /* Create the request to send to the West Bridge device */
584 req_p = cy_as_ll_create_request(dev_p,
585 CY_RQT_STOP_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 0);
587 cy_as_device_clear_s_s_s_pending(dev_p);
588 return CY_AS_ERROR_OUT_OF_MEMORY;
591 /* Reserve space for the reply, the reply data
592 * will not exceed one word */
593 reply_p = cy_as_ll_create_response(dev_p, 1);
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;
601 ret = cy_as_ll_send_request_wait_reply(dev_p,
603 if (ret != CY_AS_ERROR_SUCCESS)
606 return my_handle_response_storage_stop(dev_p,
607 req_p, reply_p, ret);
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);
614 if (ret != CY_AS_ERROR_SUCCESS)
617 /* The request and response are freed
618 * as part of the MiscFuncCallback */
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--;
628 cb(handle, ret, client, CY_FUNCT_CB_STOR_STOP, 0);
631 cy_as_device_clear_s_s_s_pending(dev_p);
636 cy_as_return_status_t
637 cy_as_storage_register_callback(cy_as_device_handle handle,
638 cy_as_storage_event_callback callback)
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;
644 if (!cy_as_device_is_configured(dev_p))
645 return CY_AS_ERROR_NOT_CONFIGURED;
647 if (!cy_as_device_is_firmware_loaded(dev_p))
648 return CY_AS_ERROR_NO_FIRMWARE;
650 if (dev_p->storage_count == 0)
651 return CY_AS_ERROR_NOT_RUNNING;
653 dev_p->storage_event_cb = NULL;
654 dev_p->storage_event_cb_ms = callback;
656 return CY_AS_ERROR_SUCCESS;
661 static cy_as_return_status_t
662 my_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)
666 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
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));
675 if (cy_as_ll_request_response__get_code(reply_p) !=
676 CY_RESP_MEDIA_CLAIMED_RELEASED) {
677 ret = CY_AS_ERROR_INVALID_RESPONSE;
681 /* The response must be about the address I am
682 * trying to claim or the firmware is broken */
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;
695 if (cy_as_ll_request_response__get_word(reply_p, 1) != 1)
696 ret = CY_AS_ERROR_NOT_ACQUIRED;
699 cy_as_ll_destroy_request(dev_p, req_p);
700 cy_as_ll_destroy_response(dev_p, reply_p);
705 static cy_as_return_status_t
706 my_storage_claim(cy_as_device *dev_p,
708 cy_as_bus_number_t bus,
711 cy_as_function_callback cb,
714 cy_as_ll_request_response *req_p , *reply_p;
715 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
717 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
718 return CY_AS_ERROR_INVALID_HANDLE;
720 ret = is_storage_active(dev_p);
721 if (ret != CY_AS_ERROR_SUCCESS)
724 if (dev_p->mtp_count > 0)
725 return CY_AS_ERROR_NOT_VALID_IN_MTP;
727 /* Create the request to send to the West Bridge device */
728 req_p = cy_as_ll_create_request(dev_p,
729 CY_RQT_CLAIM_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1);
731 return CY_AS_ERROR_OUT_OF_MEMORY;
733 cy_as_ll_request_response__set_word(req_p,
734 0, create_address(bus, device, 0));
736 /* Reserve space for the reply, the reply data will
737 * not exceed one word */
738 reply_p = cy_as_ll_create_response(dev_p, 4);
740 cy_as_ll_destroy_request(dev_p, req_p);
741 return CY_AS_ERROR_OUT_OF_MEMORY;
745 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
746 if (ret != CY_AS_ERROR_SUCCESS)
749 return my_handle_response_storage_claim(dev_p, req_p, reply_p);
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);
756 if (ret != CY_AS_ERROR_SUCCESS)
759 /* The request and response are freed as part of
760 * the MiscFuncCallback */
765 cy_as_ll_destroy_request(dev_p, req_p);
766 cy_as_ll_destroy_response(dev_p, reply_p);
771 cy_as_return_status_t
772 cy_as_storage_claim(cy_as_device_handle handle,
773 cy_as_bus_number_t bus,
775 cy_as_function_callback cb,
778 cy_as_device *dev_p = (cy_as_device *)handle;
780 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
781 return CY_AS_ERROR_NO_SUCH_BUS;
783 return my_storage_claim(dev_p, NULL, bus, device,
784 CY_AS_REQUEST_RESPONSE_MS, cb, client);
787 static cy_as_return_status_t
788 my_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)
792 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
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));
801 if (cy_as_ll_request_response__get_code(reply_p) !=
802 CY_RESP_MEDIA_CLAIMED_RELEASED) {
803 ret = CY_AS_ERROR_INVALID_RESPONSE;
807 /* The response must be about the address I am
808 * trying to release or the firmware is broken */
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;
822 if (cy_as_ll_request_response__get_word(reply_p, 1) != 0)
823 ret = CY_AS_ERROR_NOT_RELEASED;
826 cy_as_ll_destroy_request(dev_p, req_p);
827 cy_as_ll_destroy_response(dev_p, reply_p);
832 static cy_as_return_status_t
833 my_storage_release(cy_as_device *dev_p,
835 cy_as_bus_number_t bus,
838 cy_as_function_callback cb,
841 cy_as_ll_request_response *req_p , *reply_p;
842 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
844 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
845 return CY_AS_ERROR_INVALID_HANDLE;
847 ret = is_storage_active(dev_p);
848 if (ret != CY_AS_ERROR_SUCCESS)
851 if (dev_p->mtp_count > 0)
852 return CY_AS_ERROR_NOT_VALID_IN_MTP;
854 /* Create the request to send to the West Bridge device */
855 req_p = cy_as_ll_create_request(dev_p, CY_RQT_RELEASE_STORAGE,
856 CY_RQT_STORAGE_RQT_CONTEXT, 1);
858 return CY_AS_ERROR_OUT_OF_MEMORY;
860 cy_as_ll_request_response__set_word(
861 req_p, 0, create_address(bus, device, 0));
863 /* Reserve space for the reply, the reply
864 * data will not exceed one word */
865 reply_p = cy_as_ll_create_response(dev_p, 4);
867 cy_as_ll_destroy_request(dev_p, req_p);
868 return CY_AS_ERROR_OUT_OF_MEMORY;
872 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
873 if (ret != CY_AS_ERROR_SUCCESS)
876 return my_handle_response_storage_release(
877 dev_p, req_p, reply_p);
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);
884 if (ret != CY_AS_ERROR_SUCCESS)
887 /* The request and response are freed as
888 * part of the MiscFuncCallback */
893 cy_as_ll_destroy_request(dev_p, req_p);
894 cy_as_ll_destroy_response(dev_p, reply_p);
899 cy_as_return_status_t
900 cy_as_storage_release(cy_as_device_handle handle,
901 cy_as_bus_number_t bus,
903 cy_as_function_callback cb,
906 cy_as_device *dev_p = (cy_as_device *)handle;
908 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
909 return CY_AS_ERROR_NO_SUCH_BUS;
911 return my_storage_release(dev_p, NULL, bus, device,
912 CY_AS_REQUEST_RESPONSE_MS, cb, client);
915 static cy_as_return_status_t
916 my_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,
921 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
922 uint8_t code = cy_as_ll_request_response__get_code(reply_p);
925 if (code == CY_RESP_NO_SUCH_ADDRESS) {
926 ret = CY_AS_ERROR_NO_SUCH_BUS;
930 if (code != CY_RESP_BUS_DESCRIPTOR) {
931 ret = CY_AS_ERROR_INVALID_RESPONSE;
936 * verify that the response corresponds to the bus that was queried.
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;
946 v = cy_as_ll_request_response__get_word(reply_p, 1);
947 if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
949 * this request is only for the count of devices
950 * on the bus. there is no need to check the media type.
958 * this request is for the count of devices of a
959 * particular type. we need to check whether the media
960 * type found matches the queried type.
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);
967 if (queried == found)
974 cy_as_ll_destroy_request(dev_p, req_p);
975 cy_as_ll_destroy_response(dev_p, reply_p);
980 cy_as_return_status_t
981 my_storage_query_bus(cy_as_device *dev_p,
982 cy_as_bus_number_t bus,
983 cy_as_media_type type,
986 cy_as_function_callback cb,
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;
993 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
994 return CY_AS_ERROR_INVALID_HANDLE;
996 ret = is_storage_active(dev_p);
997 if (ret != CY_AS_ERROR_SUCCESS)
1000 /* Create the request to send to the Antioch device */
1001 req_p = cy_as_ll_create_request(dev_p,
1002 CY_RQT_QUERY_BUS, CY_RQT_STORAGE_RQT_CONTEXT, 2);
1004 return CY_AS_ERROR_OUT_OF_MEMORY;
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);
1010 /* Reserve space for the reply, the reply data
1011 * will not exceed two words. */
1012 reply_p = cy_as_ll_create_response(dev_p, 2);
1014 cy_as_ll_destroy_request(dev_p, req_p);
1015 return CY_AS_ERROR_OUT_OF_MEMORY;
1019 ret = cy_as_ll_send_request_wait_reply(dev_p,
1021 if (ret != CY_AS_ERROR_SUCCESS)
1024 req_p->flags |= req_flags;
1025 return my_handle_response_storage_query_bus(dev_p,
1026 req_p, reply_p, count);
1028 if (req_flags == CY_AS_REQUEST_RESPONSE_EX)
1029 cb_type = CY_FUNCT_CB_STOR_QUERYMEDIA;
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);
1035 if (ret != CY_AS_ERROR_SUCCESS)
1038 /* The request and response are freed as part of
1039 * the MiscFuncCallback */
1044 cy_as_ll_destroy_request(dev_p, req_p);
1045 cy_as_ll_destroy_response(dev_p, reply_p);
1050 cy_as_return_status_t
1051 cy_as_storage_query_bus(cy_as_device_handle handle,
1052 cy_as_bus_number_t bus,
1054 cy_as_function_callback cb,
1057 cy_as_device *dev_p = (cy_as_device *)handle;
1059 return my_storage_query_bus(dev_p, bus, cy_as_media_max_media_value,
1060 CY_AS_REQUEST_RESPONSE_MS, count, cb, client);
1063 cy_as_return_status_t
1064 cy_as_storage_query_media(cy_as_device_handle handle,
1065 cy_as_media_type type,
1067 cy_as_function_callback cb,
1070 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1071 cy_as_bus_number_t bus;
1073 cy_as_device *dev_p = (cy_as_device *)handle;
1075 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
1076 return CY_AS_ERROR_INVALID_HANDLE;
1078 ret = is_storage_active(dev_p);
1079 if (ret != CY_AS_ERROR_SUCCESS)
1082 ret = cy_an_map_bus_from_media_type(dev_p, type, &bus);
1083 if (ret != CY_AS_ERROR_SUCCESS)
1086 return my_storage_query_bus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX,
1090 static cy_as_return_status_t
1091 my_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,
1096 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1098 cy_as_bus_number_t bus;
1099 cy_as_media_type type;
1104 uint16_t block_size;
1105 uint32_t number_units;
1106 uint32_t number_eus;
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));
1115 if (cy_as_ll_request_response__get_code(reply_p) !=
1116 CY_RESP_DEVICE_DESCRIPTOR) {
1117 ret = CY_AS_ERROR_INVALID_RESPONSE;
1121 /* Unpack the response */
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);
1127 block_size = cy_as_ll_request_response__get_word(reply_p, 1);
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);
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);
1138 /* Store the results based on the version of originating function */
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;
1143 /* Make sure the response is about the address we asked
1144 * about - if not, firmware error */
1145 if ((bus != store_p->bus) || (device != store_p->device)) {
1146 ret = CY_AS_ERROR_INVALID_RESPONSE;
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;
1159 cy_as_storage_query_device_data_dep *store_p =
1160 (cy_as_storage_query_device_data_dep *)data_p;
1162 /* Make sure the response is about the address we asked
1163 * about - if not, firmware error */
1164 if ((type != store_p->type) || (device != store_p->device)) {
1165 ret = CY_AS_ERROR_INVALID_RESPONSE;
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;
1180 cy_as_ll_destroy_request(dev_p, req_p);
1181 cy_as_ll_destroy_response(dev_p, reply_p);
1186 static cy_as_return_status_t
1187 my_storage_query_device(cy_as_device *dev_p,
1190 cy_as_bus_number_t bus,
1192 cy_as_function_callback cb,
1195 cy_as_ll_request_response *req_p , *reply_p;
1196 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1198 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
1199 return CY_AS_ERROR_INVALID_HANDLE;
1201 ret = is_storage_active(dev_p);
1202 if (ret != CY_AS_ERROR_SUCCESS)
1205 /* Create the request to send to the Antioch device */
1206 req_p = cy_as_ll_create_request(dev_p,
1207 CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1);
1209 return CY_AS_ERROR_OUT_OF_MEMORY;
1211 cy_as_ll_request_response__set_word(req_p, 0,
1212 create_address(bus, device, 0));
1214 /* Reserve space for the reply, the reply data
1215 * will not exceed five words. */
1216 reply_p = cy_as_ll_create_response(dev_p, 5);
1218 cy_as_ll_destroy_request(dev_p, req_p);
1219 return CY_AS_ERROR_OUT_OF_MEMORY;
1223 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1224 if (ret != CY_AS_ERROR_SUCCESS)
1227 req_p->flags |= req_flags;
1228 return my_handle_response_storage_query_device(dev_p,
1229 req_p, reply_p, data_p);
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);
1237 if (ret != CY_AS_ERROR_SUCCESS)
1240 /* The request and response are freed as part of the
1241 * MiscFuncCallback */
1246 cy_as_ll_destroy_request(dev_p, req_p);
1247 cy_as_ll_destroy_response(dev_p, reply_p);
1252 cy_as_return_status_t
1253 cy_as_storage_query_device(cy_as_device_handle handle,
1254 cy_as_storage_query_device_data *data_p,
1255 cy_as_function_callback cb,
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);
1264 static cy_as_return_status_t
1265 my_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,
1270 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1271 cy_as_bus_number_t bus;
1274 cy_as_media_type type;
1275 uint16_t block_size;
1276 uint32_t start_block;
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));
1287 if (cy_as_ll_request_response__get_code(reply_p) !=
1288 CY_RESP_UNIT_DESCRIPTOR) {
1289 ret = CY_AS_ERROR_INVALID_RESPONSE;
1293 /* Unpack the response */
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);
1299 type = cy_as_storage_get_media_from_address(
1300 cy_as_ll_request_response__get_word(reply_p, 1));
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);
1308 /* Store the results based on the version of
1309 * originating function */
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;
1314 /* Make sure the response is about the address we
1315 * asked about - if not, firmware error */
1316 if (bus != store_p->bus || device != store_p->device ||
1317 unit != store_p->unit) {
1318 ret = CY_AS_ERROR_INVALID_RESPONSE;
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;
1327 cy_as_storage_query_unit_data_dep *store_p =
1328 (cy_as_storage_query_unit_data_dep *)data_p;
1330 /* Make sure the response is about the media type we asked
1331 * about - if not, firmware error */
1332 if ((type != store_p->type) || (device != store_p->device) ||
1333 (unit != store_p->unit)) {
1334 ret = CY_AS_ERROR_INVALID_RESPONSE;
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;
1344 dev_p->storage_device_info[bus][device].type = type;
1345 dev_p->storage_device_info[bus][device].block_size = block_size;
1348 cy_as_ll_destroy_request(dev_p, req_p);
1349 cy_as_ll_destroy_response(dev_p, reply_p);
1354 static cy_as_return_status_t
1355 my_storage_query_unit(cy_as_device *dev_p,
1358 cy_as_bus_number_t bus,
1361 cy_as_function_callback cb,
1364 cy_as_ll_request_response *req_p , *reply_p;
1365 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1367 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
1368 return CY_AS_ERROR_INVALID_HANDLE;
1370 ret = is_storage_active(dev_p);
1371 if (ret != CY_AS_ERROR_SUCCESS)
1374 /* Create the request to send to the West Bridge device */
1375 req_p = cy_as_ll_create_request(dev_p,
1376 CY_RQT_QUERY_UNIT, CY_RQT_STORAGE_RQT_CONTEXT, 1);
1378 return CY_AS_ERROR_OUT_OF_MEMORY;
1381 return CY_AS_ERROR_NO_SUCH_DEVICE;
1384 return CY_AS_ERROR_NO_SUCH_UNIT;
1386 cy_as_ll_request_response__set_word(req_p, 0,
1387 create_address(bus, device, (uint8_t)unit));
1389 /* Reserve space for the reply, the reply data
1390 * will be of seven words. */
1391 reply_p = cy_as_ll_create_response(dev_p, 7);
1393 cy_as_ll_destroy_request(dev_p, req_p);
1394 return CY_AS_ERROR_OUT_OF_MEMORY;
1398 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1399 if (ret != CY_AS_ERROR_SUCCESS)
1402 req_p->flags |= req_flags;
1403 return my_handle_response_storage_query_unit(dev_p,
1404 req_p, reply_p, data_p);
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);
1412 if (ret != CY_AS_ERROR_SUCCESS)
1415 /* The request and response are freed
1416 * as part of the MiscFuncCallback */
1421 cy_as_ll_destroy_request(dev_p, req_p);
1422 cy_as_ll_destroy_response(dev_p, reply_p);
1427 cy_as_return_status_t
1428 cy_as_storage_query_unit(cy_as_device_handle handle,
1429 cy_as_storage_query_unit_data *data_p,
1430 cy_as_function_callback cb,
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);
1439 static cy_as_return_status_t
1440 cy_as_get_block_size(cy_as_device *dev_p,
1441 cy_as_bus_number_t bus,
1443 cy_as_function_callback cb)
1445 cy_as_ll_request_response *req_p , *reply_p;
1446 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1448 /* Create the request to send to the West Bridge device */
1449 req_p = cy_as_ll_create_request(dev_p, CY_RQT_QUERY_DEVICE,
1450 CY_RQT_STORAGE_RQT_CONTEXT, 1);
1452 return CY_AS_ERROR_OUT_OF_MEMORY;
1454 cy_as_ll_request_response__set_word(req_p, 0,
1455 create_address(bus, device, 0));
1457 reply_p = cy_as_ll_create_response(dev_p, 4);
1459 cy_as_ll_destroy_request(dev_p, req_p);
1460 return CY_AS_ERROR_OUT_OF_MEMORY;
1464 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1465 if (ret != CY_AS_ERROR_SUCCESS)
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;
1474 if (cy_as_ll_request_response__get_code(reply_p) !=
1475 CY_RESP_DEVICE_DESCRIPTOR) {
1476 ret = CY_AS_ERROR_INVALID_RESPONSE;
1480 /* Make sure the response is about the media type we asked
1481 * about - if not, firmware error */
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))
1487 ret = CY_AS_ERROR_INVALID_RESPONSE;
1492 dev_p->storage_device_info[bus][device].block_size =
1493 cy_as_ll_request_response__get_word(reply_p, 1);
1495 ret = CY_AS_ERROR_INVALID_REQUEST;
1498 cy_as_ll_destroy_request(dev_p, req_p);
1499 cy_as_ll_destroy_response(dev_p, reply_p);
1504 cy_as_return_status_t
1505 my_storage_device_control(
1506 cy_as_device *dev_p,
1507 cy_as_bus_number_t bus,
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,
1515 cy_as_ll_request_response *req_p , *reply_p;
1516 cy_as_return_status_t ret;
1517 cy_bool use_gpio = cy_false;
1521 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
1522 return CY_AS_ERROR_INVALID_HANDLE;
1524 if (!cy_as_device_is_configured(dev_p))
1525 return CY_AS_ERROR_NOT_CONFIGURED;
1527 if (!cy_as_device_is_firmware_loaded(dev_p))
1528 return CY_AS_ERROR_NO_FIRMWARE;
1530 if (cy_as_device_is_in_suspend_mode(dev_p))
1531 return CY_AS_ERROR_IN_SUSPEND;
1533 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
1534 return CY_AS_ERROR_NO_SUCH_BUS;
1536 if (device >= CY_AS_MAX_STORAGE_DEVICES)
1537 return CY_AS_ERROR_NO_SUCH_DEVICE;
1539 /* If SD is not supported on the specified bus,
1540 * then return ERROR */
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;
1545 if (config_detect == cy_as_storage_detect_GPIO)
1547 else if (config_detect == cy_as_storage_detect_SDAT_3)
1548 use_gpio = cy_false;
1550 return CY_AS_ERROR_INVALID_PARAMETER;
1552 /* Create the request to send to the West Bridge device */
1553 req_p = cy_as_ll_create_request(dev_p,
1554 CY_RQT_SD_INTERFACE_CONTROL, CY_RQT_STORAGE_RQT_CONTEXT, 2);
1556 return CY_AS_ERROR_OUT_OF_MEMORY;
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));
1564 reply_p = cy_as_ll_create_response(dev_p, 1);
1566 cy_as_ll_destroy_request(dev_p, req_p);
1567 return CY_AS_ERROR_OUT_OF_MEMORY;
1571 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
1572 if (ret != CY_AS_ERROR_SUCCESS)
1575 if (cy_as_ll_request_response__get_code(reply_p) !=
1576 CY_RESP_SUCCESS_FAILURE) {
1577 ret = CY_AS_ERROR_INVALID_RESPONSE;
1581 ret = cy_as_ll_request_response__get_word(reply_p, 0);
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);
1589 if (ret != CY_AS_ERROR_SUCCESS)
1592 /* The request and response are freed as part of the
1593 * MiscFuncCallback */
1597 cy_as_ll_destroy_request(dev_p, req_p);
1598 cy_as_ll_destroy_response(dev_p, reply_p);
1603 cy_as_return_status_t
1604 cy_as_storage_device_control(cy_as_device_handle handle,
1605 cy_as_bus_number_t bus,
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,
1613 cy_as_device *dev_p = (cy_as_device *)handle;
1615 return my_storage_device_control(dev_p, bus, device, card_detect_en,
1616 write_prot_en, config_detect, cb, client);
1620 cy_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)
1624 cy_as_storage_callback_dep cb;
1625 cy_as_storage_callback cb_ms;
1631 cy_as_device_clear_storage_async_pending(dev_p);
1634 * if the LL request callback has already been called,
1635 * the user callback has to be called from here.
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;
1643 dev_p->storage_cb = 0;
1644 dev_p->storage_cb_ms = 0;
1646 if (ret == CY_AS_ERROR_SUCCESS)
1647 ret = dev_p->storage_error;
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);
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);
1667 dev_p->storage_error = ret;
1671 cy_as_async_storage_reply_callback(
1672 cy_as_device *dev_p,
1674 cy_as_ll_request_response *rqt,
1675 cy_as_ll_request_response *resp,
1676 cy_as_return_status_t ret)
1678 cy_as_storage_callback_dep cb;
1679 cy_as_storage_callback cb_ms;
1684 reqtype = cy_as_ll_request_response__get_code(rqt);
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
1691 } else if (cy_as_ll_request_response__get_code(resp) !=
1692 CY_RESP_SUCCESS_FAILURE) {
1693 ret = CY_AS_ERROR_INVALID_RESPONSE;
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);
1702 cy_as_dma_cancel(dev_p,
1703 dev_p->storage_write_endpoint, ret);
1706 dev_p->storage_wait = cy_false;
1709 * if the DMA callback has already been called, the
1710 * user callback has to be called from here.
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;
1718 dev_p->storage_cb = 0;
1719 dev_p->storage_cb_ms = 0;
1721 if (ret == CY_AS_ERROR_SUCCESS)
1722 ret = dev_p->storage_error;
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);
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);
1742 dev_p->storage_error = ret;
1745 static cy_as_return_status_t
1746 cy_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)
1753 cy_as_ll_request_response *req_p , *reply_p;
1754 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
1756 ret = is_storage_active(dev_p);
1757 if (ret != CY_AS_ERROR_SUCCESS)
1760 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
1761 return CY_AS_ERROR_NO_SUCH_BUS;
1763 if (device >= CY_AS_MAX_STORAGE_DEVICES)
1764 return CY_AS_ERROR_NO_SUCH_DEVICE;
1767 return CY_AS_ERROR_NO_SUCH_UNIT;
1769 /* We are supposed to return sucess if the number of
1772 if (num_blocks == 0) {
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);
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);
1787 return CY_AS_ERROR_SUCCESS;
1790 if (dev_p->storage_device_info[bus][device].block_size == 0)
1791 return CY_AS_ERROR_QUERY_DEVICE_NEEDED;
1794 * since async operations can be triggered by interrupt
1795 * code, we must insure that we do not get multiple
1796 * async operations going at one time and protect this
1797 * test and set operation from interrupts. also need to
1798 * check for pending async MTP writes
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;
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);
1813 * storage information about the currently outstanding request
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;
1822 /* Initialise the request to send to the West Bridge. */
1823 req_p = dev_p->storage_rw_req_p;
1824 cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5);
1826 /* Initialise the space for reply from the West Bridge. */
1827 reply_p = dev_p->storage_rw_resp_p;
1828 cy_as_ll_init_response(reply_p, 5);
1830 /* Remember which version of the API originated the request */
1831 req_p->flags |= req_flags;
1833 /* Setup the DMA request and adjust the storage
1834 * operation if we are reading */
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;
1849 if (ret != CY_AS_ERROR_SUCCESS) {
1850 cy_as_device_clear_storage_async_pending(dev_p);
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));
1865 /* Set the burst mode flag. */
1866 if (dev_p->is_storage_only_mode)
1867 req_p->data[4] |= 0x0001;
1869 /* Send the request and wait for completion
1870 * of storage request */
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);
1883 cy_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)
1891 dev_p->storage_error = err;
1895 cy_as_sync_storage_reply_callback(
1896 cy_as_device *dev_p,
1898 cy_as_ll_request_response *rqt,
1899 cy_as_ll_request_response *resp,
1900 cy_as_return_status_t ret)
1905 reqtype = cy_as_ll_request_response__get_code(rqt);
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;
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);
1916 cy_as_dma_cancel(dev_p,
1917 dev_p->storage_write_endpoint, ret);
1919 } else if (cy_as_ll_request_response__get_code(resp) !=
1920 CY_RESP_SUCCESS_FAILURE) {
1921 ret = CY_AS_ERROR_INVALID_RESPONSE;
1924 dev_p->storage_wait = cy_false;
1925 dev_p->storage_error = ret;
1927 /* Wake any threads/processes that are waiting on
1928 * the read/write completion. */
1929 cy_as_hal_wake(&dev_p->context[context]->channel);
1932 static cy_as_return_status_t
1933 cy_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)
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;
1944 ret = is_storage_active(dev_p);
1945 if (ret != CY_AS_ERROR_SUCCESS)
1948 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
1949 return CY_AS_ERROR_NO_SUCH_BUS;
1951 if (device >= CY_AS_MAX_STORAGE_DEVICES)
1952 return CY_AS_ERROR_NO_SUCH_DEVICE;
1955 return CY_AS_ERROR_NO_SUCH_UNIT;
1957 if ((cy_as_device_is_storage_async_pending(dev_p)) ||
1958 (dev_p->storage_wait))
1959 return CY_AS_ERROR_ASYNC_PENDING;
1961 /* Also need to check for pending Async MTP writes */
1962 if (cy_as_device_is_usb_async_pending(dev_p, 6))
1963 return CY_AS_ERROR_ASYNC_PENDING;
1965 /* We are supposed to return sucess if the number of
1968 if (num_blocks == 0)
1969 return CY_AS_ERROR_SUCCESS;
1971 if (dev_p->storage_device_info[bus][device].block_size == 0) {
1973 * normally, a given device has been queried via
1974 * the query device call before a read request is issued.
1975 * therefore, this normally will not be run.
1977 ret = cy_as_get_block_size(dev_p, bus, device, 0);
1978 if (ret != CY_AS_ERROR_SUCCESS)
1982 /* Initialise the request to send to the West Bridge. */
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);
1987 /* Initialise the space for reply from
1988 * the West Bridge. */
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);
1993 /* Setup the DMA request */
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;
2008 if (ret != CY_AS_ERROR_SUCCESS)
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));
2022 /* Set the burst mode flag. */
2023 if (dev_p->is_storage_only_mode)
2024 req_p->data[4] |= 0x0001;
2026 /* Send the request and wait for
2027 * completion of storage request */
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);
2034 /* Setup the DMA request */
2035 ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT];
2036 ret = cy_as_dma_drain_queue(dev_p, ep, cy_false);
2038 while (loopcount-- > 0) {
2039 if (dev_p->storage_wait == cy_false)
2041 cy_as_hal_sleep_on(&ctxt_p->channel, 10);
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;
2050 if (ret == CY_AS_ERROR_SUCCESS)
2051 ret = dev_p->storage_error;
2057 cy_as_return_status_t
2058 cy_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)
2063 cy_as_device *dev_p = (cy_as_device *)handle;
2065 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2066 return CY_AS_ERROR_INVALID_HANDLE;
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);
2073 cy_as_return_status_t
2074 cy_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)
2079 cy_as_device *dev_p = (cy_as_device *)handle;
2081 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2082 return CY_AS_ERROR_INVALID_HANDLE;
2084 if (dev_p->mtp_turbo_active)
2085 return CY_AS_ERROR_NOT_VALID_DURING_MTP;
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);
2094 cy_as_return_status_t
2095 cy_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)
2100 cy_as_device *dev_p = (cy_as_device *)handle;
2102 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2103 return CY_AS_ERROR_INVALID_HANDLE;
2106 return CY_AS_ERROR_NULL_CALLBACK;
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);
2114 cy_as_return_status_t
2115 cy_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)
2120 cy_as_device *dev_p = (cy_as_device *)handle;
2122 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2123 return CY_AS_ERROR_INVALID_HANDLE;
2126 return CY_AS_ERROR_NULL_CALLBACK;
2128 if (dev_p->mtp_turbo_active)
2129 return CY_AS_ERROR_NOT_VALID_DURING_MTP;
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);
2139 my_storage_cancel_callback(
2140 cy_as_device *dev_p,
2142 cy_as_ll_request_response *rqt,
2143 cy_as_ll_request_response *resp,
2144 cy_as_return_status_t stat)
2149 /* Nothing to do here, except free up the
2150 * request and response structures. */
2151 cy_as_ll_destroy_response(dev_p, resp);
2152 cy_as_ll_destroy_request(dev_p, rqt);
2156 cy_as_return_status_t
2157 cy_as_storage_cancel_async(cy_as_device_handle handle)
2159 cy_as_return_status_t ret;
2160 cy_as_ll_request_response *req_p , *reply_p;
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;
2166 ret = is_storage_active(dev_p);
2167 if (ret != CY_AS_ERROR_SUCCESS)
2170 if (!cy_as_device_is_storage_async_pending(dev_p))
2171 return CY_AS_ERROR_ASYNC_NOT_PENDING;
2174 * create and send a mailbox request to firmware
2175 * asking it to abort processing of the current
2176 * P2S operation. the rest of the cancel processing will be
2177 * driven through the callbacks for the read/write call.
2179 req_p = cy_as_ll_create_request(dev_p, CY_RQT_ABORT_P2S_XFER,
2180 CY_RQT_GENERAL_RQT_CONTEXT, 1);
2182 return CY_AS_ERROR_OUT_OF_MEMORY;
2184 reply_p = cy_as_ll_create_response(dev_p, 1);
2186 cy_as_ll_destroy_request(dev_p, req_p);
2187 return CY_AS_ERROR_OUT_OF_MEMORY;
2190 ret = cy_as_ll_send_request(dev_p, req_p,
2191 reply_p, cy_false, my_storage_cancel_callback);
2193 cy_as_ll_destroy_request(dev_p, req_p);
2194 cy_as_ll_destroy_response(dev_p, reply_p);
2197 return CY_AS_ERROR_SUCCESS;
2201 * This function does all the API side clean-up associated with
2202 * CyAsStorageStop, without any communication with the firmware.
2204 void cy_as_storage_cleanup(cy_as_device *dev_p)
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));
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;
2221 static cy_as_return_status_t
2222 my_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)
2228 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2229 uint8_t resp_type, i;
2231 uint8_t length = info->length;
2232 uint8_t *data_p = info->buf_p;
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;
2239 resp_len = cy_as_ll_request_response__get_word(reply_p, 0);
2240 cy_as_hal_assert(resp_len >= length);
2243 * copy the values into the output buffer after doing the
2244 * necessary bit shifting. the bit shifting is required because
2245 * the data comes out of the west bridge with a 6 bit offset.
2249 temp = ((resp_p[i] << 6) | (resp_p[i + 1] >> 10));
2252 *data_p++ = (uint8_t)(temp >> 8);
2256 *data_p++ = (uint8_t)(temp & 0xFF);
2261 if (resp_type == CY_RESP_SUCCESS_FAILURE)
2262 ret = cy_as_ll_request_response__get_word(reply_p, 0);
2264 ret = CY_AS_ERROR_INVALID_RESPONSE;
2267 cy_as_ll_destroy_response(dev_p, reply_p);
2268 cy_as_ll_destroy_request(dev_p, req_p);
2273 cy_as_return_status_t
2274 cy_as_storage_sd_register_read(
2275 cy_as_device_handle handle,
2276 cy_as_bus_number_t bus,
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,
2283 cy_as_ll_request_response *req_p , *reply_p;
2284 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2288 * sanity checks required before sending the request to the
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;
2295 ret = is_storage_active(dev_p);
2296 if (ret != CY_AS_ERROR_SUCCESS)
2299 if (device >= CY_AS_MAX_STORAGE_DEVICES)
2300 return CY_AS_ERROR_NO_SUCH_DEVICE;
2302 if (reg_type > cy_as_sd_reg_CSD)
2303 return CY_AS_ERROR_INVALID_PARAMETER;
2305 /* If SD/MMC media is not supported on the
2306 * addressed bus, return error. */
2307 if ((dev_p->media_supported[bus] & (1 << cy_as_media_sd_flash)) == 0)
2308 return CY_AS_ERROR_INVALID_PARAMETER;
2311 * find the amount of data to be returned. this will be the minimum of
2312 * the actual data length, and the length requested.
2315 case cy_as_sd_reg_OCR:
2316 length = CY_AS_SD_REG_OCR_LENGTH;
2318 case cy_as_sd_reg_CID:
2319 length = CY_AS_SD_REG_CID_LENGTH;
2321 case cy_as_sd_reg_CSD:
2322 length = CY_AS_SD_REG_CSD_LENGTH;
2327 cy_as_hal_assert(0);
2330 if (length < data_p->length)
2331 data_p->length = length;
2332 length = data_p->length;
2334 /* Create the request to send to the West Bridge device */
2335 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SD_REGISTER_READ,
2336 CY_RQT_STORAGE_RQT_CONTEXT, 1);
2338 return CY_AS_ERROR_OUT_OF_MEMORY;
2340 cy_as_ll_request_response__set_word(req_p, 0,
2341 (create_address(bus, device, 0) | (uint16_t)reg_type));
2343 reply_p = cy_as_ll_create_response(dev_p,
2344 CY_AS_SD_REG_MAX_RESP_LENGTH);
2346 cy_as_ll_destroy_request(dev_p, req_p);
2347 return CY_AS_ERROR_OUT_OF_MEMORY;
2351 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2352 if (ret != CY_AS_ERROR_SUCCESS)
2355 return my_handle_response_sd_reg_read(dev_p,
2356 req_p, reply_p, data_p);
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);
2363 if (ret != CY_AS_ERROR_SUCCESS)
2366 /* The request and response are freed as part of the
2367 * MiscFuncCallback */
2372 cy_as_ll_destroy_request(dev_p, req_p);
2373 cy_as_ll_destroy_response(dev_p, reply_p);
2378 cy_as_return_status_t
2379 cy_as_storage_create_p_partition(
2380 /* Handle to the device of interest */
2381 cy_as_device_handle handle,
2382 cy_as_bus_number_t bus,
2384 /* of P-port only partition in blocks */
2386 cy_as_function_callback cb,
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;
2393 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2394 return CY_AS_ERROR_INVALID_HANDLE;
2396 ret = is_storage_active(dev_p);
2397 if (ret != CY_AS_ERROR_SUCCESS)
2400 /* Partitions cannot be created or deleted while
2401 * the USB stack is active. */
2402 if (dev_p->usb_count)
2403 return CY_AS_ERROR_USB_RUNNING;
2405 /* Create the request to send to the West Bridge device */
2406 req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_STORAGE,
2407 CY_RQT_STORAGE_RQT_CONTEXT, 3);
2410 return CY_AS_ERROR_OUT_OF_MEMORY;
2412 /* Reserve space for the reply, the reply
2413 * data will not exceed one word */
2414 reply_p = cy_as_ll_create_response(dev_p, 1);
2416 cy_as_ll_destroy_request(dev_p, req_p);
2417 return CY_AS_ERROR_OUT_OF_MEMORY;
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));
2427 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2428 if (ret != CY_AS_ERROR_SUCCESS)
2431 return my_handle_response_no_data(dev_p, req_p, reply_p);
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);
2438 if (ret != CY_AS_ERROR_SUCCESS)
2441 /* The request and response are freed as part of the
2448 cy_as_ll_destroy_request(dev_p, req_p);
2449 cy_as_ll_destroy_response(dev_p, reply_p);
2454 cy_as_return_status_t
2455 cy_as_storage_remove_p_partition(
2456 cy_as_device_handle handle,
2457 cy_as_bus_number_t bus,
2459 cy_as_function_callback cb,
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;
2466 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2467 return CY_AS_ERROR_INVALID_HANDLE;
2469 ret = is_storage_active(dev_p);
2470 if (ret != CY_AS_ERROR_SUCCESS)
2473 /* Partitions cannot be created or deleted while
2474 * the USB stack is active. */
2475 if (dev_p->usb_count)
2476 return CY_AS_ERROR_USB_RUNNING;
2478 /* Create the request to send to the West Bridge device */
2479 req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_ERASE,
2480 CY_RQT_STORAGE_RQT_CONTEXT, 1);
2482 return CY_AS_ERROR_OUT_OF_MEMORY;
2484 /* Reserve space for the reply, the reply
2485 * data will not exceed one word */
2486 reply_p = cy_as_ll_create_response(dev_p, 1);
2488 cy_as_ll_destroy_request(dev_p, req_p);
2489 return CY_AS_ERROR_OUT_OF_MEMORY;
2492 cy_as_ll_request_response__set_word(req_p,
2493 0, create_address(bus, (uint8_t)device, 0x00));
2496 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2497 if (ret != CY_AS_ERROR_SUCCESS)
2500 return my_handle_response_no_data(dev_p, req_p, reply_p);
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);
2507 if (ret != CY_AS_ERROR_SUCCESS)
2510 /* The request and response are freed
2511 * as part of the FuncCallback */
2517 cy_as_ll_destroy_request(dev_p, req_p);
2518 cy_as_ll_destroy_response(dev_p, reply_p);
2523 static cy_as_return_status_t
2524 my_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)
2529 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2530 uint8_t code = cy_as_ll_request_response__get_code(reply_p);
2533 if (code != CY_RESP_TRANSFER_COUNT) {
2534 ret = CY_AS_ERROR_INVALID_RESPONSE;
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);
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);
2547 cy_as_ll_destroy_request(dev_p, req_p);
2548 cy_as_ll_destroy_response(dev_p, reply_p);
2553 cy_as_return_status_t
2554 cy_as_storage_get_transfer_amount(
2555 cy_as_device_handle handle,
2556 cy_as_bus_number_t bus,
2558 cy_as_m_s_c_progress_data *data_p,
2559 cy_as_function_callback cb,
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;
2567 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2568 return CY_AS_ERROR_INVALID_HANDLE;
2570 ret = is_storage_active(dev_p);
2571 if (ret != CY_AS_ERROR_SUCCESS)
2574 /* Check if the firmware image supports this feature. */
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;
2579 /* Create the request to send to the West Bridge device */
2580 req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_TRANSFER_AMOUNT,
2581 CY_RQT_STORAGE_RQT_CONTEXT, 1);
2583 return CY_AS_ERROR_OUT_OF_MEMORY;
2585 /* Reserve space for the reply, the reply data
2586 * will not exceed four words. */
2587 reply_p = cy_as_ll_create_response(dev_p, 4);
2589 cy_as_ll_destroy_request(dev_p, req_p);
2590 return CY_AS_ERROR_OUT_OF_MEMORY;
2593 cy_as_ll_request_response__set_word(req_p, 0,
2594 create_address(bus, (uint8_t)device, 0x00));
2597 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2598 if (ret != CY_AS_ERROR_SUCCESS)
2601 return my_handle_response_get_transfer_amount(dev_p,
2602 req_p, reply_p, data_p);
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);
2609 if (ret != CY_AS_ERROR_SUCCESS)
2612 /* The request and response are freed as part of the
2618 cy_as_ll_destroy_request(dev_p, req_p);
2619 cy_as_ll_destroy_response(dev_p, reply_p);
2625 cy_as_return_status_t
2626 cy_as_storage_erase(
2627 cy_as_device_handle handle,
2628 cy_as_bus_number_t bus,
2630 uint32_t erase_unit,
2631 uint16_t num_erase_units,
2632 cy_as_function_callback cb,
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;
2640 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2641 return CY_AS_ERROR_INVALID_HANDLE;
2643 ret = is_storage_active(dev_p);
2644 if (ret != CY_AS_ERROR_SUCCESS)
2647 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
2648 return CY_AS_ERROR_NO_SUCH_BUS;
2650 if (device >= CY_AS_MAX_STORAGE_DEVICES)
2651 return CY_AS_ERROR_NO_SUCH_DEVICE;
2653 if (dev_p->storage_device_info[bus][device].block_size == 0)
2654 return CY_AS_ERROR_QUERY_DEVICE_NEEDED;
2656 /* If SD is not supported on the specified bus, then return ERROR */
2657 if (dev_p->storage_device_info[bus][device].type !=
2658 cy_as_media_sd_flash)
2659 return CY_AS_ERROR_NOT_SUPPORTED;
2661 if (num_erase_units == 0)
2662 return CY_AS_ERROR_SUCCESS;
2664 /* Create the request to send to the West Bridge device */
2665 req_p = cy_as_ll_create_request(dev_p, CY_RQT_ERASE,
2666 CY_RQT_STORAGE_RQT_CONTEXT, 5);
2669 return CY_AS_ERROR_OUT_OF_MEMORY;
2671 /* Reserve space for the reply, the reply
2672 * data will not exceed four words. */
2673 reply_p = cy_as_ll_create_response(dev_p, 4);
2675 cy_as_ll_destroy_request(dev_p, req_p);
2676 return CY_AS_ERROR_OUT_OF_MEMORY;
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));
2691 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2692 if (ret != CY_AS_ERROR_SUCCESS)
2695 ret = my_handle_response_no_data(dev_p, req_p, reply_p);
2697 /* If error = "invalid response", this (very likely) means
2698 * that we are not using the SD-only firmware module which
2699 * is the only one supporting storage_erase. in this case
2700 * force a "non supported" error code */
2701 if (ret == CY_AS_ERROR_INVALID_RESPONSE)
2702 ret = CY_AS_ERROR_NOT_SUPPORTED;
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);
2711 if (ret != CY_AS_ERROR_SUCCESS)
2714 /* The request and response are freed
2715 * as part of the FuncCallback */
2720 cy_as_ll_destroy_request(dev_p, req_p);
2721 cy_as_ll_destroy_response(dev_p, reply_p);
2727 cy_as_storage_func_callback(cy_as_device *dev_p,
2729 cy_as_ll_request_response *rqt,
2730 cy_as_ll_request_response *resp,
2731 cy_as_return_status_t stat)
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;
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;
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);
2752 cntxt = cy_as_ll_request_response__get_context(rqt);
2753 cy_as_hal_assert(cntxt == CY_RQT_STORAGE_RQT_CONTEXT);
2755 code = cy_as_ll_request_response__get_code(rqt);
2757 case CY_RQT_START_STORAGE:
2758 ret = my_handle_response_storage_start(dev_p, rqt, resp, stat);
2760 case CY_RQT_STOP_STORAGE:
2761 ret = my_handle_response_storage_stop(dev_p, rqt, resp, stat);
2763 case CY_RQT_CLAIM_STORAGE:
2764 ret = my_handle_response_storage_claim(dev_p, rqt, resp);
2766 case CY_RQT_RELEASE_STORAGE:
2767 ret = my_handle_response_storage_release(dev_p, rqt, resp);
2769 case CY_RQT_QUERY_MEDIA:
2770 cy_as_hal_assert(cy_false);/* Not used any more. */
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);
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);
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);
2787 case CY_RQT_SD_INTERFACE_CONTROL:
2788 ret = my_handle_response_no_data(dev_p, rqt, resp);
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);
2795 case CY_RQT_PARTITION_STORAGE:
2796 ret = my_handle_response_no_data(dev_p, rqt, resp);
2798 case CY_RQT_PARTITION_ERASE:
2799 ret = my_handle_response_no_data(dev_p, rqt, resp);
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);
2807 ret = my_handle_response_no_data(dev_p, rqt, resp);
2809 /* If error = "invalid response", this (very likely)
2810 * means that we are not using the SD-only firmware
2811 * module which is the only one supporting storage_erase.
2812 * in this case force a "non supported" error code */
2813 if (ret == CY_AS_ERROR_INVALID_RESPONSE)
2814 ret = CY_AS_ERROR_NOT_SUPPORTED;
2819 ret = CY_AS_ERROR_INVALID_RESPONSE;
2820 cy_as_hal_assert(cy_false);
2825 * if the low level layer returns a direct error, use the
2826 * corresponding error code. if not, use the error code
2827 * based on the response from firmware.
2829 if (stat == CY_AS_ERROR_SUCCESS)
2832 /* Call the user callback, if there is one */
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);
2841 cy_as_sdio_sync_reply_callback(
2842 cy_as_device *dev_p,
2844 cy_as_ll_request_response *rqt,
2845 cy_as_ll_request_response *resp,
2846 cy_as_return_status_t ret)
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);
2861 cy_as_dma_cancel(dev_p,
2862 dev_p->storage_write_endpoint, ret);
2865 ret = CY_AS_ERROR_INVALID_RESPONSE;
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);
2874 dev_p->storage_error = (ret & 0x00FF) ?
2875 CY_AS_ERROR_INVALID_RESPONSE : CY_AS_ERROR_SUCCESS;
2877 /* Wake any threads/processes that are waiting on
2878 * the read/write completion. */
2879 cy_as_hal_wake(&dev_p->context[context]->channel);
2882 cy_as_return_status_t
2883 cy_as_sdio_device_check(
2884 cy_as_device *dev_p,
2885 cy_as_bus_number_t bus,
2888 if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
2889 return CY_AS_ERROR_INVALID_HANDLE;
2891 if (bus < 0 || bus >= CY_AS_MAX_BUSES)
2892 return CY_AS_ERROR_NO_SUCH_BUS;
2894 if (device >= CY_AS_MAX_STORAGE_DEVICES)
2895 return CY_AS_ERROR_NO_SUCH_DEVICE;
2897 if (!cy_as_device_is_astoria_dev(dev_p))
2898 return CY_AS_ERROR_NOT_SUPPORTED;
2900 return (is_storage_active(dev_p));
2903 cy_as_return_status_t
2904 cy_as_sdio_direct_io(
2905 cy_as_device_handle handle,
2906 cy_as_bus_number_t bus,
2908 uint8_t n_function_no,
2915 cy_as_ll_request_response *req_p , *reply_p;
2916 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
2920 * sanity checks required before sending the request to the
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)
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;
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);
2939 return CY_AS_ERROR_OUT_OF_MEMORY;
2941 /*Setting up request*/
2943 cy_as_ll_request_response__set_word(req_p, 0,
2944 create_address(bus, (uint8_t)device, n_function_no));
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)));
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));
2958 cy_as_ll_request_response__set_word(req_p, 2,
2959 ((uint16_t)((address&0x00007fff)<<1)));
2962 reply_p = cy_as_ll_create_response(dev_p, 2);
2965 cy_as_ll_destroy_request(dev_p, req_p);
2966 return CY_AS_ERROR_OUT_OF_MEMORY;
2969 /*Sending the request*/
2970 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
2971 if (ret != CY_AS_ERROR_SUCCESS)
2974 /*Check reply type*/
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);
2979 ret = CY_AS_ERROR_INVALID_RESPONSE;
2980 else if (data_p != 0)
2981 *(uint8_t *)(data_p) = (uint8_t)(resp_data&0x00ff);
2983 ret = CY_AS_ERROR_INVALID_RESPONSE;
2988 cy_as_ll_destroy_request(dev_p, req_p);
2990 cy_as_ll_destroy_response(dev_p, reply_p);
2995 cy_as_return_status_t
2996 cy_as_sdio_direct_read(
2997 cy_as_device_handle handle,
2998 cy_as_bus_number_t bus,
3000 uint8_t n_function_no,
3005 return cy_as_sdio_direct_io(handle, bus, device, n_function_no,
3006 address, misc_buf, 0x00, cy_false, data_p);
3009 cy_as_return_status_t
3010 cy_as_sdio_direct_write(
3011 cy_as_device_handle handle,
3012 cy_as_bus_number_t bus,
3014 uint8_t n_function_no,
3020 return cy_as_sdio_direct_io(handle, bus, device, n_function_no,
3021 address, misc_buf, argument, cy_true, data_p);
3025 cy_as_return_status_t
3026 cy_as_sdio_extended_i_o(
3027 cy_as_device_handle handle,
3028 cy_as_bus_number_t bus,
3030 uint8_t n_function_no,
3038 cy_as_ll_request_response *req_p , *reply_p;
3039 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
3043 cy_as_context *ctxt_p;
3044 uint32_t dmasize, loopcount = 200;
3045 cy_as_end_point_number_t ep;
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)
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;
3059 if ((cy_as_device_is_storage_async_pending(dev_p)) ||
3060 (dev_p->storage_wait))
3061 return CY_AS_ERROR_ASYNC_PENDING;
3063 /* Request for 0 bytes of blocks is returned as a success*/
3065 return CY_AS_ERROR_SUCCESS;
3067 /* Initialise the request to send to the West Bridge device. */
3068 if (is_write == cy_true) {
3069 reqtype = CY_RQT_SDIO_WRITE_EXTENDED;
3070 ep = dev_p->storage_write_endpoint;
3072 reqtype = CY_RQT_SDIO_READ_EXTENDED;
3073 ep = dev_p->storage_read_endpoint;
3076 req_p = dev_p->storage_rw_req_p;
3077 cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3);
3079 /* Initialise the space for reply from the Antioch. */
3080 reply_p = dev_p->storage_rw_resp_p;
3081 cy_as_ll_init_response(reply_p, 2);
3083 /* Setup the DMA request */
3084 if (!(misc_buf&CY_SDIO_BLOCKMODE)) {
3086 dev_p->sdiocard[bus].
3087 function[n_function_no-1].blocksize)
3088 return CY_AS_ERROR_INVALID_BLOCKSIZE;
3092 return CY_AS_ERROR_INVALID_BLOCKSIZE;
3095 if (argument == 512)
3098 dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ?
3099 dev_p->sdiocard[bus].function[n_function_no-1].blocksize
3100 * argument : argument;
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);
3106 if (ret != CY_AS_ERROR_SUCCESS)
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);
3121 /* Send the request and wait for completion of storage request */
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);
3126 if (ret != CY_AS_ERROR_SUCCESS) {
3127 cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED);
3129 /* Setup the DMA request */
3130 ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT];
3131 ret = cy_as_dma_drain_queue(dev_p, ep, cy_true);
3133 while (loopcount-- > 0) {
3134 if (dev_p->storage_wait == cy_false)
3136 cy_as_hal_sleep_on(&ctxt_p->channel, 10);
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;
3144 ret = dev_p->storage_error;
3146 if (ret != CY_AS_ERROR_SUCCESS)
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;
3155 ret = CY_AS_ERROR_INVALID_REQUEST;
3158 ret = CY_AS_ERROR_INVALID_RESPONSE;
3166 cy_as_sdio_async_reply_callback(
3167 cy_as_device *dev_p,
3169 cy_as_ll_request_response *rqt,
3170 cy_as_ll_request_response *resp,
3171 cy_as_return_status_t ret)
3173 cy_as_storage_callback cb_ms;
3175 uint32_t pendingblocks;
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);
3189 ret = CY_AS_ERROR_INVALID_RESPONSE;
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);
3198 cy_as_dma_cancel(dev_p,
3199 dev_p->storage_write_endpoint, ret);
3201 dev_p->storage_error = ret;
3204 dev_p->storage_wait = cy_false;
3207 * if the DMA callback has already been called,
3208 * the user callback has to be called from here.
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;
3214 dev_p->storage_cb = 0;
3215 dev_p->storage_cb_ms = 0;
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
3225 ret = CY_AS_ERROR_INVALID_RESPONSE;
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);
3232 dev_p->storage_error = ret;
3236 cy_as_return_status_t
3237 cy_as_sdio_extended_i_o_async(
3238 cy_as_device_handle handle,
3239 cy_as_bus_number_t bus,
3241 uint8_t n_function_no,
3247 cy_as_storage_callback callback)
3252 cy_as_ll_request_response *req_p , *reply_p;
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;
3258 ret = cy_as_sdio_device_check(dev_p, bus, device);
3259 if (ret != CY_AS_ERROR_SUCCESS)
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;
3269 return CY_AS_ERROR_NULL_CALLBACK;
3271 /* We are supposed to return sucess if the number of
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;
3283 * since async operations can be triggered by interrupt
3284 * code, we must insure that we do not get multiple async
3285 * operations going at one time and protect this test and
3286 * set operation from interrupts.
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;
3294 cy_as_device_set_storage_async_pending(dev_p);
3295 cy_as_hal_enable_interrupts(mask);
3299 * storage information about the currently
3300 * outstanding request
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;
3308 if (is_write == cy_true) {
3309 reqtype = CY_RQT_SDIO_WRITE_EXTENDED;
3310 ep = dev_p->storage_write_endpoint;
3312 reqtype = CY_RQT_SDIO_READ_EXTENDED;
3313 ep = dev_p->storage_read_endpoint;
3316 /* Initialise the request to send to the West Bridge. */
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);
3321 /* Initialise the space for reply from the West Bridge. */
3322 reply_p = dev_p->storage_rw_resp_p;
3323 cy_as_ll_init_response(reply_p, 2);
3325 if (!(misc_buf&CY_SDIO_BLOCKMODE)) {
3327 dev_p->sdiocard[bus].function[n_function_no-1].blocksize)
3328 return CY_AS_ERROR_INVALID_BLOCKSIZE;
3332 return CY_AS_ERROR_INVALID_BLOCKSIZE;
3335 if (argument == 512)
3337 dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ?
3338 dev_p->sdiocard[bus].function[n_function_no-1].blocksize *
3339 argument : argument;
3341 /* Setup the DMA request and adjust the storage
3342 * operation if we are reading */
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;
3354 if (ret != CY_AS_ERROR_SUCCESS) {
3355 cy_as_device_clear_storage_async_pending(dev_p);
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);
3370 /* Send the request and wait for completion of storage request */
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);
3378 cy_as_dma_kick_start(dev_p, ep);
3384 /* CMD53 Extended Read*/
3385 cy_as_return_status_t
3386 cy_as_sdio_extended_read(
3387 cy_as_device_handle handle,
3388 cy_as_bus_number_t bus,
3390 uint8_t n_function_no,
3395 cy_as_sdio_callback callback)
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);
3402 return cy_as_sdio_extended_i_o_async(handle, bus, device,
3403 n_function_no, address, misc_buf, argument, cy_false,
3407 /* CMD53 Extended Write*/
3408 cy_as_return_status_t
3409 cy_as_sdio_extended_write(
3410 cy_as_device_handle handle,
3411 cy_as_bus_number_t bus,
3413 uint8_t n_function_no,
3418 cy_as_sdio_callback callback)
3421 return cy_as_sdio_extended_i_o(handle, bus, device,
3422 n_function_no, address, misc_buf, argument, cy_true,
3425 return cy_as_sdio_extended_i_o_async(handle, bus, device,
3426 n_function_no, address, misc_buf, argument, cy_true,
3431 /* Read the CIS info tuples for the given function and Tuple ID*/
3432 cy_as_return_status_t
3433 cy_as_sdio_get_c_i_s_info(
3434 cy_as_device_handle handle,
3435 cy_as_bus_number_t bus,
3437 uint8_t n_function_no,
3442 cy_as_ll_request_response *req_p , *reply_p;
3443 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
3445 cy_as_context *ctxt_p;
3446 uint32_t loopcount = 200;
3448 cy_as_device *dev_p = (cy_as_device *)handle;
3450 ret = cy_as_sdio_device_check(dev_p, bus, device);
3451 if (ret != CY_AS_ERROR_SUCCESS)
3454 if (!(cy_as_sdio_check_function_initialized(handle, bus, 0)))
3455 return CY_AS_ERROR_INVALID_FUNCTION;
3457 if ((cy_as_device_is_storage_async_pending(dev_p)) ||
3458 (dev_p->storage_wait))
3459 return CY_AS_ERROR_ASYNC_PENDING;
3462 /* Initialise the request to send to the Antioch. */
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);
3467 /* Initialise the space for reply from the Antioch. */
3468 reply_p = dev_p->storage_rw_resp_p;
3469 cy_as_ll_init_response(reply_p, 3);
3471 /* Setup the DMA request */
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);
3475 if (ret != CY_AS_ERROR_SUCCESS)
3478 cy_as_ll_request_response__set_word(req_p, 0,
3479 create_address(bus, (uint8_t)device, n_function_no));
3481 /* Set tuple id to fetch. */
3482 cy_as_ll_request_response__set_word(req_p, 1, tuple_id<<8);
3484 /* Send the request and wait for completion of storage request */
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);
3489 if (ret != CY_AS_ERROR_SUCCESS) {
3490 cy_as_dma_cancel(dev_p,
3491 dev_p->storage_read_endpoint, CY_AS_ERROR_CANCELED);
3493 /* Setup the DMA request */
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);
3498 while (loopcount-- > 0) {
3499 if (dev_p->storage_wait == cy_false)
3501 cy_as_hal_sleep_on(&ctxt_p->channel, 10);
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;
3509 ret = dev_p->storage_error;
3511 if (ret != CY_AS_ERROR_SUCCESS)
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
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);
3525 ret = CY_AS_ERROR_INVALID_RESPONSE;
3532 cy_as_return_status_t
3533 cy_as_sdio_query_card(
3534 cy_as_device_handle handle,
3535 cy_as_bus_number_t bus,
3537 cy_as_sdio_card *data_p)
3539 cy_as_ll_request_response *req_p , *reply_p;
3540 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
3543 cy_as_device *dev_p = (cy_as_device *)handle;
3545 ret = cy_as_sdio_device_check(dev_p, bus, device);
3546 if (ret != CY_AS_ERROR_SUCCESS)
3549 /* Allocating memory to the SDIO device structure in dev_p */
3551 cy_as_hal_mem_set(&dev_p->sdiocard[bus], 0, sizeof(cy_as_sdio_device));
3553 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_QUERY_CARD,
3554 CY_RQT_STORAGE_RQT_CONTEXT, 1);
3556 return CY_AS_ERROR_OUT_OF_MEMORY;
3558 cy_as_ll_request_response__set_word(req_p, 0,
3559 create_address(bus, (uint8_t)device, 0));
3561 reply_p = cy_as_ll_create_response(dev_p, 5);
3563 cy_as_ll_destroy_request(dev_p, req_p);
3564 return CY_AS_ERROR_OUT_OF_MEMORY;
3567 ret = cy_as_ll_send_request_wait_reply(dev_p,
3570 if (ret != CY_AS_ERROR_SUCCESS)
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 =
3581 dev_p->sdiocard[bus].card.manufacturer_info =
3583 dev_p->sdiocard[bus].card.blocksize =
3585 dev_p->sdiocard[bus].card.maxblocksize =
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;
3608 if (resp_type == CY_RESP_SUCCESS_FAILURE)
3609 ret = cy_as_ll_request_response__get_word(reply_p, 0);
3611 ret = CY_AS_ERROR_INVALID_RESPONSE;
3615 cy_as_ll_destroy_request(dev_p, req_p);
3617 cy_as_ll_destroy_response(dev_p, reply_p);
3621 /*Reset SDIO card. */
3622 cy_as_return_status_t
3623 cy_as_sdio_reset_card(
3624 cy_as_device_handle handle,
3625 cy_as_bus_number_t bus,
3629 cy_as_ll_request_response *req_p , *reply_p;
3630 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
3632 cy_as_device *dev_p = (cy_as_device *)handle;
3634 ret = cy_as_sdio_device_check(dev_p, bus, device);
3636 if (ret != CY_AS_ERROR_SUCCESS)
3639 if (dev_p->sdiocard != 0) {
3640 dev_p->sdiocard[bus].function_init_map = 0;
3641 dev_p->sdiocard[bus].function_suspended_map = 0;
3644 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_RESET_DEV,
3645 CY_RQT_STORAGE_RQT_CONTEXT, 1);
3648 return CY_AS_ERROR_OUT_OF_MEMORY;
3651 cy_as_ll_request_response__set_word(req_p, 0,
3652 create_address(bus, (uint8_t)device, 0));
3654 reply_p = cy_as_ll_create_response(dev_p, 2);
3656 cy_as_ll_destroy_request(dev_p, req_p);
3657 return CY_AS_ERROR_OUT_OF_MEMORY;
3660 ret = cy_as_ll_send_request_wait_reply(dev_p,
3663 if (ret != CY_AS_ERROR_SUCCESS)
3666 resp_type = cy_as_ll_request_response__get_code(reply_p);
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);
3673 ret = CY_AS_ERROR_INVALID_RESPONSE;
3677 cy_as_ll_destroy_request(dev_p, req_p);
3679 cy_as_ll_destroy_response(dev_p, reply_p);
3683 /* Initialise an IO function*/
3684 cy_as_return_status_t
3685 cy_as_sdio_init_function(
3686 cy_as_device_handle handle,
3687 cy_as_bus_number_t bus,
3689 uint8_t n_function_no,
3692 cy_as_ll_request_response *req_p , *reply_p;
3693 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
3695 cy_as_device *dev_p = (cy_as_device *)handle;
3697 ret = cy_as_sdio_device_check(dev_p, bus, device);
3699 if (ret != CY_AS_ERROR_SUCCESS)
3702 if (!(cy_as_sdio_check_function_initialized
3704 return CY_AS_ERROR_NOT_RUNNING;
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));
3712 return CY_AS_ERROR_ALREADY_RUNNING;
3715 req_p = cy_as_ll_create_request(dev_p,
3716 CY_RQT_SDIO_INIT_FUNCTION, CY_RQT_STORAGE_RQT_CONTEXT, 1);
3718 return CY_AS_ERROR_OUT_OF_MEMORY;
3720 cy_as_ll_request_response__set_word(req_p, 0,
3721 create_address(bus, (uint8_t)device, n_function_no));
3723 reply_p = cy_as_ll_create_response(dev_p, 5);
3725 cy_as_ll_destroy_request(dev_p, req_p);
3726 return CY_AS_ERROR_OUT_OF_MEMORY;
3729 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
3731 if (ret != CY_AS_ERROR_SUCCESS)
3734 resp_type = cy_as_ll_request_response__get_code(reply_p);
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 =
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);
3757 if (resp_type == CY_RESP_SUCCESS_FAILURE)
3758 ret = cy_as_ll_request_response__get_word(reply_p, 0);
3760 ret = CY_AS_ERROR_INVALID_FUNCTION;
3765 cy_as_ll_destroy_request(dev_p, req_p);
3767 cy_as_ll_destroy_response(dev_p, reply_p);
3771 /*Query individual functions. */
3772 cy_as_return_status_t
3773 cy_as_sdio_query_function(
3774 cy_as_device_handle handle,
3775 cy_as_bus_number_t bus,
3777 uint8_t n_function_no,
3778 cy_as_sdio_func *data_p)
3780 cy_as_device *dev_p = (cy_as_device *)handle;
3781 cy_as_return_status_t ret;
3783 ret = cy_as_sdio_device_check(dev_p, bus, device);
3784 if (ret != CY_AS_ERROR_SUCCESS)
3787 if (!(cy_as_sdio_check_function_initialized(handle,
3788 bus, n_function_no)))
3789 return CY_AS_ERROR_INVALID_FUNCTION;
3792 dev_p->sdiocard[bus].function[n_function_no-1].blocksize;
3794 dev_p->sdiocard[bus].function[n_function_no-1].card_psn;
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].
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;
3807 return CY_AS_ERROR_SUCCESS;
3810 /* Abort the Current Extended IO Operation*/
3811 cy_as_return_status_t
3812 cy_as_sdio_abort_function(
3813 cy_as_device_handle handle,
3814 cy_as_bus_number_t bus,
3816 uint8_t n_function_no)
3818 cy_as_ll_request_response *req_p , *reply_p;
3819 cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
3821 cy_as_device *dev_p = (cy_as_device *)handle;
3823 ret = cy_as_sdio_device_check(dev_p, bus, device);
3824 if (ret != CY_AS_ERROR_SUCCESS)
3827 if (!(cy_as_sdio_check_function_initialized(handle,
3828 bus, n_function_no)))
3829 return CY_AS_ERROR_INVALID_FUNCTION;
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) &
3835 return CY_AS_ERROR_INVALID_COMMAND;
3838 req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_ABORT_IO,
3839 CY_RQT_GENERAL_RQT_CONTEXT, 1);
3842 return CY_AS_ERROR_OUT_OF_MEMORY;
3845 cy_as_ll_request_response__set_word(req_p, 0,
3846 create_address(bus, (uint8_t)device, n_function_no));
3848 reply_p = cy_as_ll_create_response(dev_p, 2);
3850 cy_as_ll_destroy_request(dev_p, req_p);
3851 return CY_AS_ERROR_OUT_OF_MEMORY;
3854 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
3855 if (ret != CY_AS_ERROR_SUCCESS)
3858 resp_type = cy_as_ll_request_response__get_code(reply_p);
3860 if (resp_type == CY_RESP_SUCCESS_FAILURE)
3861 ret = cy_as_ll_request_response__get_word(reply_p, 0);
3863 ret = CY_AS_ERROR_INVALID_RESPONSE;
3868 cy_as_ll_destroy_request(dev_p, req_p);
3870 cy_as_ll_destroy_response(dev_p, reply_p);
3874 /* Suspend IO to current function*/
3875 cy_as_return_status_t
3877 cy_as_device_handle handle,
3878 cy_as_bus_number_t bus,
3880 uint8_t n_function_no)
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;
3886 ret = cy_as_sdio_device_check(dev_p, bus, device);
3887 if (ret != CY_AS_ERROR_SUCCESS)
3890 if (!(cy_as_sdio_check_function_initialized(handle, bus,
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;
3900 req_p = cy_as_ll_create_request(dev_p,
3901 CY_RQT_SDIO_SUSPEND, CY_RQT_GENERAL_RQT_CONTEXT, 1);
3903 return CY_AS_ERROR_OUT_OF_MEMORY;
3906 cy_as_ll_request_response__set_word(req_p, 0,
3907 create_address(bus, (uint8_t)device, n_function_no));
3909 reply_p = cy_as_ll_create_response(dev_p, 2);
3911 cy_as_ll_destroy_request(dev_p, req_p);
3912 return CY_AS_ERROR_OUT_OF_MEMORY;
3914 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
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);
3922 cy_as_ll_destroy_request(dev_p, req_p);
3924 cy_as_ll_destroy_response(dev_p, reply_p);
3929 /*Resume suspended function*/
3930 cy_as_return_status_t
3932 cy_as_device_handle handle,
3933 cy_as_bus_number_t bus,
3935 uint8_t n_function_no,
3938 uint16_t pendingblockcount,
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;
3946 ret = cy_as_sdio_device_check(dev_p, bus, device);
3947 if (ret != CY_AS_ERROR_SUCCESS)
3950 if (!(cy_as_sdio_check_function_initialized
3951 (handle, bus, n_function_no)))
3952 return CY_AS_ERROR_INVALID_FUNCTION;
3954 /* If suspend resume is not supported return */
3955 if (!(cy_as_sdio_check_support_bus_suspend(handle, bus)))
3956 return CY_AS_ERROR_INVALID_FUNCTION;
3958 /* if the function is not suspended return. */
3959 if (!(cy_as_sdio_check_function_suspended
3960 (handle, bus, n_function_no)))
3961 return CY_AS_ERROR_INVALID_FUNCTION;
3963 req_p = cy_as_ll_create_request(dev_p,
3964 CY_RQT_SDIO_RESUME, CY_RQT_STORAGE_RQT_CONTEXT, 1);
3966 return CY_AS_ERROR_OUT_OF_MEMORY;
3969 cy_as_ll_request_response__set_word(req_p, 0,
3970 create_address(bus, (uint8_t)device, n_function_no));
3972 reply_p = cy_as_ll_create_response(dev_p, 2);
3974 cy_as_ll_destroy_request(dev_p, req_p);
3975 return CY_AS_ERROR_OUT_OF_MEMORY;
3977 ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
3979 if (ret != CY_AS_ERROR_SUCCESS)
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 /* Send extended read request to resume the read. */
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);
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);
3997 ret = CY_AS_ERROR_SUCCESS;
4000 ret = CY_AS_ERROR_INVALID_RESPONSE;
4004 cy_as_sdio_clear_function_suspended(handle, bus, n_function_no);
4006 cy_as_ll_destroy_request(dev_p, req_p);
4008 cy_as_ll_destroy_response(dev_p, reply_p);
4013 /*Set function blocksize. Size cannot exceed max
4014 * block size for the function*/
4015 cy_as_return_status_t
4016 cy_as_sdio_set_blocksize(
4017 cy_as_device_handle handle,
4018 cy_as_bus_number_t bus,
4020 uint8_t n_function_no,
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)
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
4037 return CY_AS_ERROR_SUCCESS;
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;
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)
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);
4059 if (ret != CY_AS_ERROR_SUCCESS)
4062 if (n_function_no == 0)
4063 cy_as_sdio_set_card_block_size(handle, bus, blocksize);
4065 cy_as_sdio_set_function_block_size(handle,
4066 bus, n_function_no, blocksize);
4070 /* Deinitialize an SDIO function*/
4071 cy_as_return_status_t
4072 cy_as_sdio_de_init_function(
4073 cy_as_device_handle handle,
4074 cy_as_bus_number_t bus,
4076 uint8_t n_function_no)
4078 cy_as_return_status_t ret;
4081 if (n_function_no == 0)
4082 return CY_AS_ERROR_INVALID_FUNCTION;
4084 ret = cy_as_sdio_device_check((cy_as_device *)handle, bus, device);
4085 if (ret != CY_AS_ERROR_SUCCESS)
4088 if (!(cy_as_sdio_check_function_initialized
4089 (handle, bus, n_function_no)))
4090 return CY_AS_ERROR_SUCCESS;
4092 temp = (uint8_t)(((cy_as_device *)handle)->sdiocard[bus].
4093 function_init_map & (~(1 << n_function_no)));
4095 cy_as_sdio_direct_write(handle, bus, device, 0, 0x02, 0, temp, 0);
4097 ((cy_as_device *)handle)->sdiocard[bus].function_init_map &=
4098 (~(1 << n_function_no));
4100 return CY_AS_ERROR_SUCCESS;