|
@@ -202,6 +202,32 @@ static struct interface_operation int13_command_op[] = {
|
202
|
202
|
static struct interface_descriptor int13_command_desc =
|
203
|
203
|
INTF_DESC ( struct int13_command, block, int13_command_op );
|
204
|
204
|
|
|
205
|
+/**
|
|
206
|
+ * Open (or reopen) INT 13 emulated drive underlying block device
|
|
207
|
+ *
|
|
208
|
+ * @v int13 Emulated drive
|
|
209
|
+ * @ret rc Return status code
|
|
210
|
+ */
|
|
211
|
+static int int13_reopen_block ( struct int13_drive *int13 ) {
|
|
212
|
+ int rc;
|
|
213
|
+
|
|
214
|
+ /* Close any existing block device */
|
|
215
|
+ intf_restart ( &int13->block, -ECONNRESET );
|
|
216
|
+
|
|
217
|
+ /* Open block device */
|
|
218
|
+ if ( ( rc = xfer_open_uri ( &int13->block, int13->uri ) ) != 0 ) {
|
|
219
|
+ DBGC ( int13, "INT13 drive %02x could not reopen block "
|
|
220
|
+ "device: %s\n", int13->drive, strerror ( rc ) );
|
|
221
|
+ int13->block_rc = rc;
|
|
222
|
+ return rc;
|
|
223
|
+ }
|
|
224
|
+
|
|
225
|
+ /* Clear block device error status */
|
|
226
|
+ int13->block_rc = 0;
|
|
227
|
+
|
|
228
|
+ return 0;
|
|
229
|
+}
|
|
230
|
+
|
205
|
231
|
/**
|
206
|
232
|
* Prepare to issue INT 13 command
|
207
|
233
|
*
|
|
@@ -211,11 +237,17 @@ static struct interface_descriptor int13_command_desc =
|
211
|
237
|
*/
|
212
|
238
|
static int int13_command_start ( struct int13_command *command,
|
213
|
239
|
struct int13_drive *int13 ) {
|
|
240
|
+ int rc;
|
214
|
241
|
|
215
|
242
|
/* Sanity check */
|
216
|
243
|
assert ( command->int13 == NULL );
|
217
|
244
|
assert ( ! timer_running ( &command->timer ) );
|
218
|
245
|
|
|
246
|
+ /* Reopen block device if necessary */
|
|
247
|
+ if ( ( int13->block_rc != 0 ) &&
|
|
248
|
+ ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) )
|
|
249
|
+ return rc;
|
|
250
|
+
|
219
|
251
|
/* Initialise command */
|
220
|
252
|
command->rc = -EINPROGRESS;
|
221
|
253
|
command->int13 = int13;
|
|
@@ -406,36 +438,6 @@ static int int13_guess_geometry ( struct int13_drive *int13 ) {
|
406
|
438
|
return 0;
|
407
|
439
|
}
|
408
|
440
|
|
409
|
|
-/**
|
410
|
|
- * Open (or reopen) INT 13 emulated drive underlying block device
|
411
|
|
- *
|
412
|
|
- * @v int13 Emulated drive
|
413
|
|
- * @ret rc Return status code
|
414
|
|
- */
|
415
|
|
-static int int13_reopen_block ( struct int13_drive *int13 ) {
|
416
|
|
- int rc;
|
417
|
|
-
|
418
|
|
- /* Close any existing block device */
|
419
|
|
- intf_restart ( &int13->block, -ECONNRESET );
|
420
|
|
-
|
421
|
|
- /* Open block device */
|
422
|
|
- if ( ( rc = xfer_open_uri ( &int13->block, int13->uri ) ) != 0 ) {
|
423
|
|
- DBGC ( int13, "INT13 drive %02x could not reopen block "
|
424
|
|
- "device: %s\n", int13->drive, strerror ( rc ) );
|
425
|
|
- int13->block_rc = rc;
|
426
|
|
- return rc;
|
427
|
|
- }
|
428
|
|
-
|
429
|
|
- /* Clear block device error status */
|
430
|
|
- int13->block_rc = 0;
|
431
|
|
-
|
432
|
|
- /* Read device capacity */
|
433
|
|
- if ( ( rc = int13_read_capacity ( int13 ) ) != 0 )
|
434
|
|
- return rc;
|
435
|
|
-
|
436
|
|
- return 0;
|
437
|
|
-}
|
438
|
|
-
|
439
|
441
|
/**
|
440
|
442
|
* Update BIOS drive count
|
441
|
443
|
*/
|
|
@@ -485,6 +487,10 @@ static int int13_reset ( struct int13_drive *int13,
|
485
|
487
|
if ( ( rc = int13_reopen_block ( int13 ) ) != 0 )
|
486
|
488
|
return -INT13_STATUS_RESET_FAILED;
|
487
|
489
|
|
|
490
|
+ /* Check that block device is functional */
|
|
491
|
+ if ( ( rc = int13_read_capacity ( int13 ) ) != 0 )
|
|
492
|
+ return -INT13_STATUS_RESET_FAILED;
|
|
493
|
+
|
488
|
494
|
return 0;
|
489
|
495
|
}
|
490
|
496
|
|
|
@@ -837,6 +843,11 @@ static int int13_device_path_info ( struct int13_drive *int13,
|
837
|
843
|
uint8_t sum = 0;
|
838
|
844
|
int rc;
|
839
|
845
|
|
|
846
|
+ /* Reopen block device if necessary */
|
|
847
|
+ if ( ( int13->block_rc != 0 ) &&
|
|
848
|
+ ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) )
|
|
849
|
+ return rc;
|
|
850
|
+
|
840
|
851
|
/* Get underlying hardware device */
|
841
|
852
|
device = identify_device ( &int13->block );
|
842
|
853
|
if ( ! device ) {
|
|
@@ -1125,10 +1136,6 @@ static void int13_block_close ( struct int13_drive *int13, int rc ) {
|
1125
|
1136
|
|
1126
|
1137
|
/* Shut down interfaces */
|
1127
|
1138
|
intf_restart ( &int13->block, rc );
|
1128
|
|
-
|
1129
|
|
- /* Further INT 13 calls will fail immediately. The caller may
|
1130
|
|
- * use INT 13,00 to reset the drive.
|
1131
|
|
- */
|
1132
|
1139
|
}
|
1133
|
1140
|
|
1134
|
1141
|
/** INT 13 drive interface operations */
|
|
@@ -1200,6 +1207,10 @@ static int int13_hook ( struct uri *uri, unsigned int drive ) {
|
1200
|
1207
|
if ( ( rc = int13_reopen_block ( int13 ) ) != 0 )
|
1201
|
1208
|
goto err_reopen_block;
|
1202
|
1209
|
|
|
1210
|
+ /* Read device capacity */
|
|
1211
|
+ if ( ( rc = int13_read_capacity ( int13 ) ) != 0 )
|
|
1212
|
+ return rc;
|
|
1213
|
+
|
1203
|
1214
|
/* Give drive a default geometry */
|
1204
|
1215
|
if ( ( rc = int13_guess_geometry ( int13 ) ) != 0 )
|
1205
|
1216
|
goto err_guess_geometry;
|
|
@@ -1383,6 +1394,11 @@ static int int13_describe ( unsigned int drive ) {
|
1383
|
1394
|
return -ENODEV;
|
1384
|
1395
|
}
|
1385
|
1396
|
|
|
1397
|
+ /* Reopen block device if necessary */
|
|
1398
|
+ if ( ( int13->block_rc != 0 ) &&
|
|
1399
|
+ ( ( rc = int13_reopen_block ( int13 ) ) != 0 ) )
|
|
1400
|
+ return rc;
|
|
1401
|
+
|
1386
|
1402
|
/* Clear table */
|
1387
|
1403
|
memset ( &xbftab, 0, sizeof ( xbftab ) );
|
1388
|
1404
|
|