iPXE
Data Structures | Macros | Functions | Variables
sanboot.c File Reference

SAN booting. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/timer.h>
#include <ipxe/process.h>
#include <ipxe/iso9660.h>
#include <ipxe/dhcp.h>
#include <ipxe/settings.h>
#include <ipxe/quiesce.h>
#include <ipxe/sanboot.h>

Go to the source code of this file.

Data Structures

struct  san_command_rw_params
 SAN device read/write command parameters. More...
 
union  san_command_params
 SAN device command parameters. More...
 

Macros

#define SAN_COMMAND_TIMEOUT   ( 15 * TICKS_PER_SEC )
 Timeout for block device commands (in ticks) More...
 
#define SAN_DEFAULT_RETRIES   10
 Default number of times to retry commands. More...
 
#define SAN_REOPEN_DELAY_SECS   5
 Delay between reopening attempts. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 LIST_HEAD (san_devices)
 List of SAN devices. More...
 
struct san_devicesandev_find (unsigned int drive)
 Find SAN device by drive number. More...
 
struct san_devicesandev_next (unsigned int drive)
 Find next SAN device by drive number. More...
 
static void sandev_free (struct refcnt *refcnt)
 Free SAN device. More...
 
static void sandev_command_close (struct san_device *sandev, int rc)
 Close SAN device command. More...
 
static void sandev_command_capacity (struct san_device *sandev, struct block_device_capacity *capacity)
 Record SAN device capacity. More...
 
static void sandev_command_expired (struct retry_timer *timer, int over __unused)
 Handle SAN device command timeout. More...
 
static int sanpath_open (struct san_path *sanpath)
 Open SAN path. More...
 
static void sanpath_close (struct san_path *sanpath, int rc)
 Close SAN path. More...
 
static void sanpath_block_close (struct san_path *sanpath, int rc)
 Handle closure of underlying block device interface. More...
 
static size_t sanpath_block_window (struct san_path *sanpath __unused)
 Check flow control window. More...
 
static void sanpath_step (struct san_path *sanpath)
 SAN path process. More...
 
static void sandev_restart (struct san_device *sandev, int rc)
 Restart SAN device interface. More...
 
int sandev_reopen (struct san_device *sandev)
 (Re)open SAN device More...
 
static int sandev_command_rw (struct san_device *sandev, const union san_command_params *params)
 Initiate SAN device read/write command. More...
 
static int sandev_command_read_capacity (struct san_device *sandev, const union san_command_params *params __unused)
 Initiate SAN device read capacity command. More...
 
static int sandev_command (struct san_device *sandev, int(*command)(struct san_device *sandev, const union san_command_params *params), const union san_command_params *params)
 Execute a single SAN device command and wait for completion. More...
 
int sandev_reset (struct san_device *sandev)
 Reset SAN device. More...
 
static int sandev_rw (struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len))
 Read from or write to SAN device. More...
 
int sandev_read (struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
 Read from SAN device. More...
 
int sandev_write (struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
 Write to SAN device. More...
 
static int sandev_describe (struct san_device *sandev)
 Describe SAN device. More...
 
static void sandev_undescribe (struct san_device *sandev)
 Remove SAN device descriptors. More...
 
static int sandev_parse_iso9660 (struct san_device *sandev)
 Configure SAN device as a CD-ROM, if applicable. More...
 
struct san_devicealloc_sandev (struct uri **uris, unsigned int count, size_t priv_size)
 Allocate SAN device. More...
 
int register_sandev (struct san_device *sandev, unsigned int drive, unsigned int flags)
 Register SAN device. More...
 
void unregister_sandev (struct san_device *sandev)
 Unregister SAN device. More...
 
const struct setting san_drive_setting __setting (SETTING_SANBOOT_EXTRA, san-drive)
 The "san-drive" setting. More...
 
unsigned int san_default_drive (void)
 Get default SAN drive number. More...
 
static int sandev_apply (void)
 Apply SAN boot settings. More...
 

Variables

static unsigned long san_retries = SAN_DEFAULT_RETRIES
 Number of times to retry commands. More...
 
static struct interface_operation sandev_command_op []
 SAN device command interface operations. More...
 
static struct interface_descriptor sandev_command_desc
 SAN device command interface descriptor. More...
 
static struct interface_operation sanpath_block_op []
 SAN path block interface operations. More...
 
static struct interface_descriptor sanpath_block_desc
 SAN path block interface descriptor. More...
 
static struct process_descriptor sanpath_process_desc
 SAN path process descriptor. More...
 
struct settings_applicator sandev_applicator __settings_applicator
 Settings applicator. More...
 

Detailed Description

SAN booting.

Definition in file sanboot.c.

Macro Definition Documentation

◆ SAN_COMMAND_TIMEOUT

#define SAN_COMMAND_TIMEOUT   ( 15 * TICKS_PER_SEC )

Timeout for block device commands (in ticks)

Underlying devices should ideally never become totally stuck. However, if they do, then the blocking SAN APIs provide no means for the caller to cancel the operation, and the machine appears to hang. Use an overall timeout for all commands to avoid this problem and bounce timeout failures to the caller.

Definition at line 57 of file sanboot.c.

◆ SAN_DEFAULT_RETRIES

#define SAN_DEFAULT_RETRIES   10

Default number of times to retry commands.

We may need to retry commands. For example, the underlying connection may be closed by the SAN target due to an inactivity timeout, or the SAN target may return pointless "error" messages such as "SCSI power-on occurred".

Definition at line 67 of file sanboot.c.

◆ SAN_REOPEN_DELAY_SECS

#define SAN_REOPEN_DELAY_SECS   5

Delay between reopening attempts.

Some SAN targets will always accept connections instantly and report a temporary unavailability by e.g. failing the TEST UNIT READY command. Avoid bombarding such targets by introducing a small delay between attempts.

Definition at line 77 of file sanboot.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ LIST_HEAD()

LIST_HEAD ( san_devices  )

List of SAN devices.

◆ sandev_find()

struct san_device* sandev_find ( unsigned int  drive)

Find SAN device by drive number.

Parameters
driveDrive number
Return values
sandevSAN device, or NULL

Definition at line 91 of file sanboot.c.

91  {
92  struct san_device *sandev;
93 
94  list_for_each_entry ( sandev, &san_devices, list ) {
95  if ( sandev->drive == drive )
96  return sandev;
97  }
98  return NULL;
99 }
struct list_head san_devices
uint8_t drive
Drive number.
Definition: int13.h:16
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
unsigned int drive
Drive number.
Definition: sanboot.h:65
struct list_head list
List of SAN devices.
Definition: sanboot.h:62
A SAN device.
Definition: sanboot.h:58
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References drive, san_device::drive, san_device::list, list_for_each_entry, NULL, and san_devices.

Referenced by dummy_san_unhook(), efi_block_unhook(), int13_unhook(), and register_sandev().

◆ sandev_next()

struct san_device* sandev_next ( unsigned int  drive)

Find next SAN device by drive number.

Parameters
driveMinimum drive number
Return values
sandevSAN device, or NULL

Definition at line 107 of file sanboot.c.

107  {
108  struct san_device *sandev;
109 
110  list_for_each_entry ( sandev, &san_devices, list ) {
111  if ( sandev->drive >= drive )
112  return sandev;
113  }
114  return NULL;
115 }
struct list_head san_devices
uint8_t drive
Drive number.
Definition: int13.h:16
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
unsigned int drive
Drive number.
Definition: sanboot.h:65
struct list_head list
List of SAN devices.
Definition: sanboot.h:62
A SAN device.
Definition: sanboot.h:58
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References drive, san_device::drive, san_device::list, list_for_each_entry, NULL, and san_devices.

Referenced by efi_block_boot().

◆ sandev_free()

static void sandev_free ( struct refcnt refcnt)
static

Free SAN device.

Parameters
refcntReference count

Definition at line 122 of file sanboot.c.

122  {
123  struct san_device *sandev =
124  container_of ( refcnt, struct san_device, refcnt );
125  unsigned int i;
126 
127  assert ( ! timer_running ( &sandev->timer ) );
128  assert ( ! sandev->active );
129  assert ( list_empty ( &sandev->opened ) );
130  for ( i = 0 ; i < sandev->paths ; i++ ) {
131  uri_put ( sandev->path[i].uri );
132  assert ( sandev->path[i].desc == NULL );
133  }
134  free ( sandev );
135 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
struct san_path path[0]
SAN paths.
Definition: sanboot.h:100
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:96
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
A SAN device.
Definition: sanboot.h:58
unsigned int paths
Number of paths.
Definition: sanboot.h:92
struct uri * uri
SAN device URI.
Definition: sanboot.h:42
struct san_path * active
Current active path.
Definition: sanboot.h:94
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:72
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:54
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References san_device::active, assert(), container_of, san_path::desc, free, list_empty, NULL, san_device::opened, san_device::path, san_device::paths, san_device::timer, san_path::uri, and uri_put().

Referenced by alloc_sandev().

◆ sandev_command_close()

static void sandev_command_close ( struct san_device sandev,
int  rc 
)
static

Close SAN device command.

Parameters
sandevSAN device
rcReason for close

Definition at line 143 of file sanboot.c.

143  {
144 
145  /* Stop timer */
146  stop_timer ( &sandev->timer );
147 
148  /* Restart interface */
149  intf_restart ( &sandev->command, rc );
150 
151  /* Record command status */
152  sandev->command_rc = rc;
153 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
int command_rc
Command status.
Definition: sanboot.h:74
struct interface command
Command interface.
Definition: sanboot.h:70
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:72

References san_device::command, san_device::command_rc, intf_restart(), rc, stop_timer(), and san_device::timer.

Referenced by sandev_command_expired(), sandev_restart(), and sanpath_close().

◆ sandev_command_capacity()

static void sandev_command_capacity ( struct san_device sandev,
struct block_device_capacity capacity 
)
static

Record SAN device capacity.

Parameters
sandevSAN device
capacitySAN device capacity

Definition at line 161 of file sanboot.c.

162  {
163 
164  /* Record raw capacity information */
165  memcpy ( &sandev->capacity, capacity, sizeof ( sandev->capacity ) );
166 }
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77

References san_device::capacity, and memcpy().

◆ sandev_command_expired()

static void sandev_command_expired ( struct retry_timer timer,
int over  __unused 
)
static

Handle SAN device command timeout.

Parameters
retryRetry timer

Definition at line 184 of file sanboot.c.

185  {
186  struct san_device *sandev =
187  container_of ( timer, struct san_device, timer );
188 
189  sandev_command_close ( sandev, -ETIMEDOUT );
190 }
A timer.
Definition: timer.h:28
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
A SAN device.
Definition: sanboot.h:58
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:143
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

References container_of, ETIMEDOUT, and sandev_command_close().

Referenced by alloc_sandev().

◆ sanpath_open()

static int sanpath_open ( struct san_path sanpath)
static

Open SAN path.

Parameters
sanpathSAN path
Return values
rcReturn status code

Definition at line 198 of file sanboot.c.

198  {
199  struct san_device *sandev = sanpath->sandev;
200  int rc;
201 
202  /* Sanity check */
203  list_check_contains_entry ( sanpath, &sandev->closed, list );
204 
205  /* Open interface */
206  if ( ( rc = xfer_open_uri ( &sanpath->block, sanpath->uri ) ) != 0 ) {
207  DBGC ( sandev->drive, "SAN %#02x.%d could not (re)open URI: "
208  "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
209  return rc;
210  }
211 
212  /* Update ACPI descriptor, if applicable */
213  if ( ! ( sandev->flags & SAN_NO_DESCRIBE ) ) {
214  if ( sanpath->desc )
215  acpi_del ( sanpath->desc );
216  sanpath->desc = acpi_describe ( &sanpath->block );
217  if ( sanpath->desc )
218  acpi_add ( sanpath->desc );
219  }
220 
221  /* Start process */
222  process_add ( &sanpath->process );
223 
224  /* Mark as opened */
225  list_del ( &sanpath->list );
226  list_add_tail ( &sanpath->list, &sandev->opened );
227 
228  /* Record as in progress */
229  sanpath->path_rc = -EINPROGRESS;
230 
231  return 0;
232 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of open/closed paths.
Definition: sanboot.h:44
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:67
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:47
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:96
unsigned int index
Path index.
Definition: sanboot.h:40
void acpi_del(struct acpi_descriptor *desc)
Remove ACPI descriptor.
Definition: acpi.c:306
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
unsigned int drive
Drive number.
Definition: sanboot.h:65
#define EINPROGRESS
Operation in progress.
Definition: errno.h:418
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:98
struct list_head list
List of SAN devices.
Definition: sanboot.h:62
int path_rc
Path status.
Definition: sanboot.h:51
A SAN device.
Definition: sanboot.h:58
Device should not be included in description tables.
Definition: sanboot.h:106
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:320
struct uri * uri
SAN device URI.
Definition: sanboot.h:42
struct process process
Process.
Definition: sanboot.h:49
unsigned int flags
Flags.
Definition: sanboot.h:67
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition: list.h:549
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:54
void acpi_add(struct acpi_descriptor *desc)
Add ACPI descriptor.
Definition: acpi.c:294
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References acpi_add(), acpi_del(), acpi_describe(), san_path::block, san_device::closed, DBGC, san_path::desc, san_device::drive, EINPROGRESS, san_device::flags, san_path::index, san_path::list, san_device::list, list_add_tail, list_check_contains_entry, list_del, san_device::opened, san_path::path_rc, san_path::process, process_add(), rc, SAN_NO_DESCRIBE, san_path::sandev, strerror(), san_path::uri, and xfer_open_uri().

Referenced by sandev_reopen().

◆ sanpath_close()

static void sanpath_close ( struct san_path sanpath,
int  rc 
)
static

Close SAN path.

Parameters
sanpathSAN path
rcReason for close

Definition at line 240 of file sanboot.c.

240  {
241  struct san_device *sandev = sanpath->sandev;
242 
243  /* Record status */
244  sanpath->path_rc = rc;
245 
246  /* Mark as closed */
247  list_del ( &sanpath->list );
248  list_add_tail ( &sanpath->list, &sandev->closed );
249 
250  /* Stop process */
251  process_del ( &sanpath->process );
252 
253  /* Restart interfaces, avoiding potential loops */
254  if ( sanpath == sandev->active ) {
255  intfs_restart ( rc, &sandev->command, &sanpath->block, NULL );
256  sandev->active = NULL;
257  sandev_command_close ( sandev, rc );
258  } else {
259  intf_restart ( &sanpath->block, rc );
260  }
261 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
struct list_head list
List of open/closed paths.
Definition: sanboot.h:44
struct interface block
Underlying block device interface.
Definition: sanboot.h:47
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
void intfs_restart(int rc,...)
Shut down and restart multiple object interfaces.
Definition: interface.c:386
struct interface command
Command interface.
Definition: sanboot.h:70
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:98
int path_rc
Path status.
Definition: sanboot.h:51
A SAN device.
Definition: sanboot.h:58
struct process process
Process.
Definition: sanboot.h:49
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:143
struct san_path * active
Current active path.
Definition: sanboot.h:94
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References san_device::active, san_path::block, san_device::closed, san_device::command, intf_restart(), intfs_restart(), san_path::list, list_add_tail, list_del, NULL, san_path::path_rc, san_path::process, process_del(), rc, san_path::sandev, and sandev_command_close().

Referenced by sandev_restart(), sanpath_block_close(), and sanpath_step().

◆ sanpath_block_close()

static void sanpath_block_close ( struct san_path sanpath,
int  rc 
)
static

Handle closure of underlying block device interface.

Parameters
sanpathSAN path
rcReason for close

Definition at line 269 of file sanboot.c.

269  {
270  struct san_device *sandev = sanpath->sandev;
271 
272  /* Any closure is an error from our point of view */
273  if ( rc == 0 )
274  rc = -ENOTCONN;
275  DBGC ( sandev->drive, "SAN %#02x.%d closed: %s\n",
276  sandev->drive, sanpath->index, strerror ( rc ) );
277 
278  /* Close path */
279  sanpath_close ( sanpath, rc );
280 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned int index
Path index.
Definition: sanboot.h:40
unsigned int drive
Drive number.
Definition: sanboot.h:65
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A SAN device.
Definition: sanboot.h:58
static void sanpath_close(struct san_path *sanpath, int rc)
Close SAN path.
Definition: sanboot.c:240
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References DBGC, san_device::drive, ENOTCONN, san_path::index, rc, san_path::sandev, sanpath_close(), and strerror().

◆ sanpath_block_window()

static size_t sanpath_block_window ( struct san_path *sanpath  __unused)
static

Check flow control window.

Parameters
sanpathSAN path

Definition at line 287 of file sanboot.c.

287  {
288 
289  /* We are never ready to receive data via this interface.
290  * This prevents objects that support both block and stream
291  * interfaces from attempting to send us stream data.
292  */
293  return 0;
294 }

◆ sanpath_step()

static void sanpath_step ( struct san_path sanpath)
static

SAN path process.

Parameters
sanpathSAN path

Definition at line 301 of file sanboot.c.

301  {
302  struct san_device *sandev = sanpath->sandev;
303 
304  /* Ignore if we are already the active device */
305  if ( sanpath == sandev->active )
306  return;
307 
308  /* Wait until path has become available */
309  if ( ! xfer_window ( &sanpath->block ) )
310  return;
311 
312  /* Record status */
313  sanpath->path_rc = 0;
314 
315  /* Mark as active path or close as applicable */
316  if ( ! sandev->active ) {
317  DBGC ( sandev->drive, "SAN %#02x.%d is active\n",
318  sandev->drive, sanpath->index );
319  sandev->active = sanpath;
320  } else {
321  DBGC ( sandev->drive, "SAN %#02x.%d is available\n",
322  sandev->drive, sanpath->index );
323  sanpath_close ( sanpath, 0 );
324  }
325 }
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:47
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
unsigned int index
Path index.
Definition: sanboot.h:40
unsigned int drive
Drive number.
Definition: sanboot.h:65
int path_rc
Path status.
Definition: sanboot.h:51
A SAN device.
Definition: sanboot.h:58
static void sanpath_close(struct san_path *sanpath, int rc)
Close SAN path.
Definition: sanboot.c:240
struct san_path * active
Current active path.
Definition: sanboot.h:94
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References san_device::active, san_path::block, DBGC, san_device::drive, san_path::index, san_path::path_rc, san_path::sandev, sanpath_close(), and xfer_window().

◆ sandev_restart()

static void sandev_restart ( struct san_device sandev,
int  rc 
)
static

Restart SAN device interface.

Parameters
sandevSAN device
rcReason for restart

Definition at line 348 of file sanboot.c.

348  {
349  struct san_path *sanpath;
350 
351  /* Restart all block device interfaces */
352  while ( ( sanpath = list_first_entry ( &sandev->opened,
353  struct san_path, list ) ) ) {
354  sanpath_close ( sanpath, rc );
355  }
356 
357  /* Clear active path */
358  sandev->active = NULL;
359 
360  /* Close any outstanding command */
362 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of open/closed paths.
Definition: sanboot.h:44
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:96
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
A SAN path.
Definition: sanboot.h:36
static void sanpath_close(struct san_path *sanpath, int rc)
Close SAN path.
Definition: sanboot.c:240
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:143
struct san_path * active
Current active path.
Definition: sanboot.h:94
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References san_device::active, san_path::list, list_first_entry, NULL, san_device::opened, rc, san_path::sandev, sandev_command_close(), and sanpath_close().

Referenced by register_sandev(), sandev_reopen(), and unregister_sandev().

◆ sandev_reopen()

int sandev_reopen ( struct san_device sandev)

(Re)open SAN device

Parameters
sandevSAN device
Return values
rcReturn status code

This function will block until the device is available.

Definition at line 372 of file sanboot.c.

372  {
373  struct san_path *sanpath;
374  int rc;
375 
376  /* Unquiesce system */
377  unquiesce();
378 
379  /* Close any outstanding command and restart interfaces */
381  assert ( sandev->active == NULL );
382  assert ( list_empty ( &sandev->opened ) );
383 
384  /* Open all paths */
385  while ( ( sanpath = list_first_entry ( &sandev->closed,
386  struct san_path, list ) ) ) {
387  if ( ( rc = sanpath_open ( sanpath ) ) != 0 )
388  goto err_open;
389  }
390 
391  /* Wait for any device to become available, or for all devices
392  * to fail.
393  */
394  while ( sandev->active == NULL ) {
395  step();
396  if ( list_empty ( &sandev->opened ) ) {
397  /* Get status of the first device to be
398  * closed. Do this on the basis that earlier
399  * errors (e.g. "invalid IQN") are probably
400  * more interesting than later errors
401  * (e.g. "TCP timeout").
402  */
403  rc = -ENODEV;
404  list_for_each_entry ( sanpath, &sandev->closed, list ) {
405  rc = sanpath->path_rc;
406  break;
407  }
408  DBGC ( sandev->drive, "SAN %#02x never became "
409  "available: %s\n", sandev->drive,
410  strerror ( rc ) );
411  goto err_none;
412  }
413  }
414 
415  assert ( ! list_empty ( &sandev->opened ) );
416  return 0;
417 
418  err_none:
419  err_open:
420  sandev_restart ( sandev, rc );
421  return rc;
422 }
#define ECONNRESET
Connection reset.
Definition: errno.h:363
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of open/closed paths.
Definition: sanboot.h:44
#define DBGC(...)
Definition: compiler.h:505
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:96
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:36
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
unsigned int drive
Drive number.
Definition: sanboot.h:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:98
int path_rc
Path status.
Definition: sanboot.h:51
#define ENODEV
No such device.
Definition: errno.h:509
void step(void)
Single-step a single process.
Definition: process.c:98
static void sandev_restart(struct san_device *sandev, int rc)
Restart SAN device interface.
Definition: sanboot.c:348
struct san_path * active
Current active path.
Definition: sanboot.h:94
static int sanpath_open(struct san_path *sanpath)
Open SAN path.
Definition: sanboot.c:198
void unquiesce(void)
Unquiesce system.
Definition: quiesce.c:46
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References san_device::active, assert(), san_device::closed, DBGC, san_device::drive, ECONNRESET, ENODEV, san_path::list, list_empty, list_first_entry, list_for_each_entry, NULL, san_device::opened, san_path::path_rc, rc, san_path::sandev, sandev_restart(), sanpath_open(), step(), strerror(), and unquiesce().

Referenced by int13_device_path_info(), register_sandev(), sandev_command(), and sandev_reset().

◆ sandev_command_rw()

static int sandev_command_rw ( struct san_device sandev,
const union san_command_params params 
)
static

Initiate SAN device read/write command.

Parameters
sandevSAN device
paramsCommand parameters
Return values
rcReturn status code

Definition at line 451 of file sanboot.c.

452  {
453  struct san_path *sanpath = sandev->active;
454  size_t len = ( params->rw.count * sandev->capacity.blksize );
455  int rc;
456 
457  /* Sanity check */
458  assert ( sanpath != NULL );
459 
460  /* Initiate read/write command */
461  if ( ( rc = params->rw.block_rw ( &sanpath->block, &sandev->command,
462  params->rw.lba, params->rw.count,
463  params->rw.buffer, len ) ) != 0 ) {
464  DBGC ( sandev->drive, "SAN %#02x.%d could not initiate "
465  "read/write: %s\n", sandev->drive, sanpath->index,
466  strerror ( rc ) );
467  return rc;
468  }
469 
470  return 0;
471 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * buffer
Data buffer.
Definition: sanboot.c:431
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:47
unsigned int index
Path index.
Definition: sanboot.h:40
struct interface command
Command interface.
Definition: sanboot.h:70
struct san_command_rw_params rw
Read/write command parameters.
Definition: sanboot.c:441
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:36
unsigned int drive
Drive number.
Definition: sanboot.h:65
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int(* block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
SAN device read/write operation.
Definition: sanboot.c:427
unsigned int count
Block count.
Definition: sanboot.c:435
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77
uint64_t lba
Starting LBA.
Definition: sanboot.c:433
struct san_path * active
Current active path.
Definition: sanboot.h:94
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38
size_t blksize
Block size.
Definition: blockdev.h:21

References san_device::active, assert(), block_device_capacity::blksize, san_path::block, san_command_rw_params::block_rw, san_command_rw_params::buffer, san_device::capacity, san_device::command, san_command_rw_params::count, DBGC, san_device::drive, san_path::index, san_command_rw_params::lba, len, NULL, rc, san_command_params::rw, san_path::sandev, and strerror().

Referenced by sandev_rw().

◆ sandev_command_read_capacity()

static int sandev_command_read_capacity ( struct san_device sandev,
const union san_command_params *params  __unused 
)
static

Initiate SAN device read capacity command.

Parameters
sandevSAN device
paramsCommand parameters
Return values
rcReturn status code

Definition at line 481 of file sanboot.c.

482  {
483  struct san_path *sanpath = sandev->active;
484  int rc;
485 
486  /* Sanity check */
487  assert ( sanpath != NULL );
488 
489  /* Initiate read capacity command */
490  if ( ( rc = block_read_capacity ( &sanpath->block,
491  &sandev->command ) ) != 0 ) {
492  DBGC ( sandev->drive, "SAN %#02x.%d could not initiate read "
493  "capacity: %s\n", sandev->drive, sanpath->index,
494  strerror ( rc ) );
495  return rc;
496  }
497 
498  return 0;
499 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:47
unsigned int index
Path index.
Definition: sanboot.h:40
struct interface command
Command interface.
Definition: sanboot.h:70
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:36
unsigned int drive
Drive number.
Definition: sanboot.h:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct san_path * active
Current active path.
Definition: sanboot.h:94
int block_read_capacity(struct interface *control, struct interface *data)
Read block device capacity.
Definition: blockdev.c:105
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References san_device::active, assert(), san_path::block, block_read_capacity(), san_device::command, DBGC, san_device::drive, san_path::index, NULL, rc, san_path::sandev, and strerror().

Referenced by register_sandev().

◆ sandev_command()

static int sandev_command ( struct san_device sandev,
int(*)(struct san_device *sandev, const union san_command_params *params)  command,
const union san_command_params params 
)
static

Execute a single SAN device command and wait for completion.

Parameters
sandevSAN device
commandCommand
paramsCommand parameters (if required)
Return values
rcReturn status code

Definition at line 510 of file sanboot.c.

513  {
514  unsigned int retries = 0;
515  int rc;
516 
517  /* Sanity check */
518  assert ( ! timer_running ( &sandev->timer ) );
519 
520  /* Unquiesce system */
521  unquiesce();
522 
523  /* (Re)try command */
524  do {
525 
526  /* Reopen block device if applicable */
527  if ( sandev_needs_reopen ( sandev ) &&
528  ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) {
529 
530  /* Delay reopening attempts */
532 
533  /* Retry opening indefinitely for multipath devices */
534  if ( sandev->paths <= 1 )
535  retries++;
536 
537  continue;
538  }
539 
540  /* Initiate command */
541  if ( ( rc = command ( sandev, params ) ) != 0 ) {
542  retries++;
543  continue;
544  }
545 
546  /* Start expiry timer */
548 
549  /* Wait for command to complete */
550  while ( timer_running ( &sandev->timer ) )
551  step();
552 
553  /* Check command status */
554  if ( ( rc = sandev->command_rc ) != 0 ) {
555  retries++;
556  continue;
557  }
558 
559  return 0;
560 
561  } while ( retries <= san_retries );
562 
563  /* Sanity check */
564  assert ( ! timer_running ( &sandev->timer ) );
565 
566  return rc;
567 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A command-line command.
Definition: command.h:9
int command_rc
Command status.
Definition: sanboot.h:74
static int sandev_needs_reopen(struct san_device *sandev)
Check if SAN device needs to be reopened.
Definition: sanboot.h:255
#define SAN_REOPEN_DELAY_SECS
Delay between reopening attempts.
Definition: sanboot.c:77
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int paths
Number of paths.
Definition: sanboot.h:92
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
static unsigned long san_retries
Number of times to retry commands.
Definition: sanboot.c:83
#define SAN_COMMAND_TIMEOUT
Timeout for block device commands (in ticks)
Definition: sanboot.c:57
void step(void)
Single-step a single process.
Definition: process.c:98
void sleep_fixed(unsigned int secs)
Sleep (uninterruptibly) for a fixed number of seconds.
Definition: timer.c:143
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:72
void unquiesce(void)
Unquiesce system.
Definition: quiesce.c:46
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:372
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References assert(), san_device::command_rc, san_device::paths, rc, SAN_COMMAND_TIMEOUT, SAN_REOPEN_DELAY_SECS, san_retries, san_path::sandev, sandev_needs_reopen(), sandev_reopen(), sleep_fixed(), start_timer_fixed(), step(), san_device::timer, and unquiesce().

Referenced by register_sandev(), and sandev_rw().

◆ sandev_reset()

int sandev_reset ( struct san_device sandev)

Reset SAN device.

Parameters
sandevSAN device
Return values
rcReturn status code

Definition at line 575 of file sanboot.c.

575  {
576  int rc;
577 
578  DBGC ( sandev->drive, "SAN %#02x reset\n", sandev->drive );
579 
580  /* Close and reopen underlying block device */
581  if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
582  return rc;
583 
584  return 0;
585 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned int drive
Drive number.
Definition: sanboot.h:65
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:372
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References DBGC, san_device::drive, rc, san_path::sandev, and sandev_reopen().

Referenced by efi_block_io_reset(), and int13_reset().

◆ sandev_rw()

static int sandev_rw ( struct san_device sandev,
uint64_t  lba,
unsigned int  count,
void *  buffer,
int(*)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len block_rw 
)
static

Read from or write to SAN device.

Parameters
sandevSAN device
lbaStarting logical block address
countNumber of logical blocks
bufferData buffer
block_rwBlock read/write method
Return values
rcReturn status code

Definition at line 597 of file sanboot.c.

602  {
603  union san_command_params params;
604  unsigned int remaining;
605  size_t frag_len;
606  int rc;
607 
608  /* Initialise command parameters */
609  params.rw.block_rw = block_rw;
610  params.rw.buffer = buffer;
611  params.rw.lba = ( lba << sandev->blksize_shift );
612  params.rw.count = sandev->capacity.max_count;
613  remaining = ( count << sandev->blksize_shift );
614 
615  /* Read/write fragments */
616  while ( remaining ) {
617 
618  /* Determine fragment length */
619  if ( params.rw.count > remaining )
620  params.rw.count = remaining;
621 
622  /* Execute command */
623  if ( ( rc = sandev_command ( sandev, sandev_command_rw,
624  &params ) ) != 0 )
625  return rc;
626 
627  /* Move to next fragment */
628  frag_len = ( sandev->capacity.blksize * params.rw.count );
629  params.rw.buffer += frag_len;
630  params.rw.lba += params.rw.count;
631  remaining -= params.rw.count;
632  }
633 
634  return 0;
635 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned int max_count
Maximum number of blocks per single transfer.
Definition: blockdev.h:23
SAN device command parameters.
Definition: sanboot.c:439
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
static unsigned int count
Number of entries.
Definition: dwmac.h:225
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:84
uint64_t lba
Starting block number.
Definition: int13.h:22
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77
static int sandev_command(struct san_device *sandev, int(*command)(struct san_device *sandev, const union san_command_params *params), const union san_command_params *params)
Execute a single SAN device command and wait for completion.
Definition: sanboot.c:510
static int sandev_command_rw(struct san_device *sandev, const union san_command_params *params)
Initiate SAN device read/write command.
Definition: sanboot.c:451
size_t blksize
Block size.
Definition: blockdev.h:21

References block_device_capacity::blksize, san_device::blksize_shift, san_command_rw_params::block_rw, buffer, san_command_rw_params::buffer, san_device::capacity, count, san_command_rw_params::count, lba, san_command_rw_params::lba, block_device_capacity::max_count, rc, san_command_params::rw, sandev_command(), and sandev_command_rw().

Referenced by efi_block_rw(), int13_extended_rw(), int13_rw_sectors(), sandev_read(), and sandev_write().

◆ sandev_read()

int sandev_read ( struct san_device sandev,
uint64_t  lba,
unsigned int  count,
void *  buffer 
)

Read from SAN device.

Parameters
sandevSAN device
lbaStarting logical block address
countNumber of logical blocks
bufferData buffer
Return values
rcReturn status code

Definition at line 646 of file sanboot.c.

647  {
648  int rc;
649 
650  /* Read from device */
651  if ( ( rc = sandev_rw ( sandev, lba, count, buffer,
652  block_read ) ) != 0 )
653  return rc;
654 
655  return 0;
656 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
static unsigned int count
Number of entries.
Definition: dwmac.h:225
uint64_t lba
Starting block number.
Definition: int13.h:22
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len))
Read from or write to SAN device.
Definition: sanboot.c:597
int block_read(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Read from block device.
Definition: blockdev.c:47

References block_read(), buffer, count, lba, rc, and sandev_rw().

Referenced by efi_block_io_read(), int13_cdrom_read_boot_catalog(), int13_extended_read(), int13_guess_geometry_hdd(), int13_parse_eltorito(), int13_read_sectors(), and sandev_parse_iso9660().

◆ sandev_write()

int sandev_write ( struct san_device sandev,
uint64_t  lba,
unsigned int  count,
void *  buffer 
)

Write to SAN device.

Parameters
sandevSAN device
lbaStarting logical block address
countNumber of logical blocks
bufferData buffer
Return values
rcReturn status code

Definition at line 667 of file sanboot.c.

668  {
669  int rc;
670 
671  /* Write to device */
672  if ( ( rc = sandev_rw ( sandev, lba, count, buffer,
673  block_write ) ) != 0 )
674  return rc;
675 
676  /* Quiesce system. This is a heuristic designed to ensure
677  * that the system is quiesced before Windows starts up, since
678  * a Windows SAN boot will typically write a status flag to
679  * the disk as its last action before transferring control to
680  * the native drivers.
681  */
682  quiesce();
683 
684  return 0;
685 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
int block_write(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Write to block device.
Definition: blockdev.c:78
void quiesce(void)
Quiesce system.
Definition: quiesce.c:36
static unsigned int count
Number of entries.
Definition: dwmac.h:225
uint64_t lba
Starting block number.
Definition: int13.h:22
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len))
Read from or write to SAN device.
Definition: sanboot.c:597

References block_write(), buffer, count, lba, quiesce(), rc, and sandev_rw().

Referenced by efi_block_io_write(), int13_extended_write(), and int13_write_sectors().

◆ sandev_describe()

static int sandev_describe ( struct san_device sandev)
static

Describe SAN device.

Parameters
sandevSAN device
Return values
rcReturn status code

Allow connections to progress until all existent path descriptors are complete.

Definition at line 696 of file sanboot.c.

696  {
697  struct san_path *sanpath;
698  struct acpi_descriptor *desc;
699  int rc;
700 
701  /* Wait for all paths to be either described or closed */
702  while ( 1 ) {
703 
704  /* Allow connections to progress */
705  step();
706 
707  /* Fail if any closed path has an incomplete descriptor */
708  list_for_each_entry ( sanpath, &sandev->closed, list ) {
709  desc = sanpath->desc;
710  if ( ! desc )
711  continue;
712  if ( ( rc = desc->model->complete ( desc ) ) != 0 ) {
713  DBGC ( sandev->drive, "SAN %#02x.%d could not "
714  "be described: %s\n", sandev->drive,
715  sanpath->index, strerror ( rc ) );
716  return rc;
717  }
718  }
719 
720  /* Succeed if no paths have an incomplete descriptor */
721  rc = 0;
722  list_for_each_entry ( sanpath, &sandev->opened, list ) {
723  desc = sanpath->desc;
724  if ( ! desc )
725  continue;
726  if ( ( rc = desc->model->complete ( desc ) ) != 0 )
727  break;
728  }
729  if ( rc == 0 )
730  return 0;
731  }
732 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:96
unsigned int index
Path index.
Definition: sanboot.h:40
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
A SAN path.
Definition: sanboot.h:36
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
struct list_head list
List of ACPI descriptors for this model.
Definition: acpi.h:300
unsigned int drive
Drive number.
Definition: sanboot.h:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:98
An ACPI descriptor (used to construct ACPI tables)
Definition: acpi.h:294
void step(void)
Single-step a single process.
Definition: process.c:98
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:54

References san_device::closed, DBGC, desc, san_path::desc, san_device::drive, san_path::index, acpi_descriptor::list, list_for_each_entry, san_device::opened, rc, step(), and strerror().

Referenced by register_sandev().

◆ sandev_undescribe()

static void sandev_undescribe ( struct san_device sandev)
static

Remove SAN device descriptors.

Parameters
sandevSAN device

Definition at line 739 of file sanboot.c.

739  {
740  struct san_path *sanpath;
741  unsigned int i;
742 
743  /* Remove all ACPI descriptors */
744  for ( i = 0 ; i < sandev->paths ; i++ ) {
745  sanpath = &sandev->path[i];
746  if ( sanpath->desc ) {
747  acpi_del ( sanpath->desc );
748  sanpath->desc = NULL;
749  }
750  }
751 }
struct san_path path[0]
SAN paths.
Definition: sanboot.h:100
void acpi_del(struct acpi_descriptor *desc)
Remove ACPI descriptor.
Definition: acpi.c:306
A SAN path.
Definition: sanboot.h:36
unsigned int paths
Number of paths.
Definition: sanboot.h:92
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:54
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References acpi_del(), san_path::desc, NULL, san_device::path, san_device::paths, and san_path::sandev.

Referenced by register_sandev(), and unregister_sandev().

◆ sandev_parse_iso9660()

static int sandev_parse_iso9660 ( struct san_device sandev)
static

Configure SAN device as a CD-ROM, if applicable.

Parameters
sandevSAN device
Return values
rcReturn status code

Both BIOS and UEFI require SAN devices to be accessed with a block size of 2048. While we could require the user to configure the block size appropriately, this is non-trivial and would impose a substantial learning effort on the user. Instead, we check for the presence of the ISO9660 primary volume descriptor and, if found, then we force a block size of 2048 and map read/write requests appropriately.

Definition at line 767 of file sanboot.c.

767  {
768  static const struct iso9660_primary_descriptor_fixed primary_check = {
770  .id = ISO9660_ID,
771  };
772  union {
774  char bytes[ISO9660_BLKSIZE];
775  } *scratch;
776  unsigned int blksize;
777  unsigned int blksize_shift;
778  unsigned int lba;
779  unsigned int count;
780  int rc;
781 
782  /* Calculate required blocksize shift for potential CD-ROM access */
783  blksize = sandev->capacity.blksize;
784  blksize_shift = 0;
785  while ( blksize < ISO9660_BLKSIZE ) {
786  blksize <<= 1;
787  blksize_shift++;
788  }
789  if ( blksize > ISO9660_BLKSIZE ) {
790  /* Cannot be a CD-ROM. This is not an error. */
791  rc = 0;
792  goto invalid_blksize;
793  }
794  lba = ( ISO9660_PRIMARY_LBA << blksize_shift );
795  count = ( 1 << blksize_shift );
796 
797  /* Allocate scratch area */
798  scratch = malloc ( ISO9660_BLKSIZE );
799  if ( ! scratch ) {
800  rc = -ENOMEM;
801  goto err_alloc;
802  }
803 
804  /* Read primary volume descriptor */
805  if ( ( rc = sandev_read ( sandev, lba, count, scratch ) ) != 0 ) {
806  DBGC ( sandev->drive, "SAN %#02x could not read ISO9660 "
807  "primary volume descriptor: %s\n",
808  sandev->drive, strerror ( rc ) );
809  goto err_rw;
810  }
811 
812  /* Configure as CD-ROM if applicable */
813  if ( memcmp ( &scratch->primary.fixed, &primary_check,
814  sizeof ( primary_check ) ) == 0 ) {
815  DBGC ( sandev->drive, "SAN %#02x contains an ISO9660 "
816  "filesystem; treating as CD-ROM\n", sandev->drive );
817  sandev->blksize_shift = blksize_shift;
818  sandev->is_cdrom = 1;
819  }
820 
821  err_rw:
822  free ( scratch );
823  err_alloc:
824  invalid_blksize:
825  return rc;
826 }
An ISO9660 Primary Volume Descriptor.
Definition: iso9660.h:27
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct ib_cm_path primary
Primary path.
Definition: ib_mad.h:40
#define DBGC(...)
Definition: compiler.h:505
#define ISO9660_ID
ISO9660 identifier.
Definition: iso9660.h:42
#define ISO9660_TYPE_PRIMARY
ISO9660 Primary Volume Descriptor type.
Definition: iso9660.h:33
#define ENOMEM
Not enough space.
Definition: errno.h:534
An ISO9660 Primary Volume Descriptor (fixed portion)
Definition: iso9660.h:19
unsigned int drive
Drive number.
Definition: sanboot.h:65
static unsigned int count
Number of entries.
Definition: dwmac.h:225
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:84
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
int is_cdrom
Drive is a CD-ROM.
Definition: sanboot.h:86
uint64_t lba
Starting block number.
Definition: int13.h:22
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77
uint8_t type
Descriptor type.
Definition: iso9660.h:21
#define ISO9660_BLKSIZE
ISO9660 block size.
Definition: iso9660.h:16
#define ISO9660_PRIMARY_LBA
ISO9660 Primary Volume Descriptor block address.
Definition: iso9660.h:36
uint32_t blksize
Cipher block size.
Definition: pccrr.h:14
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Read from SAN device.
Definition: sanboot.c:646
uint8_t bytes[64]
Definition: ib_mad.h:16
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
size_t blksize
Block size.
Definition: blockdev.h:21

References blksize, block_device_capacity::blksize, san_device::blksize_shift, bytes, san_device::capacity, count, DBGC, san_device::drive, ENOMEM, free, san_device::is_cdrom, ISO9660_BLKSIZE, ISO9660_ID, ISO9660_PRIMARY_LBA, ISO9660_TYPE_PRIMARY, lba, malloc(), memcmp(), primary, rc, sandev_read(), strerror(), and iso9660_primary_descriptor_fixed::type.

Referenced by register_sandev().

◆ alloc_sandev()

struct san_device* alloc_sandev ( struct uri **  uris,
unsigned int  count,
size_t  priv_size 
)

Allocate SAN device.

Parameters
urisList of URIs
countNumber of URIs
priv_sizeSize of private data
Return values
sandevSAN device, or NULL

Definition at line 836 of file sanboot.c.

837  {
838  struct san_device *sandev;
839  struct san_path *sanpath;
840  size_t size;
841  unsigned int i;
842 
843  /* Allocate and initialise structure */
844  size = ( sizeof ( *sandev ) + ( count * sizeof ( sandev->path[0] ) ) );
845  sandev = zalloc ( size + priv_size );
846  if ( ! sandev )
847  return NULL;
850  timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
851  sandev->priv = ( ( ( void * ) sandev ) + size );
852  sandev->paths = count;
855  for ( i = 0 ; i < count ; i++ ) {
856  sanpath = &sandev->path[i];
857  sanpath->sandev = sandev;
858  sanpath->index = i;
859  sanpath->uri = uri_get ( uris[i] );
860  list_add_tail ( &sanpath->list, &sandev->closed );
861  intf_init ( &sanpath->block, &sanpath_block_desc,
862  &sandev->refcnt );
863  process_init_stopped ( &sanpath->process, &sanpath_process_desc,
864  &sandev->refcnt );
865  sanpath->path_rc = -EINPROGRESS;
866  }
867 
868  return sandev;
869 }
static struct interface_descriptor sandev_command_desc
SAN device command interface descriptor.
Definition: sanboot.c:176
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:194
struct san_path path[0]
SAN paths.
Definition: sanboot.h:100
static void sandev_free(struct refcnt *refcnt)
Free SAN device.
Definition: sanboot.c:122
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
uint16_t size
Buffer size.
Definition: dwmac.h:14
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:96
struct interface command
Command interface.
Definition: sanboot.h:70
A SAN path.
Definition: sanboot.h:36
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
static unsigned int count
Number of entries.
Definition: dwmac.h:225
static struct interface_descriptor sanpath_block_desc
SAN path block interface descriptor.
Definition: sanboot.c:335
#define EINPROGRESS
Operation in progress.
Definition: errno.h:418
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:98
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
A SAN device.
Definition: sanboot.h:58
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
unsigned int paths
Number of paths.
Definition: sanboot.h:92
static void sandev_command_expired(struct retry_timer *timer, int over __unused)
Handle SAN device command timeout.
Definition: sanboot.c:184
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct refcnt refcnt
Reference count.
Definition: sanboot.h:60
void * priv
Driver private data.
Definition: sanboot.h:89
static struct process_descriptor sanpath_process_desc
SAN path process descriptor.
Definition: sanboot.c:339
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:72
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:38

References san_path::block, san_device::closed, san_device::command, count, EINPROGRESS, san_path::index, INIT_LIST_HEAD, intf_init(), san_path::list, list_add_tail, NULL, san_device::opened, san_device::path, san_path::path_rc, san_device::paths, san_device::priv, san_path::process, process_init_stopped(), ref_init, san_device::refcnt, san_path::sandev, sandev_command_desc, sandev_command_expired(), sandev_free(), sanpath_block_desc, sanpath_process_desc, size, san_device::timer, san_path::uri, uri_get(), and zalloc().

Referenced by dummy_san_hook(), efi_block_hook(), and int13_hook().

◆ register_sandev()

int register_sandev ( struct san_device sandev,
unsigned int  drive,
unsigned int  flags 
)

Register SAN device.

Parameters
sandevSAN device
driveDrive number
flagsFlags
Return values
rcReturn status code

Definition at line 879 of file sanboot.c.

880  {
881  struct san_device *before;
882  int rc;
883 
884  /* Check that drive number is not in use */
885  if ( sandev_find ( drive ) != NULL ) {
886  DBGC ( sandev->drive, "SAN %#02x is already in use\n", drive );
887  rc = -EADDRINUSE;
888  goto err_in_use;
889  }
890 
891  /* Record drive number and flags */
892  sandev->drive = drive;
893  sandev->flags = flags;
894 
895  /* Check that device is capable of being opened (i.e. that all
896  * URIs are well-formed and that at least one path is
897  * working).
898  */
899  if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
900  goto err_reopen;
901 
902  /* Describe device */
903  if ( ( rc = sandev_describe ( sandev ) ) != 0 )
904  goto err_describe;
905 
906  /* Read device capacity */
908  NULL ) ) != 0 )
909  goto err_capacity;
910 
911  /* Configure as a CD-ROM, if applicable */
912  if ( ( rc = sandev_parse_iso9660 ( sandev ) ) != 0 )
913  goto err_iso9660;
914 
915  /* Add to list of SAN devices, in drive order */
916  for_each_sandev ( before ) {
917  if ( before->drive > sandev->drive )
918  break;
919  }
920  list_add_tail ( &sandev->list, &before->list );
921  DBGC ( sandev->drive, "SAN %#02x registered\n", sandev->drive );
922 
923  return 0;
924 
925  list_del ( &sandev->list );
926  err_iso9660:
927  err_capacity:
928  err_describe:
929  err_reopen:
930  sandev_restart ( sandev, rc );
931  sandev_undescribe ( sandev );
932  err_in_use:
933  return rc;
934 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int sandev_command_read_capacity(struct san_device *sandev, const union san_command_params *params __unused)
Initiate SAN device read capacity command.
Definition: sanboot.c:481
#define EADDRINUSE
Address already in use.
Definition: errno.h:303
#define DBGC(...)
Definition: compiler.h:505
int32_t before
Initial microcode version.
Definition: ucode.h:16
uint8_t drive
Drive number.
Definition: int13.h:16
static void sandev_undescribe(struct san_device *sandev)
Remove SAN device descriptors.
Definition: sanboot.c:739
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
unsigned int drive
Drive number.
Definition: sanboot.h:65
static int sandev_describe(struct san_device *sandev)
Describe SAN device.
Definition: sanboot.c:696
uint8_t flags
Flags.
Definition: ena.h:18
struct list_head list
List of SAN devices.
Definition: sanboot.h:62
A SAN device.
Definition: sanboot.h:58
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition: sanboot.h:196
static int sandev_parse_iso9660(struct san_device *sandev)
Configure SAN device as a CD-ROM, if applicable.
Definition: sanboot.c:767
static int sandev_command(struct san_device *sandev, int(*command)(struct san_device *sandev, const union san_command_params *params), const union san_command_params *params)
Execute a single SAN device command and wait for completion.
Definition: sanboot.c:510
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:91
static void sandev_restart(struct san_device *sandev, int rc)
Restart SAN device interface.
Definition: sanboot.c:348
unsigned int flags
Flags.
Definition: sanboot.h:67
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:372
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References before, DBGC, drive, san_device::drive, EADDRINUSE, flags, san_device::flags, for_each_sandev, san_device::list, list_add_tail, list_del, NULL, rc, sandev_command(), sandev_command_read_capacity(), sandev_describe(), sandev_find(), sandev_parse_iso9660(), sandev_reopen(), sandev_restart(), and sandev_undescribe().

Referenced by dummy_san_hook(), efi_block_hook(), and int13_hook().

◆ unregister_sandev()

void unregister_sandev ( struct san_device sandev)

Unregister SAN device.

Parameters
sandevSAN device

Definition at line 941 of file sanboot.c.

941  {
942 
943  /* Sanity check */
944  assert ( ! timer_running ( &sandev->timer ) );
945 
946  /* Remove from list of SAN devices */
947  list_del ( &sandev->list );
948 
949  /* Shut down interfaces */
950  sandev_restart ( sandev, 0 );
951 
952  /* Remove ACPI descriptors */
953  sandev_undescribe ( sandev );
954 
955  DBGC ( sandev->drive, "SAN %#02x unregistered\n", sandev->drive );
956 }
#define DBGC(...)
Definition: compiler.h:505
static void sandev_undescribe(struct san_device *sandev)
Remove SAN device descriptors.
Definition: sanboot.c:739
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int drive
Drive number.
Definition: sanboot.h:65
struct list_head list
List of SAN devices.
Definition: sanboot.h:62
static void sandev_restart(struct san_device *sandev, int rc)
Restart SAN device interface.
Definition: sanboot.c:348
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:72

References assert(), DBGC, san_device::drive, san_device::list, list_del, sandev_restart(), sandev_undescribe(), and san_device::timer.

Referenced by dummy_san_hook(), dummy_san_unhook(), efi_block_hook(), efi_block_unhook(), int13_hook(), and int13_unhook().

◆ __setting()

const struct setting san_retries_setting __setting ( SETTING_SANBOOT_EXTRA  ,
san-  drive 
)
Initial value:
= {
.name = "san-retries",
.description = "SAN retry count",
.type = &setting_type_int8,
}
#define DHCP_EB_SAN_RETRY
SAN retry count.
Definition: dhcp.h:465

The "san-drive" setting.

The "san-retries" setting.

◆ san_default_drive()

unsigned int san_default_drive ( void  )

Get default SAN drive number.

Return values
driveDefault drive number

Definition at line 972 of file sanboot.c.

972  {
973  unsigned long drive;
974 
975  /* Use "san-drive" setting, if specified */
976  if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
977  return drive;
978 
979  /* Otherwise, default to booting from first hard disk */
980  return SAN_DEFAULT_DRIVE;
981 }
uint8_t drive
Drive number.
Definition: int13.h:16
int fetch_uint_setting(struct settings *settings, const struct setting *setting, unsigned long *value)
Fetch value of unsigned integer setting.
Definition: settings.c:1039
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
Definition: sanboot.h:33
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References drive, fetch_uint_setting(), NULL, and SAN_DEFAULT_DRIVE.

Referenced by netboot(), and sanboot_core_exec().

◆ sandev_apply()

static int sandev_apply ( void  )
static

Apply SAN boot settings.

Return values
rcReturn status code

Definition at line 997 of file sanboot.c.

997  {
998 
999  /* Apply "san-retries" setting */
1000  if ( fetch_uint_setting ( NULL, &san_retries_setting,
1001  &san_retries ) < 0 ) {
1003  }
1004 
1005  return 0;
1006 }
int fetch_uint_setting(struct settings *settings, const struct setting *setting, unsigned long *value)
Fetch value of unsigned integer setting.
Definition: settings.c:1039
static unsigned long san_retries
Number of times to retry commands.
Definition: sanboot.c:83
#define SAN_DEFAULT_RETRIES
Default number of times to retry commands.
Definition: sanboot.c:67
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References fetch_uint_setting(), NULL, SAN_DEFAULT_RETRIES, and san_retries.

Variable Documentation

◆ san_retries

unsigned long san_retries = SAN_DEFAULT_RETRIES
static

Number of times to retry commands.

Definition at line 83 of file sanboot.c.

Referenced by sandev_apply(), and sandev_command().

◆ sandev_command_op

struct interface_operation sandev_command_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
static void sandev_command_capacity(struct san_device *sandev, struct block_device_capacity *capacity)
Record SAN device capacity.
Definition: sanboot.c:161
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition: blockdev.c:129
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
A SAN device.
Definition: sanboot.h:58
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:143

SAN device command interface operations.

Definition at line 169 of file sanboot.c.

◆ sandev_command_desc

struct interface_descriptor sandev_command_desc
static
Initial value:
=
A command-line command.
Definition: command.h:9
A SAN device.
Definition: sanboot.h:58
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
static struct interface_operation sandev_command_op[]
SAN device command interface operations.
Definition: sanboot.c:169

SAN device command interface descriptor.

Definition at line 176 of file sanboot.c.

Referenced by alloc_sandev().

◆ sanpath_block_op

struct interface_operation sanpath_block_op[]
static
Initial value:
= {
}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
A SAN path.
Definition: sanboot.h:36
static void sanpath_block_close(struct san_path *sanpath, int rc)
Handle closure of underlying block device interface.
Definition: sanboot.c:269
static size_t sanpath_block_window(struct san_path *sanpath __unused)
Check flow control window.
Definition: sanboot.c:287
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static void sanpath_step(struct san_path *sanpath)
SAN path process.
Definition: sanboot.c:301

SAN path block interface operations.

Definition at line 328 of file sanboot.c.

◆ sanpath_block_desc

struct interface_descriptor sanpath_block_desc
static
Initial value:
=
static struct interface_operation sanpath_block_op[]
SAN path block interface operations.
Definition: sanboot.c:328
A SAN path.
Definition: sanboot.h:36
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12

SAN path block interface descriptor.

Definition at line 335 of file sanboot.c.

Referenced by alloc_sandev().

◆ sanpath_process_desc

struct process_descriptor sanpath_process_desc
static
Initial value:
=
A process.
Definition: process.h:17
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:97
A SAN path.
Definition: sanboot.h:36
static void sanpath_step(struct san_path *sanpath)
SAN path process.
Definition: sanboot.c:301

SAN path process descriptor.

Definition at line 339 of file sanboot.c.

Referenced by alloc_sandev().

◆ __settings_applicator

struct settings_applicator sandev_applicator __settings_applicator
Initial value:
= {
.apply = sandev_apply,
}
static int sandev_apply(void)
Apply SAN boot settings.
Definition: sanboot.c:997

Settings applicator.

Definition at line 1009 of file sanboot.c.