2004-01-20 21:32:43 +03:00
/*
* Guillaume Cottenceau ( gc @ mandrakesoft . com )
*
* Copyright 2000 MandrakeSoft
*
* This software may be freely redistributed under the terms of the GNU
* public license .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
*/
/*
* Portions from Erik Troan ( ewt @ redhat . com )
*
* Copyright 1996 Red Hat Software
*
*/
/*
* This contains stuff related to probing :
* ( 1 ) any ( actually only SCSI , NET , CPQ , USB Controllers ) devices ( autoprobe for PCI and USB )
* ( 2 ) IDE media
* ( 3 ) SCSI media
* ( 4 ) ETH devices
*/
# include <stdlib.h>
# include <unistd.h>
# include <stdio.h>
# include <string.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
// #include <sys/socket.h>
# include <net/if.h>
# include <sys/ioctl.h>
# include <sys/mount.h>
2007-02-27 16:11:49 +03:00
# include <dirent.h>
2004-01-20 21:32:43 +03:00
# include "stage1.h"
# include "log.h"
# include "frontend.h"
# include "modules.h"
# include "probing.h"
struct media_info {
char * name ;
char * model ;
enum media_type type ;
} ;
2004-12-15 23:43:02 +03:00
struct pci_module_map {
unsigned short vendor ; /* PCI vendor id */
unsigned short device ; /* PCI device id */
char * module ; /* module to load */
struct pci_module_map * next ;
} ;
struct usb_module_map {
unsigned short vendor ; /* PCI vendor id */
unsigned short device ; /* PCI device id */
char * module ; /* module to load */
struct usb_module_map * next ;
} ;
char * usb_hcd [ ] = {
" uhci-hcd " ,
" ohci-hcd " ,
" ehci-hcd " ,
} ;
# define HCD_NUM (sizeof(usb_hcd) / sizeof(char *))
2004-01-20 21:32:43 +03:00
static void warning_insmod_failed ( enum insmod_return r )
{
if ( IS_AUTOMATIC & & r = = INSMOD_FAILED_FILE_NOT_FOUND )
return ;
if ( r ! = INSMOD_OK ) {
if ( r = = INSMOD_FAILED_FILE_NOT_FOUND )
stg1_error_message ( " This floppy doesn't contain the driver. " ) ;
else
stg1_error_message ( " Warning, installation of driver failed. (please include msg from <Alt-F3> for bugreports) " ) ;
}
}
# ifndef DISABLE_NETWORK
struct net_description_elem
{
char * intf_name ;
char * intf_description ;
} ;
static struct net_description_elem net_descriptions [ 50 ] ;
static int net_descr_number = 0 ;
static char * intf_descr_for_discover = NULL ;
static char * net_intf_too_early_name [ 50 ] ; /* for modules providing more than one net intf */
static int net_intf_too_early_number = 0 ;
static int net_intf_too_early_ptr = 0 ;
void prepare_intf_descr ( const char * intf_descr )
{
intf_descr_for_discover = strdup ( intf_descr ) ;
}
void net_discovered_interface ( char * intf_name )
{
if ( ! intf_descr_for_discover ) {
net_intf_too_early_name [ net_intf_too_early_number + + ] = strdup ( intf_name ) ;
return ;
}
if ( ! intf_name ) {
if ( net_intf_too_early_ptr > = net_intf_too_early_number ) {
log_message ( " NET: was expecting another network interface (broken net module?) " ) ;
return ;
}
net_descriptions [ net_descr_number ] . intf_name = net_intf_too_early_name [ net_intf_too_early_ptr + + ] ;
}
else
net_descriptions [ net_descr_number ] . intf_name = strdup ( intf_name ) ;
net_descriptions [ net_descr_number ] . intf_description = strdup ( intf_descr_for_discover ) ;
intf_descr_for_discover = NULL ;
net_descr_number + + ;
}
char * get_net_intf_description ( char * intf_name )
{
int i ;
for ( i = 0 ; i < net_descr_number ; i + + )
if ( ! strcmp ( net_descriptions [ i ] . intf_name , intf_name ) )
return net_descriptions [ i ] . intf_description ;
return strdup ( " unknown " ) ;
}
# endif
2004-12-15 23:43:02 +03:00
static struct pci_module_map * get_pci_ids ( )
{
static struct pci_module_map * pcidb = NULL ;
struct pci_module_map * last , * new ;
char buf [ 50 ] ;
int v , d ;
FILE * f ;
if ( pcidb ) return pcidb ;
log_message ( " loading pcimap file " ) ;
if ( ! ( f = fopen ( " /modules/modules.map " , " rb " ) ) ) {
log_message ( " couldn't open pcimap file " ) ;
return NULL ;
}
while ( 3 = = ( fscanf ( f , " %x %x %48s " , & v , & d , buf ) ) ) {
new = ( struct pci_module_map * ) malloc ( sizeof ( * pcidb ) ) ;
new - > vendor = v ;
new - > device = d ;
new - > module = strdup ( buf ) ;
new - > next = NULL ;
if ( ! pcidb ) {
pcidb = last = new ;
} else {
last - > next = new ;
last = new ;
}
}
fclose ( f ) ;
return pcidb ;
}
2005-01-21 20:03:46 +03:00
/* forward */
static void probe_that_type ( enum driver_type type ) ;
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
/* ---- PCI probe ---------------------------------------------- */
static void pci_probe ( enum driver_type type )
{
FILE * f ;
int n ;
char buf [ 200 ] ;
char devname [ 22 ] ;
u_int8_t devdata [ 48 ] ;
static int need_usb_hcd [ HCD_NUM ] ;
struct pci_module_map * pci_ids = NULL ;
int that_class ;
2004-12-15 23:43:02 +03:00
2005-01-21 20:03:46 +03:00
switch ( type ) {
case SCSI_ADAPTERS :
that_class = PCI_CLASS_STORAGE_SCSI < < 8 ;
break ;
2005-02-15 23:33:05 +03:00
case IDE_ADAPTERS :
that_class = PCI_CLASS_STORAGE_IDE < < 8 ;
break ;
2006-11-23 18:45:18 +03:00
case RAID_ADAPTERS :
that_class = PCI_CLASS_STORAGE_RAID < < 8 ;
break ;
2005-01-21 20:03:46 +03:00
case NETWORK_DEVICES :
that_class = PCI_CLASS_NETWORK_ETHERNET < < 8 ;
break ;
2006-01-24 17:40:50 +03:00
case BRIDGE_OTHER :
that_class = PCI_CLASS_BRIDGE_OTHER < < 8 ;
break ;
2005-01-21 20:03:46 +03:00
case USB_CONTROLLERS :
that_class = PCI_CLASS_SERIAL_USB < < 8 ;
break ;
default :
return ;
}
2004-12-15 23:43:02 +03:00
2005-01-21 20:03:46 +03:00
if ( NULL = = ( pci_ids = get_pci_ids ( ) ) ) {
log_message ( " PCI: could not get pci ids " ) ;
return ;
}
2004-12-15 23:43:02 +03:00
2007-03-01 19:25:26 +03:00
if ( ! ( f = fopen ( " /proc/bus/pci/devices " , " r " ) ) ) {
2005-01-21 20:03:46 +03:00
log_message ( " PCI: could not open proc file " ) ;
return ;
}
2004-11-22 16:47:29 +03:00
2005-01-21 20:03:46 +03:00
while ( NULL ! = fgets ( buf , sizeof ( buf ) , f ) ) {
2005-02-07 20:55:26 +03:00
int i , matched , dfn , vendor , device , class , subv , subid ;
2005-01-21 20:03:46 +03:00
struct pci_module_map * pcidb ;
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
sscanf ( buf , " %x %x " , & dfn , & vendor ) ;
device = vendor & 0xFFFF ; /* because scanf from dietlibc does not support %4f */
vendor = ( vendor > > 16 ) & 0xFFFF ;
snprintf ( devname , sizeof ( devname ) , " /proc/bus/pci/%02x/%02x.%x " ,
dfn > > 8 , PCI_SLOT ( dfn & 0xff ) , PCI_FUNC ( dfn & 0xff ) ) ;
log_message ( " gathering info for %s " , devname ) ;
if ( ( i = open ( devname , O_RDONLY ) ) ! = - 1 ) {
read ( i , devdata , sizeof ( devdata ) ) ;
close ( i ) ;
} else continue ;
class = devdata [ 9 ] | ( devdata [ 10 ] < < 8 ) | ( devdata [ 11 ] < < 16 ) ;
subv = devdata [ 0x2c ] | ( devdata [ 0x2d ] < < 8 ) ;
subid = devdata [ 0x2e ] | ( devdata [ 0x2f ] < < 8 ) ;
2004-11-22 16:47:29 +03:00
2005-02-07 20:55:26 +03:00
if ( that_class ! = ( class & 0xffff00 ) ) continue ;
2005-01-21 20:03:46 +03:00
log_message ( " found pci device: %04x %04x %06x %04x %04x " ,
vendor , device , class , subv , subid ) ;
2004-11-22 16:47:29 +03:00
2005-02-07 20:55:26 +03:00
for ( matched = 0 , pcidb = pci_ids ; pcidb ; pcidb = pcidb - > next ) {
if ( pcidb - > vendor = = vendor & & pcidb - > device = = device ) {
/* vendor & device matched */
log_message ( " (pcimap) module is \" %s \" " , pcidb - > module ) ;
2004-01-20 21:32:43 +03:00
# ifndef DISABLE_MEDIAS
2006-11-23 18:45:18 +03:00
if ( type = = IDE_ADAPTERS | | type = = SCSI_ADAPTERS | | type = = RAID_ADAPTERS ) {
2005-01-21 20:03:46 +03:00
int wait_msg = 0 ;
enum insmod_return failed ;
if ( IS_AUTOMATIC ) {
2006-11-23 18:45:18 +03:00
wait_message ( " Loading driver for storage adapter: %s " , pcidb - > module ) ;
2005-01-21 20:03:46 +03:00
wait_msg = 1 ;
} else
2006-11-23 18:45:18 +03:00
stg1_info_message ( " About to load driver for storage adapter: %s " , pcidb - > module ) ;
2005-02-15 23:33:05 +03:00
failed = my_insmod ( pcidb - > module , type , NULL ) ;
2005-01-21 20:03:46 +03:00
if ( wait_msg )
remove_wait_message ( ) ;
warning_insmod_failed ( failed ) ;
}
2004-11-22 16:47:29 +03:00
# endif /* DISABLE_MEDIAS */
2004-01-20 21:32:43 +03:00
# ifndef DISABLE_NETWORK
2006-01-24 17:40:50 +03:00
if ( type = = NETWORK_DEVICES | | type = = BRIDGE_OTHER ) {
2005-03-02 23:12:09 +03:00
int wait_msg = 0 ;
enum insmod_return failed ;
if ( IS_AUTOMATIC ) {
wait_message ( " Loading driver for network device: %s " , pcidb - > module ) ;
wait_msg = 1 ;
} else
stg1_info_message ( " About to load driver for network device: %s " ,
pcidb - > module ) ;
2005-01-21 20:03:46 +03:00
prepare_intf_descr ( pcidb - > module ) ;
2006-01-24 17:40:50 +03:00
failed = my_insmod ( pcidb - > module , type , NULL ) ;
2005-03-02 23:12:09 +03:00
if ( wait_msg )
remove_wait_message ( ) ;
warning_insmod_failed ( failed ) ;
2005-01-21 20:03:46 +03:00
if ( intf_descr_for_discover ) /* for modules providing more than one net intf */
net_discovered_interface ( NULL ) ;
}
2004-11-22 16:47:29 +03:00
# endif /* DISABLE_NETWORK */
2005-01-21 20:03:46 +03:00
if ( type = = USB_CONTROLLERS ) {
/* found explicitly declared module */
for ( i = 0 ; i < HCD_NUM ; i + + ) {
if ( ptr_begins_static_str ( pcidb - > module , usb_hcd [ i ] ) ) {
need_usb_hcd [ i ] = 1 ;
break ;
2004-11-22 16:47:29 +03:00
}
}
}
2005-02-07 20:55:26 +03:00
matched = 1 ;
break ;
2004-01-20 21:32:43 +03:00
}
2005-02-07 20:55:26 +03:00
} /* end of pcidb table */
2005-08-19 20:08:40 +04:00
# ifndef DISABLE_MEDIAS
if ( ! matched & & type = = IDE_ADAPTERS ) {
/* probe ide-generic as last resort */
2005-10-28 19:05:40 +04:00
log_message ( " (guess) module is \" ide-generic \" " ) ;
2005-08-19 20:08:40 +04:00
int wait_msg = 0 ;
enum insmod_return failed ;
if ( IS_AUTOMATIC ) {
wait_message ( " Loading driver for IDE adapter: ide-generic " ) ;
wait_msg = 1 ;
} else
stg1_info_message ( " About to load driver for IDE adapter: ide-generic " ) ;
failed = my_insmod ( " ide-generic " , type , NULL ) ;
if ( wait_msg )
remove_wait_message ( ) ;
warning_insmod_failed ( failed ) ;
}
# endif /* DISABLE_MEDIAS */
2005-02-07 20:55:26 +03:00
if ( ! matched & & type = = USB_CONTROLLERS & & ( class & 0xffff0f ) = = 0x0c0300 ) {
/* no module found, trying to identify one by class:
HCD : PCI Class :
uhci - hcd 0x000c0300
ohci - hcd 0x000c0310
ehci - hcd 0x000c0320
*/
log_message ( " (guess) module is \" %s \" " , usb_hcd [ ( class & 0xf0 ) > > 4 ] ) ;
need_usb_hcd [ ( class & 0xf0 ) > > 4 ] = 1 ;
}
} /* end of this vendor & device */
2005-01-21 20:03:46 +03:00
fclose ( f ) ;
/* load all usb controller modules now, starting from possible ehci-hcd */
/* to prevent case when old-timed module sitting on newer host controller */
if ( type = = USB_CONTROLLERS ) {
2006-11-23 18:45:18 +03:00
enum insmod_return failed ;
2005-02-07 20:55:26 +03:00
for ( n = HCD_NUM - 1 ; n > = 0 ; n - - ) {
2005-01-21 20:03:46 +03:00
if ( need_usb_hcd [ n ] ) {
2006-11-23 18:45:18 +03:00
/* do it AUTOMATIC -- for usb kbd case */
/* and ever silent
wait_message ( " Loading driver for USB controller: %s " , usb_hcd [ n ] ) ;
*/
failed = my_insmod ( usb_hcd [ n ] , USB_CONTROLLERS , NULL ) ;
/*
remove_wait_message ( ) ;
*/
warning_insmod_failed ( failed ) ;
2005-01-21 20:03:46 +03:00
}
2004-01-20 21:32:43 +03:00
}
}
2005-01-21 20:03:46 +03:00
}
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
/* ---- USB probe ---------------------------------------------- */
static void usb_probe ( enum driver_type type )
{
static int already_probed_usb_controllers = 0 ;
static int already_mounted_usbdev = 0 ;
2006-11-23 18:45:18 +03:00
static int already_probed_hid = 0 ;
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
FILE * f ;
char buf [ 200 ] ;
static struct usb_module_map * usb_ids = NULL ;
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
switch ( type ) {
2004-01-20 21:32:43 +03:00
# ifdef ENABLE_USBNET
2005-01-21 20:03:46 +03:00
case NETWORK_DEVICES :
2004-01-20 21:32:43 +03:00
# endif
2005-03-03 15:37:10 +03:00
case MEDIA_ADAPTERS :
2006-11-23 18:45:18 +03:00
case HID_DEVICES :
2005-01-21 20:03:46 +03:00
break ;
default :
return ;
}
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
if ( ! already_probed_usb_controllers ) {
already_probed_usb_controllers = 1 ;
2006-11-23 18:45:18 +03:00
probe_that_type ( USB_CONTROLLERS ) ;
2005-01-21 20:03:46 +03:00
}
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
if ( ! already_mounted_usbdev ) {
already_mounted_usbdev = 1 ;
if ( mount ( " /proc/bus/usb " , " /proc/bus/usb " , " usbfs " , 0 , NULL ) ) {
log_message ( " USB: couldn't mount /proc/bus/usb " ) ;
return ;
2004-11-22 16:47:29 +03:00
}
2006-11-23 18:45:18 +03:00
/* no need to show wait message -- we're doing this very first
wait_message ( " Waiting for USB stuff to show up. " ) ;
*/
2005-01-21 20:03:46 +03:00
sleep ( 2 ) ; /* sucking background work */
2006-11-23 18:45:18 +03:00
/*
remove_wait_message ( ) ;
*/
2005-01-21 20:03:46 +03:00
}
2004-11-22 16:47:29 +03:00
2005-02-07 20:55:26 +03:00
/* dirty hacks */
2005-03-03 15:37:10 +03:00
if ( type = = MEDIA_ADAPTERS ) {
2005-01-21 20:03:46 +03:00
stg1_info_message ( " About to load driver for usb storage device: usb-storage " ) ;
my_insmod ( " usb-storage " , ANY_DRIVER_TYPE , NULL ) ;
2005-03-03 16:36:28 +03:00
sleep ( 5 ) ; /* wait for dust settles down */
2005-01-21 20:03:46 +03:00
}
2004-01-20 21:32:43 +03:00
2005-02-07 20:55:26 +03:00
# ifdef ENABLE_USBNET
if ( type = = NETWORK_DEVICES ) {
stg1_info_message ( " About to load driver for usb network device: usbnet " ) ;
my_insmod ( " usbnet " , ANY_DRIVER_TYPE , NULL ) ;
}
# endif
2007-03-01 19:25:26 +03:00
if ( ! ( f = fopen ( " /proc/bus/usb/devices " , " r " ) ) ) {
2005-01-21 20:03:46 +03:00
log_message ( " USB: could not open proc file " ) ;
return ;
}
2004-01-20 21:32:43 +03:00
2006-11-23 18:45:18 +03:00
if ( type = = HID_DEVICES & & ! already_probed_hid ) {
while ( NULL ! = fgets ( buf , sizeof ( buf ) , f ) ) {
2006-11-24 17:58:05 +03:00
if ( strstr ( buf , " Cls=03 " ) ) {
2006-11-23 18:45:18 +03:00
my_insmod ( " usbhid " , ANY_DRIVER_TYPE , NULL ) ;
already_probed_hid = 1 ;
break ;
2004-01-20 21:32:43 +03:00
}
}
}
2006-11-23 18:45:18 +03:00
2005-01-21 20:03:46 +03:00
fclose ( f ) ;
2004-01-20 21:32:43 +03:00
}
2005-01-21 20:03:46 +03:00
static void probe_that_type ( enum driver_type type )
{
if ( IS_EXPERT ) {
ask_insmod ( type ) ;
return ;
}
2005-03-03 15:37:10 +03:00
if ( type = = MEDIA_ADAPTERS ) {
2005-04-21 15:06:44 +04:00
update_splash ( ) ;
2005-03-03 15:37:10 +03:00
pci_probe ( IDE_ADAPTERS ) ;
2005-04-21 15:06:44 +04:00
update_splash ( ) ;
2005-03-03 15:37:10 +03:00
pci_probe ( SCSI_ADAPTERS ) ;
2005-04-21 15:06:44 +04:00
update_splash ( ) ;
2006-11-23 18:45:18 +03:00
pci_probe ( RAID_ADAPTERS ) ;
update_splash ( ) ;
2005-03-03 15:37:10 +03:00
usb_probe ( MEDIA_ADAPTERS ) ;
2005-04-21 15:06:44 +04:00
update_splash ( ) ;
2005-03-03 15:37:10 +03:00
} else {
2005-04-21 15:06:44 +04:00
update_splash ( ) ;
2005-03-03 15:37:10 +03:00
pci_probe ( type ) ;
2005-04-21 15:06:44 +04:00
update_splash ( ) ;
2005-03-03 15:37:10 +03:00
usb_probe ( type ) ;
2005-04-21 15:06:44 +04:00
update_splash ( ) ;
2005-03-03 15:37:10 +03:00
}
2005-01-21 20:03:46 +03:00
}
2004-01-20 21:32:43 +03:00
# ifndef DISABLE_MEDIAS
static struct media_info * medias = NULL ;
2007-03-01 19:25:26 +03:00
static void find_media ( void )
2007-02-27 16:11:49 +03:00
{
2007-03-01 19:25:26 +03:00
FILE * f ;
2007-02-27 16:11:49 +03:00
DIR * dir = NULL ;
struct dirent * dirent = NULL ;
struct stat st ;
2007-03-01 19:25:26 +03:00
struct media_info tmp [ 50 ] ;
2007-02-27 16:11:49 +03:00
char path [ SYSFS_PATH_MAX ] ;
2007-03-01 19:25:26 +03:00
char buf [ 512 ] ;
2007-02-27 16:11:49 +03:00
char * s ;
2007-03-01 19:25:26 +03:00
int count = 0 ;
if ( ! medias )
probe_that_type ( MEDIA_ADAPTERS ) ;
else
free ( medias ) ; /* that does not free the strings, by the way */
2007-02-27 16:11:49 +03:00
if ( ( dir = opendir ( " /sys/block " ) ) = = NULL ) {
log_message ( " failed to open /sys/block directory " ) ;
return ;
}
while ( ( dirent = readdir ( dir ) ) ! = NULL ) {
2007-03-01 19:25:26 +03:00
if ( ! strcmp ( dirent - > d_name , " . " ) | |
! strcmp ( dirent - > d_name , " .. " ) ) continue ;
2007-02-27 16:11:49 +03:00
memset ( path , 0 , SYSFS_PATH_MAX ) ;
strcpy ( path , " /sys/block/ " ) ;
strcat ( path , dirent - > d_name ) ;
s = path + strlen ( path ) ;
2004-01-20 21:32:43 +03:00
2007-03-01 19:25:26 +03:00
/* probe for scsi type */
strcat ( path , " /device/type " ) ;
if ( lstat ( path , & st ) = = 0 & & S_ISREG ( st . st_mode ) ) {
tmp [ count ] . name = strdup ( dirent - > d_name ) ;
tmp [ count ] . type = UNKNOWN_MEDIA ;
if ( ( f = fopen ( path , " r " ) ) ! = NULL ) {
int type ;
if ( fscanf ( f , " %d " , & type ) ) {
if ( type = = SCSI_TYPE_DISK ) tmp [ count ] . type = DISK ;
else if ( type = = SCSI_TYPE_ROM ) tmp [ count ] . type = CDROM ;
else if ( type = = SCSI_TYPE_TAPE ) tmp [ count ] . type = TAPE ;
}
fclose ( f ) ;
}
2004-01-20 21:32:43 +03:00
2007-03-01 19:25:26 +03:00
* s = 0 ;
strcat ( path , " /device/model " ) ;
if ( ( f = fopen ( path , " r " ) ) ! = NULL ) {
if ( fgets ( buf , sizeof ( buf ) , f ) ) {
tmp [ count ] . model = strdup ( buf ) ;
}
fclose ( f ) ;
} else {
tmp [ count ] . model = strdup ( " (unknown) " ) ;
}
2004-01-20 21:32:43 +03:00
2007-03-01 19:25:26 +03:00
log_message ( " SCSI/%d: %s is a %s " , tmp [ count ] . type , tmp [ count ] . name , tmp [ count ] . model ) ;
count + + ;
2004-01-20 21:32:43 +03:00
continue ;
}
2007-03-01 19:25:26 +03:00
/* assume ide */
* s = 0 ;
strcat ( s , " /device/media " ) ;
if ( lstat ( path , & st ) = = 0 & & S_ISREG ( st . st_mode ) ) {
tmp [ count ] . name = strdup ( dirent - > d_name ) ;
2004-01-20 21:32:43 +03:00
tmp [ count ] . type = UNKNOWN_MEDIA ;
2007-03-01 19:25:26 +03:00
log_message ( " IDE: name: %s " , dirent - > d_name ) ;
if ( ( f = fopen ( path , " r " ) ) ! = NULL ) {
if ( fgets ( buf , sizeof ( buf ) , f ) ) {
log_message ( " IDE: type: %s " , buf ) ;
if ( ! strncmp ( " disk " , buf , 4 ) )
2004-01-20 21:32:43 +03:00
tmp [ count ] . type = DISK ;
2007-03-01 19:25:26 +03:00
else if ( ! strncmp ( " cdrom " , buf , 5 ) )
tmp [ count ] . type = CDROM ;
else if ( ! strncmp ( " tape " , buf , 4 ) )
tmp [ count ] . type = TAPE ;
else if ( ! strncmp ( " floppy " , buf , 6 ) )
tmp [ count ] . type = FLOPPY ;
2004-01-20 21:32:43 +03:00
}
2007-03-01 19:25:26 +03:00
fclose ( f ) ;
2004-01-20 21:32:43 +03:00
}
2007-03-01 19:25:26 +03:00
/* grab model */
strcpy ( path , " /proc/ide/ " ) ;
strcat ( path , dirent - > d_name ) ;
strcat ( path , " /model " ) ;
if ( ( f = fopen ( path , " r " ) ) ! = NULL ) {
if ( fgets ( buf , sizeof ( buf ) , f ) ) {
tmp [ count ] . model = strdup ( buf ) ;
2004-01-20 21:32:43 +03:00
}
2007-03-01 19:25:26 +03:00
fclose ( f ) ;
} else {
tmp [ count ] . model = strdup ( " (none) " ) ;
2004-01-20 21:32:43 +03:00
}
2007-03-01 19:25:26 +03:00
log_message ( " IDE/%d: %s is a %s " , tmp [ count ] . type , tmp [ count ] . name , tmp [ count ] . model ) ;
count + + ;
2004-01-20 21:32:43 +03:00
}
}
2007-03-01 19:25:26 +03:00
closedir ( dir ) ;
2004-01-20 21:32:43 +03:00
tmp [ count ] . name = NULL ;
count + + ;
medias = memdup ( tmp , sizeof ( struct media_info ) * count ) ;
}
/* Finds by media */
void get_medias ( enum media_type media , char * * * names , char * * * models )
{
struct media_info * m ;
char * tmp_names [ 50 ] ;
char * tmp_models [ 50 ] ;
int count ;
find_media ( ) ;
m = medias ;
count = 0 ;
while ( m & & m - > name ) {
if ( m - > type = = media ) {
tmp_names [ count ] = strdup ( m - > name ) ;
tmp_models [ count + + ] = strdup ( m - > model ) ;
}
m + + ;
}
tmp_names [ count ] = NULL ;
tmp_models [ count + + ] = NULL ;
* names = memdup ( tmp_names , sizeof ( char * ) * count ) ;
* models = memdup ( tmp_models , sizeof ( char * ) * count ) ;
}
# endif /* DISABLE_MEDIAS */
2006-11-23 18:45:18 +03:00
void probe_hiddev ( )
{
usb_probe ( HID_DEVICES ) ;
}
2004-01-20 21:32:43 +03:00
# ifndef DISABLE_NETWORK
2004-11-22 16:47:29 +03:00
int net_device_available ( char * device )
{
2004-01-20 21:32:43 +03:00
struct ifreq req ;
int s ;
s = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
if ( s < 0 ) {
log_perror ( device ) ;
return 0 ;
}
strcpy ( req . ifr_name , device ) ;
if ( ioctl ( s , SIOCGIFFLAGS , & req ) ) {
/* if we can't get the flags, the networking device isn't available */
close ( s ) ;
return 0 ;
}
close ( s ) ;
return 1 ;
}
char * * get_net_devices ( void )
{
char * devices [ ] = {
" eth0 " , " eth1 " , " eth2 " , " eth3 " , " eth4 " , " eth5 " ,
" tr0 " ,
" plip0 " , " plip1 " , " plip2 " ,
" fddi0 " ,
# ifdef ENABLE_USBNET
" usb0 " , " usb1 " , " usb2 " , " usb3 " ,
# endif
NULL
} ;
char * * ptr = devices ;
char * tmp [ 50 ] ;
int i = 0 ;
static int already_probed = 0 ;
if ( ! already_probed ) {
already_probed = 1 ; /* cut off loop brought by: probe_that_type => my_insmod => get_net_devices */
probe_that_type ( NETWORK_DEVICES ) ;
2006-01-24 17:40:50 +03:00
/* for some chipsets having nic in it, i.e. nForcex */
probe_that_type ( BRIDGE_OTHER ) ;
2004-01-20 21:32:43 +03:00
}
while ( ptr & & * ptr ) {
if ( net_device_available ( * ptr ) )
tmp [ i + + ] = strdup ( * ptr ) ;
ptr + + ;
}
tmp [ i + + ] = NULL ;
return memdup ( tmp , sizeof ( char * ) * i ) ;
}
# endif /* DISABLE_NETWORK */