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 *** - Created Date: 04/24/2009, Water, @USB spec1.7 implement on WNR3500L 21 *******************************************************************************/ 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26#include <unistd.h> 27#include <errno.h> 28#include <dirent.h> 29#include <sys/stat.h> 30#include <sys/mount.h> 31#include <sys/wait.h> 32#include "bcmconfig.h" 33#include "shutils.h" 34#include "bcmnvram.h" 35 36//#define USB_HOTPLUG_DBG//@debug 37#define MNT_DETACH 0x00000002 /* Foxconn add , Jenny Zhao, 04/22/2009 @usb dir */ 38 39/*********************************************************************************************************************** 40* Environment of hotplug for USB: 41* DEVICE=bus_num, dev_num 42* 43* PRODUCT=Vendor, Product, bcdDevice 44* 45* TYPE= DeviceClass, DeviceSubClass, DeviceProtocol 46* 47* if DeviceClass == 0 48* -> INTERFACE=interface [0].altsetting [alt].bInterfaceClass, interface [0].altsetting [alt].bInterfaceSubClass, 49* interface [0].altsetting [alt].bInterfaceProtocol 50* 51***********************************************************************************************************************/ 52 53/* Foxconn added start pling 07/13/2009 */ 54#include <sys/types.h> 55#include <sys/ipc.h> 56#include <sys/sem.h> 57 58#define LOCK -1 59#define UNLOCK 1 60#define USB_SEM_KEY 0x5553424B // "USBK" 61 62int usb_sem_init(void) 63{ 64 struct sembuf lockop = { 0, 0, SEM_UNDO } /* sem operation */ ; 65 int semid; 66 67 /* create/init sem */ 68 if ((semid = semget (USB_SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0666)) >= 0) 69 { 70 /* initialize the sem vaule to 1 */ 71 if (semctl (semid, 0, SETVAL, 1) < 0) 72 { 73 perror("usb_sem_init"); 74 return -1; 75 } 76 return 0; 77 } 78 return -1; 79} 80 81/* static */ int usb_sem_lock(int op) 82{ 83 struct sembuf lockop = { 0, 0, SEM_UNDO } /* sem operation */ ; 84 int semid; 85 86 /* sem already created. get the semid */ 87 if ((semid = semget (USB_SEM_KEY, 1, 0666)) < 0) 88 { 89 perror("usb_sem_lock"); 90 return -1; 91 } 92 93 lockop.sem_op = op; 94 if (semop (semid, &lockop, 1) < 0) 95 return -1; 96 97 return 0; 98} 99 100#define USB_LOCK() usb_sem_lock(LOCK) 101#define USB_UNLOCK() usb_sem_lock(UNLOCK) 102/* Foxconn added end pling 07/13/2009 */ 103 104/* Foxconn add start pling 02/05/2010*/ 105/* USB LED on / off */ 106#ifdef INCLUDE_USB_LED 107#include "wps_led.h" 108#include <sys/stat.h> 109#include <fcntl.h> 110 111/* Foxconn added start, Wins, 04/11/2011 */ 112#if defined(R6300v2) || defined(R7000) 113#define MAX_BUF_LEN 512 114#define USB_MNT_TABLE "/tmp/usb_mnt_table" 115#define USB_MNT_TABLE2 "/tmp/usb_mnt_table2" 116#define USB_MNT_PATTERN "PORT=%s,DEVICE=%s,PART=%s" 117 118int get_usb_port(char *pDevPath, char *pUsbPort) 119{ 120 int rtn_val = 0; 121 char buf[256]; 122 char *strPos1 = NULL, *strPos2 = NULL; 123 124#if defined(R6300v2) 125 if ((strPos1 = strstr(pDevPath, "/usb")) != NULL) 126 { 127 sscanf(strPos1, "/usb%s", buf); 128#elif defined(R7000) 129 if ((strstr(pDevPath, "/usb1/1-") != NULL) || (strstr(pDevPath, "/usb3/3-") != NULL)) 130 { 131 132 if((strPos1 = strstr(pDevPath, "/usb1/1-")) != NULL) 133 sscanf(strPos1, "/usb1/1-%s", buf); 134 else if((strPos1 = strstr(pDevPath, "/usb3/3-")) != NULL) 135 sscanf(strPos1, "/usb3/3-%s", buf); 136#else 137 if ((strPos1 = strstr(pDevPath, "/host")) != NULL) 138 { 139 sscanf(strPos1, "/host%s", buf); 140#endif 141 if ((strPos2 = strchr(buf, '/')) != NULL) 142 { 143 144 memcpy(pUsbPort, buf, (strPos2 - buf)); 145 rtn_val = 1; 146 } 147 } 148 149 return rtn_val; 150} /* get_usb_port() */ 151 152int parse_target_path(char *pTarget, int *pDevice, int *pPart) 153{ 154 int rtn_val = 0; 155 char usb_device[4], usb_part[4]; 156 char buf[128]; 157 char *strPos1 = NULL, *strPos2 = NULL; 158 159 /* Get USB device & part */ 160 memset(usb_device, 0x0, sizeof(usb_device)); 161 memset(usb_part, 0x0, sizeof(usb_part)); 162 if ((strPos1 = strstr(pTarget, "/tmp/mnt/usb")) != NULL) { 163 sscanf(strPos1, "/tmp/mnt/usb%s", buf); 164 if ((strPos2 = strchr(buf, '/')) != NULL) { 165 memcpy(usb_device, buf, (strPos2-buf)); 166 *pDevice = atoi(usb_device); 167 strPos2 = NULL; 168 if ((strPos2 = strstr(buf, "/part")) != NULL) { 169 sscanf(strPos2, "/part%s", usb_part); 170 *pPart = atoi(usb_part); 171 rtn_val = 1; 172 } 173 } 174 } 175 176 return rtn_val; 177} /* parse_target_path() */ 178 179int add_into_mnt_file(char *pUsbPort, char *pDevice, char *pPart) 180{ 181 FILE *fp = NULL; 182 int rtn_val = 0; 183 char buf[128]; 184 185 /* Foxconn added start, Wins, 06/30/2011 */ 186 if ((fp = fopen(USB_MNT_TABLE, "r")) != NULL) 187 { 188 int rec_found = 0; 189 char patt[128]; 190 /* Check if record of USB device exists. */ 191 while(fgets(buf, sizeof(buf), fp) != NULL) 192 { 193 memset(patt, 0x0, sizeof(patt)); 194 sprintf(patt, USB_MNT_PATTERN, pUsbPort, pDevice, pPart); 195 strcat(patt, "\n"); 196 if (!strcmp(buf, patt)) 197 { 198 rec_found = 1; 199 break; /* Record exists. */ 200 } 201 } 202 fclose(fp); 203 if (rec_found) 204 return 1; /* Not need to add a duplicated record. */ 205 } 206 fp = NULL; 207 /* Foxconn added end, Wins, 06/30/2011 */ 208 209 if ((fp = fopen(USB_MNT_TABLE, "a+")) != NULL) 210 { 211 fseek(fp, 0, SEEK_END); 212 sprintf(buf, USB_MNT_PATTERN, pUsbPort, pDevice, pPart); 213 strcat(buf, "\n"); 214 fputs(buf, fp); 215 fclose(fp); 216 rtn_val = 1; 217 } 218 219 return rtn_val; 220} /* add_into_mnt_file() */ 221 222int remove_from_mnt_file(char *pUsbPort, char *pDevice, char *pPart) 223{ 224 FILE *fp = NULL, *fp2 = NULL; 225 int rtn_val = 0; 226 char usb_device[4], usb_part[4]; 227 char buf[128]; 228 char *strPos1 = NULL, *strPos2 = NULL; 229 230 if ((fp = fopen(USB_MNT_TABLE, "r+")) != NULL) 231 { 232 char buf[128]; 233 sprintf(buf, "cp -f %s %s", USB_MNT_TABLE, USB_MNT_TABLE2); 234 system(buf); 235 fclose(fp); 236 } 237 238 fp = NULL; fp2 = NULL; 239 if ((fp2 = fopen(USB_MNT_TABLE2, "r+")) != NULL) 240 { 241 char buf[MAX_BUF_LEN]; 242 char patt[MAX_BUF_LEN]; 243 sprintf(patt, USB_MNT_PATTERN, pUsbPort, pDevice, pPart); 244 if ((fp = fopen(USB_MNT_TABLE, "w+")) != NULL) 245 { 246 while (fgets(buf, MAX_BUF_LEN, fp2) != NULL) 247 { 248 if ((strPos1 = strstr(buf, patt)) != NULL) { 249 continue; 250 } 251 else { 252 fputs(buf, fp); 253 } 254 } 255 fclose(fp); 256 rtn_val = 1; 257 } 258 fclose(fp2); 259 260 sprintf(buf, "rm -f %s", USB_MNT_TABLE2); 261 system(buf); 262 } 263 264 return rtn_val; 265} /* remove_from_mnt_file() */ 266 267int usb1_led(void) 268{ 269 int rtn_val = 0; 270 int has_usb1_dev = 0; 271 int fd; 272 FILE *fp = NULL; 273 char line[250] = ""; 274 275 if ((fp = fopen(USB_MNT_TABLE, "r")) != NULL) 276 { 277 rtn_val = 1; 278 while (fgets(line, 200, fp) != NULL) { 279 if ( (strstr(line, "PORT=1") != NULL) || (strstr(line, "PORT=3") != NULL)) 280 { 281 has_usb1_dev = 1; 282 rtn_val = 2; 283 break; 284 } 285 } 286 fclose(fp); 287 } 288 /* foxconn wklin modified start, 01/19/2011 @ USB LED for WNDR4000 */ 289#if (defined GPIO_EXT_CTRL) /* WNDR4000 */ 290 if (has_usb1_dev) 291 system("gpio usbled 1"); 292 else 293 system("gpio usbled 0"); 294#else 295 fd = open("/dev/wps_led", O_RDWR); 296 if (fd >= 0) { 297 rtn_val = 3; 298 if (has_usb1_dev) 299 { 300 ioctl(fd, USB_LED_STATE_ON, 1); 301 rtn_val = 4; 302 } 303 else 304 { 305 ioctl(fd, USB_LED_STATE_OFF, 1); 306 rtn_val = 5; 307 } 308 close(fd); 309 } 310#endif /* GPIO_EXT_CTRL */ 311 /* foxconn wklin modified end ,01/19/2011 */ 312 return rtn_val; 313} /* usb1_led() */ 314 315int usb2_led(void) 316{ 317 int rtn_val = 0; 318 int has_usb2_dev = 0; 319 int fd; 320 FILE *fp = NULL; 321 char line[250] = ""; 322 323 if ((fp = fopen(USB_MNT_TABLE, "r")) != NULL) 324 { 325 rtn_val = 1; 326 while (fgets(line, 200, fp) != NULL) { 327 if (strstr(line, "PORT=2") != NULL) { 328 has_usb2_dev = 1; 329 rtn_val = 2; 330 break; 331 } 332 } 333 fclose(fp); 334 } 335 /* foxconn wklin modified start, 01/19/2011 @ USB LED for WNDR4000 */ 336#if (defined GPIO_EXT_CTRL) /* WNDR4000 */ 337 if (has_usb2_dev) 338 system("gpio usbled 1"); 339 else 340 system("gpio usbled 0"); 341#else 342 fd = open("/dev/wps_led", O_RDWR); 343 if (fd >= 0) { 344 rtn_val = 3; 345 if (has_usb2_dev) 346 { 347 ioctl(fd, USB2_LED_STATE_ON, 1); 348 rtn_val = 4; 349 } 350 else 351 { 352 ioctl(fd, USB2_LED_STATE_OFF, 1); 353 rtn_val = 5; 354 } 355 close(fd); 356 } 357#endif /* GPIO_EXT_CTRL */ 358 /* foxconn wklin modified end ,01/19/2011 */ 359 return rtn_val; 360} /* usb2_led() */ 361 362int usb_dual_led(void) 363{ 364 int rtn_val = 0; 365 366 usb1_led(); 367#if (!defined R6700) /* No USB2 LED for R6700 */ 368 usb2_led(); 369#endif 370 371 return rtn_val; 372} /* usb_dual_led() */ 373#else /* R6300v2 */ 374 375int usb_led(void) 376{ 377 int has_usb_dev = 0; 378 int fd; 379 FILE *fp = NULL; 380 char line[250] = ""; 381 382 fp = fopen("/proc/mounts", "r"); 383 if (fp != NULL) { 384 while (fgets(line, 200, fp) != NULL) { 385 if (strstr(line, "/tmp/mnt/usb") != NULL) { 386 has_usb_dev = 1; 387 break; 388 } 389 } 390 fclose(fp); 391 } 392 /* foxconn wklin modified start, 01/19/2011 @ USB LED for WNDR4000 */ 393#if (defined GPIO_EXT_CTRL) /* WNDR4000 */ 394#if 0 /* Foxconn removed pling 12/26/2011, not needed for WNDR4000AC */ 395 if (has_usb_dev) 396 system("gpio usbled 1"); 397 else 398 system("gpio usbled 0"); 399#endif 400#else 401 fd = open("/dev/wps_led", O_RDWR); 402 if (fd >= 0) { 403 if (has_usb_dev) 404 ioctl(fd, USB_LED_STATE_ON, 1); 405 else 406 ioctl(fd, USB_LED_STATE_OFF, 1); 407 close(fd); 408 } 409#endif /* GPIO_EXT_CTRL */ 410 /* foxconn wklin modified end ,01/19/2011 */ 411 return 0; 412} 413#endif /* R6300v2 */ 414/* Foxconn added end, Wins, 04/11/2011 */ 415#endif 416/* Foxconn add end pling 02/05/2010*/ 417 418int usb_mount(void) 419{ 420 char source[128]; 421 char target[128]; 422 char buf[128]; 423 int i; 424 int rval; 425 426 /*foxconn add start, @mount approved devices, water, 05/11/2009*/ 427 int index = 0; 428 FILE *fp = NULL; 429 char line[150] = ""; 430 char *ptmp = NULL; 431 char vendor[32] = ""; 432 char model[32] = ""; 433 int scsi_host_num = -1; 434 int usb_dev_approved[26] = {0}; 435 char approved_usb[20][80] = {0}; 436 int not_approved_index; 437 438 /* Foxconn added start pling 09/16/2009 */ 439 int last_scsi_host_num = -1; 440 /* Foxconn added end pling 09/16/2009 */ 441 442 sleep(3); /* pling added 06/04/2009, add this delay seems to make mount more robust. */ 443 444 if (nvram_match("enable_any_usb_dev", "0") ) 445 { 446 for (i=0; i<20; i++) 447 { 448 sprintf(line, "approved_usb_%d", i); 449 strcpy(buf, nvram_safe_get(line)); 450 if (strlen (buf) != 0) 451 { 452 sscanf(buf, "%*[^+]+%[^+]+%*[^+]", approved_usb[i]); 453 } 454 } 455 456 fp = fopen("/proc/scsi/scsi", "r"); 457 if (fp != NULL) 458 { 459 while (fgets(line, 150, fp) != NULL) 460 { 461 if (strncmp(line, "Host: scsi", strlen("Host: scsi")) == 0) 462 { 463 sscanf(line, "Host: scsi%d %*s", &scsi_host_num); 464 465 /* Foxconn added start pling 09/16/2009 */ 466 /* Handle multi-lun devices */ 467 if (scsi_host_num == last_scsi_host_num) 468 { 469 /* Keep the same "approved"/"not-approved" status 470 * as the previous LUN 471 */ 472 usb_dev_approved[index] = usb_dev_approved[index-1]; 473 index++; 474 continue; 475 } 476 /* Foxconn added end pling 09/16/2009 */ 477 478 if ((fgets(line, 150, fp) == NULL)) 479 break; 480 481 ptmp=strstr(line, "Vendor:"); 482 if ( ptmp != NULL ) 483 { 484 sscanf(ptmp, "Vendor: %s %*s", vendor); 485 if (0 == strcmp(vendor, "Model:") ) 486 strcpy(vendor, ""); 487 } 488 ptmp=strstr(line, "Model:"); 489 if ( ptmp != NULL ) 490 { 491 sscanf(ptmp, "Model: %s %*s", model); 492 if (0 == strcmp(vendor, "Rev:") ) 493 strcpy(vendor, ""); 494 } 495 sprintf(buf, "%s %s", vendor, model); 496 497 for (i=0; i<20; i++) 498 { 499 if (strlen(approved_usb[i]) == 0 ) 500 continue; 501 if (0 == strcmp(approved_usb[i], buf) ) 502 {/*this usb device was approved*/ 503 /* Foxconn modified start pling 09/16/2009 */ 504 /* Use 'index' to help check multi-LUN device */ 505 //usb_dev_approved[scsi_host_num] = 1; 506 usb_dev_approved[index] = 1; 507 /* Foxconn modified end pling 09/16/2009 */ 508 break; 509 } 510 } 511 /* Foxconn added start pling 09/16/2009 */ 512 /* Multi-LUN devices */ 513 index++; 514 last_scsi_host_num = scsi_host_num; 515 /* Foxconn added end pling 09/16/2009 */ 516 } 517 } 518 fclose(fp); 519 } 520 } 521 else 522 { 523 for (i=0; i<26; i++) 524 usb_dev_approved[i] = 1; 525 } 526 not_approved_index = 0; 527 /*foxconn add end, water, 05/11/2009*/ 528 529 index = 0; // pling added 09/16/2009, reset index for later use 530 531//------------------------------------------------------ 532// action: add 533// 1. mount dev with vfat 534// 2. if mount ok, save data to nvram 535// 3. restart smb 536//------------------------------------------------------ 537//fixme: no good. zzz@ 538/* Foxconn modified start, Jenny Zhao, 04/13/2009 @usb dir */ 539 char diskName; 540 int j = 0; 541 int max_partition = atoi(nvram_safe_get("usb_disk_max_part")); 542 for (diskName='a'; diskName<='z'; diskName++) // try to mount sda->sdz 543 { 544 /*foxconn add start, @mount approved devices, water, 05/11/2009*/ 545 if (usb_dev_approved[index++] == 1)/*this device was approved...*/ 546 scsi_host_num = 1; 547 else 548 scsi_host_num = 0; 549 /*foxconn add end, water, 05/11/2009*/ 550 for (i=0; i<=max_partition; i++) // try to mount sdx or sdx1, ..., sdx5 551 { 552 //------------------------ 553 //set up source 554 //------------------------ 555 if (!i) 556 snprintf(source, 128, "/dev/sd%c", diskName); 557 else 558 snprintf(source, 128, "/dev/sd%c%d", diskName,i); 559 560 //------------------------ 561 //set up target 562 //------------------------ 563 /*foxconn modified start, water, 05/12/2009*/ 564 /*some usb device not in approved device list, but the approved device page 565 need to show its info, so it need mount too. */ 566 //snprintf(target, 128, "/tmp/mnt/usb%d/part%d", j, i); 567 if (scsi_host_num == 1) 568 snprintf(target, 128, "/tmp/mnt/usb%d/part%d", j, i); 569 else 570 snprintf(target, 128, "/tmp/mnt/not_approved%d", not_approved_index++); 571 /*foxconn modified end, water, 05/12/2009*/ 572 573 //------------------------ 574 //start mount with sync 575 //------------------------ 576 //rval = mount(source, target, "vfat", 0, NULL); 577 rval = mount(source, target, "vfat",0, "iocharset=utf8"); //stanley add,09/14/2009 578 /* pling added start 05/07/2009 */ 579 /* Use mlabel to read VFAT volume label after successful mount */ 580 if (rval == 0) 581 { 582 /* Foxconn, add-start by MJ., for downsizing WNDR3400v2, 583 * 2011.02.11. */ 584#if (defined WNDR3400v2) || (defined R6300v2) 585 snprintf(buf, 128, "/lib/udev/vol_id %s", source); 586 /* Foxconn added start pling 12/26/2011, for WNDR4000AC */ 587#elif (defined WNDR4000AC) 588 get_vol_id(source); 589 memset(buf, 0, sizeof(buf)); 590 /* Foxconn added end pling 12/26/2011, for WNDR4000AC */ 591#else 592 /* Foxconn, add-end by MJ., for downsizing WNDR3400v2, 593 * 2011.02.11. */ 594 snprintf(buf, 128, "/usr/bin/mlabel -i %s -s ::", source); 595#endif 596 system(buf); 597 } 598 /* pling added end 05/07/2009 */ 599 600#ifdef USB_HOTPLUG_DBG//debug 601 snprintf(buf, 128, "echo \"mount %s %s with vfat, rval:%d, errno=%d\">>/tmp/usberr.log", 602 source, target, rval, errno); 603 system(buf); 604#endif 605 606 /* pling added start 08/24/2009 */ 607 /* To speed up mounting: 608 * if sda is mounted, then don't bother about sda1, sda2... 609 */ 610 if (rval == 0 && i == 0) 611 break; 612 /* pling added end 08/24/2009 */ 613 614 if (rval<0 && errno == EINVAL) 615 { 616 int ret; 617 /* Use NTFS-3g driver to provide NTFS r/w function */ 618 snprintf(buf, 128, "/bin/ntfs-3g -o large_read %s %s 2> /dev/null", source, target); 619 ret = system(buf); 620 621#ifdef USB_HOTPLUG_DBG//debug 622 snprintf(buf, 128, "echo \"try to mount %s @ %s with ntfs-3g\">>/tmp/usberr.log", source, target); 623 system(buf); 624#endif 625 626 /* Foxconn added pling 08/24/2009 */ 627 /* To speed up mounting: 628 * if sda is mounted, then don't bother about sda1, sda2... 629 */ 630 if (WIFEXITED(ret)) 631 { 632 int status = WEXITSTATUS(ret); 633 if (status == 0 && i == 0) 634 break; 635 } 636 /* Foxconn added pling 08/24/2009 */ 637 } 638 } //end of for 639 j++; 640 }//end of for(diskName = 'a';diskName < 'd';diskName++) 641 /* Foxconn modified end, Jenny Zhao, 04/13/2009 */ 642 //nvram_set("usb_dev_no_change", "0"); 643 /* send signal to httpd ,create link ,2009/05/07, jenny*/ 644 //nvram_set("usb_mount_signal", "1"); 645 system("killall -SIGUSR2 httpd"); 646 /* USB LED on / off */ 647#ifdef INCLUDE_USB_LED 648 /* Foxconn modified start, Wins, 04/11/2011 */ 649#if defined(R6300v2) || defined(R7000) 650 usb_dual_led(); 651#else /* R6300v2 */ 652 usb_led(); 653#endif /* R6300v2 */ 654 /* Foxconn modified end, Wins, 04/11/2011 */ 655#endif 656 657 //sleep(5); // Foxconn added pling 07/13/2009, wait for httpd to complete mount/umount processes 658 //nvram_set("usb_mount_signal", "0"); 659 //acosNvramConfig_save(); 660 return 0; 661} 662 663int usb_umount(void) 664{ 665 int i, j; 666 int rval; 667 char path[128]; 668 char buf[128]; 669 //------------------------------------------------------ 670 // action: remove 671 // remount devices 672 //------------------------------------------------------ 673 //fixme: no good. zzz@ 674 /* Foxconn modify start, Jenny Zhao, 04/13/2009 @usb dir */ 675 char diskName; 676 677 /*foxconn add start, water, 05/12/2009*/ 678 /*some usb device not in approved device list, but the approved device 679 page need to show its info, so it need mount too. */ 680 for (j=0; j<20; j++) 681 { 682 snprintf(path, 128, "/tmp/mnt/not_approved%d", j); 683 umount2(path, MNT_DETACH); 684 } 685 /*foxconn add end, water, 05/12/2009*/ 686 687 for (diskName='a', i=0; diskName<='z'; diskName++,i++) 688 { 689 snprintf(path, 128, "/tmp/mnt/usb%d/part0", i); 690 691 rval = umount2(path, MNT_DETACH); 692 693 for (j=0; j<16; j++) 694 { 695 snprintf(path, 128, "/tmp/mnt/usb%d/part%d", i, j); 696 697 rval = umount2(path, MNT_DETACH); 698 /* pling added start 05/07/2009 */ 699 /* remove volume name file under /tmp after a successful umount */ 700 if (rval == 0) 701 { 702 char filename[64]; 703 if (j == 0) 704 sprintf(filename, "/tmp/usb_vol_name/sd%c", diskName); 705 else 706 sprintf(filename, "/tmp/usb_vol_name/sd%c%d", diskName, j); 707 unlink(filename); 708 } 709 /* pling added end 05/07/2009 */ 710 711#ifdef USB_HOTPLUG_DBG//debug 712 snprintf(buf, 128, "echo \"umount %s, rval:%d \">>/tmp/usberr.log", path, rval); 713 system(buf); 714#endif 715 } 716 } 717 /* Foxconn modify end, Jenny Zhao, 04/13/2009 */ 718 nvram_set("usb_dev_no_change", "0"); 719 //acosNvramConfig_save(); 720 721 usb_mount(); 722 return 0; 723} 724int usb_hotplug(void) 725{ 726 char *device, *interface; 727 char *action, *product; 728 char *type, *devfs; 729 int class, subclass, protocol; 730 char cmd[512]; 731 732 /*foxconn add start, water, 05/11/2009*/ 733 if (nvram_match("restart_usb", "1") ) 734 { 735 usb_umount(); 736 nvram_unset("restart_usb"); 737 //eval("/usr/bin/setsmbftpconf"); 738 } 739 /*foxconn add end, water, 05/11/2009*/ 740 741 if (!(action = getenv("ACTION")) || 742 !(type = getenv("TYPE")) || 743 !(device = getenv("DEVICE")) || 744 !(devfs = getenv("DEVFS")) || 745 !(interface = getenv("INTERFACE")) || 746 !(product = getenv("PRODUCT"))) 747 { 748#ifdef USB_HOTPLUG_DBG//debug 749 sprintf(cmd, "echo \"return EINVAL;\" >> /tmp/hotAct\n"); 750 system(cmd); 751#endif 752 return EINVAL; 753 } 754 755#ifdef USB_HOTPLUG_DBG//debug 756 sprintf(cmd, "echo \"ACTION=%s, TYPE=%s, DEVICE=%s, DEVFS=%s, INTERFACE=%s, PRODUCT=%s\" >> /tmp/hotAct\n", 757 action, type, device, devfs, interface, product); 758 system(cmd); 759#endif 760 761 sscanf(type, "%d/%d/%d", &class, &subclass, &protocol); 762 if (class == 0) 763 { 764 sscanf(interface, "%d/%d/%d", &class, &subclass, &protocol); 765 } 766 //set LED 767 //set_usb_led();/*No usb led in WNR3500U board, need further check.*/ 768 769 //check Mass Storage for add action 770 /* Foxconn modified start pling 11/11/2009 */ 771 /* We should mount all subclasses of Mass Storage class (8), 772 * not just subclass 6 (Transparent SCSI). 773 */ 774 //if (class == 8 && subclass == 6 && !strcmp(action, "add")) 775 if (class == 8 && !strcmp(action, "add")) 776 /* Foxconn modified end pling 11/11/2009 */ 777 { 778 /* 779 sometimes usb_umount() not execute when unplug usb. 780 so before mount, we do umount firstly. 781 not sure, I think it need further test. 782 */ 783 //usb_mount(); 784 USB_LOCK(); // Foxconn added pling 07/13/2009 785 usb_umount();/*water, 11/06/2008*/ 786 USB_UNLOCK(); // Foxconn added pling 07/13/2009 787 } 788 //check Mass Storage for remove action 789 /* Foxconn modified start pling 11/11/2009 */ 790 /* We should un-mount all subclasses of Mass Storage class (8), 791 * not just subclass 6 (Transparent SCSI). 792 */ 793 //else if (class == 8 && subclass == 6 && !strcmp(action, "remove")) 794 else if (class == 8 && !strcmp(action, "remove")) 795 /* Foxconn modified end pling 11/11/2009 */ 796 { 797 USB_LOCK(); // Foxconn added pling 07/13/2009 798 usb_umount(); 799 USB_UNLOCK(); // Foxconn added pling 07/13/2009 800 } 801 802 //eval("/usr/bin/setsmbftpconf"); 803#ifdef USB_HOTPLUG_DBG//debug 804 system("echo \"/usr/bin/setsmbftpconf\">>/tmp/usberr.log"); 805#endif 806 return 0; 807} 808