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

SAN booting. More...

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

Go to the source code of this file.

Data Structures

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

Macros

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

Functions

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

Variables

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

Detailed Description

SAN booting.

Definition in file sanboot.c.

Macro Definition Documentation

◆ SAN_COMMAND_TIMEOUT

#define SAN_COMMAND_TIMEOUT   ( 15 * TICKS_PER_SEC )

Timeout for block device commands (in ticks)

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

Definition at line 58 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 68 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 78 of file sanboot.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

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

92  {
93  struct san_device *sandev;
94 
95  list_for_each_entry ( sandev, &san_devices, list ) {
96  if ( sandev->drive == drive )
97  return sandev;
98  }
99  return NULL;
100 }
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:432
unsigned int drive
Drive number.
Definition: sanboot.h:66
struct list_head list
List of SAN devices.
Definition: sanboot.h:63
A SAN device.
Definition: sanboot.h:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

108  {
109  struct san_device *sandev;
110 
111  list_for_each_entry ( sandev, &san_devices, list ) {
112  if ( sandev->drive >= drive )
113  return sandev;
114  }
115  return NULL;
116 }
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:432
unsigned int drive
Drive number.
Definition: sanboot.h:66
struct list_head list
List of SAN devices.
Definition: sanboot.h:63
A SAN device.
Definition: sanboot.h:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

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

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

144  {
145 
146  /* Stop timer */
147  stop_timer ( &sandev->timer );
148 
149  /* Restart interface */
150  intf_restart ( &sandev->command, rc );
151 
152  /* Record command status */
153  sandev->command_rc = rc;
154 }
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:344
int command_rc
Command status.
Definition: sanboot.h:75
struct interface command
Command interface.
Definition: sanboot.h:71
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:73

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

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

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

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

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

199  {
200  struct san_device *sandev = sanpath->sandev;
201  int rc;
202 
203  /* Sanity check */
204  list_check_contains_entry ( sanpath, &sandev->closed, list );
205 
206  /* Open interface */
207  if ( ( rc = xfer_open_uri ( &sanpath->block, sanpath->uri ) ) != 0 ) {
208  DBGC ( sandev->drive, "SAN %#02x.%d could not (re)open URI: "
209  "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
210  return rc;
211  }
212 
213  /* Update ACPI descriptor, if applicable */
214  if ( ! ( sandev->flags & SAN_NO_DESCRIBE ) ) {
215  if ( sanpath->desc )
216  acpi_del ( sanpath->desc );
217  sanpath->desc = acpi_describe ( &sanpath->block );
218  if ( sanpath->desc )
219  acpi_add ( sanpath->desc );
220  }
221 
222  /* Start process */
223  process_add ( &sanpath->process );
224 
225  /* Mark as opened */
226  list_del ( &sanpath->list );
227  list_add_tail ( &sanpath->list, &sandev->opened );
228 
229  /* Record as in progress */
230  sanpath->path_rc = -EINPROGRESS;
231 
232  return 0;
233 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of open/closed paths.
Definition: sanboot.h:45
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:68
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:48
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:97
unsigned int index
Path index.
Definition: sanboot.h:41
void acpi_del(struct acpi_descriptor *desc)
Remove ACPI descriptor.
Definition: acpi.c:307
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
unsigned int drive
Drive number.
Definition: sanboot.h:66
#define EINPROGRESS
Operation in progress.
Definition: errno.h:419
void process_add(struct process *process)
Add process to process list.
Definition: process.c:60
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:99
struct list_head list
List of SAN devices.
Definition: sanboot.h:63
int path_rc
Path status.
Definition: sanboot.h:52
A SAN device.
Definition: sanboot.h:59
Device should not be included in description tables.
Definition: sanboot.h:107
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:321
struct uri * uri
SAN device URI.
Definition: sanboot.h:43
struct process process
Process.
Definition: sanboot.h:50
unsigned int flags
Flags.
Definition: sanboot.h:68
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition: list.h:550
struct acpi_descriptor * desc
ACPI descriptor (if applicable)
Definition: sanboot.h:55
void acpi_add(struct acpi_descriptor *desc)
Add ACPI descriptor.
Definition: acpi.c:295
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:39

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

241  {
242  struct san_device *sandev = sanpath->sandev;
243 
244  /* Record status */
245  sanpath->path_rc = rc;
246 
247  /* Mark as closed */
248  list_del ( &sanpath->list );
249  list_add_tail ( &sanpath->list, &sandev->closed );
250 
251  /* Stop process */
252  process_del ( &sanpath->process );
253 
254  /* Restart interfaces, avoiding potential loops */
255  if ( sanpath == sandev->active ) {
256  intfs_restart ( rc, &sandev->command, &sanpath->block, NULL );
257  sandev->active = NULL;
258  sandev_command_close ( sandev, rc );
259  } else {
260  intf_restart ( &sanpath->block, rc );
261  }
262 }
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:344
struct list_head list
List of open/closed paths.
Definition: sanboot.h:45
struct interface block
Underlying block device interface.
Definition: sanboot.h:48
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:80
void intfs_restart(int rc,...)
Shut down and restart multiple object interfaces.
Definition: interface.c:387
struct interface command
Command interface.
Definition: sanboot.h:71
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:99
int path_rc
Path status.
Definition: sanboot.h:52
A SAN device.
Definition: sanboot.h:59
struct process process
Process.
Definition: sanboot.h:50
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:144
struct san_path * active
Current active path.
Definition: sanboot.h:95
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:39

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

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

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

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

◆ sanpath_step()

static void sanpath_step ( struct san_path sanpath)
static

SAN path process.

Parameters
sanpathSAN path

Definition at line 302 of file sanboot.c.

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

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

349  {
350  struct san_path *sanpath;
351 
352  /* Restart all block device interfaces */
353  while ( ( sanpath = list_first_entry ( &sandev->opened,
354  struct san_path, list ) ) ) {
355  sanpath_close ( sanpath, rc );
356  }
357 
358  /* Clear active path */
359  sandev->active = NULL;
360 
361  /* Close any outstanding command */
363 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of open/closed paths.
Definition: sanboot.h:45
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:97
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
A SAN path.
Definition: sanboot.h:37
static void sanpath_close(struct san_path *sanpath, int rc)
Close SAN path.
Definition: sanboot.c:241
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:144
struct san_path * active
Current active path.
Definition: sanboot.h:95
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:39

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

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

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

453  {
454  struct san_path *sanpath = sandev->active;
455  size_t len = ( params->rw.count * sandev->capacity.blksize );
456  int rc;
457 
458  /* Sanity check */
459  assert ( sanpath != NULL );
460 
461  /* Initiate read/write command */
462  if ( ( rc = params->rw.block_rw ( &sanpath->block, &sandev->command,
463  params->rw.lba, params->rw.count,
464  params->rw.buffer, len ) ) != 0 ) {
465  DBGC ( sandev->drive, "SAN %#02x.%d could not initiate "
466  "read/write: %s\n", sandev->drive, sanpath->index,
467  strerror ( rc ) );
468  return rc;
469  }
470 
471  return 0;
472 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * buffer
Data buffer.
Definition: sanboot.c:432
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:48
unsigned int index
Path index.
Definition: sanboot.h:41
struct interface command
Command interface.
Definition: sanboot.h:71
struct san_command_rw_params rw
Read/write command parameters.
Definition: sanboot.c:442
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:37
unsigned int drive
Drive number.
Definition: sanboot.h:66
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
int(* block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
SAN device read/write operation.
Definition: sanboot.c:428
unsigned int count
Block count.
Definition: sanboot.c:436
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:78
uint64_t lba
Starting LBA.
Definition: sanboot.c:434
struct san_path * active
Current active path.
Definition: sanboot.h:95
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:39
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 482 of file sanboot.c.

483  {
484  struct san_path *sanpath = sandev->active;
485  int rc;
486 
487  /* Sanity check */
488  assert ( sanpath != NULL );
489 
490  /* Initiate read capacity command */
491  if ( ( rc = block_read_capacity ( &sanpath->block,
492  &sandev->command ) ) != 0 ) {
493  DBGC ( sandev->drive, "SAN %#02x.%d could not initiate read "
494  "capacity: %s\n", sandev->drive, sanpath->index,
495  strerror ( rc ) );
496  return rc;
497  }
498 
499  return 0;
500 }
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:48
unsigned int index
Path index.
Definition: sanboot.h:41
struct interface command
Command interface.
Definition: sanboot.h:71
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:37
unsigned int drive
Drive number.
Definition: sanboot.h:66
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
struct san_path * active
Current active path.
Definition: sanboot.h:95
int block_read_capacity(struct interface *control, struct interface *data)
Read block device capacity.
Definition: blockdev.c:106
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:39

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

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

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

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

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

Referenced by efi_block_io_reset(), and int13_reset().

◆ sandev_rw()

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

Read from or write to SAN device.

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

Definition at line 598 of file sanboot.c.

603  {
604  union san_command_params params;
605  unsigned int remaining;
606  size_t frag_len;
607  int rc;
608 
609  /* Initialise command parameters */
610  params.rw.block_rw = block_rw;
611  params.rw.buffer = buffer;
612  params.rw.lba = ( lba << sandev->blksize_shift );
613  params.rw.count = sandev->capacity.max_count;
614  remaining = ( count << sandev->blksize_shift );
615 
616  /* Read/write fragments */
617  while ( remaining ) {
618 
619  /* Determine fragment length */
620  if ( params.rw.count > remaining )
621  params.rw.count = remaining;
622 
623  /* Execute command */
624  if ( ( rc = sandev_command ( sandev, sandev_command_rw,
625  &params ) ) != 0 )
626  return rc;
627 
628  /* Move to next fragment */
629  frag_len = ( sandev->capacity.blksize * params.rw.count );
630  params.rw.buffer += frag_len;
631  params.rw.lba += params.rw.count;
632  remaining -= params.rw.count;
633  }
634 
635  return 0;
636 }
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:440
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
static unsigned int count
Number of entries.
Definition: dwmac.h:225
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:85
uint64_t lba
Starting block number.
Definition: int13.h:22
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:78
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:511
static int sandev_command_rw(struct san_device *sandev, const union san_command_params *params)
Initiate SAN device read/write command.
Definition: sanboot.c:452
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(), and sandev_command_rw().

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

◆ sandev_read()

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

Read from SAN device.

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

Definition at line 647 of file sanboot.c.

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

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

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

◆ sandev_write()

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

Write to SAN device.

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

Definition at line 668 of file sanboot.c.

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

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

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

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

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

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

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

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

Referenced by register_sandev().

◆ alloc_sandev()

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

Allocate SAN device.

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

Definition at line 837 of file sanboot.c.

838  {
839  struct san_device *sandev;
840  struct san_path *sanpath;
841  size_t size;
842  unsigned int i;
843 
844  /* Allocate and initialise structure */
845  size = ( sizeof ( *sandev ) + ( count * sizeof ( sandev->path[0] ) ) );
846  sandev = zalloc ( size + priv_size );
847  if ( ! sandev )
848  return NULL;
851  timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
852  sandev->priv = ( ( ( void * ) sandev ) + size );
853  sandev->paths = count;
856  for ( i = 0 ; i < count ; i++ ) {
857  sanpath = &sandev->path[i];
858  sanpath->sandev = sandev;
859  sanpath->index = i;
860  sanpath->uri = uri_get ( uris[i] );
861  list_add_tail ( &sanpath->list, &sandev->closed );
862  intf_init ( &sanpath->block, &sanpath_block_desc,
863  &sandev->refcnt );
864  process_init_stopped ( &sanpath->process, &sanpath_process_desc,
865  &sandev->refcnt );
866  sanpath->path_rc = -EINPROGRESS;
867  }
868 
869  return sandev;
870 }
static struct interface_descriptor sandev_command_desc
SAN device command interface descriptor.
Definition: sanboot.c:177
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:195
struct san_path path[0]
SAN paths.
Definition: sanboot.h:101
static void sandev_free(struct refcnt *refcnt)
Free SAN device.
Definition: sanboot.c:123
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
uint16_t size
Buffer size.
Definition: dwmac.h:14
struct list_head opened
List of opened SAN paths.
Definition: sanboot.h:97
struct interface command
Command interface.
Definition: sanboot.h:71
A SAN path.
Definition: sanboot.h:37
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
static unsigned int count
Number of entries.
Definition: dwmac.h:225
static struct interface_descriptor sanpath_block_desc
SAN path block interface descriptor.
Definition: sanboot.c:336
#define EINPROGRESS
Operation in progress.
Definition: errno.h:419
struct list_head closed
List of closed SAN paths.
Definition: sanboot.h:99
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
A SAN device.
Definition: sanboot.h:59
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:146
unsigned int paths
Number of paths.
Definition: sanboot.h:93
static void sandev_command_expired(struct retry_timer *timer, int over __unused)
Handle SAN device command timeout.
Definition: sanboot.c:185
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
struct refcnt refcnt
Reference count.
Definition: sanboot.h:61
void * priv
Driver private data.
Definition: sanboot.h:90
static struct process_descriptor sanpath_process_desc
SAN path process descriptor.
Definition: sanboot.c:340
struct retry_timer timer
Command timeout timer.
Definition: sanboot.h:73
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct san_device * sandev
Containing SAN device.
Definition: sanboot.h:39

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

881  {
882  struct san_device *before;
883  int rc;
884 
885  /* Check that drive number is not in use */
886  if ( sandev_find ( drive ) != NULL ) {
887  DBGC ( sandev->drive, "SAN %#02x is already in use\n", drive );
888  rc = -EADDRINUSE;
889  goto err_in_use;
890  }
891 
892  /* Record drive number and flags */
893  sandev->drive = drive;
894  sandev->flags = flags;
895 
896  /* Check that device is capable of being opened (i.e. that all
897  * URIs are well-formed and that at least one path is
898  * working).
899  */
900  if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
901  goto err_reopen;
902 
903  /* Describe device */
904  if ( ( rc = sandev_describe ( sandev ) ) != 0 )
905  goto err_describe;
906 
907  /* Read device capacity */
909  NULL ) ) != 0 )
910  goto err_capacity;
911 
912  /* Configure as a CD-ROM, if applicable */
913  if ( ( rc = sandev_parse_iso9660 ( sandev ) ) != 0 )
914  goto err_iso9660;
915 
916  /* Add to list of SAN devices, in drive order */
917  for_each_sandev ( before ) {
918  if ( before->drive > sandev->drive )
919  break;
920  }
921  list_add_tail ( &sandev->list, &before->list );
922  DBGC ( sandev->drive, "SAN %#02x registered\n", sandev->drive );
923 
924  return 0;
925 
926  list_del ( &sandev->list );
927  err_iso9660:
928  err_capacity:
929  err_describe:
930  err_reopen:
931  sandev_restart ( sandev, rc );
932  sandev_undescribe ( sandev );
933  err_in_use:
934  return rc;
935 }
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:482
#define EADDRINUSE
Address already in use.
Definition: errno.h:304
#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:740
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
unsigned int drive
Drive number.
Definition: sanboot.h:66
static int sandev_describe(struct san_device *sandev)
Describe SAN device.
Definition: sanboot.c:697
uint8_t flags
Flags.
Definition: ena.h:18
struct list_head list
List of SAN devices.
Definition: sanboot.h:63
A SAN device.
Definition: sanboot.h:59
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition: sanboot.h:197
static int sandev_parse_iso9660(struct san_device *sandev)
Configure SAN device as a CD-ROM, if applicable.
Definition: sanboot.c:768
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:511
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:92
static void sandev_restart(struct san_device *sandev, int rc)
Restart SAN device interface.
Definition: sanboot.c:349
unsigned int flags
Flags.
Definition: sanboot.h:68
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:373
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

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

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:466

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

973  {
974  unsigned long drive;
975 
976  /* Use "san-drive" setting, if specified */
977  if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
978  return drive;
979 
980  /* Otherwise, default to booting from first hard disk */
981  return SAN_DEFAULT_DRIVE;
982 }
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:1040
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
Definition: sanboot.h:34
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

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

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

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 84 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:250
static void sandev_command_capacity(struct san_device *sandev, struct block_device_capacity *capacity)
Record SAN device capacity.
Definition: sanboot.c:162
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition: blockdev.c:130
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
A SAN device.
Definition: sanboot.h:59
static void sandev_command_close(struct san_device *sandev, int rc)
Close SAN device command.
Definition: sanboot.c:144

SAN device command interface operations.

Definition at line 170 of file sanboot.c.

◆ sandev_command_desc

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

SAN device command interface descriptor.

Definition at line 177 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:147
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:117
A SAN path.
Definition: sanboot.h:37
static void sanpath_block_close(struct san_path *sanpath, int rc)
Handle closure of underlying block device interface.
Definition: sanboot.c:270
static size_t sanpath_block_window(struct san_path *sanpath __unused)
Check flow control window.
Definition: sanboot.c:288
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
static void sanpath_step(struct san_path *sanpath)
SAN path process.
Definition: sanboot.c:302

SAN path block interface operations.

Definition at line 329 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:329
A SAN path.
Definition: sanboot.h:37
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12

SAN path block interface descriptor.

Definition at line 336 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:18
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:98
A SAN path.
Definition: sanboot.h:37
static void sanpath_step(struct san_path *sanpath)
SAN path process.
Definition: sanboot.c:302

SAN path process descriptor.

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

Settings applicator.

Definition at line 1010 of file sanboot.c.