[efi] Allow network devices to be created on top of arbitrary SNP devices

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2014-07-01 17:58:09 +01:00
parent cb2f6ca46f
commit c7051d826b
11 changed files with 653 additions and 407 deletions

View File

@@ -57,6 +57,9 @@ struct device_description {
/** TAP bus type */
#define BUS_TYPE_TAP 6
/** EFI bus type */
#define BUS_TYPE_EFI 7
/** A hardware device */
struct device {
/** Name */

View File

@@ -8,10 +8,25 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/device.h>
#include <ipxe/tables.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/DevicePath.h>
/** An EFI device */
struct efi_device {
/** Generic device */
struct device dev;
/** EFI device handle */
EFI_HANDLE device;
/** Device path */
EFI_DEVICE_PATH_PROTOCOL *path;
/** Driver for this device */
struct efi_driver *driver;
/** Driver-private data */
void *priv;
};
/** An EFI driver */
struct efi_driver {
/** Name */
@@ -19,23 +34,23 @@ struct efi_driver {
/**
* Check if driver supports device
*
* @v device Device
* @v device EFI device handle
* @ret rc Return status code
*/
int ( * supported ) ( EFI_HANDLE device );
/**
* Attach driver to device
*
* @v device Device
* @v efidev EFI device
* @ret rc Return status code
*/
int ( * start ) ( EFI_HANDLE device );
int ( * start ) ( struct efi_device *efidev );
/**
* Detach driver from device
*
* @v device Device
* @v efidev EFI device
*/
void ( * stop ) ( EFI_HANDLE device );
void ( * stop ) ( struct efi_device *efidev );
};
/** EFI driver table */
@@ -48,8 +63,32 @@ struct efi_driver {
#define EFI_DRIVER_NORMAL 02 /**< Normal drivers */
#define EFI_DRIVER_LATE 03 /**< Late drivers */
/**
* Set EFI driver-private data
*
* @v efidev EFI device
* @v priv Private data
*/
static inline void efidev_set_drvdata ( struct efi_device *efidev,
void *priv ) {
efidev->priv = priv;
}
/**
* Get EFI driver-private data
*
* @v efidev EFI device
* @ret priv Private data
*/
static inline void * efidev_get_drvdata ( struct efi_device *efidev ) {
return efidev->priv;
}
extern EFI_DEVICE_PATH_PROTOCOL *
efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path );
extern struct efi_device * efidev_parent ( struct device *dev );
extern int efidev_child_add ( struct efi_device *efidev, EFI_HANDLE device );
extern void efidev_child_del ( struct efi_device *efidev, EFI_HANDLE device );
extern int efi_driver_install ( void );
extern void efi_driver_uninstall ( void );
extern int efi_driver_connect_all ( void );

View File

@@ -8,40 +8,18 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/pci.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/PciIo.h>
#include <ipxe/efi/Protocol/DevicePath.h>
/* PciRootBridgeIo.h uses LShiftU64(), which isn't defined anywhere else */
static inline EFIAPI uint64_t LShiftU64 ( UINT64 value, UINTN shift ) {
return ( value << shift );
}
struct device;
/** An EFI PCI device */
struct efi_pci_device {
/** List of EFI PCI devices */
struct list_head list;
/** iPXE PCI device */
struct pci_device pci;
/** Underlying EFI device */
EFI_HANDLE device;
/** PCI I/O protocol */
EFI_PCI_IO_PROTOCOL *pci_io;
/** Device path */
EFI_DEVICE_PATH_PROTOCOL *path;
};
extern int efipci_create ( EFI_HANDLE device, UINT32 attributes,
struct efi_pci_device **efipci );
extern int efipci_enable ( struct efi_pci_device *efipci );
extern struct efi_pci_device * efipci_find_efi ( EFI_HANDLE device );
extern struct efi_pci_device * efipci_find ( struct device *dev );
extern int efipci_child_add ( struct efi_pci_device *efipci,
EFI_HANDLE device );
extern void efipci_child_del ( struct efi_pci_device *efipci,
EFI_HANDLE device );
extern void efipci_destroy ( struct efi_pci_device *efipci );
extern int efipci_open ( EFI_HANDLE device, UINT32 attributes,
struct pci_device *pci );
extern void efipci_close ( EFI_HANDLE device );
extern int efipci_info ( EFI_HANDLE device, struct pci_device *pci );
#endif /* _IPXE_EFI_PCI_H */

View File

@@ -24,8 +24,8 @@ struct efi_snp_device {
struct list_head list;
/** The underlying iPXE network device */
struct net_device *netdev;
/** The underlying EFI PCI device */
struct efi_pci_device *efipci;
/** The underlying EFI device */
struct efi_device *efidev;
/** EFI device handle */
EFI_HANDLE handle;
/** The SNP structure itself */
@@ -76,6 +76,7 @@ struct efi_snp_device {
extern int efi_snp_hii_install ( struct efi_snp_device *snpdev );
extern void efi_snp_hii_uninstall ( struct efi_snp_device *snpdev );
extern struct efi_snp_device * find_snpdev ( EFI_HANDLE handle );
extern struct efi_snp_device * last_opened_snpdev ( void );
extern void efi_snp_claim ( void );
extern void efi_snp_release ( void );

View File

@@ -154,6 +154,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_intel ( ERRFILE_DRIVER | 0x00650000 )
#define ERRFILE_myson ( ERRFILE_DRIVER | 0x00660000 )
#define ERRFILE_intelx ( ERRFILE_DRIVER | 0x00670000 )
#define ERRFILE_snp ( ERRFILE_DRIVER | 0x00680000 )
#define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 )
#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 )