实现USB自动挂载

来源:互联网 发布:plc三菱编程入门 编辑:程序博客网 时间:2024/06/09 08:07

我的问题:USB驱动都正常,USB插入和拔出也能正常识别.可是就是不能自动mount到/data/usb下,网上查了很多,贴出如下,可是都不适合我,我系统没有装udev,哪位大侠能帮帮我,如何实现USB自动挂载?

方法1:http://linux.chinaunix.net/bbs/archiver/?tid-1025201.html

 

方法2:http://blog.chinaunix.net/u/25969/showart_529230.html

方法3:

[c-sharp] view plaincopy
  1. #include <sys/types.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <dirent.h>  
  5. #include <unistd.h>  
  6.   
  7. int main(void)  
  8. {  
  9.       DIR *dir,*udisk_dir;  
  10.     struct dirent *next,*udisk_next;  
  11.     int dir_number=0,disk_num=0;  
  12.     int udisk_flag=0;  
  13.   
  14.     while(1)  
  15.         {  
  16.             //打开目录  
  17.             dir = opendir("/proc/bus/usb/001");  
  18.             if (!dir)  
  19.                 {  
  20.                 fprintf(stderr, "Cannot open /dev/scsi/n");  
  21.                         exit(1);  
  22.                 }  
  23.             //读取目录内文件名  
  24.             while((next = readdir(dir)) != NULL)  
  25.                 {  
  26.                     dir_number++;  
  27.                 }  
  28.             closedir(dir);  
  29.             switch(udisk_flag)  
  30.                 {  
  31.                     case 0:  
  32.                         {     
  33.                             //如果文件名大于2(除了 "." "..")说明U盘已经存在  
  34.                             if(dir_number>3)  
  35.                                 {  
  36.                                     udisk_dir = opendir("/dev/scsi/host0/bus0/target0/lun0");  
  37.                                     if (!udisk_dir)  
  38.                                             {  
  39.                                             fprintf(stderr, "Cannot open /dev/scsi/n");  
  40.                                                     exit(1);  
  41.                                             }  
  42.                                     while((udisk_next = readdir(udisk_dir)) != NULL)  
  43.                                             {  
  44.                                                 disk_num++;  
  45.                                             }  
  46.                                           
  47.                                         dir_number=0;  
  48.                                         udisk_flag=1;  
  49.                                         //如果文件个数大于4,说明U盘是由N块flash组成,需要挂载disc  
  50.                                         if(disk_num>4)  
  51.                                                 system("mknod /dev/udisk b 8 0");  
  52.                                     else  
  53.                                                 system("mknod /dev/udisk b 8 1");  
  54.                                     system("mount -t vfat /dev/udisk /mnt/usb");  
  55.                                     printf("The udisk has installed/r/n");  
  56.                                 }  
  57.                             break;  
  58.                         }  
  59.                     case 1:  
  60.                             {  
  61.                             if(dir_number==3)  
  62.                                 {  
  63.                                     dir_number=0;  
  64.                                     udisk_flag=0;  
  65.                                 system("umount /mnt/usb");  
  66.                                 system("rm -rf /dev/udisk");  
  67.                                 system("/test/udisk stop");  
  68.                                 system("/test/udisk start");  
  69.                                 printf("The udisk has uninstalled/r/n");  
  70.                                 }  
  71.                             break;  
  72.                         }   
  73.                     default:  
  74.                             break;  
  75.                 }  
  76.             //软计数器清零  
  77.             dir_number=0;   
  78.             disk_num=0;  
  79.             sleep(1);   
  80.         }  
  81.     return 0;  
  82. }  

方法4: 编写usb_scanner _driver.如下:

[c-sharp] view plaincopy
  1. /* -*- linux-c -*- */  
  2.   
  3. /*  
  4.  * Driver for USB Scanners (linux-2.6) 
  5.  * 
  6.  * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson 
  7.  * Copyright (C) 2002, 2003 Henning Meier-Geinitz 
  8.  * 
  9.  * Portions may be copyright Brad Keryan and Michael Gee. 
  10.  * 
  11.  * Previously maintained by Brian Beattie 
  12.  * 
  13.  * Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de> 
  14.  *  
  15.  * This program is free software; you can redistribute it and/or 
  16.  * modify it under the terms of the GNU General Public License as 
  17.  * published by the Free Software Foundation; either version 2 of the 
  18.  * License, or (at your option) any later version. 
  19.  * 
  20.  * This program is distributed in the hope that it will be useful, but 
  21.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  23.  * General Public License for more details. 
  24.  * 
  25.  * You should have received a copy of the GNU General Public License 
  26.  * along with this program; if not, write to the Free Software 
  27.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  28.  * 
  29.  * Originally based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). 
  30.  * 
  31.  * History 
  32.  * 
  33.  *  0.1  8/31/1999 
  34.  * 
  35.  *    Developed/tested using linux-2.3.15 with minor ohci.c changes to 
  36.  *    support short packets during bulk xfer mode.  Some testing was 
  37.  *    done with ohci-hcd but the performance was low.  Very limited 
  38.  *    testing was performed with uhci but I was unable to get it to 
  39.  *    work.  Initial relase to the linux-usb development effort. 
  40.  * 
  41.  * 
  42.  *  0.2  10/16/1999 
  43.  * 
  44.  *    - Device can't be opened unless a scanner is plugged into the USB. 
  45.  *    - Finally settled on a reasonable value for the I/O buffer's. 
  46.  *    - Cleaned up write_scanner() 
  47.  *    - Disabled read/write stats 
  48.  *    - A little more code cleanup 
  49.  * 
  50.  * 
  51.  *  0.3  10/18/1999 
  52.  * 
  53.  *    - Device registration changed to reflect new device 
  54.  *      allocation/registration for linux-2.3.22+. 
  55.  *    - Adopted David Brownell's <david-b@pacbell.net> technique for  
  56.  *      assigning bulk endpoints. 
  57.  *    - Removed unnecessary #include's 
  58.  *    - Scanner model now reported via syslog INFO after being detected  
  59.  *      *and* configured. 
  60.  *    - Added user specified vendor:product USB ID's which can be passed  
  61.  *      as module parameters. 
  62.  * 
  63.  * 
  64.  *  0.3.1 
  65.  * 
  66.  *    - Applied patches for linux-2.3.25. 
  67.  *    - Error number reporting changed to reflect negative return codes. 
  68.  * 
  69.  * 
  70.  *  0.3.2 
  71.  * 
  72.  *    - Applied patches for linux-2.3.26 to scanner_init(). 
  73.  *    - Debug read/write stats now report values as signed decimal. 
  74.  * 
  75.  * 
  76.  *  0.3.3 
  77.  * 
  78.  *    - Updated the bulk_msg() calls to usb usb_bulk_msg(). 
  79.  *    - Added a small delay in the write_scanner() method to aid in 
  80.  *      avoiding NULL data reads on HP scanners.  We'll see how this works. 
  81.  *    - Return values from usb_bulk_msg() now ignore positive values for 
  82.  *      use with the ohci driver. 
  83.  *    - Added conditional debugging instead of commenting/uncommenting 
  84.  *      all over the place. 
  85.  *    - kfree()'d the pointer after using usb_string() as documented in 
  86.  *      linux-usb-api.txt. 
  87.  *    - Added usb_set_configuration().  It got lost in version 0.3 -- ack! 
  88.  *    - Added the HP 5200C USB Vendor/Product ID's. 
  89.  * 
  90.  * 
  91.  *  0.3.4  1/23/2000 
  92.  * 
  93.  *    - Added Greg K-H's <greg@kroah.com> patch for better handling of  
  94.  *      Product/Vendor detection. 
  95.  *    - The driver now autoconfigures its endpoints including interrupt 
  96.  *      endpoints if one is detected.  The concept was originally based 
  97.  *      upon David Brownell's method. 
  98.  *    - Added some Seiko/Epson ID's. Thanks to Karl Heinz  
  99.  *      Kremer <khk@khk.net>. 
  100.  *    - Added some preliminary ioctl() calls for the PV8630 which is used 
  101.  *      by the HP4200. The ioctl()'s still have to be registered. Thanks  
  102.  *      to Adrian Perez Jorge <adrianpj@easynews.com>. 
  103.  *    - Moved/migrated stuff to scanner.h 
  104.  *    - Removed the usb_set_configuration() since this is handled by 
  105.  *      the usb_new_device() routine in usb.c. 
  106.  *    - Added the HP 3300C.  Thanks to Bruce Tenison. 
  107.  *    - Changed user specified vendor/product id so that root hub doesn't 
  108.  *      get falsely attached to. Thanks to Greg K-H. 
  109.  *    - Added some Mustek ID's. Thanks to Gernot Hoyler  
  110.  *      <Dr.Hoyler@t-online.de>. 
  111.  *    - Modified the usb_string() reporting.  See kfree() comment above. 
  112.  *    - Added Umax Astra 2000U. Thanks to Doug Alcorn <doug@lathi.net>. 
  113.  *    - Updated the printk()'s to use the info/warn/dbg macros. 
  114.  *    - Updated usb_bulk_msg() argument types to fix gcc warnings. 
  115.  * 
  116.  * 
  117.  *  0.4  2/4/2000 
  118.  * 
  119.  *    - Removed usb_string() from probe_scanner since the core now does a 
  120.  *      good job of reporting what was connnected.   
  121.  *    - Finally, simultaneous multiple device attachment! 
  122.  *    - Fixed some potential memory freeing issues should memory allocation 
  123.  *      fail in probe_scanner(); 
  124.  *    - Some fixes to disconnect_scanner(). 
  125.  *    - Added interrupt endpoint support. 
  126.  *    - Added Agfa SnapScan Touch. Thanks to Jan Van den Bergh 
  127.  *      <jan.vandenbergh@cs.kuleuven.ac.be>. 
  128.  *    - Added Umax 1220U ID's. Thanks to Maciek Klimkowski 
  129.  *      <mac@nexus.carleton.ca>. 
  130.  *    - Fixed bug in write_scanner(). The buffer was not being properly 
  131.  *      updated for writes larger than OBUF_SIZE. Thanks to Henrik  
  132.  *      Johansson <henrikjo@post.utfors.se> for identifying it. 
  133.  *    - Added Microtek X6 ID's. Thanks to Oliver Neukum 
  134.  *      <Oliver.Neukum@lrz.uni-muenchen.de>. 
  135.  * 
  136.  *  
  137.  *  0.4.1  2/15/2000 
  138.  *   
  139.  *    - Fixed 'count' bug in read_scanner(). Thanks to Henrik 
  140.  *      Johansson <henrikjo@post.utfors.se> for identifying it.  Amazing 
  141.  *      it has worked this long. 
  142.  *    - Fixed '>=' bug in both read/write_scanner methods. 
  143.  *    - Cleaned up both read/write_scanner() methods so that they are  
  144.  *      a little more readable. 
  145.  *    - Added a lot of Microtek ID's.  Thanks to Adrian Perez Jorge. 
  146.  *    - Adopted the __initcall(). 
  147.  *    - Added #include <linux/init.h> to scanner.h for __initcall(). 
  148.  *    - Added one liner in irq_scanner() to keep gcc from complaining  
  149.  *      about an unused variable (data) if debugging was disabled 
  150.  *      in scanner.c. 
  151.  *    - Increased the timeout parameter in read_scanner() to 120 Secs. 
  152.  * 
  153.  * 
  154.  *  0.4.2  3/23/2000 
  155.  * 
  156.  *    - Added Umax 1236U ID.  Thanks to Philipp Baer <ph_baer@npw.net>. 
  157.  *    - Added Primax, ReadyScan, Visioneer, Colorado, and Genius ID's. 
  158.  *      Thanks to Adrian Perez Jorge <adrianpj@easynews.com>. 
  159.  *    - Fixed error number reported for non-existant devices.  Thanks to 
  160.  *      Spyridon Papadimitriou <Spyridon_Papadimitriou@gs91.sp.cs.cmu.edu>. 
  161.  *    - Added Acer Prisascan 620U ID's.  Thanks to Joao <joey@knoware.nl>. 
  162.  *    - Replaced __initcall() with module_init()/module_exit(). Updates 
  163.  *      from patch-2.3.48. 
  164.  *    - Replaced file_operations structure with new syntax.  Updates 
  165.  *      from patch-2.3.49. 
  166.  *    - Changed #include "usb.h" to #include <linux/usb.h> 
  167.  *    - Added #define SCN_IOCTL to exclude development areas  
  168.  *      since 2.4.x is about to be released. This mainly affects the  
  169.  *      ioctl() stuff.  See scanner.h for more details. 
  170.  *    - Changed the return value for signal_pending() from -ERESTARTSYS to 
  171.  *      -EINTR. 
  172.  * 
  173.  * 
  174.  * 0.4.3  4/30/2000 
  175.  * 
  176.  *    - Added Umax Astra 2200 ID.  Thanks to Flynn Marquardt  
  177.  *      <flynn@isr.uni-stuttgart.de>. 
  178.  *    - Added iVina 1200U ID. Thanks to Dyson Lin <dyson@avision.com.tw>. 
  179.  *    - Added access time update for the device file courtesy of Paul 
  180.  *      Mackerras <paulus@samba.org>.  This allows a user space daemon 
  181.  *      to turn the lamp off for a Umax 1220U scanner after a prescribed 
  182.  *      time. 
  183.  *    - Fixed HP S20 ID's.  Thanks to Ruud Linders <rlinders@xs4all.nl>. 
  184.  *    - Added Acer ScanPrisa 620U ID. Thanks to Oliver 
  185.  *      Schwartz <Oliver.Schwartz@gmx.de> via sane-devel mail list. 
  186.  *    - Fixed bug in read_scanner for copy_to_user() function.  The returned 
  187.  *      value should be 'partial' not 'this_read'. 
  188.  *    - Fixed bug in read_scanner. 'count' should be decremented  
  189.  *      by 'this_read' and not by 'partial'.  This resulted in twice as many 
  190.  *      calls to read_scanner() for small amounts of data and possibly 
  191.  *      unexpected returns of '0'.  Thanks to Karl Heinz  
  192.  *      Kremer <khk@khk.net> and Alain Knaff <Alain.Knaff@ltnb.lu> 
  193.  *      for discovering this. 
  194.  *    - Integrated Randy Dunlap's <randy.dunlap@intel.com> patch for a 
  195.  *      scanner lookup/ident table. Thanks Randy. 
  196.  *    - Documentation updates. 
  197.  *    - Added wait queues to read_scanner(). 
  198.  * 
  199.  * 
  200.  * 0.4.3.1 
  201.  * 
  202.  *    - Fixed HP S20 ID's...again..sigh.  Thanks to Ruud 
  203.  *      Linders <rlinders@xs4all.nl>. 
  204.  * 
  205.  * 0.4.4 
  206.  *    - Added addtional Mustek ID's (BearPaw 1200, 600 CU, 1200 USB, 
  207.  *      and 1200 UB.  Thanks to Henning Meier-Geinitz <henningmg@gmx.de>. 
  208.  *    - Added the Vuego Scan Brisa 340U ID's.  Apparently this scanner is 
  209.  *      marketed by Acer Peripherals as a cheap 300 dpi model. Thanks to 
  210.  *      David Gundersen <gundersd@paradise.net.nz>. 
  211.  *    - Added the Epson Expression1600 ID's. Thanks to Karl Heinz 
  212.  *      Kremer <khk@khk.net>. 
  213.  * 
  214.  * 0.4.5  2/28/2001 
  215.  *    - Added Mustek ID's (BearPaw 2400, 1200 CU Plus, BearPaw 1200F). 
  216.  *      Thanks to Henning Meier-Geinitz <henningmg@gmx.de>. 
  217.  *    - Added read_timeout module parameter to override RD_NAK_TIMEOUT 
  218.  *      when read()'ing from devices. 
  219.  *    - Stalled pipes are now checked and cleared with 
  220.  *      usb_clear_halt() for the read_scanner() function. This should 
  221.  *      address the "funky result: -32" error messages. 
  222.  *    - Removed Microtek scanner ID's.  Microtek scanners are now 
  223.  *      supported via the drivers/usb/microtek.c driver. 
  224.  *    - Added scanner specific read timeout's. 
  225.  *    - Return status errors are NEGATIVE!!!  This should address the 
  226.  *      "funky result: -110" error messages. 
  227.  *    - Replaced USB_ST_TIMEOUT with ETIMEDOUT. 
  228.  *    - rd_nak was still defined in MODULE_PARM.  It's been updated with 
  229.  *      read_timeout.  Thanks to Mark W. Webb <markwebb@adelphia.net> for 
  230.  *      reporting this bug. 
  231.  *    - Added Epson Perfection 1640SU and 1640SU Photo.  Thanks to 
  232.  *      Jean-Luc <f5ibh@db0bm.ampr.org> and Manuel 
  233.  *      Pelayo <Manuel.Pelayo@sesips.org>. Reported to work fine by Manuel. 
  234.  * 
  235.  * 0.4.6  9/27/2001 
  236.  *    - Added IOCTL's to report back scanner USB ID's.  Thanks to 
  237.  *      Karl Heinz <khk@lynx.phpwebhosting.com> 
  238.  *    - Added Umax Astra 2100U ID's.  Thanks to Ron 
  239.  *      Wellsted <ron@wellsted.org.uk>. 
  240.  *      and Manuel Pelayo <Manuel.Pelayo@sesips.org>. 
  241.  *    - Added HP 3400 ID's. Thanks to Harald Hannelius <harald@iki.fi> 
  242.  *      and Bertrik Sikken <bertrik@zonnet.nl>.  Reported to work at 
  243.  *      htpp://home.zonnet.nl/bertrik/hp3300c/hp3300c.htm. 
  244.  *    - Added Minolta Dimage Scan Dual II ID's.  Thanks to Jose Paulo 
  245.  *      Moitinho de Almeida <moitinho@civil.ist.utl.pt> 
  246.  *    - Confirmed addition for SnapScan E20.  Thanks to Steffen H黚ner 
  247.  *      <hueb_s@gmx.de>. 
  248.  *    - Added Lifetec LT9385 ID's.  Thanks to Van Bruwaene Kris 
  249.  *      <krvbr@yahoo.co.uk> 
  250.  *    - Added Agfa SnapScan e26 ID's.  Reported to work with SANE 
  251.  *      1.0.5.  Thanks to Falk Sauer <falk@mgnkatze.franken.de>. 
  252.  *    - Added HP 4300 ID's.  Thanks to Stefan Schlosser 
  253.  *      <castla@grmmbl.org>. 
  254.  *    - Added Relisis Episode ID's.  Thanks to Manfred 
  255.  *      Morgner <odb-devel@gmx.net>. 
  256.  *    - Added many Acer ID's. Thanks to Oliver 
  257.  *      Schwartz <Oliver.Schwartz@gmx.de>. 
  258.  *    - Added Snapscan e40 ID's.  Thanks to Oliver 
  259.  *      Schwartz <Oliver.Schwartz@gmx.de>. 
  260.  *    - Thanks to Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de> 
  261.  *      for helping with races. 
  262.  *    - Added Epson Perfection 1650 ID's. Thanks to Karl Heinz 
  263.  *      Kremer <khk@khk.net>. 
  264.  *    - Added Epson Perfection 2450 ID's (aka GT-9700 for the Japanese 
  265.  *      market).  Thanks to Karl Heinz Kremer <khk@khk.net>. 
  266.  *    - Added Mustek 600 USB ID's.  Thanks to Marcus 
  267.  *      Alanen <maalanen@ra.abo.fi>. 
  268.  *    - Added Acer ScanPrisa 1240UT ID's.  Thanks to Morgan 
  269.  *      Collins <sirmorcant@morcant.org>. 
  270.  *    - Incorporated devfs patches!! Thanks to Tom Rini 
  271.  *      <trini@kernel.crashing.org>, Pavel Roskin <proski@gnu.org>, 
  272.  *      Greg KH <greg@kroah.com>, Yves Duret <yduret@mandrakesoft.com>, 
  273.  *      Flavio Stanchina <flavio.stanchina@tin.it>. 
  274.  *    - Removed Minolta ScanImage II.  This scanner uses USB SCSI.  Thanks 
  275.  *      to Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de> for pointing 
  276.  *      this out. 
  277.  *    - Added additional SMP locking.  Thanks to David Brownell and  
  278.  *      Oliver Neukum for their help. 
  279.  *    - Added version reporting - reports for both module load and modinfo 
  280.  *    - Started path to hopefully straighten/clean out ioctl()'s. 
  281.  *    - Users are now notified to consult the Documentation/usb/scanner.txt 
  282.  *      for common error messages rather than the maintainer. 
  283.  * 
  284.  * 0.4.7  11/28/2001 
  285.  *    - Fixed typo in Documentation/usb/scanner.txt.  Thanks to 
  286.  *      Karel <karel.vervaeke@pandora.be> for pointing it out. 
  287.  *    - Added ID's for a Memorex 6136u. Thanks to 羖varo Gaspar de 
  288.  *      Valenzuela" <agaspard@utsi.edu>. 
  289.  *    - Added ID's for Agfa e25.  Thanks to Heinrich  
  290.  *      Rust <Heinrich.Rust@gmx.de>.  Also reported to work with 
  291.  *      Linux and SANE (?). 
  292.  *    - Added Canon FB620U, D646U, and 1220U ID's.  Thanks to Paul 
  293.  *      Rensing <Paul_Rensing@StanfordAlumni.org>.  For more info 
  294.  *      on Linux support for these models, contact  
  295.  *      salvestrini@users.sourceforge.net. 
  296.  *    - Added Plustek OpticPro UT12, OpticPro U24, KYE/Genius 
  297.  *      ColorPage-HR6 V2 ID's in addition to many "Unknown" models 
  298.  *      under those vendors.  Thanks to 
  299.  *      Jaeger, Gerhard" <g.jaeger@earthling.net>.  These scanner are 
  300.  *      apparently based upon the LM983x IC's. 
  301.  *    - Applied Frank's patch that addressed some locking and module 
  302.  *      referencing counts.  Thanks to both 
  303.  *      Frank Zago <fzago@greshamstorage.com> and 
  304.  *      Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing. 
  305.  * 
  306.  * 0.4.8  5/30/2002 
  307.  *    - Added Mustek BearPaw 2400 TA.  Thanks to Sergey 
  308.  *      Vlasov <vsu@mivlgu.murom.ru>. 
  309.  *    - Added Mustek 1200UB Plus and Mustek BearPaw 1200 CU ID's.  These use 
  310.  *      the Grandtech GT-6801 chip. Thanks to Henning 
  311.  *      Meier-Geinitz <henning@meier-geinitz.de>. 
  312.  *    - Increased Epson timeout to 60 secs as requested from  
  313.  *      Karl Heinz Kremer <khk@khk.net>. 
  314.  *    - Changed maintainership from David E. Nelson to Brian 
  315.  *      Beattie <beattie@beattie-home.net>. 
  316.  * 
  317.  * 0.4.9  12/19/2002 
  318.  *    - Added vendor/product ids for Nikon, Mustek, Plustek, Genius, Epson, 
  319.  *      Canon, Umax, Hewlett-Packard, Benq, Agfa, Minolta scanners. 
  320.  *      Thanks to Dieter Faulbaum <faulbaum@mail.bessy.de>, Stian Jordet 
  321.  *      <liste@jordet.nu>, "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>, 
  322.  *      "Jaeger, Gerhard" <gerhard@gjaeger.de>, Ira Childress  
  323.  *      <ichildress@mn.rr.com>, Till Kamppeter <till.kamppeter@gmx.net>, 
  324.  *      Ed Hamrick <EdHamrick@aol.com>, Oliver Schwartz 
  325.  *      <Oliver.Schwartz@gmx.de> and everyone else who sent ids. 
  326.  *    - Some Benq, Genius and Plustek ids are identified now. 
  327.  *    - Accept scanners with only one bulk (in) endpoint (thanks to Sergey 
  328.  *      Vlasov <vsu@mivlgu.murom.ru>). 
  329.  *    - Accept devices with more than one interface. Only use interfaces that 
  330.  *      look like belonging to scanners. 
  331.  *    - Fix compilation error when debugging is enabled. 
  332.  *    - Add locking to ioctl_scanner(). Thanks to Oliver Neukum 
  333.  *      <oliver@neukum.name>. 
  334.  * 
  335.  * 0.4.10  01/07/2003 
  336.  *    - Added vendor/product ids for Artec, Canon, Compaq, Epson, HP, Microtek  
  337.  *      and Visioneer scanners. Thanks to William Lam <wklam@triad.rr.com>, 
  338.  *      Till Kamppeter <till.kamppeter@gmx.net> and others for all the ids. 
  339.  *    - Cleaned up list of vendor/product ids. 
  340.  *    - Print information about user-supplied ids only once at startup instead 
  341.  *      of every time any USB device is plugged in. 
  342.  *    - Removed PV8630 ioctls. Use the standard ioctls instead. 
  343.  *    - Made endpoint detection more generic. Basically, only one bulk-in  
  344.  *      endpoint is required, everything else is optional. 
  345.  *    - New maintainer: Henning Meier-Geinitz. 
  346.  *    - Print ids and device number when a device was detected. 
  347.  *    - Don't print errors when the device is busy. 
  348.  *       
  349.  * 0.4.11  2003-02-25 
  350.  *    - Added vendor/product ids for Artec, Avision, Brother, Canon, Compaq, 
  351.  *      Fujitsu, Hewlett-Packard, Lexmark, LG Electronics, Medion, Microtek, 
  352.  *      Primax, Prolink,  Plustek, SYSCAN, Trust and UMAX scanners. 
  353.  *    - Fixed generation of devfs names if dynamic minors are disabled. 
  354.  *    - Used kobject reference counting to free the scn struct when the device 
  355.  *      is closed and disconnected. Avoids crashes when writing to a  
  356.  *      disconnected device. (Thanks to Greg KH). 
  357.  * 
  358.  * 0.4.12  2003-04-11 
  359.  *    - Fixed endpoint detection. The endpoints were numbered from 1 to n but 
  360.  *      that assumption is not correct in all cases. 
  361.  * 
  362.  * 0.4.13  2003-05-30 
  363.  *    - Added vendor/product ids for Genius, Hewlett-Packard, Microtek,  
  364.  *      Mustek, Pacific Image Electronics, Plustek, and Visioneer scanners. 
  365.  *      Fixed names of some other scanners. 
  366.  * 
  367.  * 0.4.14  2003-07-15 
  368.  *    - Fixed race between open and probe (Oliver Neukum). 
  369.  *    - Added vendor/product ids for Avision, Canon, HP, Microtek and Relisys scanners. 
  370.  *    - Clean up irq urb when not enough memory is available. 
  371.  * 
  372.  * 0.4.15  2003-09-22 
  373.  *    - Use static declarations for usb_scanner_init/usb_scanner_exit  
  374.  *      (Daniele Bellucci). 
  375.  *    - Report back return codes of usb_register and usb_usbmit_urb instead of -1 or 
  376.  *      -ENONMEM (Daniele Bellucci). 
  377.  *    - Balancing usb_register_dev/usb_deregister_dev in probe_scanner when a fail  
  378.  *      condition occours (Daniele Bellucci). 
  379.  *    - Added vendor/product ids for Canon, HP, Microtek, Mustek, Siemens, UMAX, and 
  380.  *      Visioneer scanners. 
  381.  *    - Added test for USB_CLASS_CDC_DATA which is used by some fingerprint scanners. 
  382.  * 
  383.  * 0.4.16  2003-11-04 
  384.  *    - Added vendor/product ids for Epson, Genius, Microtek, Plustek, Reflecta, and 
  385.  *      Visioneer scanners. Removed ids for HP PSC devices as these are supported by 
  386.  *      the hpoj userspace driver. 
  387.  * 
  388.  * TODO 
  389.  *    - Performance 
  390.  *    - Select/poll methods 
  391.  *    - More testing 
  392.  *    - More general usage ioctl's 
  393.  * 
  394.  * 
  395.  *  Thanks to: 
  396.  * 
  397.  *    - All the folks on the linux-usb list who put up with me. :)  This  
  398.  *      has been a great learning experience for me. 
  399.  *    - To Linus Torvalds for this great OS. 
  400.  *    - The GNU folks. 
  401.  *    - The folks that forwarded Vendor:Product ID's to me. 
  402.  *    - Johannes Erdfelt for the loaning of a USB analyzer for tracking an 
  403.  *      issue with HP-4100 and uhci. 
  404.  *    - Adolfo Montero for his assistance. 
  405.  *    - All the folks who chimed in with reports and suggestions. 
  406.  *    - All the developers that are working on USB SANE backends or other 
  407.  *      applications to use USB scanners. 
  408.  *    - Thanks to Greg KH <greg@kroah.com> for setting up Brian Beattie 
  409.  *      and Henning Meier-Geinitz to be the new USB Scanner maintainer. 
  410.  * 
  411.  *  Performance: 
  412.  * 
  413.  *    System: Pentium 120, 80 MB RAM, OHCI, Linux 2.3.23, HP 4100C USB Scanner 
  414.  *            300 dpi scan of the entire bed 
  415.  *      24 Bit Color ~ 70 secs - 3.6 Mbit/sec 
  416.  *       8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */  
  417.   
  418. /* 
  419.  * For documentation, see Documentation/usb/scanner.txt. 
  420.  * Website: http://www.meier-geinitz.de/kernel/ 
  421.  * Please contact the maintainer if your scanner is not detected by this 
  422.  * driver automatically. 
  423.  */  
  424.  
  425.  
  426. #include <asm/byteorder.h>  
  427.   
  428. /*  
  429.  * Scanner definitions, macros, module info,  
  430.  * debug/ioctl/data_dump enable, and other constants. 
  431.  */   
  432. #include "scanner.h"  
  433.   
  434. static void  
  435. irq_scanner(struct urb *urb, struct pt_regs *regs)  
  436. {  
  437.   
  438. /* 
  439.  * For the meantime, this is just a placeholder until I figure out what 
  440.  * all I want to do with it -- or somebody else for that matter. 
  441.  */  
  442.   
  443.     struct scn_usb_data *scn;  
  444.     unsigned char *data;  
  445.     int status;  
  446.   
  447.     scn = urb->context;  
  448.   
  449.     data = &scn->button;  
  450.     data += 0;      /* Keep gcc from complaining about unused var */  
  451.   
  452.     switch (urb->status) {  
  453.     case 0:  
  454.         /* success */  
  455.         break;  
  456.     case -ECONNRESET:  
  457.     case -ENOENT:  
  458.     case -ESHUTDOWN:  
  459.         /* this urb is terminated, clean up */  
  460.         dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);  
  461.         return;  
  462.     default:  
  463.         dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);  
  464.             return;   
  465.     }  
  466.   
  467.     dbg("irq_scanner(%d): data:%x", scn->scn_minor, *data);  
  468.   
  469.     status = usb_submit_urb (urb, GFP_ATOMIC);  
  470.     if (status)  
  471.         err ("%s - usb_submit_urb failed with result %d",  
  472.              __FUNCTION__, status);  
  473. }  
  474.   
  475. static int  
  476. open_scanner(struct inode * inode, struct file * file)  
  477. {  
  478.     struct scn_usb_data *scn;  
  479.     struct usb_device *dev;  
  480.     struct usb_interface *intf;  
  481.   
  482.     int scn_minor;  
  483.   
  484.     int err=0;  
  485.   
  486.     down(&scn_mutex);  
  487.   
  488.     scn_minor = USB_SCN_MINOR(inode);  
  489.   
  490.     dbg("open_scanner: scn_minor:%d", scn_minor);  
  491.   
  492.     intf = usb_find_interface(&scanner_driver, scn_minor);  
  493.     if (!intf) {  
  494.         up(&scn_mutex);  
  495.         err("open_scanner(%d): Unable to access minor data", scn_minor);  
  496.         return -ENODEV;  
  497.     }  
  498.     scn = usb_get_intfdata(intf);  
  499.     kobject_get(&scn->kobj);  
  500.   
  501.     dev = scn->scn_dev;  
  502.   
  503.     down(&(scn->sem));   /* Now protect the scn_usb_data structure */   
  504.   
  505.     up(&scn_mutex); /* Now handled by the above */  
  506.   
  507.     if (!dev) {  
  508.         err("open_scanner(%d): Scanner device not present", scn_minor);  
  509.         err = -ENODEV;  
  510.         goto out_error;  
  511.     }  
  512.   
  513.     if (!scn->present) {  
  514.         err("open_scanner(%d): Scanner is not present", scn_minor);  
  515.         err = -ENODEV;  
  516.         goto out_error;  
  517.     }  
  518.   
  519.     if (scn->isopen) {  
  520.         dbg("open_scanner(%d): Scanner device is already open", scn_minor);  
  521.         err = -EBUSY;  
  522.         goto out_error;  
  523.     }  
  524.   
  525.     init_waitqueue_head(&scn->rd_wait_q);  
  526.   
  527.     scn->isopen = 1;  
  528.   
  529.     file->private_data = scn; /* Used by the read and write methods */  
  530.   
  531.   
  532. out_error:  
  533.   
  534.     up(&(scn->sem)); /* Wake up any possible contending processes */  
  535.   
  536.     return err;  
  537. }  
  538.   
  539. static int  
  540. close_scanner(struct inode * inode, struct file * file)  
  541. {  
  542.     struct scn_usb_data *scn = file->private_data;  
  543.   
  544.     int scn_minor;  
  545.   
  546.     scn_minor = USB_SCN_MINOR (inode);  
  547.   
  548.     dbg("close_scanner: scn_minor:%d", scn_minor);  
  549.   
  550.     down(&scn_mutex);  
  551.     down(&(scn->sem));  
  552.   
  553.     scn->isopen = 0;  
  554.   
  555.     file->private_data = NULL;  
  556.   
  557.     up(&scn_mutex);  
  558.     up(&(scn->sem));  
  559.   
  560.     kobject_put(&scn->kobj);  
  561.   
  562.     return 0;  
  563. }  
  564.   
  565. static ssize_t  
  566. write_scanner(struct file * file, const char * buffer,  
  567.               size_t count, loff_t *ppos)  
  568. {  
  569.     struct scn_usb_data *scn;  
  570.     struct usb_device *dev;  
  571.   
  572.     ssize_t bytes_written = 0; /* Overall count of bytes written */  
  573.     ssize_t ret = 0;  
  574.   
  575.     int scn_minor;  
  576.   
  577.     int this_write;     /* Number of bytes to write */  
  578.     int partial;        /* Number of bytes successfully written */  
  579.     int result = 0;  
  580.   
  581.     char *obuf;  
  582.   
  583.     scn = file->private_data;  
  584.   
  585.     down(&(scn->sem));  
  586.   
  587.     if (!scn->bulk_out_ep) {  
  588.         /* This scanner does not have a bulk-out endpoint */  
  589.         up(&(scn->sem));  
  590.         return -EINVAL;  
  591.     }  
  592.   
  593.     scn_minor = scn->scn_minor;  
  594.   
  595.     obuf = scn->obuf;  
  596.   
  597.     dev = scn->scn_dev;  
  598.   
  599.     file->f_dentry->d_inode->i_atime = CURRENT_TIME;  
  600.   
  601.     while (count > 0) {  
  602.   
  603.         if (signal_pending(current)) {  
  604.             ret = -ERESTARTSYS;  
  605.             break;  
  606.         }  
  607.   
  608.         this_write = (count >= OBUF_SIZE) ? OBUF_SIZE : count;  
  609.   
  610.         if (copy_from_user(scn->obuf, buffer, this_write)) {  
  611.             ret = -EFAULT;  
  612.             break;  
  613.         }  
  614.   
  615.         result = usb_bulk_msg(dev,usb_sndbulkpipe(dev, scn->bulk_out_ep), obuf, this_write, &partial, 60*HZ);  
  616.         dbg("write stats(%d): result:%d this_write:%d partial:%d", scn_minor, result, this_write, partial);  
  617.   
  618.         if (result == -ETIMEDOUT) { /* NAK -- shouldn't happen */  
  619.             warn("write_scanner: NAK received.");  
  620.             ret = result;  
  621.             break;  
  622.         } else if (result < 0) { /* We should not get any I/O errors */  
  623.             warn("write_scanner(%d): funky result: %d. Consult Documentataion/usb/scanner.txt.", scn_minor, result);  
  624.             ret = -EIO;  
  625.             break;  
  626.         }  
  627.  
  628. #ifdef WR_DATA_DUMP  
  629.         if (partial) {  
  630.             unsigned char cnt, cnt_max;  
  631.             cnt_max = (partial > 24) ? 24 : partial;  
  632.             printk(KERN_DEBUG "dump(%d): ", scn_minor);  
  633.             for (cnt=0; cnt < cnt_max; cnt++) {  
  634.                 printk("%X ", obuf[cnt]);  
  635.             }  
  636.             printk("/n");  
  637.         }  
  638. #endif  
  639.         if (partial != this_write) { /* Unable to write all contents of obuf */  
  640.             ret = -EIO;  
  641.             break;  
  642.         }  
  643.   
  644.         if (partial) { /* Data written */  
  645.             buffer += partial;  
  646.             count -= partial;  
  647.             bytes_written += partial;  
  648.         } else { /* No data written */  
  649.             ret = 0;  
  650.             break;  
  651.         }  
  652.     }  
  653.     up(&(scn->sem));  
  654.     mdelay(5);      /* This seems to help with SANE queries */  
  655.     return ret ? ret : bytes_written;  
  656. }  
  657.   
  658. static ssize_t  
  659. read_scanner(struct file * file, char * buffer,  
  660.              size_t count, loff_t *ppos)  
  661. {  
  662.     struct scn_usb_data *scn;  
  663.     struct usb_device *dev;  
  664.   
  665.     ssize_t bytes_read; /* Overall count of bytes_read */  
  666.     ssize_t ret;  
  667.   
  668.     int scn_minor;  
  669.     int partial;        /* Number of bytes successfully read */  
  670.     int this_read;      /* Max number of bytes to read */  
  671.     int result;  
  672.     int rd_expire = RD_EXPIRE;  
  673.   
  674.     char *ibuf;  
  675.   
  676.     scn = file->private_data;  
  677.   
  678.     down(&(scn->sem));  
  679.   
  680.     scn_minor = scn->scn_minor;  
  681.   
  682.     ibuf = scn->ibuf;  
  683.   
  684.     dev = scn->scn_dev;  
  685.   
  686.     bytes_read = 0;  
  687.     ret = 0;  
  688.   
  689.     file->f_dentry->d_inode->i_atime = CURRENT_TIME; /* Update the 
  690.                                                             atime of 
  691.                                                             the device 
  692.                                                             node */  
  693.     while (count > 0) {  
  694.         if (signal_pending(current)) {  
  695.             ret = -ERESTARTSYS;  
  696.             break;  
  697.         }  
  698.   
  699.         this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;  
  700.   
  701.         result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, scn->bulk_in_ep), ibuf, this_read, &partial, scn->rd_nak_timeout);  
  702.         dbg("read stats(%d): result:%d this_read:%d partial:%d count:%d", scn_minor, result, this_read, partial, count);  
  703.   
  704. /* 
  705.  * Scanners are sometimes inheriently slow since they are mechanical 
  706.  * in nature.  USB bulk reads tend to timeout while the scanner is 
  707.  * positioning, resetting, warming up the lamp, etc if the timeout is 
  708.  * set too low.  A very long timeout parameter for bulk reads was used 
  709.  * to overcome this limitation, but this sometimes resulted in folks 
  710.  * having to wait for the timeout to expire after pressing Ctrl-C from 
  711.  * an application. The user was sometimes left with the impression 
  712.  * that something had hung or crashed when in fact the USB read was 
  713.  * just waiting on data.  So, the below code retains the same long 
  714.  * timeout period, but splits it up into smaller parts so that 
  715.  * Ctrl-C's are acted upon in a reasonable amount of time. 
  716.  */  
  717.   
  718.         if (result == -ETIMEDOUT) { /* NAK */  
  719.             if (!partial) { /* No data */  
  720.                 if (--rd_expire <= 0) {  /* Give it up */  
  721.                     warn("read_scanner(%d): excessive NAK's received", scn_minor);  
  722.                     ret = result;  
  723.                     break;  
  724.                 } else { /* Keep trying to read data */  
  725.                     interruptible_sleep_on_timeout(&scn->rd_wait_q, scn->rd_nak_timeout);  
  726.                     continue;  
  727.                 }  
  728.             } else { /* Timeout w/ some data */  
  729.                 goto data_recvd;  
  730.             }  
  731.         }  
  732.           
  733.         if (result == -EPIPE) { /* No hope */  
  734.             if(usb_clear_halt(dev, scn->bulk_in_ep)) {  
  735.                 err("read_scanner(%d): Failure to clear endpoint halt condition (%Zd).", scn_minor, ret);  
  736.             }  
  737.             ret = result;  
  738.             break;  
  739.         } else if ((result < 0) && (result != -EREMOTEIO)) {  
  740.             warn("read_scanner(%d): funky result:%d. Consult Documentation/usb/scanner.txt.", scn_minor, (int)result);  
  741.             ret = -EIO;  
  742.             break;  
  743.         }  
  744.   
  745.     data_recvd:  
  746.  
  747. #ifdef RD_DATA_DUMP  
  748.         if (partial) {  
  749.             unsigned char cnt, cnt_max;  
  750.             cnt_max = (partial > 24) ? 24 : partial;  
  751.             printk(KERN_DEBUG "dump(%d): ", scn_minor);  
  752.             for (cnt=0; cnt < cnt_max; cnt++) {  
  753.                 printk("%X ", ibuf[cnt]);  
  754.             }  
  755.             printk("/n");  
  756.         }  
  757. #endif  
  758.   
  759.         if (partial) { /* Data returned */  
  760.             if (copy_to_user(buffer, ibuf, partial)) {  
  761.                 ret = -EFAULT;  
  762.                 break;  
  763.             }  
  764.             count -= this_read; /* Compensate for short reads */  
  765.             bytes_read += partial; /* Keep tally of what actually was read */  
  766.             buffer += partial;  
  767.         } else {  
  768.             ret = 0;  
  769.             break;  
  770.         }  
  771.     }  
  772.     up(&(scn->sem));  
  773.     return ret ? ret : bytes_read;  
  774. }  
  775.   
  776. static int  
  777. ioctl_scanner(struct inode *inode, struct file *file,  
  778.           unsigned int cmd, unsigned long arg)  
  779. {  
  780.     struct usb_device *dev;  
  781.     struct scn_usb_data *scn = file->private_data;  
  782.     int retval = -ENOTTY;  
  783.     int scn_minor;  
  784.   
  785.     scn_minor = USB_SCN_MINOR(inode);  
  786.     down(&(scn->sem));  
  787.   
  788.     dev = scn->scn_dev;  
  789.   
  790.     switch (cmd)  
  791.     {  
  792.     case SCANNER_IOCTL_VENDOR :  
  793.         retval = (put_user(dev->descriptor.idVendor, (unsigned int *) arg));  
  794.         break;  
  795.     case SCANNER_IOCTL_PRODUCT :  
  796.         retval = (put_user(dev->descriptor.idProduct, (unsigned int *) arg));  
  797.         break;  
  798.     case SCANNER_IOCTL_CTRLMSG:  
  799.     {  
  800.         struct ctrlmsg_ioctl {  
  801.             struct usb_ctrlrequest  req;  
  802.             void            *data;  
  803.         } cmsg;  
  804.         int pipe, nb, ret;  
  805.         unsigned char buf[64];  
  806.         retval = 0;  
  807.   
  808.         if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg))) {  
  809.             retval = -EFAULT;  
  810.             break;  
  811.         }  
  812.   
  813.         nb = cmsg.req.wLength;  
  814.   
  815.         if (nb > sizeof(buf)) {  
  816.             retval = -EINVAL;  
  817.             break;  
  818.         }  
  819.   
  820.         if ((cmsg.req.bRequestType & 0x80) == 0) {  
  821.             pipe = usb_sndctrlpipe(dev, 0);  
  822.             if (nb > 0 && copy_from_user(buf, cmsg.data, nb)) {  
  823.                 retval = -EFAULT;  
  824.                 break;  
  825.             }  
  826.         } else {  
  827.             pipe = usb_rcvctrlpipe(dev, 0);  
  828.         }  
  829.   
  830.         ret = usb_control_msg(dev, pipe, cmsg.req.bRequest,  
  831.                       cmsg.req.bRequestType,  
  832.                       cmsg.req.wValue,  
  833.                       cmsg.req.wIndex,  
  834.                       buf, nb, HZ);  
  835.   
  836.         if (ret < 0) {  
  837.             err("ioctl_scanner(%d): control_msg returned %d/n", scn_minor, ret);  
  838.             retval = -EIO;  
  839.             break;  
  840.         }  
  841.   
  842.         if (nb > 0 && (cmsg.req.bRequestType & 0x80) && copy_to_user(cmsg.data, buf, nb))  
  843.             retval = -EFAULT;  
  844.   
  845.         break;  
  846.     }  
  847.     default:  
  848.         break;  
  849.     }  
  850.     up(&(scn->sem));  
  851.     return retval;  
  852. }  
  853.   
  854. static void destroy_scanner (struct kobject *kobj)  
  855. {  
  856.     struct scn_usb_data *scn;  
  857.   
  858.     dbg ("%s", __FUNCTION__);  
  859.   
  860.     scn = to_scanner(kobj);  
  861.   
  862.     down (&scn_mutex);  
  863.     down (&(scn->sem));  
  864.   
  865.     usb_driver_release_interface(&scanner_driver,  
  866.         scn->scn_dev->actconfig->interface[scn->ifnum]);  
  867.   
  868.     kfree(scn->ibuf);  
  869.     kfree(scn->obuf);  
  870.   
  871.     usb_free_urb(scn->scn_irq);  
  872.     usb_put_dev(scn->scn_dev);  
  873.     up (&(scn->sem));  
  874.     kfree (scn);  
  875.     up (&scn_mutex);  
  876. }  
  877.   
  878. static struct kobj_type scanner_kobj_type = {  
  879.     .release = destroy_scanner,  
  880. };  
  881.   
  882. static struct  
  883. file_operations usb_scanner_fops = {  
  884.     .owner =    THIS_MODULE,  
  885.     .read =     read_scanner,  
  886.     .write =    write_scanner,  
  887.     .ioctl =    ioctl_scanner,  
  888.     .open =     open_scanner,  
  889.     .release =  close_scanner,  
  890. };  
  891.   
  892. static struct usb_class_driver scanner_class = {  
  893.     .name =     "usb/scanner%d",  
  894.     .fops =     &usb_scanner_fops,  
  895.     .mode =     S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,  
  896.     .minor_base =   SCN_BASE_MNR,  
  897. };  
  898.   
  899. static int  
  900. probe_scanner(struct usb_interface *intf,  
  901.           const struct usb_device_id *id)  
  902. {  
  903.     struct usb_device *dev = interface_to_usbdev (intf);  
  904.     struct scn_usb_data *scn;  
  905.     struct usb_host_interface *interface;  
  906.     struct usb_endpoint_descriptor *endpoint;  
  907.   
  908.     int ep_cnt;  
  909.     int ix;  
  910.     int retval;  
  911.   
  912.     char valid_device = 0;  
  913.     char have_bulk_in, have_bulk_out, have_intr;  
  914.     char name[14];  
  915.   
  916.     dbg("probe_scanner: USB dev address:%p", dev);  
  917.   
  918. /* 
  919.  * 1. Check Vendor/Product 
  920.  * 2. Determine/Assign Bulk Endpoints 
  921.  * 3. Determine/Assign Intr Endpoint 
  922.  */  
  923.   
  924. /* 
  925.  * There doesn't seem to be an imaging class defined in the USB 
  926.  * Spec. (yet).  If there is, HP isn't following it and it doesn't 
  927.  * look like anybody else is either.  Therefore, we have to test the 
  928.  * Vendor and Product ID's to see what we have.  Also, other scanners 
  929.  * may be able to use this driver by specifying both vendor and 
  930.  * product ID's as options to the scanner module in conf.modules. 
  931.  * 
  932.  * NOTE: Just because a product is supported here does not mean that 
  933.  * applications exist that support the product.  It's in the hopes 
  934.  * that this will allow developers a means to produce applications 
  935.  * that will support USB products. 
  936.  * 
  937.  * Until we detect a device which is pleasing, we silently punt. 
  938.  */  
  939.   
  940.     for (ix = 0; ix < sizeof (scanner_device_ids) / sizeof (struct usb_device_id); ix++) {  
  941.         if ((dev->descriptor.idVendor == scanner_device_ids [ix].idVendor) &&  
  942.             (dev->descriptor.idProduct == scanner_device_ids [ix].idProduct)) {  
  943.             valid_device = 1;  
  944.             break;  
  945.                 }  
  946.     }  
  947.     if (dev->descriptor.idVendor == vendor &&   /* User specified */  
  948.         dev->descriptor.idProduct == product) { /* User specified */  
  949.         valid_device = 1;  
  950.     }  
  951.   
  952.     if (!valid_device)  
  953.         return -ENODEV; /* We didn't find anything pleasing */  
  954.   
  955. /* 
  956.  * After this point we can be a little noisy about what we are trying to 
  957.  *  configure. 
  958.  */  
  959.   
  960.     if (dev->descriptor.bNumConfigurations != 1) {  
  961.         info("probe_scanner: Only one device configuration is supported.");  
  962.         return -ENODEV;  
  963.     }  
  964.   
  965.     interface = intf->altsetting;  
  966.    
  967.     if (interface[0].desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC &&  
  968.         interface[0].desc.bInterfaceClass != USB_CLASS_PER_INTERFACE &&  
  969.         interface[0].desc.bInterfaceClass != USB_CLASS_CDC_DATA &&  
  970.         interface[0].desc.bInterfaceClass != SCN_CLASS_SCANJET) {  
  971.         dbg("probe_scanner: This interface doesn't look like a scanner (class=0x%x)."interface[0].desc.bInterfaceClass);  
  972.         return -ENODEV;  
  973.     }  
  974.   
  975. /* 
  976.  * Start checking for bulk and interrupt endpoints. We are only using the first 
  977.  * one of each type of endpoint. If we have an interrupt endpoint go ahead and 
  978.  * setup the handler. FIXME: This is a future enhancement... 
  979.  */  
  980.   
  981.     dbg("probe_scanner: Number of Endpoints:%d", (intinterface->desc.bNumEndpoints);  
  982.   
  983.     ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0;  
  984.   
  985.     while (ep_cnt < interface->desc.bNumEndpoints) {  
  986.         endpoint = &interface->endpoint[ep_cnt].desc;  
  987.   
  988.         if (IS_EP_BULK_IN(endpoint)) {  
  989.             ep_cnt++;  
  990.             if (have_bulk_in) {  
  991.                 info ("probe_scanner: ignoring additional bulk_in_ep:%d", ep_cnt);  
  992.                 continue;  
  993.             }  
  994.             have_bulk_in = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;  
  995.             dbg("probe_scanner: bulk_in_ep:%d", have_bulk_in);  
  996.             continue;  
  997.         }  
  998.   
  999.         if (IS_EP_BULK_OUT(endpoint)) {  
  1000.             ep_cnt++;  
  1001.             if (have_bulk_out) {  
  1002.                 info ("probe_scanner: ignoring additional bulk_out_ep:%d", ep_cnt);  
  1003.                 continue;  
  1004.             }  
  1005.             have_bulk_out = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;  
  1006.             dbg("probe_scanner: bulk_out_ep:%d", have_bulk_out);  
  1007.             continue;  
  1008.         }  
  1009.   
  1010.         if (IS_EP_INTR(endpoint)) {  
  1011.             ep_cnt++;  
  1012.             if (have_intr) {  
  1013.                 info ("probe_scanner: ignoring additional intr_ep:%d", ep_cnt);  
  1014.                 continue;  
  1015.             }  
  1016.             have_intr = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;  
  1017.             dbg("probe_scanner: intr_ep:%d", have_intr);  
  1018.             continue;  
  1019.         }  
  1020.         info("probe_scanner: Undetected endpoint -- consult Documentation/usb/scanner.txt.");  
  1021.         return -EIO;    /* Shouldn't ever get here unless we have something weird */  
  1022.     }  
  1023.   
  1024.   
  1025. /* 
  1026.  * Perform a quick check to make sure that everything worked as it 
  1027.  * should have. 
  1028.  */  
  1029.   
  1030.     if (!have_bulk_in) {  
  1031.         err("probe_scanner: One bulk-in endpoint required.");  
  1032.         return -EIO;  
  1033.     }  
  1034.   
  1035. /* 
  1036.  * Determine a minor number and initialize the structure associated 
  1037.  * with it.  The problem with this is that we are counting on the fact 
  1038.  * that the user will sequentially add device nodes for the scanner 
  1039.  * devices.  */  
  1040.       
  1041.     down(&scn_mutex);  
  1042.   
  1043.     retval = usb_register_dev(intf, &scanner_class);  
  1044.     if (retval) {  
  1045.         err ("Not able to get a minor for this device.");  
  1046.         up(&scn_mutex);  
  1047.         return -ENOMEM;  
  1048.     }  
  1049.   
  1050.     dbg("probe_scanner: Allocated minor:%d", intf->minor);  
  1051.   
  1052.     if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) {  
  1053.         err("probe_scanner: Out of memory.");  
  1054.         up(&scn_mutex);  
  1055.         return -ENOMEM;  
  1056.     }  
  1057.     memset (scn, 0, sizeof(struct scn_usb_data));  
  1058.     kobject_init(&scn->kobj);  
  1059.     scn->kobj.ktype = &scanner_kobj_type;  
  1060.   
  1061.     scn->scn_irq = usb_alloc_urb(0, GFP_KERNEL);  
  1062.     if (!scn->scn_irq) {  
  1063.         usb_deregister_dev(intf, &scanner_class);  
  1064.         kfree(scn);  
  1065.         up(&scn_mutex);  
  1066.         return -ENOMEM;  
  1067.     }  
  1068.   
  1069.     init_MUTEX(&(scn->sem)); /* Initializes to unlocked */  
  1070.   
  1071.     dbg ("probe_scanner(%d): Address of scn:%p", intf->minor, scn);  
  1072.   
  1073. /* Ok, if we detected an interrupt EP, setup a handler for it */  
  1074.     if (have_intr) {  
  1075.         dbg("probe_scanner(%d): Configuring IRQ handler for intr EP:%d", intf->minor, have_intr);  
  1076.         usb_fill_int_urb(scn->scn_irq, dev,  
  1077.                  usb_rcvintpipe(dev, have_intr),  
  1078.                  &scn->button, 1, irq_scanner, scn,  
  1079.                  // endpoint[(int)have_intr].bInterval);  
  1080.                  250);  
  1081.   
  1082.         retval = usb_submit_urb(scn->scn_irq, GFP_KERNEL);  
  1083.         if (retval) {  
  1084.             err("probe_scanner(%d): Unable to allocate INT URB.", intf->minor);  
  1085.             usb_deregister_dev(intf, &scanner_class);  
  1086.                     kfree(scn);  
  1087.             up(&scn_mutex);  
  1088.                     return retval;  
  1089.             }  
  1090.     }  
  1091.   
  1092.   
  1093. /* Ok, now initialize all the relevant values */  
  1094.     if (!(scn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) {  
  1095.         err("probe_scanner(%d): Not enough memory for the output buffer.", intf->minor);  
  1096.         if (have_intr)  
  1097.             usb_unlink_urb(scn->scn_irq);  
  1098.         usb_free_urb(scn->scn_irq);  
  1099.         usb_deregister_dev(intf, &scanner_class);  
  1100.         kfree(scn);  
  1101.         up(&scn_mutex);  
  1102.         return -ENOMEM;  
  1103.     }  
  1104.     dbg("probe_scanner(%d): obuf address:%p", intf->minor, scn->obuf);  
  1105.   
  1106.     if (!(scn->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) {  
  1107.         err("probe_scanner(%d): Not enough memory for the input buffer.", intf->minor);  
  1108.         if (have_intr)  
  1109.             usb_unlink_urb(scn->scn_irq);  
  1110.         usb_free_urb(scn->scn_irq);  
  1111.         usb_deregister_dev(intf, &scanner_class);  
  1112.         kfree(scn->obuf);  
  1113.         kfree(scn);  
  1114.         up(&scn_mutex);  
  1115.         return -ENOMEM;  
  1116.     }  
  1117.     dbg("probe_scanner(%d): ibuf address:%p", intf->minor, scn->ibuf);  
  1118.       
  1119.   
  1120.     switch (dev->descriptor.idVendor) { /* Scanner specific read timeout parameters */  
  1121.     case 0x04b8:        /* Seiko/Epson */  
  1122.         scn->rd_nak_timeout = HZ * 60;  
  1123.         break;  
  1124.     case 0x055f:        /* Mustek */  
  1125.     case 0x0400:        /* Another Mustek */  
  1126.         scn->rd_nak_timeout = HZ * 1;  
  1127.     default:  
  1128.         scn->rd_nak_timeout = RD_NAK_TIMEOUT;  
  1129.     }  
  1130.   
  1131.   
  1132.     if (read_timeout > 0) {  /* User specified read timeout overrides everything */  
  1133.         info("probe_scanner: User specified USB read timeout - %d", read_timeout);  
  1134.         scn->rd_nak_timeout = read_timeout;  
  1135.     }  
  1136.   
  1137.   
  1138.     usb_get_dev(dev);  
  1139.     scn->bulk_in_ep = have_bulk_in;  
  1140.     scn->bulk_out_ep = have_bulk_out;  
  1141.     scn->intr_ep = have_intr;  
  1142.     scn->present = 1;  
  1143.     scn->scn_dev = dev;  
  1144.     scn->scn_minor = intf->minor;  
  1145.     scn->isopen = 0;  
  1146.   
  1147.     snprintf(name, sizeof(name), scanner_class.name,  
  1148.          intf->minor - scanner_class.minor_base);  
  1149.   
  1150.     info ("USB scanner device (0x%04x/0x%04x) now attached to %s",  
  1151.           dev->descriptor.idVendor, dev->descriptor.idProduct, name);  
  1152.   
  1153.     usb_set_intfdata(intf, scn);  
  1154.     up(&scn_mutex);  
  1155.       
  1156.     return 0;  
  1157. }  
  1158.   
  1159. static void  
  1160. disconnect_scanner(struct usb_interface *intf)  
  1161. {  
  1162.     struct scn_usb_data *scn = usb_get_intfdata(intf);  
  1163.   
  1164.     /* disable open() */  
  1165.     dbg("%s: De-allocating minor:%d", __FUNCTION__, scn->scn_minor);  
  1166.     usb_deregister_dev(intf, &scanner_class);  
  1167.   
  1168.     usb_set_intfdata(intf, NULL);  
  1169.     if(scn->intr_ep) {  
  1170.         dbg("%s(%d): Unlinking IRQ URB", __FUNCTION__, scn->scn_minor);  
  1171.         usb_unlink_urb(scn->scn_irq);  
  1172.     }  
  1173.   
  1174.     if (scn)  
  1175.         kobject_put(&scn->kobj);  
  1176. }  
  1177.   
  1178. /* we want to look at all devices, as the vendor/product id can change 
  1179.  * depending on the command line argument */  
  1180. static struct usb_device_id ids[] = {  
  1181.     {.driver_info = 42},  
  1182.     {}  
  1183. };  
  1184.   
  1185. static struct  
  1186. usb_driver scanner_driver = {  
  1187.     .owner =    THIS_MODULE,  
  1188.     .name =     "usbscanner",  
  1189.     .probe =    probe_scanner,  
  1190.     .disconnect =   disconnect_scanner,  
  1191.     .id_table = ids,  
  1192. };  
  1193.   
  1194. static void __exit  
  1195. usb_scanner_exit(void)  
  1196. {  
  1197.     usb_deregister(&scanner_driver);  
  1198. }  
  1199.   
  1200. static int __init  
  1201. usb_scanner_init (void)  
  1202. {  
  1203.     int retval;  
  1204.     retval = usb_register(&scanner_driver);  
  1205.     if (retval)  
  1206.         goto out;  
  1207.   
  1208.     info(DRIVER_VERSION ":" DRIVER_DESC);  
  1209.     if (vendor != -1 && product != -1)  
  1210.         info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product);  
  1211.  out:  
  1212.     return retval;  
  1213. }  
  1214.   
  1215. module_init(usb_scanner_init);  
  1216. module_exit(usb_scanner_exit);  

 我的系统配置:

1.LINUX2.6.14.1 FOR S3C2410+DM9000+UDA1341+64M nandflash+64M sdram

2.u-boot1.1.3

3.cramfs+yaffs2

4.nfs+tftp

我把我的linuxrc/rcS/rc.local贴出来,大家帮忙分析分析.谢谢!

[root@zmf26 rootfs]# cat linuxrc

#!/bin/ash
echo "------next to run /linuxrc"
/bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 /
/bin/mount -t tmpfs tmpfs /dev/shm
/bin/mount -f -t sysfs sysfs /sys
/bin/mount -t proc none /proc
/bin/mount -t devpts devpts /dev/pts

# mount devpts in order to use telnetd
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s

echo "------next to mount /tmp,/tmp/app,cp /etc/tmp/boa /tmp/app"
/bin/mount -t tmpfs none /root
/bin/cp /etc/udev/usbmount.sh /root/

/bin/mount -t tmpfs none /var
/bin/mkdir -p /var/lib
/bin/mkdir -p /var/run
/bin/mkdir -p /var/log/boa
/bin/cp -rf /etc/tmp/www /var/
/bin/mkdir -p /var/www/cgi-bin

/bin/mount -t ramfs ramfs /tmp
/bin/mkdir /tmp/app
/bin/mount -f -t ramfs ramfs /tmp/app
/bin/cp -rf /etc/tmp/boa /tmp/app/

echo "------next to mount yaffs2 /user,/data"
/bin/mount -t yaffs2 /dev/mtdblock/4 /user
/bin/mount -t yaffs2 /dev/mtdblock/5 /data

exec /usr/etc/rc.local

echo "------next to run /sbin/init"
exec /sbin/init

 

[root@zmf26 rootfs]# cat etc/init.d/rcS
#!/bin/ash
echo "------next to run /etc/inid.d/rcS"
/bin/mount -a
exec /linuxrc
#exec /usr/etc/rc.local


[root@zmf26 rootfs]# cat usr/etc/rc.local 
#!/bin/ash
echo "------next to run /usr/etc/rc.local "
#./usr/etc/profile
WEBPATH=/tmp/app
/sbin/inetd

#/sbin/ifconfig eth0 192.168.0.99
#/sbin/ifconfig eth0 down
#/sbin/ifconfig eth0 hw ether 00:00:f1:21:53:f5
#/sbin/pump -i eth0
/sbin/ifconfig eth0 192.168.0.99 netmask 255.255.255.0 up
/sbin/route add default gw 192.168.0.1 
/sbin/inetd
echo "------ifconfig eth0 192.168.0.99 complete"

#cd /dev
#ln -s fb/0 fb0
#ln -s vc/0 tty0               
#ln -s vc/1 tty1               
#ln -s vc/2 tty2
#echo "------ ln -s vc/2 tty2 complete"

/sbin/inetd /etc/inetd.conf

if [ -f /tmp/app/boa/boa ];
then
/tmp/app/boa/boa -c /etc/boa/&
echo "------run /tmp/app/boa/boa&"
else
echo "------error:/tmp/app/boa file dose'n exist!"
fi

if [ -f $WEBPATH/powercontrolboard ];
then
$WEBPATH/powercontrolboard&
echo "------run $WEBPATH/powercontrolboard&"
else
echo "------error:$WEBPATH/powercontrolboard file dose'n exist!"
fi

if [ -f $WEBPATH/boa/http/cgi-bin/smart_arm.cgi ];
then
echo "------$WEBPATH/boa/http/cgi-bin/smart_arm.cgi file exist!"
else
echo "------error:$WEBPATH/boa/http/cgi-bin/smart_arm.cgi file dose'n exist!" 
fi

启动信息如下:

Uncompressing Linux............................................................................................. done, booting the kernel.
Linux version 2.6.14 (root@zmf26.WORKGROUP) (gcc version 3.4.1) #108 Wed Aug 5 03:02:40 CST 2009
CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: SMDK2410
Memory policy: ECC disabled, Data cache writeback
CPU S3C2410A (id 0x32410002)
S3C2410: core 200.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz
S3C2410 Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists
Kernel command line: mem=64M console=ttySAC0,115200 root=/dev/nfs nfsroot=192.168.0.57:/home/arm/dev_home/rootfs ip=192.168.0.99:192.168.0.57:192.168.0.1:255.255.255.0::eth0:off
irq: clearing subpending status 00000002
PID hash table entries: 512 (order: 9, 8192 bytes)
timer tcon=00500000, tcnt a2c1, tcfg 00000200,00000000, usec 00001eb8
Console: colour dummy device 80x30
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 64MB = 64MB total
Memory: 61824KB available (2330K code, 559K data, 96K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
softlockup thread 0 started up.
NET: Registered protocol family 16
S3C2410: Initialising architecture
SCSI subsystem initialized
usbcore: registered new driver usbfs
usbcore: registered new driver hub
S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
NetWinder Floating Point Emulator V0.97 (double precision)
devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
NTFS driver 2.1.24 [Flags: R/W DEBUG].
yaffs Aug  2 2009 17:07:52 Installing. 
Initializing Cryptographic API
Console: switching to colour frame buffer device 80x25
fb0: Virtual frame buffer device, using 1024K of video memory
S3C2410 RTC, (c) 2004 Simtec Electronics
/dev/keybutton inited: newkoom company:zhengmeifu@sina.com
/dev/ledrpm inited: newkoom company:zhengmeifu@sina.com
s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410
s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410
s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
RAMDISK driver initialized: 8 RAM disks of 4096K size 1024 blocksize
nbd: registered device at major 43
usbcore: registered new driver ub
dm9000 Ethernet Driver
dm9000 io_base is : c4910300
eth0: dm9000 at c4910300,c4912304 IRQ 19 MAC: 02:e1:3d:a4:d7:f7
netconsole: not configured, aborting
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing: Tacls 10ns, Twrph0 40ns, Twrph1 10ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 3777 at 0x03b04000
Bad eraseblock 3778 at 0x03b08000
Bad eraseblock 3779 at 0x03b0c000
Bad eraseblock 3780 at 0x03b10000
Bad eraseblock 3781 at 0x03b14000
Bad eraseblock 3782 at 0x03b18000
Bad eraseblock 3783 at 0x03b1c000
Bad eraseblock 3784 at 0x03b20000
Bad eraseblock 3785 at 0x03b24000
Bad eraseblock 3786 at 0x03b28000
Bad eraseblock 3787 at 0x03b2c000
Bad eraseblock 3789 at 0x03b34000
Bad eraseblock 3791 at 0x03b3c000
Bad eraseblock 3794 at 0x03b48000
Bad eraseblock 3827 at 0x03bcc000
Bad eraseblock 3828 at 0x03bd0000
Bad eraseblock 3830 at 0x03bd8000
Bad eraseblock 3895 at 0x03cdc000
Bad eraseblock 4094 at 0x03ff8000
Creating 6 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x000e0000 : "bootloader"
0x000e0000-0x00100000 : "param"
0x00100000-0x00400000 : "kernel"
0x00400000-0x02200000 : "root"
0x02200000-0x02c00000 : "user"
0x02c00000-0x04000000 : "data"
usbmon: debugfs is not available
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
usb usb1: Product: S3C24XX OHCI
usb usb1: Manufacturer: Linux 2.6.14 ohci_hcd
usb usb1: SerialNumber: s3c24xx
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
Initializing USB Mass Storage driver...
usb 1-1: new full speed USB device using s3c2410-ohci and address 2
usb 1-1: Product: DataTraveler 2.0
usb 1-1: Manufacturer: Kingston
usb 1-1: SerialNumber: 5B82190008A7
ub(1.2): GetMaxLUN returned 0, using 1 LUNs
 /dev/ub/a: unknown partition table
usbcore: registered new driver usb-storage
USB Mass Storage support registered.
UDA1341 audio driver initialized
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP reno registered
TCP bic registered
eth0: link down
IP-Config: Complete:
      device=eth0, addr=192.168.0.99, mask=255.255.255.0, gw=192.168.0.1,
     host=192.168.0.99, domain=, nis-domain=(none),
     bootserver=192.168.0.57, rootserver=192.168.0.57, rootpath=
Looking up port of RPC 100003/2 on 192.168.0.57
eth0: link up, 100Mbps, full-duplex, lpa 0x41E1
Looking up port of RPC 100005/1 on 192.168.0.57
VFS: Mounted root (nfs filesystem).
Mounted devfs on /dev
Freeing init memory: 96K
init started:  BusyBox v1.1.3 (2009.07.28-04:02+0000) multi-call binary
init started:  BusyBox v1.1.3 (2009.07.28-04:02+0000) multi-call binary
Starting pid 205, console /dev/tts/0: '/etc/init.d/rcS'
------next to run /etc/inid.d/rcS
mount: Mounting none on /dev/pts failed: No such file or directory
------next to run /linuxrc
mount: Mounting none on /proc failed: Device or resource busy
mount: Mounting devpts on /dev/pts failed: Device or resource busy
------next to mount /tmp,/tmp/app,cp /etc/tmp/boa /tmp/app
------next to mount yaffs2 /user,/data
yaffs: dev is 32505860 name is "mtdblock4"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.4, "mtdblock4"
yaffs: auto selecting yaffs1
yaffs: dev is 32505861 name is "mtdblock5"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.5, "mtdblock5"
yaffs: auto selecting yaffs1
block 962 is bad
block 963 is bad
block 964 is bad
block 965 is bad
block 966 is bad
block 967 is bad
block 968 is bad
block 969 is bad
block 970 is bad
block 971 is bad
block 972 is bad
block 974 is bad
block 976 is bad
block 979 is bad
block 1012 is bad
block 1013 is bad
block 1015 is bad
block 1080 is bad
block 1279 is bad
------next to run /usr/etc/rc.local 
route: SIOC[ADD|DEL]RT: File exists
------ifconfig eth0 192.168.0.99 complete
------run /tmp/app/boa/boa&
------error:/tmp/app/powercontrolboard file dose'n exist!
------error:/tmp/app/boa/http/cgi-bin/smart_arm.cgi file dose'n exist!

Please press Enter to activate this console.

转自:http://blog.csdn.net/zhengmeifu/article/details/4539030