static struct interface_descriptor int13_command_desc =
INTF_DESC ( struct int13_command, block, int13_command_op );
+/**
+ * Open (or reopen) INT 13 emulated drive underlying block device
+ *
+ * @v int13 Emulated drive
+ * @ret rc Return status code
+ */
+static int int13_reopen_block ( struct int13_drive *int13 ) {
+ int rc;
+
+ /* Close any existing block device */
+ intf_restart ( &int13->block, -ECONNRESET );
+
+ /* Open block device */
+ if ( ( rc = xfer_open_uri ( &int13->block, int13->uri ) ) != 0 ) {
+ DBGC ( int13, "INT13 drive %02x could not reopen block "
+ "device: %s\n", int13->drive, strerror ( rc ) );
+ int13->block_rc = rc;
+ return rc;
+ }
+
+ /* Clear block device error status */
+ int13->block_rc = 0;
+
+ return 0;
+}
+
/**
* Prepare to issue INT 13 command
*
*/
static int int13_command_start ( struct int13_command *command,
struct int13_drive *int13 ) {
+ int rc;
/* Sanity check */
assert ( command->int13 == NULL );
assert ( ! timer_running ( &command->timer ) );
+ /* Reopen block device if necessary */
+ if ( ( int13->block_rc != 0 ) &&
+ ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) )
+ return rc;
+
/* Initialise command */
command->rc = -EINPROGRESS;
command->int13 = int13;
return 0;
}
-/**
- * Open (or reopen) INT 13 emulated drive underlying block device
- *
- * @v int13 Emulated drive
- * @ret rc Return status code
- */
-static int int13_reopen_block ( struct int13_drive *int13 ) {
- int rc;
-
- /* Close any existing block device */
- intf_restart ( &int13->block, -ECONNRESET );
-
- /* Open block device */
- if ( ( rc = xfer_open_uri ( &int13->block, int13->uri ) ) != 0 ) {
- DBGC ( int13, "INT13 drive %02x could not reopen block "
- "device: %s\n", int13->drive, strerror ( rc ) );
- int13->block_rc = rc;
- return rc;
- }
-
- /* Clear block device error status */
- int13->block_rc = 0;
-
- /* Read device capacity */
- if ( ( rc = int13_read_capacity ( int13 ) ) != 0 )
- return rc;
-
- return 0;
-}
-
/**
* Update BIOS drive count
*/
if ( ( rc = int13_reopen_block ( int13 ) ) != 0 )
return -INT13_STATUS_RESET_FAILED;
+ /* Check that block device is functional */
+ if ( ( rc = int13_read_capacity ( int13 ) ) != 0 )
+ return -INT13_STATUS_RESET_FAILED;
+
return 0;
}
uint8_t sum = 0;
int rc;
+ /* Reopen block device if necessary */
+ if ( ( int13->block_rc != 0 ) &&
+ ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) )
+ return rc;
+
/* Get underlying hardware device */
device = identify_device ( &int13->block );
if ( ! device ) {
/* Shut down interfaces */
intf_restart ( &int13->block, rc );
-
- /* Further INT 13 calls will fail immediately. The caller may
- * use INT 13,00 to reset the drive.
- */
}
/** INT 13 drive interface operations */
if ( ( rc = int13_reopen_block ( int13 ) ) != 0 )
goto err_reopen_block;
+ /* Read device capacity */
+ if ( ( rc = int13_read_capacity ( int13 ) ) != 0 )
+ return rc;
+
/* Give drive a default geometry */
if ( ( rc = int13_guess_geometry ( int13 ) ) != 0 )
goto err_guess_geometry;
return -ENODEV;
}
+ /* Reopen block device if necessary */
+ if ( ( int13->block_rc != 0 ) &&
+ ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) )
+ return rc;
+
/* Clear table */
memset ( &xbftab, 0, sizeof ( xbftab ) );