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