mirror of
https://github.com/ipxe/ipxe
synced 2026-02-09 23:29:33 +03:00
[block] Centralise SAN device abstraction
Create a central SAN device abstraction to be shared between BIOS and UEFI. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -72,6 +72,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_blocktrans ( ERRFILE_CORE | 0x00200000 )
|
||||
#define ERRFILE_pixbuf ( ERRFILE_CORE | 0x00210000 )
|
||||
#define ERRFILE_efi_block ( ERRFILE_CORE | 0x00220000 )
|
||||
#define ERRFILE_sanboot ( ERRFILE_CORE | 0x00230000 )
|
||||
|
||||
#define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 )
|
||||
#define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 )
|
||||
|
||||
@@ -12,9 +12,52 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/api.h>
|
||||
#include <ipxe/refcnt.h>
|
||||
#include <ipxe/list.h>
|
||||
#include <ipxe/uri.h>
|
||||
#include <ipxe/retry.h>
|
||||
#include <ipxe/blockdev.h>
|
||||
#include <config/sanboot.h>
|
||||
|
||||
struct uri;
|
||||
/** A SAN device */
|
||||
struct san_device {
|
||||
/** Reference count */
|
||||
struct refcnt refcnt;
|
||||
/** List of SAN devices */
|
||||
struct list_head list;
|
||||
|
||||
/** SAN device URI */
|
||||
struct uri *uri;
|
||||
/** Drive number */
|
||||
unsigned int drive;
|
||||
|
||||
/** Underlying block device interface */
|
||||
struct interface block;
|
||||
/** Current device status */
|
||||
int block_rc;
|
||||
|
||||
/** Command interface */
|
||||
struct interface command;
|
||||
/** Command timeout timer */
|
||||
struct retry_timer timer;
|
||||
/** Command status */
|
||||
int command_rc;
|
||||
|
||||
/** Raw block device capacity */
|
||||
struct block_device_capacity capacity;
|
||||
/** Block size shift
|
||||
*
|
||||
* To allow for emulation of CD-ROM access, this represents
|
||||
* the left-shift required to translate from exposed logical
|
||||
* I/O blocks to underlying blocks.
|
||||
*/
|
||||
unsigned int blksize_shift;
|
||||
/** Drive is a CD-ROM */
|
||||
int is_cdrom;
|
||||
|
||||
/** Driver private data */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate static inline sanboot API function name
|
||||
@@ -91,4 +134,83 @@ int san_boot ( unsigned int drive );
|
||||
*/
|
||||
int san_describe ( unsigned int drive );
|
||||
|
||||
extern struct list_head san_devices;
|
||||
|
||||
/** Iterate over all SAN devices */
|
||||
#define for_each_sandev( sandev ) \
|
||||
list_for_each_entry ( (sandev), &san_devices, list )
|
||||
|
||||
/** There exist some SAN devices
|
||||
*
|
||||
* @ret existence Existence of SAN devices
|
||||
*/
|
||||
static inline int have_sandevs ( void ) {
|
||||
return ( ! list_empty ( &san_devices ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reference to SAN device
|
||||
*
|
||||
* @v sandev SAN device
|
||||
* @ret sandev SAN device
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) struct san_device *
|
||||
sandev_get ( struct san_device *sandev ) {
|
||||
ref_get ( &sandev->refcnt );
|
||||
return sandev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop reference to SAN device
|
||||
*
|
||||
* @v sandev SAN device
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
sandev_put ( struct san_device *sandev ) {
|
||||
ref_put ( &sandev->refcnt );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate SAN device block size
|
||||
*
|
||||
* @v sandev SAN device
|
||||
* @ret blksize Sector size
|
||||
*/
|
||||
static inline size_t sandev_blksize ( struct san_device *sandev ) {
|
||||
return ( sandev->capacity.blksize << sandev->blksize_shift );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate SAN device capacity
|
||||
*
|
||||
* @v sandev SAN device
|
||||
* @ret blocks Number of blocks
|
||||
*/
|
||||
static inline uint64_t sandev_capacity ( struct san_device *sandev ) {
|
||||
return ( sandev->capacity.blocks >> sandev->blksize_shift );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if SAN device needs to be reopened
|
||||
*
|
||||
* @v sandev SAN device
|
||||
* @ret needs_reopen SAN device needs to be reopened
|
||||
*/
|
||||
static inline int sandev_needs_reopen ( struct san_device *sandev ) {
|
||||
return ( sandev->block_rc != 0 );
|
||||
}
|
||||
|
||||
extern struct san_device * sandev_find ( unsigned int drive );
|
||||
extern int sandev_reopen ( struct san_device *sandev );
|
||||
extern int sandev_reset ( struct san_device *sandev );
|
||||
extern int sandev_rw ( struct san_device *sandev, uint64_t lba,
|
||||
unsigned int count, userptr_t buffer,
|
||||
int ( * block_rw ) ( struct interface *control,
|
||||
struct interface *data,
|
||||
uint64_t lba, unsigned int count,
|
||||
userptr_t buffer, size_t len ) );
|
||||
extern struct san_device * alloc_sandev ( struct uri *uri, size_t priv_size );
|
||||
extern int register_sandev ( struct san_device *sandev );
|
||||
extern void unregister_sandev ( struct san_device *sandev );
|
||||
|
||||
#endif /* _IPXE_SANBOOT_H */
|
||||
|
||||
Reference in New Issue
Block a user