| 
														
															@@ -27,6 +27,10 @@ SdDevice sdDev = {2, 256 * 1024 * 1024 * 2}; /* For SCSI2SD */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 struct image_config_t: public S2S_TargetCfg 
														 | 
														
														 | 
														
															 struct image_config_t: public S2S_TargetCfg 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     FsFile file; 
														 | 
														
														 | 
														
															     FsFile file; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    // For CD-ROM drive ejection 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    bool ejected; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    uint8_t cdrom_events; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 }; 
														 | 
														
														 | 
														
															 }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static image_config_t g_DiskImages[S2S_MAX_TARGETS]; 
														 | 
														
														 | 
														
															 static image_config_t g_DiskImages[S2S_MAX_TARGETS]; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -370,17 +374,21 @@ static void doReadCapacity() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 static int doTestUnitReady() 
														 | 
														
														 | 
														
															 static int doTestUnitReady() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     int ready = 1; 
														 | 
														
														 | 
														
															     int ready = 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    if (likely(blockDev.state == (DISK_PRESENT | DISK_INITIALISED) && 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-		scsiDev.target->started)) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    image_config_t &img = *(image_config_t*)scsiDev.target->cfg; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (unlikely(!scsiDev.target->started || !img.file.isOpen())) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     { 
														 | 
														
														 | 
														
															     { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        // nothing to do. 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        ready = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.status = CHECK_CONDITION; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.target->sense.code = NOT_READY; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.phase = STATUS; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-    else if (unlikely(!scsiDev.target->started)) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    else if (img.ejected) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     { 
														 | 
														
														 | 
														
															     { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         ready = 0; 
														 | 
														
														 | 
														
															         ready = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         scsiDev.status = CHECK_CONDITION; 
														 | 
														
														 | 
														
															         scsiDev.status = CHECK_CONDITION; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         scsiDev.target->sense.code = NOT_READY; 
														 | 
														
														 | 
														
															         scsiDev.target->sense.code = NOT_READY; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED; 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.target->sense.asc = MEDIUM_NOT_PRESENT; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         scsiDev.phase = STATUS; 
														 | 
														
														 | 
														
															         scsiDev.phase = STATUS; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     else if (unlikely(!(blockDev.state & DISK_PRESENT))) 
														 | 
														
														 | 
														
															     else if (unlikely(!(blockDev.state & DISK_PRESENT))) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -402,6 +410,43 @@ static int doTestUnitReady() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     return ready; 
														 | 
														
														 | 
														
															     return ready; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+static void doGetEventStatusNotification(bool immed) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+{ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    image_config_t &img = *(image_config_t*)scsiDev.target->cfg; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (!immed) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        // Asynchronous notification not supported 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.status = CHECK_CONDITION; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.target->sense.code = ILLEGAL_REQUEST; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.phase = STATUS; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    else if (img.cdrom_events) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[0] = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[1] = 6; // EventDataLength 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[2] = 0x04; // Media status events 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[3] = 0x04; // Supported events 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[4] = img.cdrom_events; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[5] = 0x01; // Power status 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[6] = 0; // Start slot 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[7] = 0; // End slot 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.dataLen = 8; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.phase = DATA_IN; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        img.cdrom_events = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    else 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[0] = 0; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[1] = 2; // EventDataLength 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[2] = 0x00; // Media status events 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.data[3] = 0x04; // Supported events 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.dataLen = 4; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        scsiDev.phase = DATA_IN; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 /****************/ 
														 | 
														
														 | 
														
															 /****************/ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 /* Seek command */ 
														 | 
														
														 | 
														
															 /* Seek command */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 /****************/ 
														 | 
														
														 | 
														
															 /****************/ 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -794,6 +839,7 @@ extern "C" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 int scsiDiskCommand() 
														 | 
														
														 | 
														
															 int scsiDiskCommand() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 { 
														 | 
														
														 | 
														
															 { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     int commandHandled = 1; 
														 | 
														
														 | 
														
															     int commandHandled = 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    image_config_t &img = *(image_config_t*)scsiDev.target->cfg; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															     uint8_t command = scsiDev.cdb[0]; 
														 | 
														
														 | 
														
															     uint8_t command = scsiDev.cdb[0]; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     if (unlikely(command == 0x1B)) 
														 | 
														
														 | 
														
															     if (unlikely(command == 0x1B)) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -804,9 +850,20 @@ int scsiDiskCommand() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         int start = scsiDev.cdb[4] & 1; 
														 | 
														
														 | 
														
															         int start = scsiDev.cdb[4] & 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	    int loadEject = scsiDev.cdb[4] & 2; 
														 | 
														
														 | 
														
															 	    int loadEject = scsiDev.cdb[4] & 2; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 	 
														 | 
														
														 | 
														
															 	 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-        if (loadEject) 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if (loadEject && img.deviceType == S2S_CFG_OPTICAL) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         { 
														 | 
														
														 | 
														
															         { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-            // Ignore load/eject requests. We can't do that. 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            if (start) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                azdbg("------ CDROM close tray"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                img.ejected = false; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                img.cdrom_events = 2; // New media 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            else 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                azdbg("------ CDROM open tray"); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                img.ejected = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                img.cdrom_events = 3; // Media removal 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         } 
														 | 
														
														 | 
														
															         } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         else if (start) 
														 | 
														
														 | 
														
															         else if (start) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         { 
														 | 
														
														 | 
														
															         { 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -822,6 +879,11 @@ int scsiDiskCommand() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // TEST UNIT READY 
														 | 
														
														 | 
														
															         // TEST UNIT READY 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         doTestUnitReady(); 
														 | 
														
														 | 
														
															         doTestUnitReady(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    else if (command == 0x4A) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        bool immed = scsiDev.cdb[1] & 1; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        doGetEventStatusNotification(immed); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     else if (unlikely(!doTestUnitReady())) 
														 | 
														
														 | 
														
															     else if (unlikely(!doTestUnitReady())) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     { 
														 | 
														
														 | 
														
															     { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         // Status and sense codes already set by doTestUnitReady 
														 | 
														
														 | 
														
															         // Status and sense codes already set by doTestUnitReady 
														 |