mirror of https://github.com/ipxe/ipxe.git
[xen] Skip probing of any unsupported device types
Xen 4.4 includes the device "device/suspend/event-channel" which does not have a "backend" key. This currently causes the entire XenBus device tree probe to fail. Fix by skipping probe attempts for device types for which there is no iPXE driver. Debugged-by: Eytan Heidingsfeld <eytanh@gmail.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/67/head
parent
aeffcce44f
commit
e4461f65d8
|
@ -206,13 +206,14 @@ static struct xen_driver * xenbus_find_driver ( const char *type ) {
|
||||||
*
|
*
|
||||||
* @v xen Xen hypervisor
|
* @v xen Xen hypervisor
|
||||||
* @v parent Parent device
|
* @v parent Parent device
|
||||||
* @v type Device type
|
|
||||||
* @v instance Device instance
|
* @v instance Device instance
|
||||||
|
* @v driver Device driver
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int xenbus_probe_device ( struct xen_hypervisor *xen,
|
static int xenbus_probe_device ( struct xen_hypervisor *xen,
|
||||||
struct device *parent, const char *type,
|
struct device *parent, const char *instance,
|
||||||
const char *instance ) {
|
struct xen_driver *driver ) {
|
||||||
|
const char *type = driver->type;
|
||||||
struct xen_device *xendev;
|
struct xen_device *xendev;
|
||||||
size_t key_len;
|
size_t key_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -234,6 +235,10 @@ static int xenbus_probe_device ( struct xen_hypervisor *xen,
|
||||||
xendev->xen = xen;
|
xendev->xen = xen;
|
||||||
xendev->key = ( ( void * ) ( xendev + 1 ) );
|
xendev->key = ( ( void * ) ( xendev + 1 ) );
|
||||||
snprintf ( xendev->key, key_len, "device/%s/%s", type, instance );
|
snprintf ( xendev->key, key_len, "device/%s/%s", type, instance );
|
||||||
|
xendev->driver = driver;
|
||||||
|
xendev->dev.driver_name = driver->name;
|
||||||
|
DBGC ( xendev, "XENBUS %s has driver \"%s\"\n", xendev->key,
|
||||||
|
xendev->driver->name );
|
||||||
|
|
||||||
/* Read backend key */
|
/* Read backend key */
|
||||||
if ( ( rc = xenstore_read ( xen, &xendev->backend, xendev->key,
|
if ( ( rc = xenstore_read ( xen, &xendev->backend, xendev->key,
|
||||||
|
@ -253,18 +258,6 @@ static int xenbus_probe_device ( struct xen_hypervisor *xen,
|
||||||
DBGC ( xendev, "XENBUS %s backend=\"%s\" in domain %ld\n",
|
DBGC ( xendev, "XENBUS %s backend=\"%s\" in domain %ld\n",
|
||||||
xendev->key, xendev->backend, xendev->backend_id );
|
xendev->key, xendev->backend, xendev->backend_id );
|
||||||
|
|
||||||
/* Look for a driver */
|
|
||||||
xendev->driver = xenbus_find_driver ( type );
|
|
||||||
if ( ! xendev->driver ) {
|
|
||||||
DBGC ( xendev, "XENBUS %s has no driver\n", xendev->key );
|
|
||||||
/* Not a fatal error */
|
|
||||||
rc = 0;
|
|
||||||
goto err_no_driver;
|
|
||||||
}
|
|
||||||
xendev->dev.driver_name = xendev->driver->name;
|
|
||||||
DBGC ( xendev, "XENBUS %s has driver \"%s\"\n", xendev->key,
|
|
||||||
xendev->driver->name );
|
|
||||||
|
|
||||||
/* Probe driver */
|
/* Probe driver */
|
||||||
if ( ( rc = xendev->driver->probe ( xendev ) ) != 0 ) {
|
if ( ( rc = xendev->driver->probe ( xendev ) ) != 0 ) {
|
||||||
DBGC ( xendev, "XENBUS could not probe %s: %s\n",
|
DBGC ( xendev, "XENBUS could not probe %s: %s\n",
|
||||||
|
@ -276,7 +269,6 @@ static int xenbus_probe_device ( struct xen_hypervisor *xen,
|
||||||
|
|
||||||
xendev->driver->remove ( xendev );
|
xendev->driver->remove ( xendev );
|
||||||
err_probe:
|
err_probe:
|
||||||
err_no_driver:
|
|
||||||
err_read_backend_id:
|
err_read_backend_id:
|
||||||
free ( xendev->backend );
|
free ( xendev->backend );
|
||||||
err_read_backend:
|
err_read_backend:
|
||||||
|
@ -310,11 +302,21 @@ static void xenbus_remove_device ( struct xen_device *xendev ) {
|
||||||
*/
|
*/
|
||||||
static int xenbus_probe_type ( struct xen_hypervisor *xen,
|
static int xenbus_probe_type ( struct xen_hypervisor *xen,
|
||||||
struct device *parent, const char *type ) {
|
struct device *parent, const char *type ) {
|
||||||
|
struct xen_driver *driver;
|
||||||
char *children;
|
char *children;
|
||||||
char *child;
|
char *child;
|
||||||
size_t len;
|
size_t len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/* Look for a driver */
|
||||||
|
driver = xenbus_find_driver ( type );
|
||||||
|
if ( ! driver ) {
|
||||||
|
DBGC ( xen, "XENBUS has no driver for \"%s\" devices\n", type );
|
||||||
|
/* Not a fatal error */
|
||||||
|
rc = 0;
|
||||||
|
goto err_no_driver;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get children of this key */
|
/* Get children of this key */
|
||||||
if ( ( rc = xenstore_directory ( xen, &children, &len, "device",
|
if ( ( rc = xenstore_directory ( xen, &children, &len, "device",
|
||||||
type, NULL ) ) != 0 ) {
|
type, NULL ) ) != 0 ) {
|
||||||
|
@ -326,8 +328,8 @@ static int xenbus_probe_type ( struct xen_hypervisor *xen,
|
||||||
/* Probe each child */
|
/* Probe each child */
|
||||||
for ( child = children ; child < ( children + len ) ;
|
for ( child = children ; child < ( children + len ) ;
|
||||||
child += ( strlen ( child ) + 1 /* NUL */ ) ) {
|
child += ( strlen ( child ) + 1 /* NUL */ ) ) {
|
||||||
if ( ( rc = xenbus_probe_device ( xen, parent, type,
|
if ( ( rc = xenbus_probe_device ( xen, parent, child,
|
||||||
child ) ) != 0 )
|
driver ) ) != 0 )
|
||||||
goto err_probe_device;
|
goto err_probe_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +339,7 @@ static int xenbus_probe_type ( struct xen_hypervisor *xen,
|
||||||
err_probe_device:
|
err_probe_device:
|
||||||
free ( children );
|
free ( children );
|
||||||
err_directory:
|
err_directory:
|
||||||
|
err_no_driver:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue