[PATCH v4 3/3] cdrom: gdrom: verify device access after disc swap

Florian Fuchs <[email protected]>
Newsgroups gmane.linux.ports.sh.devel,gmane.linux.kernel
Message-ID <[email protected]>
From: Artur Rojek <[email protected]>

To ready the drive for cdrom_open(), this driver sends a spin disc
command. However, if the cd lid has been opened and the disc de-spinned,
the very next SPI command will return UNIT_ATTENTION sense error,
resulting in a failure to mount the disc.

Fix this by sending a dummy TEST_UNIT command, which will catch the
above error, and allow subsequent commands to execute correctly.

Signed-off-by: Artur Rojek <[email protected]>
Signed-off-by: Florian Fuchs <[email protected]>
---
v3->v4: no change
v3: new patch added from Artur Rojek and also verified that it works.

v3: https://lore.kernel.org/linux-sh/[email protected]/

 drivers/cdrom/gdrom.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 603429756a34..0827f4f0344d 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -219,6 +219,33 @@ static char gdrom_execute_diagnostic(void)
 	return __raw_readb(GDROM_ERROR_REG);
 }
 
+/*
+ * Test unit command
+ * byte 0 = 0x0
+ *
+ * This command verifies whether device can be accessed.
+ *
+ * -EIO indicates that device is not ready for operation.
+ */
+static int gdrom_test_unit_cmd(void)
+{
+	struct packet_command *test_command;
+
+	test_command = kzalloc_obj(struct packet_command);
+	if (!test_command)
+		return -ENOMEM;
+	test_command->cmd[0] = 0x0;
+	test_command->buflen = 0;
+	gd.pending = 1;
+	gdrom_packetcommand(gd.cd_info, test_command);
+	wait_event_interruptible_timeout(command_queue, gd.pending == 0,
+					 GDROM_DEFAULT_TIMEOUT);
+	gd.pending = 0;
+	kfree(test_command);
+
+	return gd.status & 0x1 ? -EIO : 0;
+}
+
 /*
  * Prepare disk command
  * byte 0 = 0x70
@@ -353,6 +380,9 @@ static int gdrom_get_last_session(struct cdrom_device_info *cd_info,
 
 static int gdrom_open(struct cdrom_device_info *cd_info, int purpose)
 {
+	/* Sink pending UNIT_ATTENTION sense error after a disc swap. */
+	(void)gdrom_test_unit_cmd();
+
 	/* spin up the disk */
 	return gdrom_preparedisk_cmd();
 }
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.