summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2017-03-04 19:43:07 +0100
committerMichael Brown2017-03-07 14:40:35 +0100
commit4adc7b029013bf93c0e5f79eddb9231ba2b50292 (patch)
tree2290eacb2fa965e4b8d1b2aa1857c8be998461fb /src/include
parent[block] Remove spurious comments (diff)
downloadipxe-4adc7b029013bf93c0e5f79eddb9231ba2b50292.tar.gz
ipxe-4adc7b029013bf93c0e5f79eddb9231ba2b50292.tar.xz
ipxe-4adc7b029013bf93c0e5f79eddb9231ba2b50292.zip
[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>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ipxe/errfile.h1
-rw-r--r--src/include/ipxe/sanboot.h124
2 files changed, 124 insertions, 1 deletions
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index 1a037b10..cd5c1959 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -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 )
diff --git a/src/include/ipxe/sanboot.h b/src/include/ipxe/sanboot.h
index 1c68a58c..420d4dbe 100644
--- a/src/include/ipxe/sanboot.h
+++ b/src/include/ipxe/sanboot.h
@@ -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 */