[PATCH 1/2] cdrom: gdrom: replace port I/O with MMIO accessors

Florian Fuchs <[email protected]>
Newsgroups gmane.linux.ports.sh.devel,gmane.linux.kernel
Message-ID <[email protected]>
GDROM_DATA_REG is a memory-mapped data register, but the driver uses
outsw() and insw() only for this register. Replace this with local
helpers using MMIO accessors ioread16_rep() / iowrite16_rep().

Before, it oopsed accessing the data register, as the io_port_base
P2SEG gets added to the argument in outsw() / insw(), which leads to an
unusable drive:

        BUG: unable to handle kernel paging request at 405f7080
        PC: [<8c28d5b4>] gdrom_spicommand+0x6c/0xb0

Signed-off-by: Florian Fuchs <[email protected]>
---
The original Oops can be reproduced just by mounting a disc, like:
mount -t iso9660 -o ro /dev/gdrom /mnt
---
 drivers/cdrom/gdrom.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 4ba4dd06cbf4..dccf41fa5d0a 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -171,6 +171,16 @@ static void gdrom_identifydevice(void *buf)
 		data[c] = __raw_readw(GDROM_DATA_REG);
 }
 
+static void gdrom_fifo_readw(void *buf, unsigned int words)
+{
+	ioread16_rep((void __iomem *)GDROM_DATA_REG, buf, words);
+}
+
+static void gdrom_fifo_writew(const void *buf, unsigned int words)
+{
+	iowrite16_rep((void __iomem *)GDROM_DATA_REG, buf, words);
+}
+
 static void gdrom_spicommand(void *spi_string, int buflen)
 {
 	short *cmd = spi_string;
@@ -198,7 +208,7 @@ static void gdrom_spicommand(void *spi_string, int buflen)
 		gdrom_getsense(NULL);
 		return;
 	}
-	outsw(GDROM_DATA_REG, cmd, 6);
+	gdrom_fifo_writew(cmd, 6);
 }
 
 
@@ -282,7 +292,7 @@ static int gdrom_readtoc_cmd(struct gdromtoc *toc, int session)
 		err = -EINVAL;
 		goto cleanup_readtoc;
 	}
-	insw(GDROM_DATA_REG, toc, tocsize/2);
+	gdrom_fifo_readw(toc, tocsize / 2);
 	if (gd.status & 0x01)
 		err = -EINVAL;
 
@@ -433,7 +443,7 @@ static int gdrom_getsense(short *bufstring)
 		GDROM_DEFAULT_TIMEOUT);
 	if (gd.pending)
 		goto cleanup_sense;
-	insw(GDROM_DATA_REG, &sense, sense_command->buflen/2);
+	gdrom_fifo_readw(sense, sense_command->buflen / 2);
 	if (sense[1] & 40) {
 		pr_info("Drive not ready - command aborted\n");
 		goto cleanup_sense;
@@ -612,7 +622,7 @@ static blk_status_t gdrom_readdisk_dma(struct request *req)
 		cpu_relax();
 	gd.pending = 1;
 	gd.transfer = 1;
-	outsw(GDROM_DATA_REG, &read_command->cmd, 6);
+	gdrom_fifo_writew(read_command->cmd, 6);
 	timeout = jiffies + HZ / 2;
 	/* Wait for any pending DMA to finish */
 	while (__raw_readb(GDROM_DMA_STATUS_REG) &&
-- 
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.