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

SAN booting. More...

#include <stdint.h>
#include <stdlib.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_DEFAULT_DRIVE   0x80
 Default SAN drive number. More...
 
#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...
 
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, userptr_t buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t 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, userptr_t buffer)
 Read from SAN device. More...
 
int sandev_write (struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t 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_DEFAULT_DRIVE

#define SAN_DEFAULT_DRIVE   0x80

Default SAN drive number.

The drive number is a meaningful concept only in a BIOS environment, where it represents the INT13 drive number (0x80 for the first hard disk). We retain it in other environments to allow for a simple way for iPXE commands to refer to SAN drives.

Definition at line 55 of file sanboot.c.

◆ 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 66 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 76 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 86 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 100 of file sanboot.c.

100  {
101  struct san_device *sandev;
102 
103  list_for_each_entry ( sandev, &san_devices, list ) {
104  if ( sandev->drive == drive )
105  return sandev;
106  }
107  return NULL;
108 }
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:420
unsigned int drive
Drive number.
Definition: sanboot.h:54
struct list_head list
List of SAN devices.
Definition: sanboot.h:51
A SAN device.
Definition: sanboot.h:47
#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_boot(), efi_block_unhook(), int13_unhook(), and register_sandev().

◆ sandev_free()

static void sandev_free ( struct refcnt refcnt)
static

Free SAN device.

Parameters
refcntReference count

Definition at line 115 of file sanboot.c.

115  {
116  struct san_device *sandev =
117  container_of ( refcnt, struct san_device, refcnt );
118  unsigned int i;
119 
120  assert ( ! timer_running ( &sandev->timer ) );
121  assert ( ! sandev->active );
122  assert ( list_empty ( &sandev->opened ) );
123  for ( i = 0 ; i < sandev->paths ; i++ ) {
124  uri_put ( sandev->path[i].uri );
125  assert ( sandev->path[i].desc == NULL );
126  }
127  free ( sandev );
128 }
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:89
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:85
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:47
unsigned int paths
Number of paths.
Definition: sanboot.h:81
struct uri * uri
SAN device URI.
Definition: sanboot.h:31
struct san_path * active
Current active path.
Definition: sanboot.h:83
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:61
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:43
#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 136 of file sanboot.c.

136  {
137 
138  /* Stop timer */
139  stop_timer ( &sandev->timer );
140 
141  /* Restart interface */
142  intf_restart ( &sandev->command, rc );
143 
144  /* Record command status */
145  sandev->command_rc = rc;
146 }
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:63
struct interface command
Command interface.
Definition: sanboot.h:59
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:61

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 154 of file sanboot.c.

155  {
156 
157  /* Record raw capacity information */
158  memcpy ( &sandev->capacity, capacity, sizeof ( sandev->capacity ) );
159 }
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:66

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 177 of file sanboot.c.

178  {
179  struct san_device *sandev =
180  container_of ( timer, struct san_device, timer );
181 
182  sandev_command_close ( sandev, -ETIMEDOUT );
183 }
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:47
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:136
#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 191 of file sanboot.c.

191  {
192  struct san_device *sandev = sanpath->sandev;
193  int rc;
194 
195  /* Sanity check */
196  list_check_contains_entry ( sanpath, &sandev->closed, list );
197 
198  /* Open interface */
199  if ( ( rc = xfer_open_uri ( &sanpath->block, sanpath->uri ) ) != 0 ) {
200  DBGC ( sandev, "SAN %#02x.%d could not (re)open URI: "
201  "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
202  return rc;
203  }
204 
205  /* Update ACPI descriptor, if applicable */
206  if ( ! ( sandev->flags & SAN_NO_DESCRIBE ) ) {
207  if ( sanpath->desc )
208  acpi_del ( sanpath->desc );
209  sanpath->desc = acpi_describe ( &sanpath->block );
210  if ( sanpath->desc )
211  acpi_add ( sanpath->desc );
212  }
213 
214  /* Start process */
215  process_add ( &sanpath->process );
216 
217  /* Mark as opened */
218  list_del ( &sanpath->list );
219  list_add_tail ( &sanpath->list, &sandev->opened );
220 
221  /* Record as in progress */
222  sanpath->path_rc = -EINPROGRESS;
223 
224  return 0;
225 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of open/closed paths.
Definition: sanboot.h:33
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:36
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:85
unsigned int index
Path index.
Definition: sanboot.h:29
void acpi_del(struct acpi_descriptor *desc)
Remove ACPI descriptor.
Definition: acpi.c:299
#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:54
#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:87
struct list_head list
List of SAN devices.
Definition: sanboot.h:51
int path_rc
Path status.
Definition: sanboot.h:40
A SAN device.
Definition: sanboot.h:47
Device should not be included in description tables.
Definition: sanboot.h:95
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:313
struct uri * uri
SAN device URI.
Definition: sanboot.h:31
struct process process
Process.
Definition: sanboot.h:38
unsigned int flags
Flags.
Definition: sanboot.h:56
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition: list.h:522
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:43
void acpi_add(struct acpi_descriptor *desc)
Add ACPI descriptor.
Definition: acpi.c:287
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

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 233 of file sanboot.c.

233  {
234  struct san_device *sandev = sanpath->sandev;
235 
236  /* Record status */
237  sanpath->path_rc = rc;
238 
239  /* Mark as closed */
240  list_del ( &sanpath->list );
241  list_add_tail ( &sanpath->list, &sandev->closed );
242 
243  /* Stop process */
244  process_del ( &sanpath->process );
245 
246  /* Restart interfaces, avoiding potential loops */
247  if ( sanpath == sandev->active ) {
248  intfs_restart ( rc, &sandev->command, &sanpath->block, NULL );
249  sandev->active = NULL;
250  sandev_command_close ( sandev, rc );
251  } else {
252  intf_restart ( &sanpath->block, rc );
253  }
254 }
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:33
struct interface block
Underlying block device interface.
Definition: sanboot.h:36
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:59
#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:87
int path_rc
Path status.
Definition: sanboot.h:40
A SAN device.
Definition: sanboot.h:47
struct process process
Process.
Definition: sanboot.h:38
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:136
struct san_path * active
Current active path.
Definition: sanboot.h:83
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

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 262 of file sanboot.c.

262  {
263  struct san_device *sandev = sanpath->sandev;
264 
265  /* Any closure is an error from our point of view */
266  if ( rc == 0 )
267  rc = -ENOTCONN;
268  DBGC ( sandev, "SAN %#02x.%d closed: %s\n",
269  sandev->drive, sanpath->index, strerror ( rc ) );
270 
271  /* Close path */
272  sanpath_close ( sanpath, rc );
273 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned int index
Path index.
Definition: sanboot.h:29
unsigned int drive
Drive number.
Definition: sanboot.h:54
#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:47
static void sanpath_close(struct san_path *sanpath, int rc)
Close SAN path.
Definition: sanboot.c:233
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

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 280 of file sanboot.c.

280  {
281 
282  /* We are never ready to receive data via this interface.
283  * This prevents objects that support both block and stream
284  * interfaces from attempting to send us stream data.
285  */
286  return 0;
287 }

◆ sanpath_step()

static void sanpath_step ( struct san_path sanpath)
static

SAN path process.

Parameters
sanpathSAN path

Definition at line 294 of file sanboot.c.

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

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 341 of file sanboot.c.

341  {
342  struct san_path *sanpath;
343 
344  /* Restart all block device interfaces */
345  while ( ( sanpath = list_first_entry ( &sandev->opened,
346  struct san_path, list ) ) ) {
347  sanpath_close ( sanpath, rc );
348  }
349 
350  /* Clear active path */
351  sandev->active = NULL;
352 
353  /* Close any outstanding command */
355 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of open/closed paths.
Definition: sanboot.h:33
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:85
#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:25
static void sanpath_close(struct san_path *sanpath, int rc)
Close SAN path.
Definition: sanboot.c:233
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:136
struct san_path * active
Current active path.
Definition: sanboot.h:83
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

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 365 of file sanboot.c.

365  {
366  struct san_path *sanpath;
367  int rc;
368 
369  /* Unquiesce system */
370  unquiesce();
371 
372  /* Close any outstanding command and restart interfaces */
374  assert ( sandev->active == NULL );
375  assert ( list_empty ( &sandev->opened ) );
376 
377  /* Open all paths */
378  while ( ( sanpath = list_first_entry ( &sandev->closed,
379  struct san_path, list ) ) ) {
380  if ( ( rc = sanpath_open ( sanpath ) ) != 0 )
381  goto err_open;
382  }
383 
384  /* Wait for any device to become available, or for all devices
385  * to fail.
386  */
387  while ( sandev->active == NULL ) {
388  step();
389  if ( list_empty ( &sandev->opened ) ) {
390  /* Get status of the first device to be
391  * closed. Do this on the basis that earlier
392  * errors (e.g. "invalid IQN") are probably
393  * more interesting than later errors
394  * (e.g. "TCP timeout").
395  */
396  rc = -ENODEV;
397  list_for_each_entry ( sanpath, &sandev->closed, list ) {
398  rc = sanpath->path_rc;
399  break;
400  }
401  DBGC ( sandev, "SAN %#02x never became available: %s\n",
402  sandev->drive, strerror ( rc ) );
403  goto err_none;
404  }
405  }
406 
407  assert ( ! list_empty ( &sandev->opened ) );
408  return 0;
409 
410  err_none:
411  err_open:
412  sandev_restart ( sandev, rc );
413  return rc;
414 }
#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:33
#define DBGC(...)
Definition: compiler.h:505
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:85
#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:25
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
unsigned int drive
Drive number.
Definition: sanboot.h:54
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:87
int path_rc
Path status.
Definition: sanboot.h:40
#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:341
struct san_path * active
Current active path.
Definition: sanboot.h:83
static int sanpath_open(struct san_path *sanpath)
Open SAN path.
Definition: sanboot.c:191
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:27

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 443 of file sanboot.c.

444  {
445  struct san_path *sanpath = sandev->active;
446  size_t len = ( params->rw.count * sandev->capacity.blksize );
447  int rc;
448 
449  /* Sanity check */
450  assert ( sanpath != NULL );
451 
452  /* Initiate read/write command */
453  if ( ( rc = params->rw.block_rw ( &sanpath->block, &sandev->command,
454  params->rw.lba, params->rw.count,
455  params->rw.buffer, len ) ) != 0 ) {
456  DBGC ( sandev, "SAN %#02x.%d could not initiate read/write: "
457  "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
458  return rc;
459  }
460 
461  return 0;
462 }
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:36
unsigned int index
Path index.
Definition: sanboot.h:29
struct interface command
Command interface.
Definition: sanboot.h:59
struct san_command_rw_params rw
Read/write command parameters.
Definition: sanboot.c:433
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:25
unsigned int drive
Drive number.
Definition: sanboot.h:54
userptr_t buffer
Data buffer.
Definition: sanboot.c:423
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
unsigned int count
Block count.
Definition: sanboot.c:427
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:66
uint32_t len
Length.
Definition: ena.h:14
int(* block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len)
SAN device read/write operation.
Definition: sanboot.c:419
uint64_t lba
Starting LBA.
Definition: sanboot.c:425
struct san_path * active
Current active path.
Definition: sanboot.h:83
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27
size_t blksize
Block size.
Definition: blockdev.h:22

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 472 of file sanboot.c.

473  {
474  struct san_path *sanpath = sandev->active;
475  int rc;
476 
477  /* Sanity check */
478  assert ( sanpath != NULL );
479 
480  /* Initiate read capacity command */
481  if ( ( rc = block_read_capacity ( &sanpath->block,
482  &sandev->command ) ) != 0 ) {
483  DBGC ( sandev, "SAN %#02x.%d could not initiate read capacity: "
484  "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
485  return rc;
486  }
487 
488  return 0;
489 }
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:36
unsigned int index
Path index.
Definition: sanboot.h:29
struct interface command
Command interface.
Definition: sanboot.h:59
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:25
unsigned int drive
Drive number.
Definition: sanboot.h:54
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct san_path * active
Current active path.
Definition: sanboot.h:83
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:27

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 500 of file sanboot.c.

503  {
504  unsigned int retries = 0;
505  int rc;
506 
507  /* Sanity check */
508  assert ( ! timer_running ( &sandev->timer ) );
509 
510  /* Unquiesce system */
511  unquiesce();
512 
513  /* (Re)try command */
514  do {
515 
516  /* Reopen block device if applicable */
517  if ( sandev_needs_reopen ( sandev ) &&
518  ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) {
519 
520  /* Delay reopening attempts */
522 
523  /* Retry opening indefinitely for multipath devices */
524  if ( sandev->paths <= 1 )
525  retries++;
526 
527  continue;
528  }
529 
530  /* Initiate command */
531  if ( ( rc = command ( sandev, params ) ) != 0 ) {
532  retries++;
533  continue;
534  }
535 
536  /* Start expiry timer */
538 
539  /* Wait for command to complete */
540  while ( timer_running ( &sandev->timer ) )
541  step();
542 
543  /* Check command status */
544  if ( ( rc = sandev->command_rc ) != 0 ) {
545  retries++;
546  continue;
547  }
548 
549  return 0;
550 
551  } while ( retries <= san_retries );
552 
553  /* Sanity check */
554  assert ( ! timer_running ( &sandev->timer ) );
555 
556  return rc;
557 }
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:63
static int sandev_needs_reopen(struct san_device *sandev)
Check if SAN device needs to be reopened.
Definition: sanboot.h:232
#define SAN_REOPEN_DELAY_SECS
Delay between reopening attempts.
Definition: sanboot.c:86
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int paths
Number of paths.
Definition: sanboot.h:81
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:92
#define SAN_COMMAND_TIMEOUT
Timeout for block device commands (in ticks)
Definition: sanboot.c:66
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:61
void unquiesce(void)
Unquiesce system.
Definition: quiesce.c:46
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:365
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

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 565 of file sanboot.c.

565  {
566  int rc;
567 
568  DBGC ( sandev, "SAN %#02x reset\n", sandev->drive );
569 
570  /* Close and reopen underlying block device */
571  if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
572  return rc;
573 
574  return 0;
575 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned int drive
Drive number.
Definition: sanboot.h:54
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:365
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

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,
userptr_t  buffer,
int(*)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t 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 587 of file sanboot.c.

592  {
593  union san_command_params params;
594  unsigned int remaining;
595  size_t frag_len;
596  int rc;
597 
598  /* Initialise command parameters */
599  params.rw.block_rw = block_rw;
600  params.rw.buffer = buffer;
601  params.rw.lba = ( lba << sandev->blksize_shift );
602  params.rw.count = sandev->capacity.max_count;
603  remaining = ( count << sandev->blksize_shift );
604 
605  /* Read/write fragments */
606  while ( remaining ) {
607 
608  /* Determine fragment length */
609  if ( params.rw.count > remaining )
610  params.rw.count = remaining;
611 
612  /* Execute command */
613  if ( ( rc = sandev_command ( sandev, sandev_command_rw,
614  &params ) ) != 0 )
615  return rc;
616 
617  /* Move to next fragment */
618  frag_len = ( sandev->capacity.blksize * params.rw.count );
619  params.rw.buffer = userptr_add ( params.rw.buffer, frag_len );
620  params.rw.lba += params.rw.count;
621  remaining -= params.rw.count;
622  }
623 
624  return 0;
625 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned int max_count
Maximum number of blocks per single transfer.
Definition: blockdev.h:24
SAN device command parameters.
Definition: sanboot.c:431
uint32_t lba
Start address.
Definition: scsi.h:23
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
userptr_t userptr_add(userptr_t userptr, off_t offset)
Add offset to user pointer.
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:73
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:66
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:500
uint16_t count
Number of entries.
Definition: ena.h:22
static int sandev_command_rw(struct san_device *sandev, const union san_command_params *params)
Initiate SAN device read/write command.
Definition: sanboot.c:443
size_t blksize
Block size.
Definition: blockdev.h:22

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(), sandev_command_rw(), and userptr_add().

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,
userptr_t  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 636 of file sanboot.c.

637  {
638  int rc;
639 
640  /* Read from device */
641  if ( ( rc = sandev_rw ( sandev, lba, count, buffer, block_read ) ) != 0 )
642  return rc;
643 
644  return 0;
645 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t lba
Start address.
Definition: scsi.h:23
static 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))
Read from or write to SAN device.
Definition: sanboot.c:587
int block_read(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len)
Read from block device.
Definition: blockdev.c:47
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
uint16_t count
Number of entries.
Definition: ena.h:22

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,
userptr_t  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 656 of file sanboot.c.

657  {
658  int rc;
659 
660  /* Write to device */
661  if ( ( rc = sandev_rw ( sandev, lba, count, buffer, block_write ) ) != 0 )
662  return rc;
663 
664  /* Quiesce system. This is a heuristic designed to ensure
665  * that the system is quiesced before Windows starts up, since
666  * a Windows SAN boot will typically write a status flag to
667  * the disk as its last action before transferring control to
668  * the native drivers.
669  */
670  quiesce();
671 
672  return 0;
673 }
int block_write(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len)
Write to block device.
Definition: blockdev.c:78
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t lba
Start address.
Definition: scsi.h:23
static 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))
Read from or write to SAN device.
Definition: sanboot.c:587
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
void quiesce(void)
Quiesce system.
Definition: quiesce.c:36
uint16_t count
Number of entries.
Definition: ena.h:22

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 684 of file sanboot.c.

684  {
685  struct san_path *sanpath;
686  struct acpi_descriptor *desc;
687  int rc;
688 
689  /* Wait for all paths to be either described or closed */
690  while ( 1 ) {
691 
692  /* Allow connections to progress */
693  step();
694 
695  /* Fail if any closed path has an incomplete descriptor */
696  list_for_each_entry ( sanpath, &sandev->closed, list ) {
697  desc = sanpath->desc;
698  if ( ! desc )
699  continue;
700  if ( ( rc = desc->model->complete ( desc ) ) != 0 ) {
701  DBGC ( sandev, "SAN %#02x.%d could not be "
702  "described: %s\n", sandev->drive,
703  sanpath->index, strerror ( rc ) );
704  return rc;
705  }
706  }
707 
708  /* Succeed if no paths have an incomplete descriptor */
709  rc = 0;
710  list_for_each_entry ( sanpath, &sandev->opened, list ) {
711  desc = sanpath->desc;
712  if ( ! desc )
713  continue;
714  if ( ( rc = desc->model->complete ( desc ) ) != 0 )
715  break;
716  }
717  if ( rc == 0 )
718  return 0;
719  }
720 }
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:85
unsigned int index
Path index.
Definition: sanboot.h:29
struct acpi_model * model
Table model.
Definition: acpi.h:282
A SAN path.
Definition: sanboot.h:25
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct list_head list
List of ACPI descriptors for this model.
Definition: acpi.h:284
unsigned int drive
Drive number.
Definition: sanboot.h:54
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:87
int(* complete)(struct acpi_descriptor *desc)
Check if ACPI descriptor is complete.
Definition: acpi.h:313
An ACPI descriptor (used to construct ACPI tables)
Definition: acpi.h:278
void step(void)
Single-step a single process.
Definition: process.c:98
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:43

References san_device::closed, acpi_model::complete, DBGC, san_path::desc, san_device::drive, san_path::index, acpi_descriptor::list, list_for_each_entry, acpi_descriptor::model, 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 727 of file sanboot.c.

727  {
728  struct san_path *sanpath;
729  unsigned int i;
730 
731  /* Remove all ACPI descriptors */
732  for ( i = 0 ; i < sandev->paths ; i++ ) {
733  sanpath = &sandev->path[i];
734  if ( sanpath->desc ) {
735  acpi_del ( sanpath->desc );
736  sanpath->desc = NULL;
737  }
738  }
739 }
struct san_path path[0]
SAN paths.
Definition: sanboot.h:89
void acpi_del(struct acpi_descriptor *desc)
Remove ACPI descriptor.
Definition: acpi.c:299
A SAN path.
Definition: sanboot.h:25
unsigned int paths
Number of paths.
Definition: sanboot.h:81
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:43
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

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 755 of file sanboot.c.

755  {
756  static const struct iso9660_primary_descriptor_fixed primary_check = {
758  .id = ISO9660_ID,
759  };
760  union {
762  char bytes[ISO9660_BLKSIZE];
763  } *scratch;
764  unsigned int blksize;
765  unsigned int blksize_shift;
766  unsigned int lba;
767  unsigned int count;
768  int rc;
769 
770  /* Calculate required blocksize shift for potential CD-ROM access */
771  blksize = sandev->capacity.blksize;
772  blksize_shift = 0;
773  while ( blksize < ISO9660_BLKSIZE ) {
774  blksize <<= 1;
775  blksize_shift++;
776  }
777  if ( blksize > ISO9660_BLKSIZE ) {
778  /* Cannot be a CD-ROM. This is not an error. */
779  rc = 0;
780  goto invalid_blksize;
781  }
782  lba = ( ISO9660_PRIMARY_LBA << blksize_shift );
783  count = ( 1 << blksize_shift );
784 
785  /* Allocate scratch area */
786  scratch = malloc ( ISO9660_BLKSIZE );
787  if ( ! scratch ) {
788  rc = -ENOMEM;
789  goto err_alloc;
790  }
791 
792  /* Read primary volume descriptor */
793  if ( ( rc = sandev_read ( sandev, lba, count,
794  virt_to_user ( scratch ) ) ) != 0 ) {
795  DBGC ( sandev, "SAN %#02x could not read ISO9660 primary"
796  "volume descriptor: %s\n",
797  sandev->drive, strerror ( rc ) );
798  goto err_rw;
799  }
800 
801  /* Configure as CD-ROM if applicable */
802  if ( memcmp ( &scratch->primary.fixed, &primary_check,
803  sizeof ( primary_check ) ) == 0 ) {
804  DBGC ( sandev, "SAN %#02x contains an ISO9660 filesystem; "
805  "treating as CD-ROM\n", sandev->drive );
806  sandev->blksize_shift = blksize_shift;
807  sandev->is_cdrom = 1;
808  }
809 
810  err_rw:
811  free ( scratch );
812  err_alloc:
813  invalid_blksize:
814  return rc;
815 }
An ISO9660 Primary Volume Descriptor.
Definition: iso9660.h:27
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t lba
Start address.
Definition: scsi.h:23
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
uint32_t blksize
Block size for this segment.
Definition: pccrc.h:24
#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:54
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:73
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:75
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:636
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:66
uint8_t type
Descriptor type.
Definition: iso9660.h:21
uint16_t count
Number of entries.
Definition: ena.h:22
#define ISO9660_BLKSIZE
ISO9660 block size.
Definition: iso9660.h:16
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#define ISO9660_PRIMARY_LBA
ISO9660 Primary Volume Descriptor block address.
Definition: iso9660.h:36
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:22

References block_device_capacity::blksize, 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(), iso9660_primary_descriptor_fixed::type, and virt_to_user().

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 825 of file sanboot.c.

826  {
827  struct san_device *sandev;
828  struct san_path *sanpath;
829  size_t size;
830  unsigned int i;
831 
832  /* Allocate and initialise structure */
833  size = ( sizeof ( *sandev ) + ( count * sizeof ( sandev->path[0] ) ) );
834  sandev = zalloc ( size + priv_size );
835  if ( ! sandev )
836  return NULL;
839  timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
840  sandev->priv = ( ( ( void * ) sandev ) + size );
841  sandev->paths = count;
844  for ( i = 0 ; i < count ; i++ ) {
845  sanpath = &sandev->path[i];
846  sanpath->sandev = sandev;
847  sanpath->index = i;
848  sanpath->uri = uri_get ( uris[i] );
849  list_add_tail ( &sanpath->list, &sandev->closed );
850  intf_init ( &sanpath->block, &sanpath_block_desc,
851  &sandev->refcnt );
852  process_init_stopped ( &sanpath->process, &sanpath_process_desc,
853  &sandev->refcnt );
854  sanpath->path_rc = -EINPROGRESS;
855  }
856 
857  return sandev;
858 }
static struct interface_descriptor sandev_command_desc
SAN device command interface descriptor.
Definition: sanboot.c:169
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:89
static void sandev_free(struct refcnt *refcnt)
Free SAN device.
Definition: sanboot.c:115
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:85
struct interface command
Command interface.
Definition: sanboot.h:59
A SAN path.
Definition: sanboot.h:25
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
static struct interface_descriptor sanpath_block_desc
SAN path block interface descriptor.
Definition: sanboot.c:328
#define EINPROGRESS
Operation in progress.
Definition: errno.h:418
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:87
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
A SAN device.
Definition: sanboot.h:47
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:81
static void sandev_command_expired(struct retry_timer *timer, int over __unused)
Handle SAN device command timeout.
Definition: sanboot.c:177
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct refcnt refcnt
Reference count.
Definition: sanboot.h:49
void * priv
Driver private data.
Definition: sanboot.h:78
static struct process_descriptor sanpath_process_desc
SAN path process descriptor.
Definition: sanboot.c:332
uint16_t count
Number of entries.
Definition: ena.h:22
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:61
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:27

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 868 of file sanboot.c.

869  {
870  int rc;
871 
872  /* Check that drive number is not in use */
873  if ( sandev_find ( drive ) != NULL ) {
874  DBGC ( sandev, "SAN %#02x is already in use\n", drive );
875  rc = -EADDRINUSE;
876  goto err_in_use;
877  }
878 
879  /* Record drive number and flags */
880  sandev->drive = drive;
881  sandev->flags = flags;
882 
883  /* Check that device is capable of being opened (i.e. that all
884  * URIs are well-formed and that at least one path is
885  * working).
886  */
887  if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
888  goto err_reopen;
889 
890  /* Describe device */
891  if ( ( rc = sandev_describe ( sandev ) ) != 0 )
892  goto err_describe;
893 
894  /* Read device capacity */
896  NULL ) ) != 0 )
897  goto err_capacity;
898 
899  /* Configure as a CD-ROM, if applicable */
900  if ( ( rc = sandev_parse_iso9660 ( sandev ) ) != 0 )
901  goto err_iso9660;
902 
903  /* Add to list of SAN devices */
905  DBGC ( sandev, "SAN %#02x registered\n", sandev->drive );
906 
907  return 0;
908 
909  list_del ( &sandev->list );
910  err_iso9660:
911  err_capacity:
912  err_describe:
913  err_reopen:
914  sandev_restart ( sandev, rc );
916  err_in_use:
917  return rc;
918 }
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:472
#define EADDRINUSE
Address already in use.
Definition: errno.h:303
#define DBGC(...)
Definition: compiler.h:505
struct list_head san_devices
uint8_t drive
Drive number.
Definition: int13.h:16
static void sandev_undescribe(struct san_device *sandev)
Remove SAN device descriptors.
Definition: sanboot.c:727
#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:54
static int sandev_describe(struct san_device *sandev)
Describe SAN device.
Definition: sanboot.c:684
struct list_head list
List of SAN devices.
Definition: sanboot.h:51
static int sandev_parse_iso9660(struct san_device *sandev)
Configure SAN device as a CD-ROM, if applicable.
Definition: sanboot.c:755
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:500
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:100
static void sandev_restart(struct san_device *sandev, int rc)
Restart SAN device interface.
Definition: sanboot.c:341
unsigned int flags
Flags.
Definition: sanboot.h:56
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:365
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27
uint8_t flags
Flags.
Definition: ena.h:18

References DBGC, drive, san_device::drive, EADDRINUSE, flags, san_device::flags, san_device::list, list_add_tail, list_del, NULL, rc, san_devices, san_path::sandev, 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 925 of file sanboot.c.

925  {
926 
927  /* Sanity check */
928  assert ( ! timer_running ( &sandev->timer ) );
929 
930  /* Remove from list of SAN devices */
931  list_del ( &sandev->list );
932 
933  /* Shut down interfaces */
934  sandev_restart ( sandev, 0 );
935 
936  /* Remove ACPI descriptors */
938 
939  DBGC ( sandev, "SAN %#02x unregistered\n", sandev->drive );
940 }
#define DBGC(...)
Definition: compiler.h:505
static void sandev_undescribe(struct san_device *sandev)
Remove SAN device descriptors.
Definition: sanboot.c:727
#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:54
struct list_head list
List of SAN devices.
Definition: sanboot.h:51
static void sandev_restart(struct san_device *sandev, int rc)
Restart SAN device interface.
Definition: sanboot.c:341
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:61
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:27

References assert(), DBGC, san_device::drive, san_device::list, list_del, san_path::sandev, 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:463

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 956 of file sanboot.c.

956  {
957  unsigned long drive;
958 
959  /* Use "san-drive" setting, if specified */
960  if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
961  return drive;
962 
963  /* Otherwise, default to booting from first hard disk */
964  return SAN_DEFAULT_DRIVE;
965 }
uint8_t drive
Drive number.
Definition: int13.h:16
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
Definition: sanboot.c:55
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 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 981 of file sanboot.c.

981  {
982 
983  /* Apply "san-retries" setting */
984  if ( fetch_uint_setting ( NULL, &san_retries_setting,
985  &san_retries ) < 0 ) {
987  }
988 
989  return 0;
990 }
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:92
#define SAN_DEFAULT_RETRIES
Default number of times to retry commands.
Definition: sanboot.c:76
#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 92 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:154
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:47
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:136

SAN device command interface operations.

Definition at line 162 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:47
#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:162

SAN device command interface descriptor.

Definition at line 169 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:25
static void sanpath_block_close(struct san_path *sanpath, int rc)
Handle closure of underlying block device interface.
Definition: sanboot.c:262
static size_t sanpath_block_window(struct san_path *sanpath __unused)
Check flow control window.
Definition: sanboot.c:280
#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:294

SAN path block interface operations.

Definition at line 321 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:321
uint16_t block
Definition: tftp.h:12
A SAN path.
Definition: sanboot.h:25
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

SAN path block interface descriptor.

Definition at line 328 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:25
static void sanpath_step(struct san_path *sanpath)
SAN path process.
Definition: sanboot.c:294

SAN path process descriptor.

Definition at line 332 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:981

Settings applicator.

Definition at line 993 of file sanboot.c.