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>
# 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 ;
2005-01-21 20:03:46 +03:00
case NETWORK_DEVICES :
that_class = PCI_CLASS_NETWORK_ETHERNET < < 8 ;
break ;
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
2005-01-21 20:03:46 +03:00
if ( ! ( f = fopen ( " /proc/bus/pci/devices " , " rb " ) ) ) {
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
2005-03-03 15:37:10 +03:00
if ( type = = IDE_ADAPTERS | | type = = SCSI_ADAPTERS ) {
2005-01-21 20:03:46 +03:00
int wait_msg = 0 ;
enum insmod_return failed ;
if ( IS_AUTOMATIC ) {
2005-03-02 21:51:34 +03:00
wait_message ( " Loading driver for %s adapter: %s " ,
2005-02-15 23:33:05 +03:00
type = = SCSI_ADAPTERS ? " SCSI " : " IDE " , pcidb - > module ) ;
2005-01-21 20:03:46 +03:00
wait_msg = 1 ;
} else
2005-03-02 21:51:34 +03:00
stg1_info_message ( " About to load driver for %s adapter: %s " ,
2005-02-15 23:33:05 +03:00
type = = SCSI_ADAPTERS ? " SCSI " : " IDE " , pcidb - > module ) ;
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
2005-01-21 20:03:46 +03:00
if ( type = = NETWORK_DEVICES ) {
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 ) ;
2005-03-02 23:12:09 +03:00
failed = my_insmod ( pcidb - > module , NETWORK_DEVICES , NULL ) ;
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 */
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 ) {
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 ] ) {
stg1_info_message ( " About to load driver for usb controller: %s " , usb_hcd [ n ] ) ;
my_insmod ( usb_hcd [ n ] , USB_CONTROLLERS , NULL ) ;
}
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 ;
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 :
/*
usbdb = usbnet_usb_ids ;
*/
break ;
2004-01-20 21:32:43 +03:00
# endif
2005-03-03 15:37:10 +03:00
case MEDIA_ADAPTERS :
2005-01-21 20:03:46 +03:00
/*
usbdb = usbstorage_usb_ids ;
*/
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 ;
probe_that_type ( USB_CONTROLLERS ) ;
}
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
}
2005-01-21 20:03:46 +03:00
wait_message ( " Waiting for USB stuff to show up. " ) ;
sleep ( 2 ) ; /* sucking background work */
remove_wait_message ( ) ;
}
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
2005-01-21 20:03:46 +03:00
if ( ! ( f = fopen ( " /proc/bus/usb/devices " , " rb " ) ) ) {
log_message ( " USB: could not open proc file " ) ;
return ;
}
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
while ( NULL ! = fgets ( buf , sizeof ( buf ) , f ) ) {
int vendor , device ;
struct usb_module_map * usbdb ;
if ( strstr ( buf , " Keyboard " ) ) {
my_insmod ( " usbkbd " , ANY_DRIVER_TYPE , NULL ) ;
my_insmod ( " keybdev " , ANY_DRIVER_TYPE , NULL ) ;
}
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
if ( sscanf ( buf , " P: Vendor=%x ProdID=%x " , & vendor , & device ) ! = 2 )
continue ;
2004-01-20 21:32:43 +03:00
2005-01-21 20:03:46 +03:00
for ( usbdb = usb_ids ; usbdb ; usbdb = usbdb - > next ) {
if ( usbdb - > vendor = = vendor & & usbdb - > device = = device ) {
log_message ( " USB: device %04x %04x is \" %s \" " , vendor , device , usbdb - > module ) ;
2004-01-20 21:32:43 +03:00
# ifdef ENABLE_USBNET
2005-01-21 20:03:46 +03:00
if ( type = = NETWORK_DEVICES ) {
stg1_info_message ( " About to load driver for usb network device: \n \n %s " , usbdb - > module ) ;
prepare_intf_descr ( usbdb - > module ) ;
warning_insmod_failed ( my_insmod ( usbdb - > module , NETWORK_DEVICES , NULL ) ) ;
if ( intf_descr_for_discover ) /* for modules providing more than one net intf */
net_discovered_interface ( NULL ) ;
2004-01-20 21:32:43 +03:00
}
2005-01-21 20:03:46 +03:00
# endif
2004-01-20 21:32:43 +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 ( ) ;
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 ;
2005-01-21 20:03:46 +03:00
int find_scsi_media ( char * buf , struct media_info * media )
{
enum { SCSI_TOP , SCSI_HOST , SCSI_VENDOR , SCSI_TYPE } state = SCSI_TOP ;
char * start , * chptr , * next , * end ;
char scsi_disk_count = ' a ' ;
char scsi_cdrom_count = ' 0 ' ;
char scsi_tape_count = ' 0 ' ;
char scsi_no_devices [ ] = " Attached devices: none " ;
char scsi_some_devices [ ] = " Attached devices: " ;
char scsi_host [ ] = " Host: " ;
char scsi_vendor [ ] = " Vendor: " ;
int count = 0 ;
if ( ptr_begins_static_str ( buf , scsi_no_devices ) ) return 0 ;
start = buf ;
while ( * start ) {
char tmp_model [ 50 ] ;
char tmp_name [ 10 ] ;
chptr = start ;
while ( * chptr ! = ' \n ' ) chptr + + ;
* chptr = ' \0 ' ;
next = chptr + 1 ;
switch ( state ) {
case SCSI_TOP :
if ( ! ptr_begins_static_str ( start , scsi_some_devices ) ) return count ;
state = SCSI_HOST ;
break ;
case SCSI_HOST :
if ( ! ptr_begins_static_str ( start , scsi_host ) ) return count ;
state = SCSI_VENDOR ;
break ;
case SCSI_VENDOR :
if ( ! ptr_begins_static_str ( start , scsi_vendor ) ) return count ;
/* (1) Grab Vendor info */
start + = 10 ;
end = chptr = strstr ( start , " Model: " ) ;
if ( ! chptr ) return count ;
chptr - - ;
while ( * chptr = = ' ' )
chptr - - ;
if ( * chptr = = ' : ' ) {
chptr + + ;
* ( chptr + 1 ) = ' \0 ' ;
strcpy ( tmp_model , " (unknown) " ) ;
} else {
* ( chptr + 1 ) = ' \0 ' ;
strcpy ( tmp_model , start ) ;
}
/* (2) Grab Model info */
start = end ;
start + = 7 ;
chptr = strstr ( start , " Rev: " ) ;
if ( ! chptr ) return count ;
chptr - - ;
while ( * chptr = = ' ' ) chptr - - ;
* ( chptr + 1 ) = ' \0 ' ;
strcat ( tmp_model , " " ) ;
strcat ( tmp_model , start ) ;
media - > model = strdup ( tmp_model ) ;
state = SCSI_TYPE ;
break ;
case SCSI_TYPE :
if ( strncmp ( " Type: " , start , 7 ) ) return count ;
* tmp_name = ' \0 ' ;
if ( strstr ( start , " Direct-Access " ) ) {
sprintf ( tmp_name , " sd%c " , scsi_disk_count + + ) ;
media - > type = DISK ;
} else if ( strstr ( start , " Sequential-Access " ) ) {
sprintf ( tmp_name , " st%c " , scsi_tape_count + + ) ;
media - > type = TAPE ;
} else if ( strstr ( start , " CD-ROM " ) ) {
sprintf ( tmp_name , " sr%c " , scsi_cdrom_count + + ) ;
media - > type = CDROM ;
}
if ( * tmp_name ) {
media - > name = strdup ( tmp_name ) ;
log_message ( " SCSI/%d: %s is a %s " , media - > type , media - > name , media - > model ) ;
count + + ;
media + + ;
}
state = SCSI_HOST ;
}
start = next ;
}
return count ;
}
2004-01-20 21:32:43 +03:00
static void find_media ( void )
{
2004-11-22 16:47:29 +03:00
char b [ 50 ] ;
2004-01-20 21:32:43 +03:00
char buf [ 5000 ] ;
struct media_info tmp [ 50 ] ;
int count ;
2004-11-22 16:47:29 +03:00
int fd ;
2004-01-20 21:32:43 +03:00
2004-11-22 16:47:29 +03:00
if ( ! medias ) {
2005-03-03 15:37:10 +03:00
probe_that_type ( MEDIA_ADAPTERS ) ;
2004-11-22 16:47:29 +03:00
}
2004-01-20 21:32:43 +03:00
else
free ( medias ) ; /* that does not free the strings, by the way */
/* ----------------------------------------------- */
log_message ( " looking for ide media " ) ;
2004-11-22 16:47:29 +03:00
count = 0 ;
strcpy ( b , " /proc/ide/hd " ) ;
for ( b [ 12 ] = ' a ' ; b [ 12 ] < = ' h ' ; b [ 12 ] + + ) {
2004-01-20 21:32:43 +03:00
int i ;
char ide_disk [ ] = " disk " ;
char ide_cdrom [ ] = " cdrom " ;
char ide_tape [ ] = " tape " ;
char ide_floppy [ ] = " floppy " ;
/* first, test if file exists (will tell if attached medium exists) */
b [ 13 ] = ' \0 ' ;
if ( access ( b , R_OK ) )
continue ;
tmp [ count ] . name = strdup ( " hda " ) ;
tmp [ count ] . name [ 2 ] = b [ 12 ] ;
/* media type */
strcpy ( b + 13 , " /media " ) ;
fd = open ( b , O_RDONLY ) ;
if ( fd = = - 1 ) {
log_message ( " failed to open %s for reading " , b ) ;
continue ;
}
i = read ( fd , buf , sizeof ( buf ) ) ;
if ( i = = - 1 ) {
log_message ( " failed to read %s " , b ) ;
continue ;
}
buf [ i ] = ' \0 ' ;
close ( fd ) ;
if ( ptr_begins_static_str ( buf , ide_disk ) )
tmp [ count ] . type = DISK ;
else if ( ptr_begins_static_str ( buf , ide_cdrom ) )
tmp [ count ] . type = CDROM ;
else if ( ptr_begins_static_str ( buf , ide_tape ) )
tmp [ count ] . type = TAPE ;
else if ( ptr_begins_static_str ( buf , ide_floppy ) )
tmp [ count ] . type = FLOPPY ;
else
tmp [ count ] . type = UNKNOWN_MEDIA ;
/* media model */
strcpy ( b + 13 , " /model " ) ;
fd = open ( b , O_RDONLY ) ;
if ( fd = = - 1 ) {
log_message ( " failed to open %s for reading " , b ) ;
continue ;
}
i = read ( fd , buf , sizeof ( buf ) ) ;
if ( i < = 0 ) {
log_message ( " failed to read %s " , b ) ;
tmp [ count ] . model = strdup ( " (none) " ) ;
}
else {
buf [ i - 1 ] = ' \0 ' ; /* eat the \n */
tmp [ count ] . model = strdup ( buf ) ;
}
close ( fd ) ;
log_message ( " IDE/%d: %s is a %s " , tmp [ count ] . type , tmp [ count ] . name , tmp [ count ] . model ) ;
count + + ;
2004-11-22 16:47:29 +03:00
}
2004-01-20 21:32:43 +03:00
/* ----------------------------------------------- */
log_message ( " looking for scsi media " ) ;
fd = open ( " /proc/scsi/scsi " , O_RDONLY ) ;
if ( fd ! = - 1 ) {
int i = read ( fd , & buf , sizeof ( buf ) - 1 ) ;
2005-01-21 20:03:46 +03:00
if ( i > 1 ) {
buf [ i ] = ' \0 ' ;
count + = find_scsi_media ( buf , & tmp [ count ] ) ;
2004-01-20 21:32:43 +03:00
}
close ( fd ) ;
}
2005-01-21 20:03:46 +03:00
2004-01-20 21:32:43 +03:00
/* ----------------------------------------------- */
log_message ( " looking for Compaq Smart Array media " ) ;
{
char * procfiles [ ] = { " /proc/driver/cpqarray/ida0 " , " /proc/driver/cciss/cciss0 " , // 2.4 style
" /proc/array/ida " , " /proc/cciss/cciss " , // 2.2 style
NULL } ;
static char cpq_descr [ ] = " Compaq RAID logical disk " ;
char * * procfile = procfiles ;
FILE * f ;
while ( procfile & & * procfile & & ( f = fopen ( * procfile , " rb " ) ) ) {
while ( fgets ( buf , sizeof ( buf ) , f ) ) {
if ( ptr_begins_static_str ( buf , " ida/ " ) | | ptr_begins_static_str ( buf , " cciss/ " ) ) {
char * end = strchr ( buf , ' : ' ) ;
if ( ! end )
log_message ( " Inconsistency in %s, line: \n %s " , * procfile , buf ) ;
else {
* end = ' \0 ' ;
tmp [ count ] . name = strdup ( buf ) ;
tmp [ count ] . type = DISK ;
tmp [ count ] . model = cpq_descr ;
log_message ( " CPQ: found %s " , tmp [ count ] . name ) ;
count + + ;
}
}
}
fclose ( f ) ;
procfile + + ;
}
}
/* ----------------------------------------------- */
log_message ( " looking for DAC960 " ) ;
{
FILE * f ;
if ( ( f = fopen ( " /tmp/syslog " , " rb " ) ) ) {
while ( fgets ( buf , sizeof ( buf ) , f ) ) {
char * start ;
if ( ( start = strstr ( buf , " /dev/rd/ " ) ) ) {
char * end = strchr ( start , ' : ' ) ;
if ( ! end )
log_message ( " Inconsistency in syslog, line: \n %s " , buf ) ;
else {
* end = ' \0 ' ;
tmp [ count ] . name = strdup ( start + 5 ) ;
tmp [ count ] . type = DISK ;
start = end + 2 ;
end = strchr ( start , ' , ' ) ;
if ( end ) {
* end = ' \0 ' ;
tmp [ count ] . model = strdup ( start ) ;
} else
tmp [ count ] . model = " (unknown) " ;
log_message ( " DAC960: found %s (%s) " , tmp [ count ] . name , tmp [ count ] . model ) ;
count + + ;
}
}
}
fclose ( f ) ;
}
}
/* ----------------------------------------------- */
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 */
# 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 ) ;
}
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 */