OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [disk/] [opencores/] [sdcmsc/] [current/] [src/] [if_sdcmsc.c] - Blame information for rev 798

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 798 skrzyp
//==========================================================================
2
//
3
//      if_sdcmsc.c
4
//
5
//      Provide a disk device driver for SDCard Mass Storage Controller
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 2004, 2006 Free Software Foundation, Inc.                  
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author:       Piotr Skrzypek
43
// Date:         2012-05-01
44
//
45
//####DESCRIPTIONEND####
46
//==========================================================================
47
 
48
#include <pkgconf/system.h>
49
#include <cyg/infra/cyg_type.h>
50
#include <cyg/infra/cyg_ass.h>
51
#include <cyg/infra/diag.h>
52
#include <cyg/hal/hal_arch.h>
53
#include <cyg/hal/hal_if.h>
54
#include <cyg/hal/hal_intr.h>
55
#include <string.h>
56
#include <errno.h>
57
#include <cyg/io/io.h>
58
#include <cyg/io/devtab.h>
59
#include <cyg/io/disk.h>
60
 
61
// Settings exported from CDL
62
#include <pkgconf/devs_disk_opencores_sdcmsc.h>
63
 
64
// SDCMSC address space
65
#define SDCMSC_BASE 0x9e000000
66
 
67
// Register space
68
#define SDCMSC_ARGUMENT           0x00
69
#define SDCMSC_COMMAND            0x04
70
#define SDCMSC_CARD_STATUS        0x08
71
#define SDCMSC_RESPONSE           0x0C
72
#define SDCMSC_CONTROLLER_SETTING 0x1C
73
#define SDCMSC_BLOCK_SIZE         0x20
74
#define SDCMSC_POWER_CONTROL      0x24
75
#define SDCMSC_SOFTWARE_RESET     0x28
76
#define SDCMSC_TIMEOUT            0x2C
77
#define SDCMSC_NORMAL_INT_STATUS  0x30
78
#define SDCMSC_ERROR_INT_STATUS   0x34
79
#define SDCMSC_NORMAL_INT_ENABLE  0x38
80
#define SDCMSC_ERROR_INT_ENABLE   0x3C
81
#define SDCMSC_CAPABILITY         0x48
82
#define SDCMSC_CLOCK_DIVIDER      0x4C
83
#define SDCMSC_BD_BUFFER_STATUS   0x50
84
#define SDCMSC_DAT_INT_STATUS     0x54
85
#define SDCMSC_DAT_INT_ENABLE     0x58
86
#define SDCMSC_BD_RX              0x60
87
#define SDCMSC_BD_TX              0x80
88
 
89
// SDCMSC_COMMAND bits
90
#define SDCMSC_COMMAND_CMDI(x) (x << 8)
91
#define SDCMSC_COMMAND_CMDW(x) (x << 6)
92
#define SDCMSC_COMMAND_CICE    0x10
93
#define SDCMSC_COMMAND_CIRC    0x08
94
#define SDCMSC_COMMAND_RTS_48  0x02
95
#define SDCMSC_COMMAND_RTS_136 0x01
96
 
97
//SDCMSC_CARD_STATUS bits
98
#define SDCMSC_CARD_STATUS_CICMD 0x01
99
 
100
// SDCMSC_NORMAL_INT_STATUS bits
101
#define SDCMSC_NORMAL_INT_STATUS_EI 0x8000
102
#define SDCMSC_NORMAL_INT_STATUS_CC 0x0001
103
 
104
// SDCMSC_DAT_INT_STATUS
105
#define SDCMSC_DAT_INT_STATUS_TRS 0x01
106
 
107
typedef struct cyg_sdcmsc_disk_info_t {
108
        int is_v20;
109
        int is_sdhc;
110
        cyg_uint32 rca;
111
        int connected;
112
} cyg_sdcmsc_disk_info_t;
113
 
114
static int sdcmsc_card_cmd(cyg_uint32 cmd,
115
                           cyg_uint32 arg,
116
                           cyg_uint32 *response) {
117
 
118
        // Send command to card
119
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_COMMAND, cmd);
120
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_ARGUMENT, arg);
121
 
122
        // Wait for response
123
        cyg_uint32 reg;
124
        cyg_uint32 mask = SDCMSC_NORMAL_INT_STATUS_EI |
125
                          SDCMSC_NORMAL_INT_STATUS_CC;
126
 
127
        do {
128
                HAL_READ_UINT32(SDCMSC_BASE + SDCMSC_NORMAL_INT_STATUS, reg);
129
        } while(!(reg & mask));
130
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_NORMAL_INT_STATUS, 0);
131
 
132
        // Optionally read response register
133
        if(response) {
134
                HAL_READ_UINT32(SDCMSC_BASE + SDCMSC_RESPONSE, *response);
135
        }
136
 
137
        // Check for errors
138
        if(reg & SDCMSC_NORMAL_INT_STATUS_EI) {
139
                HAL_READ_UINT32(SDCMSC_BASE + SDCMSC_ERROR_INT_STATUS, reg);
140
                if(reg & (1 << 3)) diag_printf("Command index error\n");
141
                if(reg & (1 << 1)) diag_printf("Command CRC error\n");
142
                if(reg & (1 << 0)) diag_printf("Command timeout\n");
143
                HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_ERROR_INT_STATUS, 0);
144
                return 0;
145
        }
146
        else {
147
                return 1;
148
        }
149
}
150
 
151
// Card initialization and identification implemented according to
152
// Physical Layer Simplified Specification Version 3.01
153
static int sdcmsc_card_init(cyg_sdcmsc_disk_info_t *data,
154
                            char *serial,
155
                            char *firmware_rev,
156
                            char *model_num,
157
                            cyg_uint32 *capacity) {
158
 
159
        cyg_uint32 reg;
160
        cyg_uint32 cmd;
161
        cyg_uint32 arg;
162
 
163
        // Send CMD0 to switch the card to idle state
164
        cmd = SDCMSC_COMMAND_CMDI(0);
165
        if(!sdcmsc_card_cmd(cmd, 0, NULL)) return 0;
166
 
167
        // Send CMD8 offering 2.7V to 3.6V range
168
        // If the card doesn't responde it means either:
169
        // 1. Card supports v2.0 but can't communicate using
170
        //    current voltage levels
171
        // 2. Card does not support v2.0
172
        cmd = SDCMSC_COMMAND_CMDI(8) |
173
              SDCMSC_COMMAND_CICE |
174
              SDCMSC_COMMAND_CIRC |
175
              SDCMSC_COMMAND_RTS_48;
176
        data->is_v20 = sdcmsc_card_cmd(cmd, 0x1AA, NULL);
177
 
178
        do {
179
                HAL_READ_UINT32(SDCMSC_BASE + SDCMSC_CARD_STATUS, reg);
180
        } while(reg & SDCMSC_CARD_STATUS_CICMD);
181
 
182
        // Repeat ACMD41 until card set the busy bit to 1
183
        // Since ACMD is an extended command, it must be preceded
184
        // by CMD55
185
        do {
186
                cmd = SDCMSC_COMMAND_CMDI(55) |
187
                      SDCMSC_COMMAND_CICE |
188
                      SDCMSC_COMMAND_CIRC |
189
                      SDCMSC_COMMAND_RTS_48;
190
                if(!sdcmsc_card_cmd(cmd, 0, NULL)) return 0;
191
 
192
                cmd = SDCMSC_COMMAND_CMDI(41) |
193
                      SDCMSC_COMMAND_RTS_48;
194
                arg = data->is_v20 ?
195
                      0x40FF8000 :
196
                      0x00FF8000;
197
                if(!sdcmsc_card_cmd(cmd, arg, &reg)) return 0;
198
 
199
        } while(!(reg & 0x80000000));
200
 
201
        data->is_sdhc = !!(reg & 0x40000000);
202
 
203
        // Issue CMD2 to switch from ready state to ident. Unfortunately, it is
204
        // not possible to read whole CID because the command can be issued only
205
        // once, and the peripheral can store only 32bit of the command at once.
206
        cmd = SDCMSC_COMMAND_CMDI(2) |
207
              SDCMSC_COMMAND_RTS_136;
208
        if(!sdcmsc_card_cmd(cmd, 0, NULL)) return 0;
209
 
210
        // Issue CMD3 to get RCA and switch from ident state to stby.
211
        cmd = SDCMSC_COMMAND_CMDI(3) |
212
              SDCMSC_COMMAND_CICE |
213
              SDCMSC_COMMAND_CIRC |
214
              SDCMSC_COMMAND_RTS_48;
215
        if(!sdcmsc_card_cmd(cmd, 0, &reg)) return 0;
216
        data->rca = reg & 0xFFFF0000;
217
 
218
        // Calculate card capacity. Use information stored in CSD register.
219
        cyg_uint32 card_capacity;
220
        if(data->is_sdhc) {
221
                cmd = SDCMSC_COMMAND_CMDI(9) |
222
                      SDCMSC_COMMAND_CMDW(1) |
223
                      SDCMSC_COMMAND_RTS_136;
224
                if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
225
                card_capacity = reg & 0x3F;
226
                card_capacity <<= 16;
227
 
228
                cmd = SDCMSC_COMMAND_CMDI(9) |
229
                      SDCMSC_COMMAND_CMDW(2) |
230
                      SDCMSC_COMMAND_RTS_136;
231
                if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
232
                reg >>= 16;
233
                card_capacity |= reg;
234
                card_capacity += 1;
235
                card_capacity *= 1000;
236
        }
237
        else {
238
                cmd = SDCMSC_COMMAND_CMDI(9) |
239
                      SDCMSC_COMMAND_CMDW(1) |
240
                      SDCMSC_COMMAND_RTS_136;
241
                if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
242
                cyg_uint32 read_bl_len = (reg >> 16) & 0x0F;
243
                cyg_uint32 c_size = reg & 0x3FF;
244
                c_size <<= 2;
245
 
246
                cmd = SDCMSC_COMMAND_CMDI(9) |
247
                      SDCMSC_COMMAND_CMDW(2) |
248
                      SDCMSC_COMMAND_RTS_136;
249
                if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
250
                c_size |= (reg >> 30) & 0x03;
251
                cyg_uint32 c_size_mult = (reg >> 15) & 0x07;
252
                card_capacity = c_size + 1;
253
                card_capacity *= 1 << (c_size_mult + 2);
254
                card_capacity *= 1 << (read_bl_len);
255
                card_capacity >>= 9;
256
        }
257
 
258
        // Fill disk identification struct using information in CID register
259
        // use OEM/APPlication ID field to fill model_num,
260
        // Product revision field to fill firmware_rev,
261
        // and Product serial number to field to fill serial
262
        cmd = SDCMSC_COMMAND_CMDI(10) |
263
              SDCMSC_COMMAND_CMDW(0) |
264
              SDCMSC_COMMAND_RTS_136;
265
        if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
266
        model_num[0] = (reg >> 16) & 0xFF;
267
        model_num[1] = (reg >> 8) & 0xFF;
268
        model_num[2] = 0;
269
 
270
        cmd = SDCMSC_COMMAND_CMDI(10) |
271
              SDCMSC_COMMAND_CMDW(2) |
272
              SDCMSC_COMMAND_RTS_136;
273
        if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
274
        firmware_rev[0] = (reg >> 24) & 0xFF;
275
        firmware_rev[1] = 0;
276
        serial[0] = (reg >> 16) & 0xFF;
277
        serial[1] = (reg >> 8) & 0xFF;
278
        serial[2] = reg & 0xFF;
279
 
280
        cmd = SDCMSC_COMMAND_CMDI(10) |
281
              SDCMSC_COMMAND_CMDW(3) |
282
              SDCMSC_COMMAND_RTS_136;
283
        if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
284
        serial[3] = (reg >> 24) & 0xFF;
285
 
286
        // Put card in transfer state 
287
        cmd = SDCMSC_COMMAND_CMDI(7) |
288
              SDCMSC_COMMAND_CICE |
289
              SDCMSC_COMMAND_CIRC |
290
              SDCMSC_COMMAND_RTS_48;
291
        if(!sdcmsc_card_cmd(cmd, data->rca, &reg)) return 0;
292
        if(reg != 0x700) return 0;
293
 
294
        // Set block size to 512
295
        cmd = SDCMSC_COMMAND_CMDI(16) |
296
              SDCMSC_COMMAND_CICE |
297
              SDCMSC_COMMAND_CIRC |
298
              SDCMSC_COMMAND_RTS_48;
299
        if(!sdcmsc_card_cmd(cmd, 512, NULL)) return 0;
300
 
301
        // Set 4-bits bus mode
302
        cmd = SDCMSC_COMMAND_CMDI(55) |
303
              SDCMSC_COMMAND_CICE |
304
              SDCMSC_COMMAND_CIRC |
305
              SDCMSC_COMMAND_RTS_48;
306
        if(!sdcmsc_card_cmd(cmd, data->rca, NULL)) return 0;
307
 
308
        cmd = SDCMSC_COMMAND_CMDI(6) |
309
              SDCMSC_COMMAND_CICE |
310
              SDCMSC_COMMAND_CIRC |
311
              SDCMSC_COMMAND_RTS_48;
312
        if(!sdcmsc_card_cmd(cmd, 0x02, NULL)) return 0;
313
 
314
        return 1;
315
}
316
 
317
static int sdcmsc_card_queue(cyg_sdcmsc_disk_info_t *data,
318
                        int direction_transmit,
319
                        int block_addr,
320
                        cyg_uint32 buffer_addr) {
321
 
322
        // SDSC cards use byte addressing, while SDHC use block addressing.
323
        // It is therefore required to multiply the address by 512 if
324
        // we are dealing with SDSC card, to remain compatible with the API.
325
        if(!data->is_sdhc) {
326
                block_addr <<= 9;
327
        }
328
 
329
        if(direction_transmit) {
330
                HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_BD_TX, buffer_addr);
331
                HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_BD_TX, block_addr);
332
        }
333
        else {
334
                HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_BD_RX, buffer_addr);
335
                HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_BD_RX, block_addr);
336
        }
337
 
338
        // Now wait for the response
339
        cyg_uint32 reg;
340
        do {
341
                HAL_READ_UINT32(SDCMSC_BASE + SDCMSC_DAT_INT_STATUS, reg);
342
        } while(!reg);
343
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_DAT_INT_STATUS, 0);
344
 
345
        // Check for errors
346
        if(reg == SDCMSC_DAT_INT_STATUS_TRS) {
347
                return 1;
348
        }
349
        else {
350
                if(reg & (1 << 5)) diag_printf("Transmission error\n");
351
                if(reg & (1 << 4)) diag_printf("Command error\n");
352
                if(reg & (1 << 2)) diag_printf("FIFO error\n");
353
                if(reg & (1 << 1)) diag_printf("Retry error\n");
354
                return 0;
355
        }
356
}
357
 
358
// This is an API function. Is is called once, in the beginning
359
static cyg_bool sdcmsc_disk_init(struct cyg_devtab_entry* tab) {
360
 
361
        // Set highest possible timeout
362
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_TIMEOUT, 0xFFFE);
363
 
364
        // Reset the peripheral
365
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_SOFTWARE_RESET, 1);
366
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_CLOCK_DIVIDER, 2);
367
        HAL_WRITE_UINT32(SDCMSC_BASE + SDCMSC_SOFTWARE_RESET, 0);
368
 
369
        // Call upper level
370
        disk_channel* ch = (disk_channel*) tab->priv;
371
        return (*ch->callbacks->disk_init)(tab);
372
}
373
 
374
// This function is called when user mounts the disk
375
static Cyg_ErrNo sdcmsc_disk_lookup(struct cyg_devtab_entry** tab,
376
                                    struct cyg_devtab_entry *sub_tab,
377
                                    const char* name) {
378
 
379
        disk_channel *ch = (disk_channel*) (*tab)->priv;
380
        cyg_sdcmsc_disk_info_t *data = (cyg_sdcmsc_disk_info_t*) ch->dev_priv;
381
 
382
        // If the card was not initialized yet, it's time to do it
383
        // and call disk_connected callback
384
        if(!data->connected) {
385
 
386
                cyg_disk_identify_t id;
387
 
388
                // Pass dummy CHS geometry and hope the upper level 
389
                // will use LBA mode. To guess CHS we would need to
390
                // analyze partition table and confront LBA and CHS
391
                // addresses. And it would work only if proper LBA
392
                // field is stored in MBR. Is is definitely something
393
                // that should be done by upper level.
394
                id.cylinders_num = 1;
395
                id.heads_num = 1;
396
                id.sectors_num = 1;
397
 
398
                id.phys_block_size = 1;
399
                id.max_transfer = 512;
400
 
401
                // Initialize the card
402
                data->connected = sdcmsc_card_init(data,
403
                                                   id.serial,
404
                                                   id.firmware_rev,
405
                                                   id.model_num,
406
                                                   &id.lba_sectors_num);
407
 
408
                if(data->connected) {
409
                        // Let upper level know there is a new disk
410
                        (*ch->callbacks->disk_connected)(*tab, &id);
411
                }
412
        }
413
 
414
        // Call upper level
415
        return (*ch->callbacks->disk_lookup)(tab, sub_tab, name);
416
}
417
 
418
// API function to read block from the disk
419
static Cyg_ErrNo sdcmsc_disk_read(disk_channel* ch,
420
                                  void* buf,
421
                                  cyg_uint32 blocks,
422
                                  cyg_uint32 first_block) {
423
 
424
        cyg_sdcmsc_disk_info_t *data = (cyg_sdcmsc_disk_info_t*) ch->dev_priv;
425
 
426
        int i;
427
        int result;
428
        cyg_uint32 reg;
429
        for(i = 0; i < blocks; i++) {
430
 
431
                // Check for free receive buffers
432
                HAL_READ_UINT32(SDCMSC_BASE + SDCMSC_BD_BUFFER_STATUS, reg);
433
                reg >>= 8;
434
                reg &= 0xFF;
435
                if(reg == 0) {
436
                        return -EIO;
437
                }
438
 
439
                result = sdcmsc_card_queue(data, 0, first_block, (cyg_uint32) buf);
440
                if(!result) {
441
                        return -EIO;
442
                }
443
        }
444
 
445
        return ENOERR;
446
 
447
}
448
 
449
// API function to write block to disk
450
static Cyg_ErrNo sdcmsc_disk_write(disk_channel* ch,
451
                                   const void* buf,
452
                                   cyg_uint32 blocks,
453
                                   cyg_uint32 first_block) {
454
 
455
        cyg_sdcmsc_disk_info_t *data = (cyg_sdcmsc_disk_info_t*) ch->dev_priv;
456
 
457
        int i;
458
        int result;
459
        cyg_uint32 reg;
460
        for(i = 0; i < blocks; i++) {
461
 
462
                // Check for free transmit buffers
463
                HAL_READ_UINT32(SDCMSC_BASE + SDCMSC_BD_BUFFER_STATUS, reg);
464
                reg &= 0xFF;
465
                if(reg == 0) {
466
                        return -EIO;
467
                }
468
 
469
                result = sdcmsc_card_queue(data, 1, first_block, (cyg_uint32) buf);
470
                if(!result) {
471
                        return -EIO;
472
                }
473
        }
474
 
475
        return ENOERR;
476
 
477
}
478
 
479
// API function to fetch driver configuration and disk info.
480
static Cyg_ErrNo sdcmsc_disk_get_config(disk_channel* ch,
481
                                        cyg_uint32 key,
482
                                        const void* buf,
483
                                        cyg_uint32* len) {
484
 
485
        CYG_UNUSED_PARAM(disk_channel*, ch);
486
        CYG_UNUSED_PARAM(cyg_uint32, key);
487
        CYG_UNUSED_PARAM(const void*, buf);
488
        CYG_UNUSED_PARAM(cyg_uint32*, len);
489
 
490
        return -EINVAL;
491
}
492
 
493
// API function to update driver status information.
494
static Cyg_ErrNo sdcmsc_disk_set_config(disk_channel* ch,
495
                                        cyg_uint32 key,
496
                                        const void* buf,
497
                                        cyg_uint32* len) {
498
 
499
        cyg_sdcmsc_disk_info_t *data = (cyg_sdcmsc_disk_info_t*) ch->dev_priv;
500
 
501
        if(key == CYG_IO_SET_CONFIG_DISK_UMOUNT) {
502
                if(ch->info->mounts == 0) {
503
                        data->connected = false;
504
                        return (ch->callbacks->disk_disconnected)(ch);
505
                }
506
                else {
507
                        return ENOERR;
508
                }
509
        }
510
        else {
511
                return -EINVAL;
512
        }
513
 
514
}
515
 
516
// Register the driver in the system
517
 
518
static cyg_sdcmsc_disk_info_t cyg_sdcmsc_disk0_hwinfo = {
519
        .connected = 0
520
};
521
 
522
DISK_FUNS(cyg_sdcmsc_disk_funs,
523
          sdcmsc_disk_read,
524
          sdcmsc_disk_write,
525
          sdcmsc_disk_get_config,
526
          sdcmsc_disk_set_config
527
);
528
 
529
 
530
DISK_CONTROLLER(cyg_sdcmsc_disk_controller_0, cyg_sdcmsc_disk0_hwinfo);
531
 
532
DISK_CHANNEL(cyg_sdcmsc_disk0_channel,
533
             cyg_sdcmsc_disk_funs,
534
             cyg_sdcmsc_disk0_hwinfo,
535
             cyg_sdcmsc_disk_controller_0,
536
             true, //mbr supported
537
             4 //partitions
538
);
539
 
540
BLOCK_DEVTAB_ENTRY(cyg_sdcmsc_disk0_devtab_entry,
541
                   CYGDAT_DEVS_DISK_OPENCORES_SDCMSC_DISK0_NAME,
542
                   0,
543
                   &cyg_io_disk_devio,
544
                   &sdcmsc_disk_init,
545
                   &sdcmsc_disk_lookup,
546
                   &cyg_sdcmsc_disk0_channel);
547
 
548
// EOF if_sdcmsc.c

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.