USB 调试(个人存档)

版本1: 发现错误描述符报错返回
版本2: 版本1产生的内核OOPS问题解决

--------------------------------------------------------------------------------------
版本1:
这次USB主要改变了linux-2.6.29-0xlab\drivers\usb\core\config.c文件
1.修改usb_parse_configuration函数在发现描述符长度不合法时的处理,
旧的是breakt跳出循环,新的是返回EAGAIN(再处理一次)
     修改前:
 header = (struct usb_descriptor_header *) buffer2;
 if ((header->bLength > size2) || (header->bLength < 2)) {
  dev_warn(ddev, "config %d has an invalid descriptor "
      "of length %d, skipping remainder of the config\n",
      cfgno, header->bLength);
  break;
 }
     修改后:
 header = (struct usb_descriptor_header *) buffer2;
 if ((header->bLength > size2) || (header->bLength < 2)) {
  dev_warn(ddev, "config %d has an invalid descriptor "
      "of length %d, skipping remainder of the config\n",
      cfgno, header->bLength);
  return EAGAIN;
 }
2.修改usb_get_configuration函数中调用usb_parse_configuration函数返回结果的处理
旧的只有当结果为负值时,做错误处理;新的增加了一个返回EAGAIN时重复操作处理
(设置为最多3次,经过测试,基本2次以内可以得到合法的操作符)
    修改前:
 if (result < 0) {
  ++cfgno;
  goto err;
 }
    修改后:(增加对返回EAGAIN的处理)
 if (result < 0) {
  ++cfgno;
  goto err;
 }

 if (EAGAIN == result){
  times++;
  if(2 == times){
   times = 0;
   cfgno++;
  }
  cfgno--;
 }     /*通过减少cfgno配置的下标达到重复的目的,当重复两次后,cfgno的值不变
  达到跳到下一个配置的处理*/

------------------------------------------------------------------------------------------
版本2:
1.USB遗留问题:
  上次解决重新获取描述符的方法是采用在发现错误的时候报错返回,再限制对报错处理的次数来解决问题.
但是这样遗留下了一个很重要的问题,就是当出错次数超过报错次数的时候(即没有对错误做处理),这时候
会产生内核OOPS,报错情况如下:

Console: switching to colour frame buffer device 100x30
usb 1-1: config 1 has an invalid descriptor of length 0, skipping remainder of the config
usbcore: bogus descriptor, type 0 length 0
usb 1-1: New USB device found, idVendor=1a40, idProduct=0101
usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
usb 1-1: Product: USB 2.0 Hub [MTT]
Unable to handle kernel NULL pointer dereference at virtual address 0000000d
pgd = c0004000
[0000000d] *pgd=00000000
Internal error: Oops: 5 [#1]
Modules linked in:
CPU: 0    Not tainted  (2.6.29-omap1 #41)
PC is at usb_choose_configuration+0x6c/0x1c8
LR is at 0x32
pc : [<c0230d78>]    lr : [<00000032>]    psr: 20000013
sp : cf96bdc0  ip : 000001f8  fp : cf96bde4
r10: c0473670  r9 : 00000002  r8 : 00000000
r7 : 00000001  r6 : 00000000  r5 : cf9a3c00  r4 : 00000000
r3 : 00000008  r2 : cf931200  r1 : 00000000  r0 : 00000001
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c5387d  Table: 80004019  DAC: 00000017

2.遗留问题解决办法:
  通过采用限制发现报错返回次数,并对报错做处理(次数不限),来达到重新获取描述符的目的.
即把限制重新获取描述符的限制条件转移到发现错误的地方.
  a) 旧的解决方法:
     usb_parse_configuration函数中发现错误并返回:
 header = (struct usb_descriptor_header *) buffer2;
 if ((header->bLength > size2) || (header->bLength < 2)) {
  dev_warn(ddev, "config %d has an invalid descriptor "
      "of length %d, skipping remainder of the config\n",
      cfgno, header->bLength);
  return EAGAIN;
 }   /* 发现错误并报错*/
    
     usb_get_configuration函数获取usb_parse_configuration的错误返回,并错误处理,次数限制为2次:
 if (result < 0) {
  ++cfgno;
  goto err;
 }

 if (EAGAIN == result){
  times++;
  if(2 == times){
   times = 0;
   cfgno++;
  }
  cfgno--;
 }     /*通过减少cfgno配置的下标达到重复的目的,当重复两次后,cfgno的值不变
  达到跳到下一个配置的处理*/

  b) 新的解决办法:
     usb_parse_configuration函数中发现错误并限制错误返回次数(超过次数则继续按原来USB的流程走),
  次数增加到3次:
 header = (struct usb_descriptor_header *) buffer2;
 if ((header->bLength > size2) || (header->bLength < 2)) {
  dev_warn(ddev, "config %d has an invalid descriptor "
      "of length %d, skipping remainder of the config\n",
      cfgno, header->bLength);
  if(3 == times){
   times = 0;
   break;
  }               /* 限制出错返回次数为3次*/
  times++;
  return EAGAIN;   /* 发现错误前三次报错返回 */
 }

     usb_get_configuration函数获取usb_parse_configuration的错误返回,并错误处理:
 result = usb_parse_configuration(&dev->dev, cfgno,
     &dev->config[cfgno], bigbuffer, length);
 if (result < 0) {
  ++cfgno;
  goto err;
 }

 if (EAGAIN == result){
  cfgno--;
 }    /* 对发现错误描述符时做错误处理 */

你可能感兴趣的:(USB 调试(个人存档))