1/*************************************************************************** 2 *** 3 *** Copyright 2005 Hon Hai Precision Ind. Co. Ltd. 4 *** All Rights Reserved. 5 *** No portions of this material shall be reproduced in any form without the 6 *** written permission of Hon Hai Precision Ind. Co. Ltd. 7 *** 8 *** All information contained in this document is Hon Hai Precision Ind. 9 *** Co. Ltd. company private, proprietary, and trade secret property and 10 *** are protected by international intellectual property laws and treaties. 11 *** 12 **************************************************************************** 13 *** 14 *** Filename: hotplug_usb.c 15 *** 16 *** Description: 17 *** USB automount function 18 *** 19 *** History: 20 *** 21 *** Modify Reason Author Date Search Flag(Option) 22 ***-------------------------------------------------------------------------------------- 23 *** Created zZz 09/14/2007 24 ** Port to WNR3500U Water 10/31/2008 25 *******************************************************************************/ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30#include <errno.h> 31#include <dirent.h> 32#include <sys/stat.h> 33#include <sys/mount.h> 34#include "bcmconfig.h" 35 36//#define USB_HOTPLUG_DBG//@debug 37 38#if 0 39static set_usb_led() 40{ 41 FILE *fp; 42 unsigned char line[256]; 43 unsigned char port[2] = {0, 0}; 44 char cmd[32]; 45 46 fp = fopen("/proc/bus/usb/devices", "r"); 47 48 if(fp == NULL) 49 { 50 fprintf(stderr, "open usb info failure\n"); 51 } 52 53//------------------ 54//reset flag 55//------------------ 56 port[0] = 0; 57 port[1] = 0; 58 59//---------------------------- 60//parse /proc/bus/usb/devices 61//---------------------------- 62 while(1) 63 { 64 fgets(line, 256, fp); 65 66 //---------------------------- 67 //parse Toplogy info 68 //---------------------------- 69 if (strncmp(line, "T: ", 3) == 0) 70 { 71 char *subtoken; 72 char *saveptr1, *saveptr2; 73 char *token = strtok_r(line, " \t\n", &saveptr1); 74 int tmpNum; 75 76 if (token) 77 { 78 while (1) 79 { 80 token = strtok_r(NULL, " \t\n", &saveptr1); 81 if (token == NULL) 82 { 83 break; 84 } 85 //fprintf(stderr, "%s \n", token); 86 if (strncmp(token, "Prnt=", 5) == 0 ) 87 { 88 //----------------------------------------- 89 //Parent = 0x1 -> leaf of root hub -> a node 90 //Then read Port: port 0 -> USB1 91 // port 1 -> USB2 92 //----------------------------------------- 93 //fprintf(stderr, "%s ", token); 94 subtoken = strtok_r(token, "=", &saveptr2); 95 //fprintf(stderr, "%s ", subtoken); 96 subtoken = strtok_r(NULL, "=", &saveptr2); 97 //fprintf(stderr, "%s ", subtoken); 98 99 tmpNum = atoi(subtoken); 100 if (tmpNum == 1) 101 { 102 //------------------ 103 //get port 104 //------------------ 105 token = strtok_r(NULL, " \t\n", &saveptr1); 106 //fprintf(stderr, "%s ", token); 107 subtoken = strtok_r(token, "=", &saveptr2); 108 //fprintf(stderr, "%s ", subtoken); 109 subtoken = strtok_r(NULL, "=", &saveptr2); 110 //fprintf(stderr, "%s ", subtoken); 111 112 //------------------ 113 //set flag 114 //------------------ 115 tmpNum = atoi(subtoken); 116 if (tmpNum == 0) 117 { 118 port[0] = 1; 119 } 120 else if(tmpNum == 1) 121 { 122 port[1] = 1; 123 } 124 else 125 { 126 fprintf(stderr, "unexcepted port #\n"); 127 } 128 break; 129 } //parse port if parent is 1 (root) 130 } //parset parent 131 } //while 1 132 } //if token 133 } //strcmp T: 134 if (feof(fp)) 135 { 136 break; 137 } 138 } //while 1 -> read lines in files 139 fclose(fp); 140 //------------------ 141 //set LED 142 //------------------ 143 snprintf(cmd, 32, "/sbin/gpio 9 %d", (int)port[0]); 144 system(cmd); 145 146 snprintf(cmd, 32, "/sbin/gpio 10 %d", (int)port[1]); 147 system(cmd); 148} 149#endif/*No usb led in WNR3500U board, need further check.*/ 150 151/*********************************************************************************************************************** 152* Environment of hotplug for USB: 153* DEVICE=bus_num, dev_num 154* 155* PRODUCT=Vendor, Product, bcdDevice 156* 157* TYPE= DeviceClass, DeviceSubClass, DeviceProtocol 158* 159* if DeviceClass == 0 160* -> INTERFACE=interface [0].altsetting [alt].bInterfaceClass, interface [0].altsetting [alt].bInterfaceSubClass, 161* interface [0].altsetting [alt].bInterfaceProtocol 162* 163***********************************************************************************************************************/ 164 165int usb_mount() 166{ 167 char source[128]; 168 char target[128]; 169 char buf[128]; 170 int i; 171 int rval; 172//------------------------------------------------------ 173// action: add 174// 1. mount dev with vfat 175// 2. if mount ok, save data to nvram 176// 3. restart smb 177//------------------------------------------------------ 178//fixme: no good. zzz@ 179 for (i=1; i<16; i++ ) 180 { 181#if 0 182 //------------------------ 183 //set up source 184 //------------------------ 185 snprintf(source, 128, "/dev/sda%d", i); 186 187 //------------------------ 188 //set up target 189 //------------------------ 190 snprintf(target, 128, "/tmp/mnt/usb%d", i); 191 192 //------------------------ 193 //start mount with sync 194 //------------------------ 195 rval = mount(source, target, "vfat", MS_SYNCHRONOUS, 0); 196 197#ifdef USB_HOTPLUG_DBG//debug 198 snprintf(buf, 128, "echo \"mount %s %s with vfat, rval:%d \">>/tmp/usberr.log", source, target, rval); 199 system(buf); 200#endif 201 if (rval) 202 { 203 rval = mount(source, target, "ntfs", MS_RDONLY, 0); 204#ifdef USB_HOTPLUG_DBG//debug 205 snprintf(buf, 128, "echo \"mount %s %s with ntfs, rval:%d \">>/tmp/usberr.log", source, target, rval); 206 system(buf); 207#endif 208 } 209 /*foxconn add start, water, 12/08/2008*/ 210#endif/*if 0, removed water, 12/08/2008, @write throughput too low.*/ 211 /*If we do mount by key in mount command in the console. the write throughput is ok.*/ 212 /*I think there're some bugs in the above mount function. But the mount command build by busybox is ok.*/ 213 /*So we use mount command here. It isn't a good solution. Just a "work around".*/ 214 snprintf(buf, 128, "/bin/mount -t vfat /dev/sda%d /tmp/mnt/usb%d", i, i); 215 system(buf); 216 217 /*ntfs read only supported*/ 218 snprintf(buf, 128, "/bin/mount -t ntfs /dev/sda%d /tmp/mnt/usb%d", i, i); 219 system(buf); 220 /*foxconn add end, water, 12/08/2008*/ 221 } //end of for 222 223 return 0; 224} 225 226int usb_umount() 227{ 228 int i, j; 229 int rval; 230 char path[128]; 231 char buf[128]; 232 //------------------------------------------------------ 233 // action: remove 234 // remount devices 235 //------------------------------------------------------ 236 //fixme: no good. zzz@ 237 238 for (j=1; j<16; j++) 239 { 240 snprintf(path, 128, "/bin/umount /tmp/mnt/usb%d", j); 241 242 rval = system(path); 243#ifdef USB_HOTPLUG_DBG//debug 244 snprintf(buf, 128, "echo \"umount %s, rval:%d \">>/tmp/usberr.log", path, rval); 245 system(buf); 246#endif 247 } 248 249 usb_mount(); 250 return 0; 251} 252int usb_hotplug(void) 253{ 254 char *device, *interface; 255 char *action, *product; 256 char *type, *devfs; 257 int class, subclass, protocol; 258 char cmd[512]; 259 260 if (!(action = getenv("ACTION")) || 261 !(type = getenv("TYPE")) || 262 !(device = getenv("DEVICE")) || 263 !(devfs = getenv("DEVFS")) || 264 !(interface = getenv("INTERFACE")) || 265 !(product = getenv("PRODUCT"))) 266 { 267#ifdef USB_HOTPLUG_DBG//debug 268 sprintf(cmd, "echo \"return EINVAL;\" >> /tmp/hotAct\n"); 269 system(cmd); 270#endif 271 return EINVAL; 272 } 273 274#ifdef USB_HOTPLUG_DBG//debug 275 sprintf(cmd, "echo \"ACTION=%s, TYPE=%s, DEVICE=%s, DEVFS=%s, INTERFACE=%s, PRODUCT=%s\" >> /tmp/hotAct\n", 276 action, type, device, devfs, interface, product); 277 system(cmd); 278#endif 279 280 sscanf(type, "%d/%d/%d", &class, &subclass, &protocol); 281 if (class == 0) 282 { 283 sscanf(interface, "%d/%d/%d", &class, &subclass, &protocol); 284 } 285 //set LED 286 //set_usb_led();/*No usb led in WNR3500U board, need further check.*/ 287 288 //check Mass Storage for add action 289 if (class == 8 && subclass == 6 && !strcmp(action, "add")) 290 { 291 /* 292 sometimes usb_umount() not execute when unplug usb. 293 so before mount, we do umount firstly. 294 not sure, I think it need further test. 295 */ 296 //usb_mount(); 297 usb_umount();/*water, 11/06/2008*/ 298 } 299 //check Mass Storage for remove action 300 else if (class == 8 && subclass == 6 && !strcmp(action, "remove")) 301 { 302 usb_umount(); 303 } 304 305 system("/usr/bin/setsmbftpconf"); 306#ifdef USB_HOTPLUG_DBG//debug 307 system("echo \"/usr/bin/setsmbftpconf\">>/tmp/usberr.log"); 308#endif 309 return 0; 310} 311