^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");