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(WNDR4500REV) || defined(R4500) 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 118/* for Time Machine , added start by EricHuang, 12/22/2011 */ 119#if defined(INCLUDE_AFP) 120#define USB_MNT_TABLE3 "/tmp/usb_mnt_table3" 121#define USB_MNT_TABLE4 "/tmp/usb_mnt_table4" 122 123int add_into_mnt_src_file(char *target, char *src) 124{ 125 FILE *fp = NULL; 126 int rtn_val = 0; 127 char buf[128]; 128 129 /* Foxconn added start, Wins, 06/30/2011 */ 130 if ((fp = fopen(USB_MNT_TABLE3, "r")) != NULL) 131 { 132 int rec_found = 0; 133 char patt[128]; 134 /* Check if record of USB device exists. */ 135 while(fgets(buf, sizeof(buf), fp) != NULL) 136 { 137 memset(patt, 0x0, sizeof(patt)); 138 sprintf(patt, "%s %s", src, target); 139 strcat(patt, "\n"); 140 if (!strcmp(buf, patt)) 141 { 142 rec_found = 1; 143 break; /* Record exists. */ 144 } 145 } 146 fclose(fp); 147 if (rec_found) 148 return 1; /* Not need to add a duplicated record. */ 149 } 150 fp = NULL; 151 /* Foxconn added end, Wins, 06/30/2011 */ 152 153 if ((fp = fopen(USB_MNT_TABLE3, "a+")) != NULL) 154 { 155 fseek(fp, 0, SEEK_END); 156 sprintf(buf, "%s %s", src, target); 157 strcat(buf, "\n"); 158 fputs(buf, fp); 159 fclose(fp); 160 rtn_val = 1; 161 } 162 163 return rtn_val; 164} /* add_into_mnt_src_file() */ 165 166int remove_from_mnt_src_file(char *pUsbPort, char *pDevice, char *pPart) 167{ 168 FILE *fp = NULL, *fp2 = NULL; 169 int rtn_val = 0; 170 char usb_device[4], usb_part[4]; 171 char buf[128]; 172 char *strPos1 = NULL, *strPos2 = NULL; 173 174 if ((fp = fopen(USB_MNT_TABLE3, "r+")) != NULL) 175 { 176 char buf[128]; 177 sprintf(buf, "cp -f %s %s", USB_MNT_TABLE3, USB_MNT_TABLE4); 178 system(buf); 179 fclose(fp); 180 } 181 182 fp = NULL; fp2 = NULL; 183 if ((fp2 = fopen(USB_MNT_TABLE4, "r+")) != NULL) 184 { 185 char buf[MAX_BUF_LEN]; 186 char patt[MAX_BUF_LEN]; 187 sprintf(patt, USB_MNT_PATTERN, pUsbPort, pDevice, pPart); 188 if ((fp = fopen(USB_MNT_TABLE3, "w+")) != NULL) 189 { 190 while (fgets(buf, MAX_BUF_LEN, fp2) != NULL) 191 { 192 if ((strPos1 = strstr(buf, patt)) != NULL) { 193 continue; 194 } 195 else { 196 fputs(buf, fp); 197 } 198 } 199 fclose(fp); 200 rtn_val = 1; 201 } 202 fclose(fp2); 203 204 sprintf(buf, "rm -f %s", USB_MNT_TABLE4); 205 system(buf); 206 } 207 208 return rtn_val; 209} /* remove_from_mnt_src_file() */ 210#endif 211/* for Time Machine , added end by EricHuang, 12/22/2011 */ 212 213int get_usb_port(char *pDevPath, char *pUsbPort) 214{ 215 int rtn_val = 0; 216 char buf[256]; 217 char *strPos1 = NULL, *strPos2 = NULL; 218 219 if ((strPos1 = strstr(pDevPath, "/usb1/1-1/1-1.")) != NULL) { 220 sscanf(strPos1, "/usb1/1-1/1-1.%s", buf); 221 if ((strPos2 = strchr(buf, '/')) != NULL) { 222 memcpy(pUsbPort, buf, (strPos2 - buf)); 223 rtn_val = 1; 224 } 225 } 226 227 return rtn_val; 228} /* get_usb_port() */ 229 230int parse_target_path(char *pTarget, int *pDevice, int *pPart) 231{ 232 int rtn_val = 0; 233 char usb_device[4], usb_part[4]; 234 char buf[128]; 235 char *strPos1 = NULL, *strPos2 = NULL; 236 237 /* Get USB device & part */ 238 memset(usb_device, 0x0, sizeof(usb_device)); 239 memset(usb_part, 0x0, sizeof(usb_part)); 240 if ((strPos1 = strstr(pTarget, "/tmp/mnt/usb")) != NULL) { 241 sscanf(strPos1, "/tmp/mnt/usb%s", buf); 242 if ((strPos2 = strchr(buf, '/')) != NULL) { 243 memcpy(usb_device, buf, (strPos2-buf)); 244 *pDevice = atoi(usb_device); 245 strPos2 = NULL; 246 if ((strPos2 = strstr(buf, "/part")) != NULL) { 247 sscanf(strPos2, "/part%s", usb_part); 248 *pPart = atoi(usb_part); 249 rtn_val = 1; 250 } 251 } 252 } 253 254 return rtn_val; 255} /* parse_target_path() */ 256 257int add_into_mnt_file(char *pUsbPort, char *pDevice, char *pPart) 258{ 259 FILE *fp = NULL; 260 int rtn_val = 0; 261 char buf[128]; 262 263 /* Foxconn added start, Wins, 06/30/2011 */ 264 if ((fp = fopen(USB_MNT_TABLE, "r")) != NULL) 265 { 266 int rec_found = 0; 267 char patt[128]; 268 /* Check if record of USB device exists. */ 269 while(fgets(buf, sizeof(buf), fp) != NULL) 270 { 271 memset(patt, 0x0, sizeof(patt)); 272 sprintf(patt, USB_MNT_PATTERN, pUsbPort, pDevice, pPart); 273 strcat(patt, "\n"); 274 if (!strcmp(buf, patt)) 275 { 276 rec_found = 1; 277 break; /* Record exists. */ 278 } 279 } 280 fclose(fp); 281 if (rec_found) 282 return 1; /* Not need to add a duplicated record. */ 283 } 284 fp = NULL; 285 /* Foxconn added end, Wins, 06/30/2011 */ 286 287 if ((fp = fopen(USB_MNT_TABLE, "a+")) != NULL) 288 { 289 fseek(fp, 0, SEEK_END); 290 sprintf(buf, USB_MNT_PATTERN, pUsbPort, pDevice, pPart); 291 strcat(buf, "\n"); 292 fputs(buf, fp); 293 fclose(fp); 294 rtn_val = 1; 295 } 296 297 return rtn_val; 298} /* add_into_mnt_file() */ 299 300int remove_from_mnt_file(char *pUsbPort, char *pDevice, char *pPart) 301{ 302 FILE *fp = NULL, *fp2 = NULL; 303 int rtn_val = 0; 304 char usb_device[4], usb_part[4]; 305 char buf[128]; 306 char *strPos1 = NULL, *strPos2 = NULL; 307 308 if ((fp = fopen(USB_MNT_TABLE, "r+")) != NULL) 309 { 310 char buf[128]; 311 sprintf(buf, "cp -f %s %s", USB_MNT_TABLE, USB_MNT_TABLE2); 312 system(buf); 313 fclose(fp); 314 } 315 316 fp = NULL; fp2 = NULL; 317 if ((fp2 = fopen(USB_MNT_TABLE2, "r+")) != NULL) 318 { 319 char buf[MAX_BUF_LEN]; 320 char patt[MAX_BUF_LEN]; 321 sprintf(patt, USB_MNT_PATTERN, pUsbPort, pDevice, pPart); 322 if ((fp = fopen(USB_MNT_TABLE, "w+")) != NULL) 323 { 324 while (fgets(buf, MAX_BUF_LEN, fp2) != NULL) 325 { 326 if ((strPos1 = strstr(buf, patt)) != NULL) { 327 continue; 328 } 329 else { 330 fputs(buf, fp); 331 } 332 } 333 fclose(fp); 334 rtn_val = 1; 335 } 336 fclose(fp2); 337 338 sprintf(buf, "rm -f %s", USB_MNT_TABLE2); 339 system(buf); 340 } 341 342 return rtn_val; 343} /* remove_from_mnt_file() */ 344 345int usb1_led(void) 346{ 347 int rtn_val = 0; 348 int has_usb1_dev = 0; 349 int fd; 350 FILE *fp = NULL; 351 char line[250] = ""; 352 353 if ((fp = fopen(USB_MNT_TABLE, "r")) != NULL) 354 { 355 rtn_val = 1; 356 while (fgets(line, 200, fp) != NULL) { 357 if (strstr(line, "PORT=1") != NULL) { 358 has_usb1_dev = 1; 359 rtn_val = 2; 360 break; 361 } 362 } 363 fclose(fp); 364 } 365 /* foxconn wklin modified start, 01/19/2011 @ USB LED for WNDR4000 */ 366 367 /* Foxconn added start pling 10/05/2012 */ 368 /* Before we turn off USB LED 1, check whether we have 369 * a printer connected or not. 370 */ 371 if (!has_usb1_dev) 372 { 373 fp = fopen("/proc/NetUSB/0/device", "r"); 374 if (fp) 375 { 376 memset(line, 0, sizeof(line)); 377 fgets(line, sizeof(line), fp); 378 fclose(fp); 379 if (strlen(line) > 2) 380 { 381 printf("%s: USB LED1 on!\n", __FUNCTION__); 382 has_usb1_dev = 1; 383 } 384 } 385 } 386 /* Foxconn added end pling 10/05/2012 */ 387 388#if (defined GPIO_EXT_CTRL) /* WNDR4000 */ 389 if (has_usb1_dev) 390 system("gpio usbled 1"); 391 else 392 system("gpio usbled 0"); 393#else 394 fd = open("/dev/wps_led", O_RDWR); 395 if (fd >= 0) { 396 rtn_val = 3; 397 if (has_usb1_dev) 398 { 399 ioctl(fd, USB_LED_STATE_ON, 1); 400 rtn_val = 4; 401 } 402 else 403 { 404 ioctl(fd, USB_LED_STATE_OFF, 1); 405 rtn_val = 5; 406 } 407 close(fd); 408 } 409#endif /* GPIO_EXT_CTRL */ 410 /* foxconn wklin modified end ,01/19/2011 */ 411 return rtn_val; 412} /* usb1_led() */ 413 414int usb2_led(void) 415{ 416 int rtn_val = 0; 417 int has_usb2_dev = 0; 418 int fd; 419 FILE *fp = NULL; 420 char line[250] = ""; 421 422 if ((fp = fopen(USB_MNT_TABLE, "r")) != NULL) 423 { 424 rtn_val = 1; 425 while (fgets(line, 200, fp) != NULL) { 426 if (strstr(line, "PORT=2") != NULL) { 427 has_usb2_dev = 1; 428 rtn_val = 2; 429 break; 430 } 431 } 432 fclose(fp); 433 } 434 /* foxconn wklin modified start, 01/19/2011 @ USB LED for WNDR4000 */ 435 436 /* Foxconn added start pling 10/05/2012 */ 437 /* Before we turn off USB LED 2, check whether we have 438 * a printer connected or not. 439 */ 440 if (!has_usb2_dev) 441 { 442 fp = fopen("/proc/NetUSB/1/device", "r"); 443 if (fp) 444 { 445 memset(line, 0, sizeof(line)); 446 fgets(line, sizeof(line), fp); 447 fclose(fp); 448 if (strlen(line) > 2) 449 { 450 printf("%s: USB LED2 on!\n", __FUNCTION__); 451 has_usb2_dev = 1; 452 } 453 } 454 } 455 /* Foxconn added end pling 10/05/2012 */ 456 457#if (defined GPIO_EXT_CTRL) /* WNDR4000 */ 458 if (has_usb2_dev) 459 system("gpio usbled 1"); 460 else 461 system("gpio usbled 0"); 462#else 463 fd = open("/dev/wps_led", O_RDWR); 464 if (fd >= 0) { 465 rtn_val = 3; 466 if (has_usb2_dev) 467 { 468 ioctl(fd, USB2_LED_STATE_ON, 1); 469 rtn_val = 4; 470 } 471 else 472 { 473 ioctl(fd, USB2_LED_STATE_OFF, 1); 474 rtn_val = 5; 475 } 476 close(fd); 477 } 478#endif /* GPIO_EXT_CTRL */ 479 /* foxconn wklin modified end ,01/19/2011 */ 480 return rtn_val; 481} /* usb2_led() */ 482 483int usb_dual_led(void) 484{ 485 int rtn_val = 0; 486 487 usb1_led(); 488 usb2_led(); 489 490 return rtn_val; 491} /* usb_dual_led() */ 492#else /* WNDR4500REV */ 493 494int usb_led(void) 495{ 496 int has_usb_dev = 0; 497 int fd; 498 FILE *fp = NULL; 499 char line[250] = ""; 500 501 fp = fopen("/proc/mounts", "r"); 502 if (fp != NULL) { 503 while (fgets(line, 200, fp) != NULL) { 504 if (strstr(line, "/tmp/mnt/usb") != NULL) { 505 has_usb_dev = 1; 506 break; 507 } 508 } 509 fclose(fp); 510 } 511 /* foxconn wklin modified start, 01/19/2011 @ USB LED for WNDR4000 */ 512#if (defined GPIO_EXT_CTRL) /* WNDR4000 */ 513 if (has_usb_dev) 514 system("gpio usbled 1"); 515 else 516 system("gpio usbled 0"); 517#else 518 fd = open("/dev/wps_led", O_RDWR); 519 if (fd >= 0) { 520 if (has_usb_dev) 521 ioctl(fd, USB_LED_STATE_ON, 1); 522 else 523 ioctl(fd, USB_LED_STATE_OFF, 1); 524 close(fd); 525 } 526#endif /* GPIO_EXT_CTRL */ 527 /* foxconn wklin modified end ,01/19/2011 */ 528 return 0; 529} 530#endif /* WNDR4500REV */ 531/* Foxconn added end, Wins, 04/11/2011 */ 532#endif 533/* Foxconn add end pling 02/05/2010*/ 534 535int usb_mount(void) 536{ 537 char source[128]; 538 char target[128]; 539 char buf[128]; 540 int i; 541 int rval; 542 543 /*foxconn add start, @mount approved devices, water, 05/11/2009*/ 544 int index = 0; 545 FILE *fp = NULL; 546 char line[150] = ""; 547 char *ptmp = NULL; 548 char vendor[32] = ""; 549 char model[32] = ""; 550 int scsi_host_num = -1; 551 int usb_dev_approved[26] = {0}; 552 char approved_usb[20][80] = {0}; 553 int not_approved_index; 554 555 /* Foxconn added start pling 09/16/2009 */ 556 int last_scsi_host_num = -1; 557 /* Foxconn added end pling 09/16/2009 */ 558 559 sleep(3); /* pling added 06/04/2009, add this delay seems to make mount more robust. */ 560 561 if (nvram_match("enable_any_usb_dev", "0") ) 562 { 563 for (i=0; i<20; i++) 564 { 565 sprintf(line, "approved_usb_%d", i); 566 strcpy(buf, nvram_safe_get(line)); 567 if (strlen (buf) != 0) 568 { 569 sscanf(buf, "%*[^+]+%[^+]+%*[^+]", approved_usb[i]); 570 } 571 } 572 573 fp = fopen("/proc/scsi/scsi", "r"); 574 if (fp != NULL) 575 { 576 while (fgets(line, 150, fp) != NULL) 577 { 578 if (strncmp(line, "Host: scsi", strlen("Host: scsi")) == 0) 579 { 580 sscanf(line, "Host: scsi%d %*s", &scsi_host_num); 581 582 /* Foxconn added start pling 09/16/2009 */ 583 /* Handle multi-lun devices */ 584 if (scsi_host_num == last_scsi_host_num) 585 { 586 /* Keep the same "approved"/"not-approved" status 587 * as the previous LUN 588 */ 589 usb_dev_approved[index] = usb_dev_approved[index-1]; 590 index++; 591 continue; 592 } 593 /* Foxconn added end pling 09/16/2009 */ 594 595 if ((fgets(line, 150, fp) == NULL)) 596 break; 597 598 ptmp=strstr(line, "Vendor:"); 599 if ( ptmp != NULL ) 600 { 601 sscanf(ptmp, "Vendor: %s %*s", vendor); 602 if (0 == strcmp(vendor, "Model:") ) 603 strcpy(vendor, ""); 604 } 605 ptmp=strstr(line, "Model:"); 606 if ( ptmp != NULL ) 607 { 608 sscanf(ptmp, "Model: %s %*s", model); 609 if (0 == strcmp(vendor, "Rev:") ) 610 strcpy(vendor, ""); 611 } 612 sprintf(buf, "%s %s", vendor, model); 613 614 for (i=0; i<20; i++) 615 { 616 if (strlen(approved_usb[i]) == 0 ) 617 continue; 618 if (0 == strcmp(approved_usb[i], buf) ) 619 {/*this usb device was approved*/ 620 /* Foxconn modified start pling 09/16/2009 */ 621 /* Use 'index' to help check multi-LUN device */ 622 //usb_dev_approved[scsi_host_num] = 1; 623 usb_dev_approved[index] = 1; 624 /* Foxconn modified end pling 09/16/2009 */ 625 break; 626 } 627 } 628 /* Foxconn added start pling 09/16/2009 */ 629 /* Multi-LUN devices */ 630 index++; 631 last_scsi_host_num = scsi_host_num; 632 /* Foxconn added end pling 09/16/2009 */ 633 } 634 } 635 fclose(fp); 636 } 637 } 638 else 639 { 640 for (i=0; i<26; i++) 641 usb_dev_approved[i] = 1; 642 } 643 not_approved_index = 0; 644 /*foxconn add end, water, 05/11/2009*/ 645 646 index = 0; // pling added 09/16/2009, reset index for later use 647 648//------------------------------------------------------ 649// action: add 650// 1. mount dev with vfat 651// 2. if mount ok, save data to nvram 652// 3. restart smb 653//------------------------------------------------------ 654//fixme: no good. zzz@ 655/* Foxconn modified start, Jenny Zhao, 04/13/2009 @usb dir */ 656 char diskName; 657 int j = 0; 658 int max_partition = atoi(nvram_safe_get("usb_disk_max_part")); 659 for (diskName='a'; diskName<='z'; diskName++) // try to mount sda->sdz 660 { 661 /*foxconn add start, @mount approved devices, water, 05/11/2009*/ 662 if (usb_dev_approved[index++] == 1)/*this device was approved...*/ 663 scsi_host_num = 1; 664 else 665 scsi_host_num = 0; 666 /*foxconn add end, water, 05/11/2009*/ 667 for (i=0; i<=max_partition; i++) // try to mount sdx or sdx1, ..., sdx5 668 { 669 //------------------------ 670 //set up source 671 //------------------------ 672 if (!i) 673 snprintf(source, 128, "/dev/sd%c", diskName); 674 else 675 snprintf(source, 128, "/dev/sd%c%d", diskName,i); 676 677 //------------------------ 678 //set up target 679 //------------------------ 680 /*foxconn modified start, water, 05/12/2009*/ 681 /*some usb device not in approved device list, but the approved device page 682 need to show its info, so it need mount too. */ 683 //snprintf(target, 128, "/tmp/mnt/usb%d/part%d", j, i); 684 if (scsi_host_num == 1) 685 snprintf(target, 128, "/tmp/mnt/usb%d/part%d", j, i); 686 else 687 snprintf(target, 128, "/tmp/mnt/not_approved%d", not_approved_index++); 688 /*foxconn modified end, water, 05/12/2009*/ 689 690 //------------------------ 691 //start mount with sync 692 //------------------------ 693 //rval = mount(source, target, "vfat", 0, NULL); 694 rval = mount(source, target, "vfat",0, "iocharset=utf8"); //stanley add,09/14/2009 695 /* pling added start 05/07/2009 */ 696 /* Use mlabel to read VFAT volume label after successful mount */ 697 if (rval == 0) 698 { 699 /* Foxconn, add-start by MJ., for downsizing WNDR3400v2, 700 * 2011.02.11. */ 701#if (defined WNDR3400v2) || (defined U12H189) 702 snprintf(buf, 128, "/lib/udev/vol_id %s", source); 703#else 704 /* Foxconn, add-end by MJ., for downsizing WNDR3400v2, 705 * 2011.02.11. */ 706 snprintf(buf, 128, "/usr/bin/mlabel -i %s -s ::", source); 707#endif 708 system(buf); 709 } 710 /* pling added end 05/07/2009 */ 711 712#ifdef USB_HOTPLUG_DBG//debug 713 snprintf(buf, 128, "echo \"mount %s %s with vfat, rval:%d, errno=%d\">>/tmp/usberr.log", 714 source, target, rval, errno); 715 system(buf); 716#endif 717 718 /* pling added start 08/24/2009 */ 719 /* To speed up mounting: 720 * if sda is mounted, then don't bother about sda1, sda2... 721 */ 722 if (rval == 0 && i == 0) 723 break; 724 /* pling added end 08/24/2009 */ 725 726 if (rval<0 && errno == EINVAL) 727 { 728 int ret; 729 /* Use NTFS-3g driver to provide NTFS r/w function */ 730 snprintf(buf, 128, "/bin/ntfs-3g -o large_read %s %s 2> /dev/null", source, target); 731 ret = system(buf); 732 733#ifdef USB_HOTPLUG_DBG//debug 734 snprintf(buf, 128, "echo \"try to mount %s @ %s with ntfs-3g\">>/tmp/usberr.log", source, target); 735 system(buf); 736#endif 737 738 /* Foxconn added pling 08/24/2009 */ 739 /* To speed up mounting: 740 * if sda is mounted, then don't bother about sda1, sda2... 741 */ 742 if (WIFEXITED(ret)) 743 { 744 int status = WEXITSTATUS(ret); 745 if (status == 0 && i == 0) 746 break; 747 } 748 /* Foxconn added pling 08/24/2009 */ 749 } 750 } //end of for 751 j++; 752 }//end of for(diskName = 'a';diskName < 'd';diskName++) 753 /* Foxconn modified end, Jenny Zhao, 04/13/2009 */ 754 //nvram_set("usb_dev_no_change", "0"); 755 /* send signal to httpd ,create link ,2009/05/07, jenny*/ 756 //nvram_set("usb_mount_signal", "1"); 757 system("killall -SIGUSR2 httpd"); 758 /* USB LED on / off */ 759#ifdef INCLUDE_USB_LED 760 /* Foxconn modified start, Wins, 04/11/2011 */ 761#if defined(WNDR4500REV) || defined(R4500) 762 usb_dual_led(); 763#else /* WNDR4500REV */ 764 usb_led(); 765#endif /* WNDR4500REV */ 766 /* Foxconn modified end, Wins, 04/11/2011 */ 767#endif 768 769 //sleep(5); // Foxconn added pling 07/13/2009, wait for httpd to complete mount/umount processes 770 //nvram_set("usb_mount_signal", "0"); 771 //acosNvramConfig_save(); 772 return 0; 773} 774 775int usb_umount(void) 776{ 777 int i, j; 778 int rval; 779 char path[128]; 780 char buf[128]; 781 //------------------------------------------------------ 782 // action: remove 783 // remount devices 784 //------------------------------------------------------ 785 //fixme: no good. zzz@ 786 /* Foxconn modify start, Jenny Zhao, 04/13/2009 @usb dir */ 787 char diskName; 788 789 /*foxconn add start, water, 05/12/2009*/ 790 /*some usb device not in approved device list, but the approved device 791 page need to show its info, so it need mount too. */ 792 for (j=0; j<20; j++) 793 { 794 snprintf(path, 128, "/tmp/mnt/not_approved%d", j); 795 umount2(path, MNT_DETACH); 796 } 797 /*foxconn add end, water, 05/12/2009*/ 798 799 for (diskName='a', i=0; diskName<='z'; diskName++,i++) 800 { 801 snprintf(path, 128, "/tmp/mnt/usb%d/part0", i); 802 803 rval = umount2(path, MNT_DETACH); 804 805 for (j=0; j<16; j++) 806 { 807 snprintf(path, 128, "/tmp/mnt/usb%d/part%d", i, j); 808 809 rval = umount2(path, MNT_DETACH); 810 /* pling added start 05/07/2009 */ 811 /* remove volume name file under /tmp after a successful umount */ 812 if (rval == 0) 813 { 814 char filename[64]; 815 if (j == 0) 816 sprintf(filename, "/tmp/usb_vol_name/sd%c", diskName); 817 else 818 sprintf(filename, "/tmp/usb_vol_name/sd%c%d", diskName, j); 819 unlink(filename); 820 } 821 /* pling added end 05/07/2009 */ 822 823#ifdef USB_HOTPLUG_DBG//debug 824 snprintf(buf, 128, "echo \"umount %s, rval:%d \">>/tmp/usberr.log", path, rval); 825 system(buf); 826#endif 827 } 828 } 829 /* Foxconn modify end, Jenny Zhao, 04/13/2009 */ 830 nvram_set("usb_dev_no_change", "0"); 831 //acosNvramConfig_save(); 832 833 usb_mount(); 834 return 0; 835} 836int usb_hotplug(void) 837{ 838 char *device, *interface; 839 char *action, *product; 840 char *type, *devfs; 841 int class, subclass, protocol; 842 char cmd[512]; 843 844 /*foxconn add start, water, 05/11/2009*/ 845 if (nvram_match("restart_usb", "1") ) 846 { 847 usb_umount(); 848 nvram_unset("restart_usb"); 849 //eval("/usr/bin/setsmbftpconf"); 850 } 851 /*foxconn add end, water, 05/11/2009*/ 852 853 if (!(action = getenv("ACTION")) || 854 !(type = getenv("TYPE")) || 855 !(device = getenv("DEVICE")) || 856 !(devfs = getenv("DEVFS")) || 857 !(interface = getenv("INTERFACE")) || 858 !(product = getenv("PRODUCT"))) 859 { 860#ifdef USB_HOTPLUG_DBG//debug 861 sprintf(cmd, "echo \"return EINVAL;\" >> /tmp/hotAct\n"); 862 system(cmd); 863#endif 864 return EINVAL; 865 } 866 867#ifdef USB_HOTPLUG_DBG//debug 868 sprintf(cmd, "echo \"ACTION=%s, TYPE=%s, DEVICE=%s, DEVFS=%s, INTERFACE=%s, PRODUCT=%s\" >> /tmp/hotAct\n", 869 action, type, device, devfs, interface, product); 870 system(cmd); 871#endif 872 873 sscanf(type, "%d/%d/%d", &class, &subclass, &protocol); 874 if (class == 0) 875 { 876 sscanf(interface, "%d/%d/%d", &class, &subclass, &protocol); 877 } 878 //set LED 879 //set_usb_led();/*No usb led in WNR3500U board, need further check.*/ 880 881 //check Mass Storage for add action 882 /* Foxconn modified start pling 11/11/2009 */ 883 /* We should mount all subclasses of Mass Storage class (8), 884 * not just subclass 6 (Transparent SCSI). 885 */ 886 //if (class == 8 && subclass == 6 && !strcmp(action, "add")) 887 if (class == 8 && !strcmp(action, "add")) 888 /* Foxconn modified end pling 11/11/2009 */ 889 { 890 /* 891 sometimes usb_umount() not execute when unplug usb. 892 so before mount, we do umount firstly. 893 not sure, I think it need further test. 894 */ 895 //usb_mount(); 896 USB_LOCK(); // Foxconn added pling 07/13/2009 897 usb_umount();/*water, 11/06/2008*/ 898 USB_UNLOCK(); // Foxconn added pling 07/13/2009 899 } 900 //check Mass Storage for remove action 901 /* Foxconn modified start pling 11/11/2009 */ 902 /* We should un-mount all subclasses of Mass Storage class (8), 903 * not just subclass 6 (Transparent SCSI). 904 */ 905 //else if (class == 8 && subclass == 6 && !strcmp(action, "remove")) 906 else if (class == 8 && !strcmp(action, "remove")) 907 /* Foxconn modified end pling 11/11/2009 */ 908 { 909 USB_LOCK(); // Foxconn added pling 07/13/2009 910 usb_umount(); 911 USB_UNLOCK(); // Foxconn added pling 07/13/2009 912 } 913 914 //eval("/usr/bin/setsmbftpconf"); 915#ifdef USB_HOTPLUG_DBG//debug 916 system("echo \"/usr/bin/setsmbftpconf\">>/tmp/usberr.log"); 917#endif 918 return 0; 919} 920