|
@@ -21,11 +21,12 @@
|
|
|
|
|
|
static rt_list_t blk_devices;
|
|
static rt_list_t blk_devices;
|
|
|
|
|
|
-struct mmcsd_blk_device {
|
|
|
|
|
|
+struct mmcsd_blk_device
|
|
|
|
+{
|
|
struct rt_mmcsd_card *card;
|
|
struct rt_mmcsd_card *card;
|
|
- rt_list_t list;
|
|
|
|
- struct rt_device dev;
|
|
|
|
- struct dfs_partition part;
|
|
|
|
|
|
+ rt_list_t list;
|
|
|
|
+ struct rt_device dev;
|
|
|
|
+ struct dfs_partition part;
|
|
struct rt_device_blk_geometry geometry;
|
|
struct rt_device_blk_geometry geometry;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -96,6 +97,8 @@ static rt_int32_t mmcsd_num_wr_blocks(struct rt_mmcsd_card *card)
|
|
|
|
|
|
static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector, void *buf, rt_size_t blks, rt_uint8_t dir)
|
|
static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector, void *buf, rt_size_t blks, rt_uint8_t dir)
|
|
{
|
|
{
|
|
|
|
+ void *aligned_buf;
|
|
|
|
+
|
|
struct rt_mmcsd_cmd cmd, stop;
|
|
struct rt_mmcsd_cmd cmd, stop;
|
|
struct rt_mmcsd_data data;
|
|
struct rt_mmcsd_data data;
|
|
struct rt_mmcsd_req req;
|
|
struct rt_mmcsd_req req;
|
|
@@ -152,7 +155,23 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector,
|
|
|
|
|
|
mmcsd_set_data_timeout(&data, card);
|
|
mmcsd_set_data_timeout(&data, card);
|
|
|
|
|
|
- data.buf = buf;
|
|
|
|
|
|
+ if (((rt_uint32_t)buf & (32 - 1)) != 0) /* the buf address is not aligned to 32 */
|
|
|
|
+ {
|
|
|
|
+ aligned_buf = rt_malloc_align(data.blks * data.blksize, 32);
|
|
|
|
+
|
|
|
|
+ if (aligned_buf == RT_NULL)
|
|
|
|
+ {
|
|
|
|
+ rt_kprintf("allocate memory failed\n");
|
|
|
|
+ return -RT_ENOMEM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (dir)//write
|
|
|
|
+ rt_memcpy(aligned_buf, buf, data.blks*data.blksize);
|
|
|
|
+
|
|
|
|
+ data.buf = aligned_buf;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ data.buf = buf;
|
|
|
|
|
|
mmcsd_send_request(host, &req);
|
|
mmcsd_send_request(host, &req);
|
|
|
|
|
|
@@ -178,7 +197,6 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector,
|
|
*/
|
|
*/
|
|
} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
|
|
} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
|
|
(R1_CURRENT_STATE(cmd.resp[0]) == 7));
|
|
(R1_CURRENT_STATE(cmd.resp[0]) == 7));
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
mmcsd_host_unlock(host);
|
|
mmcsd_host_unlock(host);
|
|
@@ -187,9 +205,20 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector,
|
|
{
|
|
{
|
|
rt_kprintf("mmcsd request blocks error\n");
|
|
rt_kprintf("mmcsd request blocks error\n");
|
|
rt_kprintf("%d,%d,%d, 0x%08x,0x%08x\n", cmd.err, data.err, stop.err, data.flags, sector);
|
|
rt_kprintf("%d,%d,%d, 0x%08x,0x%08x\n", cmd.err, data.err, stop.err, data.flags, sector);
|
|
|
|
+
|
|
|
|
+ if (((rt_uint32_t)buf & (32 - 1)) != 0)
|
|
|
|
+ rt_free_align(aligned_buf);
|
|
|
|
+
|
|
return -RT_ERROR;
|
|
return -RT_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (((rt_uint32_t)buf & (32 - 1)) != 0)
|
|
|
|
+ {
|
|
|
|
+ if (!dir)//read
|
|
|
|
+ rt_memcpy(buf, data.buf, data.blks*data.blksize);
|
|
|
|
+ rt_free_align(aligned_buf);
|
|
|
|
+ }
|
|
|
|
+
|
|
return RT_EOK;
|
|
return RT_EOK;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -213,15 +242,16 @@ static rt_err_t rt_mmcsd_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
|
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
|
|
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
|
|
switch (cmd)
|
|
switch (cmd)
|
|
{
|
|
{
|
|
- case RT_DEVICE_CTRL_BLK_GETGEOME:
|
|
|
|
- rt_memcpy(args, &blk_dev->geometry, sizeof(struct rt_device_blk_geometry));
|
|
|
|
- break;
|
|
|
|
- default: break;
|
|
|
|
|
|
+ case RT_DEVICE_CTRL_BLK_GETGEOME:
|
|
|
|
+ rt_memcpy(args, &blk_dev->geometry, sizeof(struct rt_device_blk_geometry));
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
return RT_EOK;
|
|
return RT_EOK;
|
|
}
|
|
}
|
|
|
|
|
|
-static rt_size_t rt_mmcsd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
|
|
|
|
|
+static rt_size_t rt_mmcsd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
|
|
{
|
|
{
|
|
rt_err_t err;
|
|
rt_err_t err;
|
|
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
|
|
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
|
|
@@ -246,13 +276,13 @@ static rt_size_t rt_mmcsd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_s
|
|
return size;
|
|
return size;
|
|
}
|
|
}
|
|
|
|
|
|
-static rt_size_t rt_mmcsd_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
|
|
|
|
|
+static rt_size_t rt_mmcsd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
|
|
{
|
|
{
|
|
rt_err_t err;
|
|
rt_err_t err;
|
|
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
|
|
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
|
|
struct dfs_partition *part = &blk_dev->part;
|
|
struct dfs_partition *part = &blk_dev->part;
|
|
|
|
|
|
- if ( dev == RT_NULL )
|
|
|
|
|
|
+ if (dev == RT_NULL)
|
|
{
|
|
{
|
|
rt_set_errno(-DFS_STATUS_EINVAL);
|
|
rt_set_errno(-DFS_STATUS_EINVAL);
|
|
return 0;
|
|
return 0;
|
|
@@ -289,8 +319,7 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card)
|
|
|
|
|
|
if (err)
|
|
if (err)
|
|
{
|
|
{
|
|
- rt_kprintf("MMCSD: unable to set block size to %d: %d\n",
|
|
|
|
- cmd.arg, err);
|
|
|
|
|
|
+ rt_kprintf("MMCSD: unable to set block size to %d: %d\n", cmd.arg, err);
|
|
return -RT_ERROR;
|
|
return -RT_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -299,7 +328,7 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card)
|
|
|
|
|
|
rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
|
rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
|
{
|
|
{
|
|
- rt_int32_t err = 0;
|
|
|
|
|
|
+ rt_int32_t err = 0;
|
|
rt_uint8_t i, status;
|
|
rt_uint8_t i, status;
|
|
rt_uint8_t *sector;
|
|
rt_uint8_t *sector;
|
|
char dname[4];
|
|
char dname[4];
|
|
@@ -313,7 +342,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
|
}
|
|
}
|
|
|
|
|
|
/* get the first sector to read partition table */
|
|
/* get the first sector to read partition table */
|
|
- sector = (rt_uint8_t*) rt_malloc (SECTOR_SIZE);
|
|
|
|
|
|
+ sector = (rt_uint8_t *)rt_malloc_align(SECTOR_SIZE, 32);
|
|
if (sector == RT_NULL)
|
|
if (sector == RT_NULL)
|
|
{
|
|
{
|
|
rt_kprintf("allocate partition sector buffer failed\n");
|
|
rt_kprintf("allocate partition sector buffer failed\n");
|
|
@@ -341,7 +370,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
|
blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
|
|
blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
|
|
|
|
|
|
/* register mmcsd device */
|
|
/* register mmcsd device */
|
|
- blk_dev->dev.type = RT_Device_Class_Block;
|
|
|
|
|
|
+ blk_dev->dev.type = RT_Device_Class_Block;
|
|
blk_dev->dev.init = rt_mmcsd_init;
|
|
blk_dev->dev.init = rt_mmcsd_init;
|
|
blk_dev->dev.open = rt_mmcsd_open;
|
|
blk_dev->dev.open = rt_mmcsd_open;
|
|
blk_dev->dev.close = rt_mmcsd_close;
|
|
blk_dev->dev.close = rt_mmcsd_close;
|
|
@@ -415,11 +444,9 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
|
}
|
|
}
|
|
|
|
|
|
/* release sector buffer */
|
|
/* release sector buffer */
|
|
- rt_free(sector);
|
|
|
|
|
|
+ rt_free_align(sector);
|
|
|
|
|
|
return err;
|
|
return err;
|
|
-
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
|
|
void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
|
|
@@ -439,8 +466,6 @@ void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
void rt_mmcsd_blk_init(void)
|
|
void rt_mmcsd_blk_init(void)
|
|
{
|
|
{
|
|
list_init(&blk_devices);
|
|
list_init(&blk_devices);
|