Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* GD ROM driver for the SEGA Dreamcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * copyright Adrian McMenamin, 2007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * With thanks to Marcus Comstedt and Nathan Keynes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * for work in reversing PIO and DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/cdrom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/genhd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/blk-mq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <asm/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <mach/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <mach/sysasic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define GDROM_DEV_NAME "gdrom"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define GD_SESSION_OFFSET 150
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) /* GD Rom commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define GDROM_COM_SOFTRESET 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define GDROM_COM_EXECDIAG 0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define GDROM_COM_PACKET 0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define GDROM_COM_IDDEV 0xA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /* GD Rom registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define GDROM_BASE_REG			0xA05F7000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define GDROM_ALTSTATUS_REG		(GDROM_BASE_REG + 0x18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define GDROM_DATA_REG			(GDROM_BASE_REG + 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define GDROM_ERROR_REG		(GDROM_BASE_REG + 0x84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define GDROM_INTSEC_REG		(GDROM_BASE_REG + 0x88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define GDROM_SECNUM_REG		(GDROM_BASE_REG + 0x8C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define GDROM_BCL_REG			(GDROM_BASE_REG + 0x90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define GDROM_BCH_REG			(GDROM_BASE_REG + 0x94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define GDROM_DSEL_REG			(GDROM_BASE_REG + 0x98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define GDROM_STATUSCOMMAND_REG	(GDROM_BASE_REG + 0x9C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define GDROM_RESET_REG		(GDROM_BASE_REG + 0x4E4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define GDROM_DMA_STARTADDR_REG	(GDROM_BASE_REG + 0x404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define GDROM_DMA_LENGTH_REG		(GDROM_BASE_REG + 0x408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define GDROM_DMA_DIRECTION_REG	(GDROM_BASE_REG + 0x40C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define GDROM_DMA_ENABLE_REG		(GDROM_BASE_REG + 0x414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define GDROM_DMA_STATUS_REG		(GDROM_BASE_REG + 0x418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define GDROM_DMA_WAIT_REG		(GDROM_BASE_REG + 0x4A0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define GDROM_DMA_ACCESS_CTRL_REG	(GDROM_BASE_REG + 0x4B8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define GDROM_HARD_SECTOR	2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define BLOCK_LAYER_SECTOR	512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define GD_TO_BLK		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define GDROM_DEFAULT_TIMEOUT	(HZ * 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static DEFINE_MUTEX(gdrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	int sense_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	const char * const text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) } sense_texts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	{NO_SENSE, "OK"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	{RECOVERED_ERROR, "Recovered from error"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	{NOT_READY, "Device not ready"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	{MEDIUM_ERROR, "Disk not ready"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	{HARDWARE_ERROR, "Hardware error"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	{ILLEGAL_REQUEST, "Command has failed"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	{UNIT_ATTENTION, "Device needs attention - disk may have been changed"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	{DATA_PROTECT, "Data protection error"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{ABORTED_COMMAND, "Command aborted"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static struct platform_device *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static int gdrom_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static DECLARE_WAIT_QUEUE_HEAD(command_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static DECLARE_WAIT_QUEUE_HEAD(request_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) struct gdromtoc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	unsigned int entry[99];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	unsigned int first, last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	unsigned int leadout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static struct gdrom_unit {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	struct gendisk *disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct cdrom_device_info *cd_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	int pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	int transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	char disk_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	struct gdromtoc *toc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	struct request_queue *gdrom_rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	struct blk_mq_tag_set tag_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) } gd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct gdrom_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	char mid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	char modid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	char verid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	char padA[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	char mname[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	char modname[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	char firmver[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	char padB[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static int gdrom_getsense(short *bufstring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int gdrom_packetcommand(struct cdrom_device_info *cd_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct packet_command *command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int gdrom_hardreset(struct cdrom_device_info *cd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static bool gdrom_is_busy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	return (__raw_readb(GDROM_ALTSTATUS_REG) & 0x80) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static bool gdrom_data_request(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	return (__raw_readb(GDROM_ALTSTATUS_REG) & 0x88) == 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static bool gdrom_wait_clrbusy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	unsigned long timeout = jiffies + GDROM_DEFAULT_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	while ((__raw_readb(GDROM_ALTSTATUS_REG) & 0x80) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		(time_before(jiffies, timeout)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return time_before(jiffies, timeout + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static bool gdrom_wait_busy_sleeps(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	/* Wait to get busy first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	timeout = jiffies + GDROM_DEFAULT_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	while (!gdrom_is_busy() && time_before(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	/* Now wait for busy to clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return gdrom_wait_clrbusy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void gdrom_identifydevice(void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	short *data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	/* If the device won't clear it has probably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	* been hit by a serious failure - but we'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	* try to return a sense key even so */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (!gdrom_wait_clrbusy()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		gdrom_getsense(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	__raw_writeb(GDROM_COM_IDDEV, GDROM_STATUSCOMMAND_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (!gdrom_wait_busy_sleeps()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		gdrom_getsense(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	/* now read in the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	for (c = 0; c < 40; c++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		data[c] = __raw_readw(GDROM_DATA_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static void gdrom_spicommand(void *spi_string, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	short *cmd = spi_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	/* ensure IRQ_WAIT is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	__raw_writeb(0x08, GDROM_ALTSTATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	/* specify how many bytes we expect back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	__raw_writeb(buflen & 0xFF, GDROM_BCL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	__raw_writeb((buflen >> 8) & 0xFF, GDROM_BCH_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	/* other parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	__raw_writeb(0, GDROM_INTSEC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	__raw_writeb(0, GDROM_SECNUM_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	__raw_writeb(0, GDROM_ERROR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	/* Wait until we can go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (!gdrom_wait_clrbusy()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		gdrom_getsense(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	timeout = jiffies + GDROM_DEFAULT_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	__raw_writeb(GDROM_COM_PACKET, GDROM_STATUSCOMMAND_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	while (!gdrom_data_request() && time_before(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (!time_before(jiffies, timeout + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		gdrom_getsense(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	outsw(GDROM_DATA_REG, cmd, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* gdrom_command_executediagnostic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * Used to probe for presence of working GDROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * Restarts GDROM device and then applies standard ATA 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * Execute Diagnostic Command: a return of '1' indicates device 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * present and device 1 absent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static char gdrom_execute_diagnostic(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	gdrom_hardreset(gd.cd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (!gdrom_wait_clrbusy())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	__raw_writeb(GDROM_COM_EXECDIAG, GDROM_STATUSCOMMAND_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	if (!gdrom_wait_busy_sleeps())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	return __raw_readb(GDROM_ERROR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * Prepare disk command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * byte 0 = 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * byte 1 = 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int gdrom_preparedisk_cmd(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	struct packet_command *spin_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	spin_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (!spin_command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	spin_command->cmd[0] = 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	spin_command->cmd[2] = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	spin_command->buflen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	gd.pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	gdrom_packetcommand(gd.cd_info, spin_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	/* 60 second timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	wait_event_interruptible_timeout(command_queue, gd.pending == 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		GDROM_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	gd.pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	kfree(spin_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (gd.status & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		/* log an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		gdrom_getsense(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * Read TOC command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * byte 0 = 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * byte 1 = session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * byte 3 = sizeof TOC >> 8  ie upper byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  * byte 4 = sizeof TOC & 0xff ie lower byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int gdrom_readtoc_cmd(struct gdromtoc *toc, int session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	int tocsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct packet_command *toc_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	toc_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (!toc_command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	tocsize = sizeof(struct gdromtoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	toc_command->cmd[0] = 0x14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	toc_command->cmd[1] = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	toc_command->cmd[3] = tocsize >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	toc_command->cmd[4] = tocsize & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	toc_command->buflen = tocsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (gd.pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		goto cleanup_readtoc_final;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	gd.pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	gdrom_packetcommand(gd.cd_info, toc_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	wait_event_interruptible_timeout(command_queue, gd.pending == 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		GDROM_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	if (gd.pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		goto cleanup_readtoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	insw(GDROM_DATA_REG, toc, tocsize/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (gd.status & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) cleanup_readtoc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	gd.pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) cleanup_readtoc_final:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	kfree(toc_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* TOC helpers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int get_entry_lba(int track)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	return (cpu_to_be32(track & 0xffffff00) - GD_SESSION_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static int get_entry_q_ctrl(int track)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	return (track & 0x000000f0) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int get_entry_track(int track)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	return (track & 0x0000ff00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int gdrom_get_last_session(struct cdrom_device_info *cd_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct cdrom_multisession *ms_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	int fentry, lentry, track, data, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	if (!gd.toc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	/* Check if GD-ROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	err = gdrom_readtoc_cmd(gd.toc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	/* Not a GD-ROM so check if standard CD-ROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		err = gdrom_readtoc_cmd(gd.toc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			pr_info("Could not get CD table of contents\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	fentry = get_entry_track(gd.toc->first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	lentry = get_entry_track(gd.toc->last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	/* Find the first data track */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	track = get_entry_track(gd.toc->last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		data = gd.toc->entry[track - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		if (get_entry_q_ctrl(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			break;	/* ie a real data track */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		track--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	} while (track >= fentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if ((track > 100) || (track < get_entry_track(gd.toc->first))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		pr_info("No data on the last session of the CD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		gdrom_getsense(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	ms_info->addr_format = CDROM_LBA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	ms_info->addr.lba = get_entry_lba(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	ms_info->xa_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int gdrom_open(struct cdrom_device_info *cd_info, int purpose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	/* spin up the disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	return gdrom_preparedisk_cmd();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* this function is required even if empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static void gdrom_release(struct cdrom_device_info *cd_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static int gdrom_drivestatus(struct cdrom_device_info *cd_info, int ignore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	/* read the sense key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	char sense = __raw_readb(GDROM_ERROR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	sense &= 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (sense == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		return CDS_DISC_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	if (sense == 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		return CDS_DRIVE_NOT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	/* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return CDS_NO_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static unsigned int gdrom_check_events(struct cdrom_device_info *cd_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 				       unsigned int clearing, int ignore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	/* check the sense key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	return (__raw_readb(GDROM_ERROR_REG) & 0xF0) == 0x60 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		DISK_EVENT_MEDIA_CHANGE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* reset the G1 bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static int gdrom_hardreset(struct cdrom_device_info *cd_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	__raw_writel(0x1fffff, GDROM_RESET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	for (count = 0xa0000000; count < 0xa0200000; count += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		__raw_readl(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* keep the function looking like the universal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * CD Rom specification  - returning int */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int gdrom_packetcommand(struct cdrom_device_info *cd_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct packet_command *command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	gdrom_spicommand(&command->cmd, command->buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* Get Sense SPI command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  * From Marcus Comstedt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  * cmd = 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  * cmd + 4 = length of returned buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  * Returns 5 16 bit words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int gdrom_getsense(short *bufstring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	struct packet_command *sense_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	short sense[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	int sense_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	int err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	sense_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	if (!sense_command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	sense_command->cmd[0] = 0x13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	sense_command->cmd[4] = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	sense_command->buflen = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	/* even if something is pending try to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	* the sense key if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	if (gd.pending && !gdrom_wait_clrbusy()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		goto cleanup_sense_final;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	gd.pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	gdrom_packetcommand(gd.cd_info, sense_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	wait_event_interruptible_timeout(command_queue, gd.pending == 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		GDROM_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (gd.pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		goto cleanup_sense;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	insw(GDROM_DATA_REG, &sense, sense_command->buflen/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (sense[1] & 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		pr_info("Drive not ready - command aborted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		goto cleanup_sense;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	sense_key = sense[1] & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (sense_key < ARRAY_SIZE(sense_texts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		pr_info("%s\n", sense_texts[sense_key].text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		pr_err("Unknown sense key: %d\n", sense_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	if (bufstring) /* return addional sense data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		memcpy(bufstring, &sense[4], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	if (sense_key < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) cleanup_sense:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	gd.pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) cleanup_sense_final:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	kfree(sense_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int gdrom_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			     void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static const struct cdrom_device_ops gdrom_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	.open			= gdrom_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	.release		= gdrom_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	.drive_status		= gdrom_drivestatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	.check_events		= gdrom_check_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	.get_last_session	= gdrom_get_last_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	.reset			= gdrom_hardreset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	.audio_ioctl		= gdrom_audio_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	.generic_packet		= cdrom_dummy_generic_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	.capability		= CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 				  CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	bdev_check_media_change(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	mutex_lock(&gdrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	ret = cdrom_open(gd.cd_info, bdev, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	mutex_unlock(&gdrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static void gdrom_bdops_release(struct gendisk *disk, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	mutex_lock(&gdrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	cdrom_release(gd.cd_info, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	mutex_unlock(&gdrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static unsigned int gdrom_bdops_check_events(struct gendisk *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 					     unsigned int clearing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	return cdrom_check_events(gd.cd_info, clearing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	unsigned cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	mutex_lock(&gdrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	ret = cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	mutex_unlock(&gdrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static const struct block_device_operations gdrom_bdops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	.owner			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	.open			= gdrom_bdops_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	.release		= gdrom_bdops_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	.check_events		= gdrom_bdops_check_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	.ioctl			= gdrom_bdops_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	.compat_ioctl		= blkdev_compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	gd.status = __raw_readb(GDROM_STATUSCOMMAND_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (gd.pending != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	gd.pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	wake_up_interruptible(&command_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static irqreturn_t gdrom_dma_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	gd.status = __raw_readb(GDROM_STATUSCOMMAND_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	if (gd.transfer != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	gd.transfer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	wake_up_interruptible(&request_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static int gdrom_set_interrupt_handlers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	err = request_irq(HW_EVENT_GDROM_CMD, gdrom_command_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		0, "gdrom_command", &gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	err = request_irq(HW_EVENT_GDROM_DMA, gdrom_dma_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		0, "gdrom_dma", &gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		free_irq(HW_EVENT_GDROM_CMD, &gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* Implement DMA read using SPI command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  * 0 -> 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)  * 1 -> mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)  * 2 -> block >> 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)  * 3 -> block >> 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)  * 4 -> block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)  * 8 -> sectors >> 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)  * 9 -> sectors >> 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)  * 10 -> sectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static blk_status_t gdrom_readdisk_dma(struct request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	int block, block_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	blk_status_t err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	struct packet_command *read_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	read_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	if (!read_command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		return BLK_STS_RESOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	read_command->cmd[0] = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	read_command->cmd[1] = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	block = blk_rq_pos(req)/GD_TO_BLK + GD_SESSION_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	block_cnt = blk_rq_sectors(req)/GD_TO_BLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	__raw_writel(virt_to_phys(bio_data(req->bio)), GDROM_DMA_STARTADDR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	__raw_writel(block_cnt * GDROM_HARD_SECTOR, GDROM_DMA_LENGTH_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	__raw_writel(1, GDROM_DMA_DIRECTION_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	__raw_writel(1, GDROM_DMA_ENABLE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	read_command->cmd[2] = (block >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	read_command->cmd[3] = (block >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	read_command->cmd[4] = block & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	read_command->cmd[8] = (block_cnt >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	read_command->cmd[9] = (block_cnt >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	read_command->cmd[10] = block_cnt & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	/* set for DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	__raw_writeb(1, GDROM_ERROR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	/* other registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	__raw_writeb(0, GDROM_SECNUM_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	__raw_writeb(0, GDROM_BCL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	__raw_writeb(0, GDROM_BCH_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	__raw_writeb(0, GDROM_DSEL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	__raw_writeb(0, GDROM_INTSEC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	/* Wait for registers to reset after any previous activity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	timeout = jiffies + HZ / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	while (gdrom_is_busy() && time_before(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	__raw_writeb(GDROM_COM_PACKET, GDROM_STATUSCOMMAND_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	timeout = jiffies + HZ / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	/* Wait for packet command to finish */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	while (gdrom_is_busy() && time_before(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	gd.pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	gd.transfer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	outsw(GDROM_DATA_REG, &read_command->cmd, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	timeout = jiffies + HZ / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	/* Wait for any pending DMA to finish */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	while (__raw_readb(GDROM_DMA_STATUS_REG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		time_before(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	/* start transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	__raw_writeb(1, GDROM_DMA_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	wait_event_interruptible_timeout(request_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		gd.transfer == 0, GDROM_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	err = gd.transfer ? BLK_STS_IOERR : BLK_STS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	gd.transfer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	gd.pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	blk_mq_end_request(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	kfree(read_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	return BLK_STS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static blk_status_t gdrom_queue_rq(struct blk_mq_hw_ctx *hctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 				   const struct blk_mq_queue_data *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	blk_mq_start_request(bd->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	switch (req_op(bd->rq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	case REQ_OP_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		return gdrom_readdisk_dma(bd->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	case REQ_OP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		pr_notice("Read only device - write request ignored\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		return BLK_STS_IOERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		printk(KERN_DEBUG "gdrom: Non-fs request ignored\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		return BLK_STS_IOERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* Print string identifying GD ROM device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static int gdrom_outputversion(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	struct gdrom_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	char *model_name, *manuf_name, *firmw_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	/* query device ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	id = kzalloc(sizeof(struct gdrom_id), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	gdrom_identifydevice(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	model_name = kstrndup(id->modname, 16, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	if (!model_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		goto free_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	manuf_name = kstrndup(id->mname, 16, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (!manuf_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		goto free_model_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	firmw_ver = kstrndup(id->firmver, 16, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	if (!firmw_ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		goto free_manuf_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	pr_info("%s from %s with firmware %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		model_name, manuf_name, firmw_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	kfree(firmw_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) free_manuf_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	kfree(manuf_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) free_model_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	kfree(model_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) free_id:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	kfree(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* set the default mode for DMA transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static int gdrom_init_dma_mode(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	__raw_writeb(0x13, GDROM_ERROR_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	__raw_writeb(0x22, GDROM_INTSEC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	if (!gdrom_wait_clrbusy())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	__raw_writeb(0xEF, GDROM_STATUSCOMMAND_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if (!gdrom_wait_busy_sleeps())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	/* Memory protection setting for GDROM DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	* Bits 31 - 16 security: 0x8843
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	* Bits 15 and 7 reserved (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	* Bits 14 - 8 start of transfer range in 1 MB blocks OR'ed with 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	* Bits 6 - 0 end of transfer range in 1 MB blocks OR'ed with 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	* (0x40 | 0x80) = start range at 0x0C000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	* (0x7F | 0x80) = end range at 0x0FFFFFFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	__raw_writel(0x8843407F, GDROM_DMA_ACCESS_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	__raw_writel(9, GDROM_DMA_WAIT_REG); /* DMA word setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static void probe_gdrom_setupcd(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	gd.cd_info->ops = &gdrom_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	gd.cd_info->capacity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	strcpy(gd.cd_info->name, GDROM_DEV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	gd.cd_info->mask = CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		CDC_SELECT_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static void probe_gdrom_setupdisk(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	gd.disk->major = gdrom_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	gd.disk->first_minor = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	gd.disk->minors = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	strcpy(gd.disk->disk_name, GDROM_DEV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static int probe_gdrom_setupqueue(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	blk_queue_logical_block_size(gd.gdrom_rq, GDROM_HARD_SECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	/* using DMA so memory will need to be contiguous */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	blk_queue_max_segments(gd.gdrom_rq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	/* set a large max size to get most from DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	blk_queue_max_segment_size(gd.gdrom_rq, 0x40000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	gd.disk->queue = gd.gdrom_rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	return gdrom_init_dma_mode();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static const struct blk_mq_ops gdrom_mq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	.queue_rq	= gdrom_queue_rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)  * register this as a block device and as compliant with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)  * universal CD Rom driver interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static int probe_gdrom(struct platform_device *devptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	 * Ensure our "one" device is initialized properly in case of previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	 * usages of it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	memset(&gd, 0, sizeof(gd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	/* Start the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	if (gdrom_execute_diagnostic() != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		pr_warn("ATA Probe for GDROM failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	/* Print out firmware ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	if (gdrom_outputversion())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	/* Register GDROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	gdrom_major = register_blkdev(0, GDROM_DEV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	if (gdrom_major <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		return gdrom_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	pr_info("Registered with major number %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		gdrom_major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	/* Specify basic properties of drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	gd.cd_info = kzalloc(sizeof(struct cdrom_device_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	if (!gd.cd_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		goto probe_fail_no_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	probe_gdrom_setupcd();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	gd.disk = alloc_disk(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	if (!gd.disk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		goto probe_fail_no_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	probe_gdrom_setupdisk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	if (register_cdrom(gd.disk, gd.cd_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		goto probe_fail_cdrom_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	gd.disk->fops = &gdrom_bdops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	gd.disk->events = DISK_EVENT_MEDIA_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	/* latch on to the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	err = gdrom_set_interrupt_handlers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		goto probe_fail_cmdirq_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	gd.gdrom_rq = blk_mq_init_sq_queue(&gd.tag_set, &gdrom_mq_ops, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 				BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	if (IS_ERR(gd.gdrom_rq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		err = PTR_ERR(gd.gdrom_rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		gd.gdrom_rq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 		goto probe_fail_requestq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	blk_queue_bounce_limit(gd.gdrom_rq, BLK_BOUNCE_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	err = probe_gdrom_setupqueue();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		goto probe_fail_toc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	gd.toc = kzalloc(sizeof(struct gdromtoc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	if (!gd.toc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		goto probe_fail_toc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	add_disk(gd.disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) probe_fail_toc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	blk_cleanup_queue(gd.gdrom_rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	blk_mq_free_tag_set(&gd.tag_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) probe_fail_requestq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	free_irq(HW_EVENT_GDROM_DMA, &gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	free_irq(HW_EVENT_GDROM_CMD, &gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) probe_fail_cmdirq_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) probe_fail_cdrom_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	del_gendisk(gd.disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) probe_fail_no_disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	kfree(gd.cd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) probe_fail_no_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	unregister_blkdev(gdrom_major, GDROM_DEV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	gdrom_major = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	pr_warn("Probe failed - error is 0x%X\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static int remove_gdrom(struct platform_device *devptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	blk_cleanup_queue(gd.gdrom_rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	blk_mq_free_tag_set(&gd.tag_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	free_irq(HW_EVENT_GDROM_CMD, &gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	free_irq(HW_EVENT_GDROM_DMA, &gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	del_gendisk(gd.disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	if (gdrom_major)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 		unregister_blkdev(gdrom_major, GDROM_DEV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	unregister_cdrom(gd.cd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	kfree(gd.cd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	kfree(gd.toc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static struct platform_driver gdrom_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	.probe = probe_gdrom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	.remove = remove_gdrom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 			.name = GDROM_DEV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static int __init init_gdrom(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	rc = platform_driver_register(&gdrom_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	pd = platform_device_register_simple(GDROM_DEV_NAME, -1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	if (IS_ERR(pd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 		platform_driver_unregister(&gdrom_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 		return PTR_ERR(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static void __exit exit_gdrom(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	platform_device_unregister(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 	platform_driver_unregister(&gdrom_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) module_init(init_gdrom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) module_exit(exit_gdrom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) MODULE_DESCRIPTION("SEGA Dreamcast GD-ROM Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) MODULE_LICENSE("GPL");