[PATCH] file_storage usb gadget : add serial number parameter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi

Add a parameter to file_storage usb gadget module to be able to specify
the serial number of a device (for example, the serial number of an
emulated usb stick).

Things i'm not sure i've done well about :
- 12 chars limitation for CBI transport : I need more (24 chars) for sticks serial, so i've
  modified the static serial declaration, and cut this string (\0 in serial[12]) if CBI is selected.
- i've keep the serial static, but now that it can be modified, perhaps it should be integrated
  in the mod_data struct.
- DRIVER_SERIAL_NUM_NOT_SET : i need a way to know if the parameter have been passed, only find that.
- hexadecimal characters check : is there a better way ?
- The string copy handling between char array (serial) and char pointer (serial_parm). I'm not sure
  it's rock-solid.
- I keep the dead (moved) code enclosed in /* */

Be smart, it's my first day :)


--- linux-2.6.31/drivers/usb/gadget/file_storage.c.orig 2009-09-10 00:13:59.000000000 +0200
+++ linux-2.6.31/drivers/usb/gadget/file_storage.c      2010-05-24 01:30:44.000000000 +0200
@@ -56,7 +56,7 @@                                                                          
  * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03),            
  * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by                 
  * the optional "protocol" module parameter.  In addition, the default                    
- * Vendor ID, Product ID, and release number can be overridden.                           
+ * Vendor ID, Product ID, release and serial number can be overridden.                    
  *                                                                                        
  * There is support for multiple logical units (LUNs), each of which has                  
  * its own backing file.  The number of LUNs can be set using the optional                
@@ -106,6 +106,8 @@                                                                        
  *     vendor=0xVVVV           Default 0x0525 (NetChip), USB Vendor ID                    
  *     product=0xPPPP          Default 0xa4a5 (FSG), USB Product ID                       
  *     release=0xRRRR          Override the USB release number (bcdDevice)                
+ *     serial=112233445566778899AABBCC                                                    
+ *                             Override serial number                                     
  *     buflen=N                Default N=16384, buffer size used (will be                 
  *                                     rounded down to a multiple of                      
  *                                     PAGE_CACHE_SIZE)                                   
@@ -288,6 +290,8 @@ MODULE_LICENSE("Dual BSD/GPL");                                        
 #define DRIVER_VENDOR_ID       0x0525  // NetChip                                         
 #define DRIVER_PRODUCT_ID      0xa4a5  // Linux-USB File-backed Storage Gadget            
                                                                                           
+/* Serial number test string. */                                                          
+#define DRIVER_SERIAL_NUM_NOT_SET      "Not set"                                          
                                                                                           
 /*                                                                                        
  * This driver assumes self-powered hardware and has no way for users to                  
@@ -356,6 +360,7 @@ static struct {                                                        
                                                                                           
        char            *transport_parm;                                                   
        char            *protocol_parm;                                                    
+       char            *serial_parm;                                                      
        unsigned short  vendor;                                                            
        unsigned short  product;                                                           
        unsigned short  release;                                                           
@@ -369,6 +374,7 @@ static struct {                                                        
 } mod_data = {                                 // Default values                          
        .transport_parm         = "BBB",                                                   
        .protocol_parm          = "SCSI",                                                  
+       .serial_parm            = DRIVER_SERIAL_NUM_NOT_SET,                               
        .removable              = 0,                                                       
        .can_stall              = 1,                                                       
        .cdrom                  = 0,                                                       
@@ -419,6 +425,9 @@ MODULE_PARM_DESC(product, "USB Product I                               
 module_param_named(release, mod_data.release, ushort, S_IRUGO);                           
 MODULE_PARM_DESC(release, "USB release number");                                          
                                                                                           
+module_param_named(serial, mod_data.serial_parm, charp, S_IRUGO);                         
+MODULE_PARM_DESC(serial, "USB serial number");                                            
+                                                                                          
 module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);                               
 MODULE_PARM_DESC(buflen, "I/O buffer size");                                              
                                                                                           
@@ -996,8 +1005,10 @@ ep_desc(struct usb_gadget *g, struct usb                             
                                                                                           
 /* The CBI specification limits the serial string to 12 uppercase hexadecimal             
  * characters. */                                                                         
+/* Others can handle more : Typically 12 uppercase hexadecimal *bytes* for                
+ * usb sticks, ie 24 characters. */                                                       
 static char                            manufacturer[64];                                  
-static char                            serial[13];                                        
+static char                            serial[25];                                        
                                                                                           
 /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */              
 static struct usb_string               strings[] = {                                      
@@ -3853,11 +3864,11 @@ static void /* __init_or_exit */ fsg_unb                           
        set_gadget_data(gadget, NULL);                                                     
 }                                                                                         
                                                                                           
-                                                                                          
 static int __init check_parameters(struct fsg_dev *fsg)                                   
 {                                                                                         
        int     prot;                                                                      
        int     gcnum;                                                                     
+       int     i;                                                                         
                                                                                           
        /* Store the default values */                                                     
        mod_data.transport_type = USB_PR_BULK;                                             
@@ -3937,6 +3948,41 @@ static int __init check_parameters(struc                            
                ERROR(fsg, "invalid buflen\n");                                            
                return -ETOOSMALL;                                                         
        }                                                                                  
+                                                                                          
+       /* Serial string handling */                                                       
+       memset(&serial, 0, sizeof(serial));                                                
+       if (strncmp(mod_data.serial_parm, DRIVER_SERIAL_NUM_NOT_SET, 10) == 0) {           
+               /* Serial number not specified, make our own. */                           
+               /* On a real device, serial[] would be loaded from permanent               
+                * storage.  We just encode it from the driver version string.             
+                */                                                                        
+               for (i = 0; i < sizeof(serial) - 2; i += 2) {                              
+                       unsigned char           c = DRIVER_VERSION[i / 2];                 
+                                                                                          
+                       if (!c)                                                            
+                               break;                                                     
+                       sprintf(&serial[i], "%02X", c);                                    
+               }                                                                          
+       } else {                                                                           
+               int slength = min(sizeof(serial), strlen(mod_data.serial_parm));           
+               for (i = 0; i < slength; i += 1) {                                         
+                       unsigned char   c = mod_data.serial_parm[i];                       
+                       if (!((c >= '0' && c <= '9') ||                                    
+                             (c >= 'A' && c <= 'F'))) {                                   
+                               ERROR(fsg, "invalid serial string: %s\n", mod_data.serial_parm);
+                               return -EINVAL;                                                 
+                       }                                                                       
+                       sprintf(&serial[i], "%c", c);                                           
+               }                                                                               
+       }
+
+       /* The CBI specification limits the serial string to 12 uppercase
+        * hexadecimal characters. */
+       if (mod_data.transport_type == USB_PR_CBI && strlen(serial) > 12) {
+               WARNING(fsg, "Cutting the serial string to 12 characters (See CBI spec).\n");
+               serial[12] = '\0';
+       }
+
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */

        return 0;
@@ -4110,8 +4156,10 @@ static int __init fsg_bind(struct usb_ga
                        init_utsname()->sysname, init_utsname()->release,
                        gadget->name);

+       /* Serial string handling moved to __init check_parameters */
        /* On a real device, serial[] would be loaded from permanent
         * storage.  We just encode it from the driver version string. */
+       /*
        for (i = 0; i < sizeof(serial) - 2; i += 2) {
                unsigned char           c = DRIVER_VERSION[i / 2];

@@ -4119,6 +4167,7 @@ static int __init fsg_bind(struct usb_ga
                        break;
                sprintf(&serial[i], "%02X", c);
        }
+        */

        fsg->thread_task = kthread_create(fsg_main_thread, fsg,
                        "file-storage-gadget");




-- 
Yann Cantin
A4FEB47F
--


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux