@@ -602,6 +602,7 @@ struct device HIDDEN
602602}
603603
604604int HIDDEN
605+ /* FIXME Rename */
605606make_blockdev_path (uint8_t * buf , ssize_t size , struct device * dev )
606607{
607608 ssize_t off = 0 ;
@@ -635,23 +636,25 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
635636{
636637 struct ifreq ifr ;
637638 struct ethtool_drvinfo drvinfo = { 0 , };
638- int fd = -1 , rc ;
639+ int fd = -1 , rc , i ;
640+ unsigned int n = 0 ;
639641 ssize_t ret = -1 , sz , off = 0 ;
640- char busname [ PATH_MAX + 1 ] = "" ;
641- struct device dev ;
642+ struct device devbuf ;
643+ struct device * dev = & devbuf ;
642644
643- memset (& dev , 0 , sizeof (dev ));
644- dev . interface_type = network ;
645- dev . ifname = strdupa (ifname );
646- if (!dev . ifname )
645+ memset (dev , 0 , sizeof (* dev ));
646+ dev -> interface_type = network ;
647+ dev -> ifname = strdupa (ifname );
648+ if (!dev -> ifname )
647649 return -1 ;
650+ dev -> driver = "" ;
648651
649652 /*
650653 * find the device link, which looks like:
651654 * ../../devices/$PCI_STUFF/net/$IFACE
652655 */
653- rc = sysfs_readlink (& dev . link , "class/net/%s" , ifname );
654- if (rc < 0 || !dev . link )
656+ rc = sysfs_readlink (& ( dev -> link ) , "class/net/%s" , ifname );
657+ if (rc < 0 || !dev -> link )
655658 goto err ;
656659
657660 memset (& ifr , 0 , sizeof (ifr ));
@@ -668,13 +671,106 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
668671 if (rc < 0 )
669672 goto err ;
670673
671- strncpy (busname , drvinfo .bus_info , PATH_MAX );
674+ /*
675+ * FIXME: copy/paste of device_get()
676+ */
677+ size_t nmemb = (sizeof (dev_probes )
678+ / sizeof (dev_probes [0 ])) + 1 ;
679+
680+ dev -> probes = calloc (nmemb , sizeof (struct dev_probe * ));
681+ if (!dev -> probes ) {
682+ efi_error ("could not allocate %zd bytes" ,
683+ nmemb * sizeof (struct dev_probe * ));
684+ goto err ;
685+ }
686+
687+ const char * current = dev -> link ;
688+ bool needs_root = true;
689+ int last_successful_probe = -1 ;
690+
691+ debug ("searching for device nodes in %s" , dev -> link );
692+ for (i = 0 ;
693+ dev_probes [i ] && dev_probes [i ]-> parse && * current ;
694+ i ++ ) {
695+ struct dev_probe * probe = dev_probes [i ];
696+ int pos ;
697+
698+ if (!needs_root &&
699+ (probe -> flags & DEV_PROVIDES_ROOT )) {
700+ debug ("not testing %s because flags is 0x%x" ,
701+ probe -> name , probe -> flags );
702+ continue ;
703+ }
704+
705+ debug ("trying %s" , probe -> name );
706+ pos = probe -> parse (dev , current , dev -> link );
707+ if (pos < 0 ) {
708+ efi_error ("parsing %s failed" , probe -> name );
709+ goto err ;
710+ } else if (pos > 0 ) {
711+ char match [pos + 1 ];
712+
713+ strncpy (match , current , pos );
714+ match [pos ] = '\0' ;
715+ debug ("%s matched '%s'" , probe -> name , match );
716+ dev -> flags |= probe -> flags ;
717+
718+ if (probe -> flags & DEV_PROVIDES_ROOT ||
719+ probe -> flags & DEV_ABBREV_ONLY )
720+ needs_root = false;
721+
722+ /* FIXME: useless code */
723+ if (probe -> create )
724+ print_dev_dp_node (dev , probe );
725+
726+ dev -> probes [n ++ ] = dev_probes [i ];
727+ current += pos ;
728+ if (current [0 ] == '\0' )
729+ debug ("finished" );
730+ else
731+ debug ("current:'%s'" , current );
732+ last_successful_probe = i ;
733+
734+ if (!* current || !strncmp (current , "net/" , 4 ))
735+ break ;
736+
737+ continue ;
738+ }
739+
740+ debug ("dev_probes[%d]: %p dev->interface_type: %d\n" ,
741+ i + 1 , dev_probes [i + 1 ], dev -> interface_type );
742+ if (dev_probes [i + 1 ] == NULL && dev -> interface_type == unknown ) {
743+ pos = 0 ;
744+ rc = sscanf (current , "%*[^/]/%n" , & pos );
745+ if (rc < 0 ) {
746+ slash_err :
747+ efi_error ("Cannot parse device link segment \"%s\"" , current );
748+ goto err ;
749+ }
750+
751+ while (current [pos ] == '/' )
752+ pos += 1 ;
753+
754+ if (!current [pos ])
755+ goto slash_err ;
756+
757+ debug ("Cannot parse device link segment '%s'" , current );
758+ debug ("Skipping to '%s'" , current + pos );
759+ debug ("This means we can only create abbreviated paths" );
760+ dev -> flags |= DEV_ABBREV_ONLY ;
761+ i = last_successful_probe ;
762+ current += pos ;
763+
764+ if (!* current || !strncmp (current , "net/" , 4 ))
765+ break ;
766+ }
767+ }
672768
673769 rc = ioctl (fd , SIOCGIFHWADDR , & ifr );
674770 if (rc < 0 )
675771 goto err ;
676772
677- sz = pci_parser . create ( & dev , buf , size , off );
773+ sz = make_blockdev_path ( buf , size , dev );
678774 if (sz < 0 )
679775 goto err ;
680776 off += sz ;
@@ -687,10 +783,13 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
687783 goto err ;
688784
689785 off += sz ;
786+
690787 ret = off ;
691788err :
692789 if (fd >= 0 )
693790 close (fd );
791+ if (dev -> probes )
792+ free (dev -> probes );
694793 return ret ;
695794}
696795
0 commit comments