summaryrefslogtreecommitdiff
path: root/platform/fatfs/usbh_fatfs.c
blob: abb7181bfc668cf56ee8abec4ab24746ea2d7ab7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 * Copyright (c) 2024, sakumisu
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include "ff.h"
#include "diskio.h"
#include "usbh_core.h"
#include "usbh_msc.h"

struct usbh_msc *active_msc_class;

int USB_disk_initialize(void)
{
    active_msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
    if (active_msc_class == NULL) {
        printf("do not find /dev/sda\r\n");
        return RES_NOTRDY;
    }
    if (usbh_msc_scsi_init(active_msc_class) < 0) {
        return RES_NOTRDY;
    }
    return RES_OK;
}

int USB_disk_status(void)
{
    return RES_OK;
}

int USB_disk_read(BYTE *buff, LBA_t sector, UINT count)
{
    int ret;
    uint8_t *align_buf;

    align_buf = (uint8_t *)buff;

    if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
        align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
        if (!align_buf) {
            printf("msc get align buf failed\r\n");
            return -USB_ERR_NOMEM;
        }
    }

    ret = usbh_msc_scsi_read10(active_msc_class, sector, align_buf, count);
    if (ret < 0) {
        ret = RES_ERROR;
    } else {
        ret = RES_OK;
    }

    if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
        usb_memcpy(buff, align_buf, count * active_msc_class->blocksize);
        free(align_buf);
    }

    return ret;
}

int USB_disk_write(const BYTE *buff, LBA_t sector, UINT count)
{
    int ret;
    uint8_t *align_buf;

    align_buf = (uint8_t *)buff;

    if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
        align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
        if (!align_buf) {
            printf("msc get align buf failed\r\n");
            return -USB_ERR_NOMEM;
        }
        usb_memcpy(align_buf, buff, count * active_msc_class->blocksize);
    }

    ret = usbh_msc_scsi_write10(active_msc_class, sector, align_buf, count);
    if (ret < 0) {
        ret = RES_ERROR;
    } else {
        ret = RES_OK;
    }

    if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
        free(align_buf);
    }

    return ret;
}

int USB_disk_ioctl(BYTE cmd, void *buff)
{
    int result = 0;

    switch (cmd) {
        case CTRL_SYNC:
            result = RES_OK;
            break;

        case GET_SECTOR_SIZE:
            *(WORD *)buff = active_msc_class->blocksize;
            result = RES_OK;
            break;

        case GET_BLOCK_SIZE:
            *(DWORD *)buff = 1;
            result = RES_OK;
            break;

        case GET_SECTOR_COUNT:
            *(DWORD *)buff = active_msc_class->blocknum;
            result = RES_OK;
            break;

        default:
            result = RES_PARERR;
            break;
    }

    return result;
}