Subversion Repositories freemyipod

Rev

Rev 531 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 531 Rev 891
Line 21... Line 21...
21
//
21
//
22
 
22
 
23
 
23
 
24
#include "global.h"
24
#include "global.h"
25
#include "usb/usbtarget.h"
25
#include "usb/usbtarget.h"
26
#include "usb/usbdrv.h"
26
#include "usb/usb.h"
27
#include "nand.h"
27
#include "nand.h"
28
 
28
 
29
 
29
 
30
int usb_target_handle_request(uint32_t* buffer, int bufsize)
30
int usb_target_handle_request(uint32_t* buf, int bufsize, void** addr)
31
{
31
{
32
    int size = 0;
32
    int len = 0;
33
    switch (buffer[0])
33
    switch (buf[0])
34
    {
34
    {
35
        case 0xffff0001:  // GET NAND INFO
35
        case 0xffff0001:  // GET NAND INFO
36
        {
36
        {
37
            int banks = 1;
37
            int banks;
38
            const struct nand_device_info_type* type = nand_get_device_type(0);
38
            const struct nand_device_info_type* type = nand_get_device_type(0);
39
            for (; banks < 4; banks++)
39
            for (banks = 1; banks < 4; banks++)
40
                if (!nand_get_device_type(banks))
40
                if (!nand_get_device_type(banks))
41
                    break;
41
                    break;
42
            buffer[0] = 1;
42
            buf[0] = 1;
43
            buffer[1] = type->id;
43
            buf[1] = type->id;
44
            buffer[2] = (banks << 16) | type->pagesperblock;
44
            buf[2] = (banks << 16) | type->pagesperblock;
45
            buffer[3] = (type->blocks << 16) | type->userblocks;
45
            buf[3] = (type->blocks << 16) | type->userblocks;
46
            size = 16;
-
 
47
            break;
46
            break;
48
        }
47
        }
49
        case 0xffff0002:  // READ NAND PAGES
48
        case 0xffff0002:  // READ NAND PAGES
50
        case 0xffff0003:  // WRITE NAND PAGES
49
        case 0xffff0003:  // WRITE NAND PAGES
51
        {
50
        {
52
            int banks = 1;
51
            int banks;
53
            const struct nand_device_info_type* type = nand_get_device_type(0);
52
            const struct nand_device_info_type* type = nand_get_device_type(0);
54
            for (; banks < 4; banks++)
53
            for (banks = 1; banks < 4; banks++)
55
                if (!nand_get_device_type(banks))
54
                if (!nand_get_device_type(banks))
56
                    break;
55
                    break;
57
            uint32_t pagecount = banks * type->blocks * type->pagesperblock;
56
            uint32_t pagecount = banks * type->blocks * type->pagesperblock;
58
            if (buffer[2] + buffer[3] > pagecount)
57
            if (buf[2] + buf[3] > pagecount)
59
            {
58
            {
60
                buffer[0] = 0xffff0001;
59
                buf[0] = 0xffff0001;
61
                size = 16;
-
 
62
                break;
60
                break;
63
            }
61
            }
64
            int i;
62
            int i;
65
            uint32_t database = buffer[1] & ~0xc0000000;
63
            uint32_t database = buf[1] & ~0xc0000000;
66
            uint32_t sparebase = database + buffer[3] * 2048;
64
            uint32_t sparebase = database + buf[3] * 2048;
67
            uint32_t resultbase = sparebase + buffer[3] * 64;
65
            uint32_t resultbase = sparebase + buf[3] * 64;
68
            int doecc = buffer[1] & 0x80000000;
66
            int doecc = buf[1] & 0x80000000;
69
            int checkempty = buffer[1] & 0x40000000;
67
            int checkempty = buf[1] & 0x40000000;
70
            for (i = 0; i < buffer[3]; i++)
68
            for (i = 0; i < buf[3]; i++)
71
            {
69
            {
72
                int lpage = buffer[2] + i;
70
                int lpage = buf[2] + i;
73
                int bank = lpage % banks;
71
                int bank = lpage % banks;
74
                int page = lpage / banks;
72
                int page = lpage / banks;
75
                int result;
73
                int result;
76
                if (buffer[0] == 0xffff0002)
74
                if (buf[0] == 0xffff0002)
77
                    result = nand_read_page(bank, page, (void*)(database + i * 2048),
75
                    result = nand_read_page(bank, page, (void*)(database + i * 2048),
78
                                            (void*)(sparebase + i * 64), doecc, checkempty);
76
                                            (void*)(sparebase + i * 64), doecc, checkempty);
79
                else if (buffer[0] == 0xffff0003)
77
                else if (buf[0] == 0xffff0003)
80
                    result = nand_write_page(bank, page, (void*)(database + i * 2048),
78
                    result = nand_write_page(bank, page, (void*)(database + i * 2048),
81
                                             (void*)(sparebase + i * 64), doecc);
79
                                             (void*)(sparebase + i * 64), doecc);
82
                *((int*)(resultbase + i * 4)) = result;
80
                *((int*)(resultbase + i * 4)) = result;
83
            }
81
            }
84
            buffer[0] = 1;
82
            buf[0] = 1;
85
            size = 16;
-
 
86
            break;
83
            break;
87
        }
84
        }
88
        case 0xffff0004:  // ERASE NAND PAGES
85
        case 0xffff0004:  // ERASE NAND PAGES
89
        {
86
        {
90
            int banks = 1;
87
            int banks;
91
            const struct nand_device_info_type* type = nand_get_device_type(0);
88
            const struct nand_device_info_type* type = nand_get_device_type(0);
92
            for (; banks < 4; banks++)
89
            for (banks = 1; banks < 4; banks++)
93
                if (!nand_get_device_type(banks))
90
                if (!nand_get_device_type(banks))
94
                    break;
91
                    break;
95
            uint32_t blockcount = banks * type->blocks;
92
            uint32_t blockcount = banks * type->blocks;
96
            if (buffer[2] + buffer[3] > blockcount)
93
            if (buf[2] + buf[3] > blockcount)
97
            {
94
            {
98
                buffer[0] = 0xffff0001;
95
                buf[0] = 0xffff0001;
99
                size = 16;
-
 
100
                break;
96
                break;
101
            }
97
            }
102
            int i;
98
            int i;
103
            for (i = 0; i < buffer[3]; i++)
99
            for (i = 0; i < buf[3]; i++)
104
            {
100
            {
105
                int lblock = buffer[2] + i;
101
                int lblock = buf[2] + i;
106
                int bank = lblock % banks;
102
                int bank = lblock % banks;
107
                int block = lblock / banks;
103
                int block = lblock / banks;
108
                int result = nand_block_erase(bank, block * type->pagesperblock); 
104
                int result = nand_block_erase(bank, block * type->pagesperblock); 
109
                *((int*)(buffer[1] + i * 4)) = result;
105
                *((int*)(buf[1] + i * 4)) = result;
110
            }
106
            }
111
            buffer[0] = 1;
107
            buf[0] = 1;
112
            size = 16;
-
 
113
            break;
108
            break;
114
        }
109
        }
115
        default:
110
        default:
116
            buffer[0] = 2;
111
            buf[0] = 2;
117
            size = 16;
112
            break;
118
    }
113
    }
119
    return size;
114
    return len;
120
}
115
}