1 /*
2 ********************************************************************************************************************
3 * usb_host
4 *
5 * (c) Copyright 2007-2009, holi.China
6 * All Rights Reserved
7 *
8 * File Name : usbh_buff_manager.c
9 *
10 * Author : javen
11 *
12 * Version : 2.0
13 *
14 * Date : 2009.08.19
15 *
16 * Description : 启用缓存机制,用来提高USBH的读写速度.
17 * 当fs_buffer < 32k的时候,这种机制才有效
18 * 当fs_buffer >= 32k的时候,这种机制反而会影响速度
19 * 当fs_buffer的地址是不连续的地址,必须用这种机制, 因为dma读写必须保证是连续的物理地址
20 *
21 * 注: 缓存管理的基础是device处于连接状态. 如果device被拔走了, 必须重新配置buff
22 *
23 * History :
24 * v1.0 holi 2008.11.22 - 读写速度快, 但是只支持单个lun
25 * v2.0 javen 2009.08.19 - 支持多个lun 和 多种类型的设备, 但是读写速度不如以前
26 ********************************************************************************************************************
27 */
28 #include "usb_os_platform.h"
29 #include "usbh_buff_manager.h"
30 #include "error.h"
31 #include "usb_msc_i.h"
32
33 static usbh_buff_manager_t usbh_buff_manager;
34
35 typedef int(* buff_blk_func_t)(void *pBuffer, unsigned int blk, unsigned int n, void *hDev);
36
37
38 /* usbh_temp_buff的最大长度 */
usbh_temp_buff_max_len(void)39 static unsigned int usbh_temp_buff_max_len(void)
40 {
41 return usbh_buff_manager.temp_buff_len;
42 }
43
44 /*
45 *********************************************************************
46 * set_usbh_temp_buff_default
47 *
48 * Description:
49 * 初始化一个usbh_temp_buff
50 * Arguments:
51 *
52 * Returns:
53 *
54 * note:
55 *
56 *
57 *********************************************************************
58 */
set_usbh_temp_buff_default(usbh_temp_buff_t * temp_buff)59 static void set_usbh_temp_buff_default(usbh_temp_buff_t *temp_buff)
60 {
61 unsigned int cpu_sr = 0;
62
63 if (temp_buff == NULL)
64 {
65 //DMSG_PANIC("ERR: set_usbh_temp_buff_default: input error\n");
66 //DMSG_PANIC("ERR: temp_buff = 0x%x\n", temp_buff);
67 return ;
68 }
69
70 ENTER_CRITICAL(cpu_sr);
71 temp_buff->dev_id = 0xffffffff;
72 temp_buff->start_lba = 0;
73 temp_buff->end_lba = 0;
74 temp_buff->sector_size = 0;
75 temp_buff->used_time = 0;
76 temp_buff->is_valid = 0;
77 temp_buff->is_busy = 0;
78 memset(temp_buff->buff, 0, temp_buff->buff_len);
79 EXIT_CRITICAL(cpu_sr);
80 }
81
82 /* 设置目标buff为busy状态, 此时buff的状态不允许被修改。
83 *
84 * usbh_temp_buff在使用dma接收数据期间, 可能有blk_read或者blk_write
85 * 请求试图去修改buff的属性, 如设置buff为无效。busy状态可以防止这样的
86 * 事情发生
87 */
set_usbh_temp_buff_busy(unsigned int buff_num)88 static void set_usbh_temp_buff_busy(unsigned int buff_num)
89 {
90 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
91 unsigned int cpu_sr = 0;
92 //unsigned int i = 0;
93
94 if (buff_num >= buff_mgr->temp_buff_nr)
95 {
96 //DMSG_PANIC("ERR: set_usbh_temp_buff_busy: input error\n");
97 //DMSG_PANIC("ERR: buff_num = 0x%x\n", buff_num);
98 return ;
99 }
100
101 //for (i = 0; i < buff_mgr->temp_buff_nr; i++)
102 {
103 //if (buff_mgr->buff_array[i].buff == temp_buff)
104 {
105 ENTER_CRITICAL(cpu_sr);
106 buff_mgr->buff_array[buff_num].is_busy = 1;
107 EXIT_CRITICAL(cpu_sr);
108 }
109 }
110 }
111
112 /* 设置目标buff为不busy状态, 此时buff的状态允许被修改。 */
set_usbh_temp_buff_free(unsigned int buff_num)113 static void set_usbh_temp_buff_free(unsigned int buff_num)
114 {
115 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
116 unsigned int cpu_sr = 0;
117 //unsigned int i = 0;
118
119 if (buff_num >= buff_mgr->temp_buff_nr)
120 {
121 //DMSG_PANIC("ERR: set_usbh_temp_buff_free: input error\n");
122 //DMSG_PANIC("ERR: buff_num = 0x%x\n", buff_num);
123 return ;
124 }
125
126 //for (i = 0; i < buff_mgr->temp_buff_nr; i++)
127 {
128 //if (buff_mgr->buff_array[i].buff == temp_buff)
129 {
130 ENTER_CRITICAL(cpu_sr);
131 buff_mgr->buff_array[buff_num].is_busy = 0;
132 EXIT_CRITICAL(cpu_sr);
133 }
134 }
135 }
136
137 /*
138 *********************************************************************
139 * set_usbh_temp_buff_valid
140 *
141 * Description:
142 * 如果成功的装载了device的数据, 就认为这个buffer是有效的
143 * Arguments:
144 * buff : input. 待设置有效的buff
145 * dev_id : input. 设备标识符
146 * start_lba : input. 起始扇区
147 * sector_size : input. 扇区大小
148 * Returns:
149 *
150 * note:
151 *
152 *
153 *********************************************************************
154 */
set_usbh_temp_buff_valid(unsigned int buff_num,unsigned int dev_id,unsigned int start_lba,unsigned int sector_size)155 static int set_usbh_temp_buff_valid(unsigned int buff_num, unsigned int dev_id, unsigned int start_lba, unsigned int sector_size)
156 {
157 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
158 //unsigned int i = 0;
159 unsigned int cpu_sr = 0;
160
161 if (buff_num >= buff_mgr->temp_buff_nr || sector_size == 0)
162 {
163 //DMSG_PANIC("ERR: set_usbh_temp_buff_valid: input error\n");
164 //DMSG_PANIC("ERR: buff_num = %d, sector_size = 0x%x\n", buff_num, sector_size);
165 return -1;
166 }
167
168 //for (i = 0; i < buff_mgr->temp_buff_nr; i++)
169 {
170 //设置buff有效,并且保存它所记录的起始扇区
171 //if (buff_mgr->buff_array[i].buff == buff)
172 {
173 ENTER_CRITICAL(cpu_sr);
174 buff_mgr->buff_array[buff_num].dev_id = dev_id;
175 buff_mgr->buff_array[buff_num].sector_size = sector_size;
176 buff_mgr->buff_array[buff_num].start_lba = start_lba;
177 buff_mgr->buff_array[buff_num].end_lba = start_lba + (buff_mgr->buff_array[buff_num].buff_len / sector_size) - 1;
178 buff_mgr->buff_array[buff_num].used_time = 1; /* 第一次被fs使用 */
179 buff_mgr->buff_array[buff_num].is_valid = 1;
180 EXIT_CRITICAL(cpu_sr);
181 /*
182 //DMSG_TEMP_TEST("valid buffer is %d, start_lba = %d, end_lba = %d\n",
183 i, start_lba, buff_mgr->buff_array[i].end_lba);
184 */
185 return 0;
186 }
187 }
188
189 ////DMSG_PANIC("ERR: the buff is not belong to usbh temp buff manager\n");
190 //return -1;
191 }
192
193 /*
194 ***************************************************************************
195 * set_usbh_temp_buff_invalid
196 *
197 * Description:
198 * 设置dev的某一个buff无效。lba内容的落到buffer内,就认为次buffer无效
199 * Arguments:
200 * dev_id : input. 用来确定设备的身份
201 * lba : input. 用来查找buff
202 * Returns:
203 * 返回成功与失败
204 * note:
205 *
206 *
207 ***************************************************************************
208 */
set_usbh_temp_buff_invalid(unsigned int dev_id,unsigned int lba)209 static int set_usbh_temp_buff_invalid(unsigned int dev_id, unsigned int lba)
210 {
211 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
212 unsigned int i = 0;
213
214 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
215 {
216 //设置dev的lba的buff无效
217 if ((buff_mgr->buff_array[i].dev_id == dev_id)
218 && (buff_mgr->buff_array[i].start_lba <= lba)
219 && (lba <= buff_mgr->buff_array[i].end_lba))
220 {
221 set_usbh_temp_buff_default(&(buff_mgr->buff_array[i]));
222 }
223 }
224
225 return 0;
226 }
227
228 /*
229 *********************************************************************
230 * set_usbh_temp_buff_invalid_by_dev
231 *
232 * Description:
233 * 设置和dev_id匹配的buff无效
234 * Arguments:
235 * dev_id : input. 用来确定设备的身份
236 * Returns:
237 * 返回成功与失败
238 * note:
239 *
240 *
241 *********************************************************************
242 */
set_usbh_temp_buff_invalid_by_dev(unsigned int dev_id)243 int set_usbh_temp_buff_invalid_by_dev(unsigned int dev_id)
244 {
245 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
246 unsigned int i = 0;
247
248 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
249 {
250 //与dev_id匹配的所有的buff都无效
251 if (buff_mgr->buff_array[i].dev_id == dev_id)
252 {
253 set_usbh_temp_buff_default(&(buff_mgr->buff_array[i]));
254 }
255 }
256
257 return 0;
258 }
259
260 /*
261 *********************************************************************
262 * set_usbh_temp_buff_invalid
263 *
264 * Description:
265 * 设置和dev_id匹配的buff无效
266 * Arguments:
267 * dev_id : input. 用来确定设备的身份
268 * Returns:
269 * 返回成功与失败
270 * note:
271 *
272 *********************************************************************
273 */
set_all_usbh_temp_buff_invalid(void)274 int set_all_usbh_temp_buff_invalid(void)
275 {
276 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
277 unsigned int i = 0;
278
279 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
280 {
281 set_usbh_temp_buff_default(&(buff_mgr->buff_array[i]));
282 }
283
284 return 0;
285 }
286
287 /*
288 *********************************************************************
289 * select_invalid_usbh_temp_buff
290 *
291 * Description:
292 * 选择一个没有用的buff,用来转载device的数据
293 * Arguments:
294 *
295 * Returns:
296 *
297 * note:
298 * 挑选的策略为:
299 * 1、buff处于busy状态, 不选
300 * 2、挑选invalid buff
301 * 3、挑选valid buff里面被fs使用次数最少的一个buff
302 * 4、所有的buff的bit次数一样, 就按顺序挑选一个非busy的buff
303 * 5、以上条件都不满足, 挑选失败, 返回NULL
304 *
305 *
306 *********************************************************************
307 */
select_invalid_usbh_temp_buff(unsigned int * buff_num)308 static void *select_invalid_usbh_temp_buff(unsigned int *buff_num)
309 {
310 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
311 void *temp_buff = NULL;
312 unsigned int min_used = 0xffffffff; //最小的使用次数
313 //unsigned int buff_num = 0; //被选中的buff的号
314 unsigned int i = 0;
315
316 if (buff_num == NULL)
317 {
318 return NULL;
319 }
320
321 //--<1>--挑选invalid的buffer
322 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
323 {
324 //--<1-1>--设备处于busy状态, 就去挑选下一个
325 if (buff_mgr->buff_array[i].is_busy)
326 {
327 continue;
328 }
329
330 //--<1-2>--挑选invalid的buffer
331 if (buff_mgr->buff_array[i].is_valid == 0)
332 {
333 temp_buff = buff_mgr->buff_array[i].buff;
334 *buff_num = i;
335 set_usbh_temp_buff_default(&(buff_mgr->buff_array[*buff_num]));
336 return temp_buff;
337 }
338
339 //--<1-3>--buffer都有效,就去挑选被fs使用次数最少的一个buff
340 if (min_used > buff_mgr->buff_array[i].used_time)
341 {
342 min_used = buff_mgr->buff_array[i].used_time;
343 *buff_num = i;
344 temp_buff = buff_mgr->buff_array[i].buff;
345 }
346
347 //--<1-4>--在每次挑选的过程中, used_time除2
348 //如果在下一次挑选之前, 又被fs使用, 这样它又慢慢生长了; 否则,会慢慢老去
349 buff_mgr->buff_array[i].used_time = buff_mgr->buff_array[i].used_time >> 1;
350 }
351
352 //--<2>--挑选被fs使用次数最少的buffer
353 if (min_used != 0xffffffff)
354 {
355 set_usbh_temp_buff_default(&(buff_mgr->buff_array[*buff_num]));
356 return temp_buff;
357 }
358
359 //--<3>--没有找到理想的buffer就按顺序挑选一个不常用的,
360 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
361 {
362 if (buff_mgr->buff_array[i].is_busy == 0)
363 {
364 temp_buff = buff_mgr->buff_array[i].buff;
365 *buff_num = i;
366 set_usbh_temp_buff_default(&(buff_mgr->buff_array[*buff_num]));
367 return temp_buff;
368 }
369 }
370
371 //--<4>--所有的buff都处于busy状态, 就无buff可用了
372 temp_buff = NULL;
373 return temp_buff;
374 }
375
376 /* 选择最优的buffer, 返回最优的buffer号 */
select_best_buffer(unsigned int dev_id,unsigned int lba,unsigned int size,unsigned int * nr)377 static int select_best_buffer(unsigned int dev_id, unsigned int lba, unsigned int size, unsigned int *nr)
378 {
379 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
380 unsigned int max_len = 0; /* 命中buffer里存放的最大数据长度 */
381 unsigned int i = 0;
382
383 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
384 {
385 if ((dev_id == buff_mgr->buff_array[i].dev_id) && buff_mgr->buff_array[i].is_valid)
386 {
387 /* 落到了buffer内 */
388 if (buff_mgr->buff_array[i].start_lba <= lba && buff_mgr->buff_array[i].end_lba >= lba)
389 {
390 if (max_len <= (buff_mgr->buff_array[i].end_lba - lba + 1))
391 {
392 max_len = (buff_mgr->buff_array[i].end_lba - lba + 1);
393 *nr = i;
394 }
395
396 if (max_len >= size)
397 {
398 break;
399 }
400 }
401 }
402 }
403
404 if (i >= buff_mgr->temp_buff_nr && max_len == 0)
405 {
406 ////DMSG_PANIC("find best buffer find\n");
407 *nr = 0xff;
408 return -1;
409 }
410
411 return 0;
412 }
413
414 /*
415 ******************************************************************************
416 * read_usbh_temp_buff
417 *
418 * Description:
419 * 如果成功的装载了device的数据, 就认为这个buffer是有效的
420 *
421 * Arguments:
422 * dev_id : input. 用来查找指定设备的buff
423 * lba : input. 本次读写的起始扇区
424 * size : input. 本次读写的扇区个数
425 * buff : output. 转载本次读的数据
426 *
427 * Returns:
428 * is_copy = 1: 返回从buffer中读取的数据
429 * is_copy = 0: 返回从buffer中最大效数据长度
430 *
431 * note:
432 * start lba lba+size end
433 * usbh_temp_buff: |---------|----------------------|----------------|
434 * |----valid_sector------|
435 * |-------------left_sector---------------|
436 *
437 ******************************************************************************
438 */
read_usbh_temp_buff(unsigned int dev_id,unsigned int lba,unsigned int size,void * buff,unsigned int is_copy)439 static int read_usbh_temp_buff(unsigned int dev_id, unsigned int lba, unsigned int size, void *buff, unsigned int is_copy)
440 {
441 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
442 unsigned int buff_start = 0; /* 数据在buff的起始地址 */
443 unsigned int valid_sector = 0; /* buffer里的效数据长度 */
444 unsigned int max_valid_sector = 0; /* buffer里的最大效数据长度 */
445 unsigned int buff_len = 0; /* 本次读写数据的长度 */
446 unsigned int buff_no = 0;
447 #define min( x, y ) ( (x) < (y) ? (x) : (y) )
448
449 if (buff == NULL)
450 {
451 //DMSG_PANIC("ERR: read_usbh_temp_buff: input error\n");
452 return 0;
453 }
454
455 if (select_best_buffer(dev_id, lba, size, &buff_no) == 0)
456 {
457 max_valid_sector = buff_mgr->buff_array[buff_no].end_lba - lba + 1;
458
459 if (is_copy)
460 {
461 buff_start = (lba - buff_mgr->buff_array[buff_no].start_lba) * (buff_mgr->buff_array[buff_no].sector_size);
462 valid_sector = min(size, max_valid_sector);
463 buff_len = valid_sector * (buff_mgr->buff_array[buff_no].sector_size);
464
465 if (buff_mgr->buff_array[buff_no].buff == NULL)
466 {
467 //DMSG_PANIC("ERR: usbh temp buff had free, can not used\n");
468 return -1;
469 }
470
471 //DMSG_TEMP_TEST("special buffer is %d, start_lba = %d, end_lba = %d\n",
472 //buff_no,
473 //buff_mgr->buff_array[buff_no].start_lba,
474 //buff_mgr->buff_array[buff_no].end_lba);
475 buff_mgr->buff_array[buff_no].used_time++;
476 memcpy(buff, (void *)((unsigned char *)(buff_mgr->buff_array[buff_no].buff) + buff_start), buff_len);
477 return valid_sector;
478 }
479 }
480
481 return max_valid_sector;
482 }
483
484 /*
485 ******************************************************************************
486 * write_usbh_temp_buff
487 *
488 * Description:
489 * 数据在写入device之前, 更新usbh_temp_buff, 以便下次直接读取
490 * Arguments:
491 * dev_id : input. 用来查找指定设备的buff
492 * lba : input. 本次读写的起始扇区
493 * size : input. 本次读写的扇区个数
494 * buff : input. 转载本次写的数据
495 *
496 * Returns:
497 * 返回写成功的buff地址
498 * note:
499 *
500 *
501 ******************************************************************************
502 */
write_usbh_temp_buff(unsigned int dev_id,unsigned int lba,unsigned int size,const void * buff)503 static void *write_usbh_temp_buff(unsigned int dev_id, unsigned int lba, unsigned int size, const void *buff)
504 {
505 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
506 unsigned int buff_start = 0; /* 数据在buff的起始地址 */
507 unsigned int buff_len = 0; /* 本次读写数据的长度 */
508 unsigned int i = 0;
509
510 if (buff == NULL)
511 {
512 //DMSG_PANIC("ERR: write_usbh_temp_buff: input error\n");
513 return NULL;
514 }
515
516 //--<1>--在现有的buff里面去寻找合适的buff
517 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
518 {
519 //dev_id匹配, 并且这个buff有效, 就去确认本次读写的lba是否完整的落在buff内
520 if ((dev_id == buff_mgr->buff_array[i].dev_id) && buff_mgr->buff_array[i].is_valid)
521 {
522 //要读的lba落在buff内, 并且size没有超出buff的范围, 就可以直接更新了
523 if ((buff_mgr->buff_array[i].start_lba <= (lba + size))
524 && ((lba + size) < buff_mgr->buff_array[i].end_lba)
525 && (buff_mgr->buff_array[i].start_lba <= lba)
526 && (lba < buff_mgr->buff_array[i].end_lba))
527 {
528 buff_start = (lba - buff_mgr->buff_array[i].start_lba) * (buff_mgr->buff_array[i].sector_size);
529 buff_len = size * (buff_mgr->buff_array[i].sector_size);
530
531 if (buff_mgr->buff_array[i].buff == NULL)
532 {
533 //DMSG_PANIC("ERR: usbh temp buff had free, can not used\n");
534 return NULL;
535 }
536
537 buff_mgr->buff_array[i].used_time++;
538 memcpy((void *)((unsigned char *)(buff_mgr->buff_array[i].buff) + buff_start), buff, buff_len);
539 //这里返回blk的偏移地址
540 //return buff_mgr->buff_array[i].buff;
541 return (void *)((unsigned char *)(buff_mgr->buff_array[i].buff) + buff_start);
542 }
543 }
544 }
545
546 return NULL;
547 }
548
549 /*
550 ********************************************************************************************************
551 * usbh_msc_special_read
552 *
553 * Description:
554 * 通过usbh_temp_buff管理来读取设备的数据, 如果usbh_temp_buff里面有
555 * 想要的数据,就从usbh_temp_buff里读。否则直接向device读取数据。
556 *
557 * Arguments:
558 * pBuffer : output. 接收本次读的数据
559 * blk : input. 本次读写的起始扇区
560 * n : input. 本次读写的扇区个数
561 * hDev : input. 设备句柄
562 * dev_id : input. 设备号
563 * blk_read_entry : input. 块设备读函数的入口, 如sd_read.
564 *
565 * Returns:
566 * 返回读成功的blk数
567 * note:
568 *
569 * usbh_temp_buff读的策略是:
570 *
571 * 1、user buffer size小于usb temp buffer size
572 * (1)、查询单个temp buffer里有多少有效数据, 查询有效数据最大的哪个buffer
573 * (2)、如果满足user buffer的要求, 就返回。
574 * (3)、如果不能够满足,就开启另外一个usb temp buffer
575 * 从device取数据,把有效数据copy到user buffer中。
576 *
577 * 2、user buffer size大于等于usb temp buffer size
578 * (1)、从usb temp buffer里取有效数据
579 * (2)、如果剩余数据大于等于usb temp buffer size,就直接用user buffer从设备取数据
580 * (3)、如果剩余数据小于usb temp buffer size,就开启另外一个usb temp buffer
581 * 从device取数据,把有效数据copy到user buffer中。
582 *
583 ********************************************************************************************************
584 */
585 #if 1
usbh_msc_special_read(void * pBuffer,unsigned int blk,unsigned int n,void * hDev,unsigned int dev_id,unsigned int secter_size,void * blk_read_entry)586 int usbh_msc_special_read(void *pBuffer,
587 unsigned int blk,
588 unsigned int n,
589 void *hDev,
590 unsigned int dev_id,
591 unsigned int secter_size,
592 void *blk_read_entry)
593 {
594 unsigned char *Buffer_temp = (unsigned char *)pBuffer;
595 unsigned int temp_sector_1 = 0; //本次所要读写的数据长度
596 unsigned int total_len = 0; //本次所要读写的数据长度
597 unsigned int left_sector = 0; /* 剩余扇区个数 */
598 // unsigned int sector_nr = 0; //本次成功读取的扇区个数
599 void *usbh_temp_buff = NULL; //usbh_temp_buff
600 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
601 buff_blk_func_t buff_blk_read;
602
603 //--<1>--check input
604 if (pBuffer == NULL || n == 0 || hDev == NULL || blk_read_entry == NULL)
605 {
606 //DMSG_PANIC("ERR : usbh_msc_special_read: input is error\n");
607 //DMSG_PANIC("ERR : usbh_msc_special_read: pBuffer = 0x%x, n = %d, hDev = 0x%x,blk_read = 0x%x\n",
608 // pBuffer, n, hDev, blk_read_entry);
609 return 0;
610 }
611
612 //DMSG_TEMP_TEST("read: --<1-0>--, Buffer_temp_s = %x, Buffer_temp_e = %x\n",
613 // Buffer_temp, (Buffer_temp + n * secter_size));
614 buff_blk_read = (buff_blk_func_t)blk_read_entry;
615 total_len = (n * secter_size);
616
617 if (total_len < usbh_temp_buff_max_len())
618 {
619 unsigned int buff_num = 0;
620 //(1)、查询单个temp buffer里有多少有效数据, 查询有效数据最大的哪个buffer
621 temp_sector_1 = read_usbh_temp_buff(dev_id, blk, n, pBuffer, 0);
622 //DMSG_TEMP_TEST("read: --<1-1>--, secter_size = %d, blk = %d, n = %d, temp_sector_1 = %d\n",
623 // secter_size, blk, n, temp_sector_1);
624
625 //(2)、如果满足user buffer的要求, 就返回。
626 if (temp_sector_1 >= n)
627 {
628 ////DMSG_TEMP_TEST("read: --<1-2>--, secter_size = %d, blk = %d, n = %d, temp_sector_1 = %d\n",
629 // secter_size, blk, n, temp_sector_1);
630 return read_usbh_temp_buff(dev_id, blk, n, pBuffer, 1);
631 }
632
633 /*
634 (3)、如果不能够满足,就开启另外一个usb temp buffer
635 从device取数据,把有效数据copy到user buffer中。
636 */
637 //--<3-1>--挑选一个无用的buff, 去device里取数据
638 usbh_temp_buff = select_invalid_usbh_temp_buff(&buff_num);
639
640 if (usbh_temp_buff == NULL)
641 {
642 //DMSG_PANIC("ERR: select_invalid_usbh_temp_buff failed\n");
643 //既然不能再使用usbh_temp_buff了, 就直接读吧
644 return buff_blk_read(pBuffer, blk, n, hDev);
645 }
646
647 //--<3-2>--从设备读数据
648 set_usbh_temp_buff_busy(buff_num);
649 temp_sector_1 = buff_blk_read(usbh_temp_buff, blk, buff_mgr->temp_buff_len / secter_size, hDev);
650 set_usbh_temp_buff_free(buff_num);
651
652 if (temp_sector_1 != (buff_mgr->temp_buff_len / secter_size))
653 {
654 //DMSG_PANIC("ERR: usbh_msc_special_read: buff_blk_read failed\n");
655 return 0;
656 }
657
658 //--<3-3>--设置这个buff有效
659 set_usbh_temp_buff_valid(buff_num, dev_id, blk, secter_size);
660 //--<3-4>--把从设备读数据, 传递给fs
661 memcpy(pBuffer, usbh_temp_buff, total_len);
662 //DMSG_TEMP_TEST("memcpy1: pBuffer = %x,pBuffer_s = %x, pBuffer_e = %x\n",
663 //(unsigned int)pBuffer, Buffer_temp, Buffer_temp + total_len);
664 //DMSG_TEMP_TEST("read: --<1-3>--, secter_size = %d, blk = %d, n = %d, total_len = %d\n",
665 //secter_size, blk, n, total_len);
666 return n;
667 }
668 else
669 {
670 unsigned int buff_num = 0;
671 //(1)、从usb temp buffer里取有效数据
672 temp_sector_1 = read_usbh_temp_buff(dev_id, blk, n, pBuffer, 1);
673 //DMSG_TEMP_TEST("read: --<2-1>--, secter_size = %d, blk = %d, n = %d, temp_sector_1 = %d\n",
674 //secter_size, blk, n, temp_sector_1);
675
676 if (((n - temp_sector_1) * secter_size) >= usbh_temp_buff_max_len())
677 {
678 //(2)、如果剩余数据大于等于usb temp buffer size,就直接用user buffer从设备取数据
679 left_sector = buff_blk_read(Buffer_temp + (temp_sector_1 * secter_size),
680 (blk + temp_sector_1),
681 (n - temp_sector_1),
682 hDev);
683 //DMSG_TEMP_TEST("read: --<2-2>--, secter_size = %d, blk = %d, n = %d, left_sector = %d\n",
684 //secter_size, blk, n, left_sector);
685 //DMSG_TEMP_TEST("memcpy4: pBuffer_s = %x, pBuffer_e = %x\n",
686 //Buffer_temp + (temp_sector_1 * secter_size),
687 //Buffer_temp + (temp_sector_1 * secter_size) + ((n - temp_sector_1) * secter_size));
688
689 if (left_sector)
690 {
691 return (left_sector + temp_sector_1);
692 }
693 else
694 {
695 return 0; /* read faild */
696 }
697 }
698 else
699 {
700 /* (3)、如果剩余数据小于usb temp buffer size,就开启另外一个usb temp buffer
701 从device取数据,把有效数据copy到user buffer中。 */
702 //--<3-1>--挑选一个无用的buff, 去device里取数据
703 usbh_temp_buff = select_invalid_usbh_temp_buff(&buff_num);
704
705 if (usbh_temp_buff == NULL)
706 {
707 //DMSG_PANIC("ERR: select_invalid_usbh_temp_buff failed\n");
708 //既然不能再使用usbh_temp_buff了, 就直接读吧
709 return buff_blk_read(pBuffer, blk, n, hDev);
710 }
711
712 //--<3-2>--从设备读数据
713 set_usbh_temp_buff_busy(buff_num);
714 left_sector = buff_blk_read(usbh_temp_buff, (blk + temp_sector_1), buff_mgr->temp_buff_len / secter_size, hDev);
715 set_usbh_temp_buff_free(buff_num);
716
717 if (left_sector != (buff_mgr->temp_buff_len / secter_size))
718 {
719 //DMSG_PANIC("ERR: usbh_msc_special_read: buff_blk_read failed\n");
720 return 0;
721 }
722
723 //--<3-3>--设置这个buff有效
724 set_usbh_temp_buff_valid(buff_num, dev_id, (blk + temp_sector_1), secter_size);
725 //--<3-4>--把从设备读数据, 传递给fs
726 memcpy(Buffer_temp + (temp_sector_1 * secter_size),
727 usbh_temp_buff,
728 ((n - temp_sector_1) * secter_size));
729 //DMSG_TEMP_TEST("memcpy2: pBuffer_s = %x, pBuffer_e = %x\n",
730 // Buffer_temp + (temp_sector_1 * secter_size),
731 // Buffer_temp + (temp_sector_1 * secter_size) + ((n - temp_sector_1) * secter_size));
732 //DMSG_TEMP_TEST("read: --<2-3>--, secter_size = %d, blk = %d, n = %d, left_sector = %d\n",
733 // secter_size, blk, n, (n - temp_sector_1));
734 return n;
735 }
736 }
737 }
738 #else
739 /*
740 ********************************************************************************************************
741 * usbh_msc_special_read
742 *
743 * Description:
744 * 通过usbh_temp_buff管理来读取设备的数据, 如果usbh_temp_buff里面有
745 * 想要的数据,就从usbh_temp_buff里读。否则直接向device读取数据。
746 *
747 * Arguments:
748 * pBuffer : output. 接收本次读的数据
749 * blk : input. 本次读写的起始扇区
750 * n : input. 本次读写的扇区个数
751 * hDev : input. 设备句柄
752 * dev_id : input. 设备号
753 * blk_read_entry : input. 块设备读函数的入口, 如sd_read.
754 *
755 * Returns:
756 * 返回读成功的blk数
757 * note:
758 *
759 * usbh_temp_buff读的策略是:
760 *
761 ********************************************************************************************************
762 */
usbh_msc_special_read(void * pBuffer,unsigned int blk,unsigned int n,void * hDev,unsigned int dev_id,unsigned int secter_size,void * blk_read_entry)763 int usbh_msc_special_read(void *pBuffer,
764 unsigned int blk,
765 unsigned int n,
766 void *hDev,
767 unsigned int dev_id,
768 unsigned int secter_size,
769 void *blk_read_entry)
770 {
771 unsigned char *Buffer_temp = (unsigned char *)pBuffer;
772 unsigned int this_len = 0; //本次所要读写的数据长度
773 unsigned int sector_nr = 0; //本次成功读取的扇区个数
774 void *usbh_temp_buff = NULL; //usbh_temp_buff
775 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
776 buff_blk_func_t buff_blk_read;
777
778 //--<1>--check input
779 if (pBuffer == NULL || n == 0 || hDev == NULL || blk_read_entry == NULL)
780 {
781 //DMSG_PANIC("ERR : usbh_msc_special_read: input is error\n");
782 //DMSG_PANIC("ERR : usbh_msc_special_read: pBuffer = 0x%x, n = %d, hDev = 0x%x,blk_read = 0x%x\n",
783 pBuffer, n, hDev, blk_read_entry);
784 return 0;
785 }
786
787 //--<2>--满足如下之一, 就使用usbh_temp_buff
788 /* 1、没有超出了usbh_temp_buff的最大范围
789 * 2、pBuffer地址物理不连续
790 * 3、地址不对其
791 */
792 sector_nr = n;
793 this_len = n * secter_size;
794 buff_blk_read = (buff_blk_func_t)blk_read_entry;
795
796 if (this_len <= usbh_temp_buff_max_len())
797 {
798 int ret = 0;
799 //--<3-1>--尝试到usbh_temp_buff里读, 读成功就直接闪人
800 /*
801 if(read_usbh_temp_buff(dev_id, blk, n, pBuffer) == 0){
802 return sector_nr;
803 }
804 */
805 sector_nr = read_usbh_temp_buff(dev_id, blk, n, pBuffer, 0);
806
807 if (sector_nr)
808 {
809 /* 如果现有的buffer里面有一半以上的数据可用, 就先从buffer里取数据, 再向设备去剩余数据 */
810 if (sector_nr /*> (n/2)*/)
811 {
812 sector_nr = read_usbh_temp_buff(dev_id, blk, n, pBuffer, 1);
813
814 if (sector_nr < n)
815 {
816 sector_nr += buff_blk_read(Buffer_temp + (sector_nr * secter_size),
817 (blk + sector_nr),
818 (n - sector_nr),
819 hDev);
820 }
821
822 return sector_nr;
823 }
824 }
825
826 //--<3-2>--挑选一个无用的buff, 去device里取数据
827 usbh_temp_buff = select_invalid_usbh_temp_buff();
828
829 if (usbh_temp_buff == NULL)
830 {
831 //DMSG_PANIC("ERR: select_invalid_usbh_temp_buff failed\n");
832 //既然不能再使用usbh_temp_buff了, 就直接读吧
833 return buff_blk_read(pBuffer, blk, n, hDev);
834 }
835
836 //--<3-3>--从设备读数据
837 set_usbh_temp_buff_busy(usbh_temp_buff);
838 ret = buff_blk_read(usbh_temp_buff, blk, buff_mgr->temp_buff_len / secter_size, hDev);
839 set_usbh_temp_buff_free(usbh_temp_buff);
840
841 if (ret != (buff_mgr->temp_buff_len / secter_size))
842 {
843 //DMSG_PANIC("ERR: usbh_msc_special_read: buff_blk_read failed\n");
844 return 0;
845 }
846
847 //--<3-2-4>--设置这个buff有效
848 set_usbh_temp_buff_valid(usbh_temp_buff, dev_id, blk, secter_size);
849 //--<3-4>--把从设备读数据, 传递给fs
850 memcpy(pBuffer, usbh_temp_buff, this_len);
851 return n;
852 }
853 else
854 {
855 /*
856 *******************************************************************
857 * 大于32k读的时候, 不用usbh_temp_buff也就不用更新usbh_temp_buff了
858 * usbh_temp_buff的内容依旧和device是同步的
859 *******************************************************************
860 */
861 sector_nr = read_usbh_temp_buff(dev_id, blk, n, pBuffer, 1);
862
863 if (sector_nr)
864 {
865 if (sector_nr < n)
866 {
867 sector_nr += buff_blk_read(Buffer_temp + (sector_nr * secter_size),
868 (blk + sector_nr),
869 (n - sector_nr),
870 hDev);
871 }
872 }
873 else
874 {
875 sector_nr = buff_blk_read(pBuffer, blk, n, hDev);
876 }
877
878 return sector_nr;
879 }
880 }
881 #endif
882
883 /*
884 ****************************************************************************
885 * usbh_msc_special_write
886 *
887 * Description:
888 * 通过usbh_temp_buff管理来读取设备的数据, 如果usbh_temp_buff里面有
889 * 想要的数据,就从usbh_temp_buff里读。否则直接向device读取数据。
890 *
891 * Arguments:
892 * pBuffer : input. 要写入device的数据
893 * blk : input. 本次读写的起始扇区
894 * n : input. 本次读写的扇区个数
895 * hDev : input. 设备句柄
896 * dev_id : input. 设备号
897 * blk_write_entry : input. 块设备读函数的入口, 如sd_write.
898 *
899 * Returns:
900 * 返回读成功的blk数
901 * note:
902 * 满足如下之一, 就使用usbh_temp_buff
903 * 1、没有超出了usbh_temp_buff的最大范围
904 * 2、pBuffer地址物理不连续
905 * 3、地址不对其
906 *
907 * usbh_temp_buff写的策略是:
908 * 1、data_len < 32k, pBuffer地址物理不连续, 地址不对其
909 * (1)、尝试更新usbh_temp_buff成功, 就去写device
910 * (2)、尝试更新usbh_temp_buff失败, 就把相关的usbh_temp_buff无效掉
911 * (3)、掉选一个无效的buff,用来传输数据。(因为pbuffer可能是物理不连续的)
912 *
913 * 2、data_len >= 32k, pBuffer地址物理连续, 地址对其
914 * (1)、把相关的usbh_temp_buff无效掉
915 * (2)、掉选一个无效的buff, 更新。
916 * (3)、设置这个buff有效
917
918 *
919 ****************************************************************************
920 */
usbh_msc_special_write(void * pBuffer,unsigned int blk,unsigned int n,void * hDev,unsigned int dev_id,unsigned int secter_size,void * blk_write_entry)921 int usbh_msc_special_write(void *pBuffer,
922 unsigned int blk,
923 unsigned int n,
924 void *hDev,
925 unsigned int dev_id,
926 unsigned int secter_size,
927 void *blk_write_entry)
928 {
929 unsigned int this_len = 0; //本次所要读写的数据长度
930 void *usbh_temp_buff = NULL; //usbh_temp_buff
931 buff_blk_func_t buff_blk_write;
932
933 //--<1>--check input
934 if (pBuffer == NULL || n == 0 || hDev == NULL || blk_write_entry == NULL)
935 {
936 //DMSG_PANIC("ERR : usbh_msc_special_read: input is error\n");
937 //DMSG_PANIC("ERR : usbh_msc_special_read: pBuffer = 0x%x, n = %d, hDev = 0x%x,blk_read = 0x%x\n",
938 // pBuffer, n, hDev, blk_write_entry);
939 return 0;
940 }
941
942 //--<3>--满足如下之一, 就使用usbh_temp_buff
943 /* 1、没有超出了usbh_temp_buff的最大范围
944 * 2、pBuffer地址物理不连续
945 * 3、地址不对齐
946 */
947 this_len = n * secter_size;
948 buff_blk_write = (buff_blk_func_t)blk_write_entry;
949
950 if (this_len < usbh_temp_buff_max_len())
951 {
952 unsigned int buff_num = 0;
953 //--<3-1-1>--尝试更新usbh_temp_buff, 返回的usbh_temp_buff可能并不是buff的起始地址
954 usbh_temp_buff = write_usbh_temp_buff(dev_id, blk, n, pBuffer);
955
956 if (usbh_temp_buff != NULL)
957 {
958 //更新成功, 就直接开始写了
959 return buff_blk_write(usbh_temp_buff, blk, n, hDev);
960 }
961
962 //更新失败, 就设置这个buff无效
963 //有些buff存放了部分内容,这里必须把这部分内容无效掉
964 set_usbh_temp_buff_invalid(dev_id, blk);
965 //--<3-1-2>--挑选一个无用的buff, 这个buff仅仅是为了传数据
966 usbh_temp_buff = select_invalid_usbh_temp_buff(&buff_num);
967
968 if (usbh_temp_buff == NULL)
969 {
970 //DMSG_PANIC("ERR: select_invalid_usbh_temp_buff failed\n");
971 //既然不能再使用usbh_temp_buff了, 就直接写把
972 return buff_blk_write(pBuffer, blk, n, hDev);
973 }
974
975 memcpy(usbh_temp_buff, pBuffer, this_len);
976 /*
977 **********************************************************
978 * 这里因为this_len不满32k,所以不能设置usbh_temp_buff有效
979 **********************************************************
980 */
981 //--<3-1-3>--用usbh_temp_buff来进行写
982 return buff_blk_write(usbh_temp_buff, blk, n, hDev);
983 }
984 else
985 {
986 //数据大于32k, 就设置与dev_id匹配的buffer无效
987 set_usbh_temp_buff_invalid_by_dev(dev_id);
988 return buff_blk_write(pBuffer, blk, n, hDev);
989 }
990 }
991
992 /*
993 *********************************************************************
994 * init_usbh_buff_manager
995 *
996 * Description:
997 * 初始化 usbh 临时buffer,用来提高USBH的读写速度
998 * Arguments:
999 *
1000 * Returns:
1001 *
1002 * note:
1003 *
1004 *
1005 *********************************************************************
1006 */
init_usbh_buff_manager(void)1007 int init_usbh_buff_manager(void)
1008 {
1009 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
1010 unsigned int i = 0;
1011 unsigned int page = 0;
1012 //--<1>--初始化usbh_buff_manager
1013 memset(buff_mgr, 0, sizeof(usbh_buff_manager_t));
1014 buff_mgr->temp_buff_nr = USBH_TEMP_BUFFER_MAX_NUM;
1015 buff_mgr->temp_buff_len = USBH_TEMP_BUFFER_MAX_LEN;
1016 page = ((buff_mgr->temp_buff_len + 1023) >> 10) << 10;
1017 //DMSG_INFO("usb temp buffer size is %d\n", buff_mgr->temp_buff_len);
1018
1019 //--<2>--构造并且初始化每一个temp_buff
1020 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
1021 {
1022 buff_mgr->buff_array[i].buff = (void *)hal_malloc(page);
1023
1024 if (buff_mgr->buff_array[i].buff == NULL)
1025 {
1026 //分配失败,就放弃使用缓冲机制
1027 //DMSG_PANIC("ERR: init_usbh_buff_manager: USB_OS_PAGE_MALLOC failed\n");
1028 goto failed;
1029 }
1030
1031 memset((void *)buff_mgr->buff_array[i].buff, 0, buff_mgr->temp_buff_len);
1032 buff_mgr->buff_array[i].buff_len = buff_mgr->temp_buff_len;
1033 buff_mgr->buff_array[i].num = i;
1034 set_usbh_temp_buff_default(&(buff_mgr->buff_array[i]));
1035 }
1036
1037 return 0;
1038 failed:
1039
1040 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
1041 {
1042 if (buff_mgr->buff_array[i].buff)
1043 {
1044 hal_free(buff_mgr->buff_array[i].buff);
1045 buff_mgr->buff_array[i].buff = NULL;
1046 }
1047 else
1048 {
1049 //DMSG_PANIC("ERR: parameter is invalid, pfree failed\n");
1050 }
1051 }
1052
1053 memset(buff_mgr, 0, sizeof(usbh_buff_manager_t));
1054 return -1;
1055 }
1056
1057 /*
1058 *********************************************************************
1059 * exit_usbh_buff_manager
1060 *
1061 * Description:
1062 * sd信息设备,目前主要用于监测sd设备的读写情况
1063 * Arguments:
1064 *
1065 * Returns:
1066 *
1067 * note:
1068 *
1069 *
1070 *********************************************************************
1071 */
exit_usbh_buff_manager(void)1072 int exit_usbh_buff_manager(void)
1073 {
1074 usbh_buff_manager_t *buff_mgr = &usbh_buff_manager;
1075 unsigned int i = 0;
1076 set_all_usbh_temp_buff_invalid();
1077
1078 for (i = 0; i < buff_mgr->temp_buff_nr; i++)
1079 {
1080 if (buff_mgr->buff_array[i].buff)
1081 {
1082 hal_free(buff_mgr->buff_array[i].buff);
1083 buff_mgr->buff_array[i].buff = NULL;
1084 }
1085 else
1086 {
1087 //DMSG_PANIC("ERR: parameter is invalid, pfree failed\n");
1088 }
1089 }
1090
1091 memset(buff_mgr, 0, sizeof(usbh_buff_manager_t));
1092 return 0;
1093 }
1094
1095