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_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, 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_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 56 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 66 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 76 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 90 of file sanboot.c.

90  {
91  struct san_device *sandev;
92 
93  list_for_each_entry ( sandev, &san_devices, list ) {
94  if ( sandev->drive == drive )
95  return sandev;
96  }
97  return NULL;
98 }
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 106 of file sanboot.c.

106  {
107  struct san_device *sandev;
108 
109  list_for_each_entry ( sandev, &san_devices, list ) {
110  if ( sandev->drive >= drive )
111  return sandev;
112  }
113  return NULL;
114 }
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 121 of file sanboot.c.

121  {
122  struct san_device *sandev =
123  container_of ( refcnt, struct san_device, refcnt );
124  unsigned int i;
125 
126  assert ( ! timer_running ( &sandev->timer ) );
127  assert ( ! sandev->active );
128  assert ( list_empty ( &sandev->opened ) );
129  for ( i = 0 ; i < sandev->paths ; i++ ) {
130  uri_put ( sandev->path[i].uri );
131  assert ( sandev->path[i].desc == NULL );
132  }
133  free ( sandev );
134 }
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 142 of file sanboot.c.

142  {
143 
144  /* Stop timer */
145  stop_timer ( &sandev->timer );
146 
147  /* Restart interface */
148  intf_restart ( &sandev->command, rc );
149 
150  /* Record command status */
151  sandev->command_rc = rc;
152 }
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 160 of file sanboot.c.

161  {
162 
163  /* Record raw capacity information */
164  memcpy ( &sandev->capacity, capacity, sizeof ( sandev->capacity ) );
165 }
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 183 of file sanboot.c.

184  {
185  struct san_device *sandev =
186  container_of ( timer, struct san_device, timer );
187 
188  sandev_command_close ( sandev, -ETIMEDOUT );
189 }
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:142
#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 197 of file sanboot.c.

197  {
198  struct san_device *sandev = sanpath->sandev;
199  int rc;
200 
201  /* Sanity check */
202  list_check_contains_entry ( sanpath, &sandev->closed, list );
203 
204  /* Open interface */
205  if ( ( rc = xfer_open_uri ( &sanpath->block, sanpath->uri ) ) != 0 ) {
206  DBGC ( sandev->drive, "SAN %#02x.%d could not (re)open URI: "
207  "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
208  return rc;
209  }
210 
211  /* Update ACPI descriptor, if applicable */
212  if ( ! ( sandev->flags & SAN_NO_DESCRIBE ) ) {
213  if ( sanpath->desc )
214  acpi_del ( sanpath->desc );
215  sanpath->desc = acpi_describe ( &sanpath->block );
216  if ( sanpath->desc )
217  acpi_add ( sanpath->desc );
218  }
219 
220  /* Start process */
221  process_add ( &sanpath->process );
222 
223  /* Mark as opened */
224  list_del ( &sanpath->list );
225  list_add_tail ( &sanpath->list, &sandev->opened );
226 
227  /* Record as in progress */
228  sanpath->path_rc = -EINPROGRESS;
229 
230  return 0;
231 }
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: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: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:313
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:287
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 239 of file sanboot.c.

239  {
240  struct san_device *sandev = sanpath->sandev;
241 
242  /* Record status */
243  sanpath->path_rc = rc;
244 
245  /* Mark as closed */
246  list_del ( &sanpath->list );
247  list_add_tail ( &sanpath->list, &sandev->closed );
248 
249  /* Stop process */
250  process_del ( &sanpath->process );
251 
252  /* Restart interfaces, avoiding potential loops */
253  if ( sanpath == sandev->active ) {
254  intfs_restart ( rc, &sandev->command, &sanpath->block, NULL );
255  sandev->active = NULL;
256  sandev_command_close ( sandev, rc );
257  } else {
258  intf_restart ( &sanpath->block, rc );
259  }
260 }
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:142
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 268 of file sanboot.c.

268  {
269  struct san_device *sandev = sanpath->sandev;
270 
271  /* Any closure is an error from our point of view */
272  if ( rc == 0 )
273  rc = -ENOTCONN;
274  DBGC ( sandev->drive, "SAN %#02x.%d closed: %s\n",
275  sandev->drive, sanpath->index, strerror ( rc ) );
276 
277  /* Close path */
278  sanpath_close ( sanpath, rc );
279 }
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:239
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 286 of file sanboot.c.

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

◆ sanpath_step()

static void sanpath_step ( struct san_path sanpath)
static

SAN path process.

Parameters
sanpathSAN path

Definition at line 300 of file sanboot.c.

300  {
301  struct san_device *sandev = sanpath->sandev;
302 
303  /* Ignore if we are already the active device */
304  if ( sanpath == sandev->active )
305  return;
306 
307  /* Wait until path has become available */
308  if ( ! xfer_window ( &sanpath->block ) )
309  return;
310 
311  /* Record status */
312  sanpath->path_rc = 0;
313 
314  /* Mark as active path or close as applicable */
315  if ( ! sandev->active ) {
316  DBGC ( sandev->drive, "SAN %#02x.%d is active\n",
317  sandev->drive, sanpath->index );
318  sandev->active = sanpath;
319  } else {
320  DBGC ( sandev->drive, "SAN %#02x.%d is available\n",
321  sandev->drive, sanpath->index );
322  sanpath_close ( sanpath, 0 );
323  }
324 }
#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:239
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 347 of file sanboot.c.

347  {
348  struct san_path *sanpath;
349 
350  /* Restart all block device interfaces */
351  while ( ( sanpath = list_first_entry ( &sandev->opened,
352  struct san_path, list ) ) ) {
353  sanpath_close ( sanpath, rc );
354  }
355 
356  /* Clear active path */
357  sandev->active = NULL;
358 
359  /* Close any outstanding command */
361 }
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:239
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:142
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 371 of file sanboot.c.

371  {
372  struct san_path *sanpath;
373  int rc;
374 
375  /* Unquiesce system */
376  unquiesce();
377 
378  /* Close any outstanding command and restart interfaces */
380  assert ( sandev->active == NULL );
381  assert ( list_empty ( &sandev->opened ) );
382 
383  /* Open all paths */
384  while ( ( sanpath = list_first_entry ( &sandev->closed,
385  struct san_path, list ) ) ) {
386  if ( ( rc = sanpath_open ( sanpath ) ) != 0 )
387  goto err_open;
388  }
389 
390  /* Wait for any device to become available, or for all devices
391  * to fail.
392  */
393  while ( sandev->active == NULL ) {
394  step();
395  if ( list_empty ( &sandev->opened ) ) {
396  /* Get status of the first device to be
397  * closed. Do this on the basis that earlier
398  * errors (e.g. "invalid IQN") are probably
399  * more interesting than later errors
400  * (e.g. "TCP timeout").
401  */
402  rc = -ENODEV;
403  list_for_each_entry ( sanpath, &sandev->closed, list ) {
404  rc = sanpath->path_rc;
405  break;
406  }
407  DBGC ( sandev->drive, "SAN %#02x never became "
408  "available: %s\n", sandev->drive,
409  strerror ( rc ) );
410  goto err_none;
411  }
412  }
413 
414  assert ( ! list_empty ( &sandev->opened ) );
415  return 0;
416 
417  err_none:
418  err_open:
419  sandev_restart ( sandev, rc );
420  return rc;
421 }
#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:347
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:197
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 450 of file sanboot.c.

451  {
452  struct san_path *sanpath = sandev->active;
453  size_t len = ( params->rw.count * sandev->capacity.blksize );
454  int rc;
455 
456  /* Sanity check */
457  assert ( sanpath != NULL );
458 
459  /* Initiate read/write command */
460  if ( ( rc = params->rw.block_rw ( &sanpath->block, &sandev->command,
461  params->rw.lba, params->rw.count,
462  params->rw.buffer, len ) ) != 0 ) {
463  DBGC ( sandev->drive, "SAN %#02x.%d could not initiate "
464  "read/write: %s\n", sandev->drive, sanpath->index,
465  strerror ( rc ) );
466  return rc;
467  }
468 
469  return 0;
470 }
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
struct san_command_rw_params rw
Read/write command parameters.
Definition: sanboot.c:440
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
userptr_t buffer
Data buffer.
Definition: sanboot.c:430
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
unsigned int count
Block count.
Definition: sanboot.c:434
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77
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:426
uint64_t lba
Starting LBA.
Definition: sanboot.c:432
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: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 480 of file sanboot.c.

481  {
482  struct san_path *sanpath = sandev->active;
483  int rc;
484 
485  /* Sanity check */
486  assert ( sanpath != NULL );
487 
488  /* Initiate read capacity command */
489  if ( ( rc = block_read_capacity ( &sanpath->block,
490  &sandev->command ) ) != 0 ) {
491  DBGC ( sandev->drive, "SAN %#02x.%d could not initiate read "
492  "capacity: %s\n", sandev->drive, sanpath->index,
493  strerror ( rc ) );
494  return rc;
495  }
496 
497  return 0;
498 }
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 509 of file sanboot.c.

512  {
513  unsigned int retries = 0;
514  int rc;
515 
516  /* Sanity check */
517  assert ( ! timer_running ( &sandev->timer ) );
518 
519  /* Unquiesce system */
520  unquiesce();
521 
522  /* (Re)try command */
523  do {
524 
525  /* Reopen block device if applicable */
526  if ( sandev_needs_reopen ( sandev ) &&
527  ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) {
528 
529  /* Delay reopening attempts */
531 
532  /* Retry opening indefinitely for multipath devices */
533  if ( sandev->paths <= 1 )
534  retries++;
535 
536  continue;
537  }
538 
539  /* Initiate command */
540  if ( ( rc = command ( sandev, params ) ) != 0 ) {
541  retries++;
542  continue;
543  }
544 
545  /* Start expiry timer */
547 
548  /* Wait for command to complete */
549  while ( timer_running ( &sandev->timer ) )
550  step();
551 
552  /* Check command status */
553  if ( ( rc = sandev->command_rc ) != 0 ) {
554  retries++;
555  continue;
556  }
557 
558  return 0;
559 
560  } while ( retries <= san_retries );
561 
562  /* Sanity check */
563  assert ( ! timer_running ( &sandev->timer ) );
564 
565  return rc;
566 }
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:76
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:82
#define SAN_COMMAND_TIMEOUT
Timeout for block device commands (in ticks)
Definition: sanboot.c:56
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:371
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 574 of file sanboot.c.

574  {
575  int rc;
576 
577  DBGC ( sandev->drive, "SAN %#02x reset\n", sandev->drive );
578 
579  /* Close and reopen underlying block device */
580  if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
581  return rc;
582 
583  return 0;
584 }
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:371
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,
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 596 of file sanboot.c.

601  {
602  union san_command_params params;
603  unsigned int remaining;
604  size_t frag_len;
605  int rc;
606 
607  /* Initialise command parameters */
608  params.rw.block_rw = block_rw;
609  params.rw.buffer = buffer;
610  params.rw.lba = ( lba << sandev->blksize_shift );
611  params.rw.count = sandev->capacity.max_count;
612  remaining = ( count << sandev->blksize_shift );
613 
614  /* Read/write fragments */
615  while ( remaining ) {
616 
617  /* Determine fragment length */
618  if ( params.rw.count > remaining )
619  params.rw.count = remaining;
620 
621  /* Execute command */
622  if ( ( rc = sandev_command ( sandev, sandev_command_rw,
623  &params ) ) != 0 )
624  return rc;
625 
626  /* Move to next fragment */
627  frag_len = ( sandev->capacity.blksize * params.rw.count );
628  params.rw.buffer = userptr_add ( params.rw.buffer, frag_len );
629  params.rw.lba += params.rw.count;
630  remaining -= params.rw.count;
631  }
632 
633  return 0;
634 }
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:438
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:84
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:509
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:450
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 645 of file sanboot.c.

646  {
647  int rc;
648 
649  /* Read from device */
650  if ( ( rc = sandev_rw ( sandev, lba, count, buffer, block_read ) ) != 0 )
651  return rc;
652 
653  return 0;
654 }
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:596
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 665 of file sanboot.c.

666  {
667  int rc;
668 
669  /* Write to device */
670  if ( ( rc = sandev_rw ( sandev, lba, count, buffer, block_write ) ) != 0 )
671  return rc;
672 
673  /* Quiesce system. This is a heuristic designed to ensure
674  * that the system is quiesced before Windows starts up, since
675  * a Windows SAN boot will typically write a status flag to
676  * the disk as its last action before transferring control to
677  * the native drivers.
678  */
679  quiesce();
680 
681  return 0;
682 }
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:596
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 693 of file sanboot.c.

693  {
694  struct san_path *sanpath;
695  struct acpi_descriptor *desc;
696  int rc;
697 
698  /* Wait for all paths to be either described or closed */
699  while ( 1 ) {
700 
701  /* Allow connections to progress */
702  step();
703 
704  /* Fail if any closed path has an incomplete descriptor */
705  list_for_each_entry ( sanpath, &sandev->closed, list ) {
706  desc = sanpath->desc;
707  if ( ! desc )
708  continue;
709  if ( ( rc = desc->model->complete ( desc ) ) != 0 ) {
710  DBGC ( sandev->drive, "SAN %#02x.%d could not "
711  "be described: %s\n", sandev->drive,
712  sanpath->index, strerror ( rc ) );
713  return rc;
714  }
715  }
716 
717  /* Succeed if no paths have an incomplete descriptor */
718  rc = 0;
719  list_for_each_entry ( sanpath, &sandev->opened, list ) {
720  desc = sanpath->desc;
721  if ( ! desc )
722  continue;
723  if ( ( rc = desc->model->complete ( desc ) ) != 0 )
724  break;
725  }
726  if ( rc == 0 )
727  return 0;
728  }
729 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#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
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:284
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:278
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 736 of file sanboot.c.

736  {
737  struct san_path *sanpath;
738  unsigned int i;
739 
740  /* Remove all ACPI descriptors */
741  for ( i = 0 ; i < sandev->paths ; i++ ) {
742  sanpath = &sandev->path[i];
743  if ( sanpath->desc ) {
744  acpi_del ( sanpath->desc );
745  sanpath->desc = NULL;
746  }
747  }
748 }
struct san_path path[0]
SAN paths.
Definition: sanboot.h:100
void acpi_del(struct acpi_descriptor *desc)
Remove ACPI descriptor.
Definition: acpi.c:299
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 764 of file sanboot.c.

764  {
765  static const struct iso9660_primary_descriptor_fixed primary_check = {
767  .id = ISO9660_ID,
768  };
769  union {
771  char bytes[ISO9660_BLKSIZE];
772  } *scratch;
773  unsigned int blksize;
774  unsigned int blksize_shift;
775  unsigned int lba;
776  unsigned int count;
777  int rc;
778 
779  /* Calculate required blocksize shift for potential CD-ROM access */
780  blksize = sandev->capacity.blksize;
781  blksize_shift = 0;
782  while ( blksize < ISO9660_BLKSIZE ) {
783  blksize <<= 1;
784  blksize_shift++;
785  }
786  if ( blksize > ISO9660_BLKSIZE ) {
787  /* Cannot be a CD-ROM. This is not an error. */
788  rc = 0;
789  goto invalid_blksize;
790  }
791  lba = ( ISO9660_PRIMARY_LBA << blksize_shift );
792  count = ( 1 << blksize_shift );
793 
794  /* Allocate scratch area */
795  scratch = malloc ( ISO9660_BLKSIZE );
796  if ( ! scratch ) {
797  rc = -ENOMEM;
798  goto err_alloc;
799  }
800 
801  /* Read primary volume descriptor */
802  if ( ( rc = sandev_read ( sandev, lba, count,
803  virt_to_user ( scratch ) ) ) != 0 ) {
804  DBGC ( sandev->drive, "SAN %#02x could not read ISO9660 "
805  "primary volume descriptor: %s\n",
806  sandev->drive, strerror ( rc ) );
807  goto err_rw;
808  }
809 
810  /* Configure as CD-ROM if applicable */
811  if ( memcmp ( &scratch->primary.fixed, &primary_check,
812  sizeof ( primary_check ) ) == 0 ) {
813  DBGC ( sandev->drive, "SAN %#02x contains an ISO9660 "
814  "filesystem; treating as CD-ROM\n", sandev->drive );
815  sandev->blksize_shift = blksize_shift;
816  sandev->is_cdrom = 1;
817  }
818 
819  err_rw:
820  free ( scratch );
821  err_alloc:
822  invalid_blksize:
823  return rc;
824 }
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:65
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
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:645
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77
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 834 of file sanboot.c.

835  {
836  struct san_device *sandev;
837  struct san_path *sanpath;
838  size_t size;
839  unsigned int i;
840 
841  /* Allocate and initialise structure */
842  size = ( sizeof ( *sandev ) + ( count * sizeof ( sandev->path[0] ) ) );
843  sandev = zalloc ( size + priv_size );
844  if ( ! sandev )
845  return NULL;
848  timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
849  sandev->priv = ( ( ( void * ) sandev ) + size );
850  sandev->paths = count;
853  for ( i = 0 ; i < count ; i++ ) {
854  sanpath = &sandev->path[i];
855  sanpath->sandev = sandev;
856  sanpath->index = i;
857  sanpath->uri = uri_get ( uris[i] );
858  list_add_tail ( &sanpath->list, &sandev->closed );
859  intf_init ( &sanpath->block, &sanpath_block_desc,
860  &sandev->refcnt );
861  process_init_stopped ( &sanpath->process, &sanpath_process_desc,
862  &sandev->refcnt );
863  sanpath->path_rc = -EINPROGRESS;
864  }
865 
866  return sandev;
867 }
static struct interface_descriptor sandev_command_desc
SAN device command interface descriptor.
Definition: sanboot.c:175
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:121
#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: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 struct interface_descriptor sanpath_block_desc
SAN path block interface descriptor.
Definition: sanboot.c:334
#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:624
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:183
#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:338
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: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 877 of file sanboot.c.

878  {
879  struct san_device *before;
880  int rc;
881 
882  /* Check that drive number is not in use */
883  if ( sandev_find ( drive ) != NULL ) {
884  DBGC ( sandev->drive, "SAN %#02x is already in use\n", drive );
885  rc = -EADDRINUSE;
886  goto err_in_use;
887  }
888 
889  /* Record drive number and flags */
890  sandev->drive = drive;
891  sandev->flags = flags;
892 
893  /* Check that device is capable of being opened (i.e. that all
894  * URIs are well-formed and that at least one path is
895  * working).
896  */
897  if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
898  goto err_reopen;
899 
900  /* Describe device */
901  if ( ( rc = sandev_describe ( sandev ) ) != 0 )
902  goto err_describe;
903 
904  /* Read device capacity */
906  NULL ) ) != 0 )
907  goto err_capacity;
908 
909  /* Configure as a CD-ROM, if applicable */
910  if ( ( rc = sandev_parse_iso9660 ( sandev ) ) != 0 )
911  goto err_iso9660;
912 
913  /* Add to list of SAN devices, in drive order */
914  for_each_sandev ( before ) {
915  if ( before->drive > sandev->drive )
916  break;
917  }
918  list_add_tail ( &sandev->list, &before->list );
919  DBGC ( sandev->drive, "SAN %#02x registered\n", sandev->drive );
920 
921  return 0;
922 
923  list_del ( &sandev->list );
924  err_iso9660:
925  err_capacity:
926  err_describe:
927  err_reopen:
928  sandev_restart ( sandev, rc );
929  sandev_undescribe ( sandev );
930  err_in_use:
931  return rc;
932 }
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:480
#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:736
#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:693
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:764
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:509
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:90
static void sandev_restart(struct san_device *sandev, int rc)
Restart SAN device interface.
Definition: sanboot.c:347
unsigned int flags
Flags.
Definition: sanboot.h:67
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:371
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint8_t flags
Flags.
Definition: ena.h:18

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

939  {
940 
941  /* Sanity check */
942  assert ( ! timer_running ( &sandev->timer ) );
943 
944  /* Remove from list of SAN devices */
945  list_del ( &sandev->list );
946 
947  /* Shut down interfaces */
948  sandev_restart ( sandev, 0 );
949 
950  /* Remove ACPI descriptors */
951  sandev_undescribe ( sandev );
952 
953  DBGC ( sandev->drive, "SAN %#02x unregistered\n", sandev->drive );
954 }
#define DBGC(...)
Definition: compiler.h:505
static void sandev_undescribe(struct san_device *sandev)
Remove SAN device descriptors.
Definition: sanboot.c:736
#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:347
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: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 970 of file sanboot.c.

970  {
971  unsigned long drive;
972 
973  /* Use "san-drive" setting, if specified */
974  if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
975  return drive;
976 
977  /* Otherwise, default to booting from first hard disk */
978  return SAN_DEFAULT_DRIVE;
979 }
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 995 of file sanboot.c.

995  {
996 
997  /* Apply "san-retries" setting */
998  if ( fetch_uint_setting ( NULL, &san_retries_setting,
999  &san_retries ) < 0 ) {
1001  }
1002 
1003  return 0;
1004 }
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:82
#define SAN_DEFAULT_RETRIES
Default number of times to retry commands.
Definition: sanboot.c:66
#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 82 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:160
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:142

SAN device command interface operations.

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

SAN device command interface descriptor.

Definition at line 175 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:268
static size_t sanpath_block_window(struct san_path *sanpath __unused)
Check flow control window.
Definition: sanboot.c:286
#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:300

SAN path block interface operations.

Definition at line 327 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:327
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 334 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:300

SAN path process descriptor.

Definition at line 338 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:995

Settings applicator.

Definition at line 1007 of file sanboot.c.