summaryrefslogtreecommitdiffstats
path: root/drivers/cdrom
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-01-10 17:17:53 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-01-10 17:17:53 +0000
commitb2ad5f821b1381492d792ca10b1eb7a107b48f14 (patch)
tree954a648692e7da983db1d2470953705f6a729264 /drivers/cdrom
parentc9c06167e7933d93a6e396174c68abf242294abb (diff)
Merge with Linux 2.4.0-prerelease. Big Makefile rewrite, test your
Makefiles.
Diffstat (limited to 'drivers/cdrom')
-rw-r--r--drivers/cdrom/Makefile20
-rw-r--r--drivers/cdrom/cdrom.c147
2 files changed, 82 insertions, 85 deletions
diff --git a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile
index 225c230e8..21f402d49 100644
--- a/drivers/cdrom/Makefile
+++ b/drivers/cdrom/Makefile
@@ -3,6 +3,7 @@
# 30 Jan 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
# Rewritten to use lists instead of if-statements.
+O_TARGET := driver.o
# All of the (potential) objects that export symbols.
@@ -42,25 +43,6 @@ obj-$(CONFIG_SBPCD4) += sbpcd4.o cdrom.o
obj-$(CONFIG_SJCD) += sjcd.o
obj-$(CONFIG_CDU535) += sonycd535.o
-
-
-# Files that are both resident and modular: remove from modular.
-
-obj-m := $(filter-out $(obj-y), $(obj-m))
-
-
-
-# Translate to Rules.make lists.
-
-L_TARGET := cdrom.a
-
-L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y)))
-LX_OBJS := $(sort $(filter $(export-objs), $(obj-y)))
-M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
-MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
-
-
-
# Hand off to Rules.make.
include $(TOPDIR)/Rules.make
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 23fe03584..1e555da55 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -224,11 +224,14 @@
3.11 Jun 12, 2000 - Jens Axboe <axboe@suse.de>
-- Fix bug in getting rpc phase 2 region info.
-- Reinstate "correct" CDROMPLAYTRKIND
-
+
+ 3.12 Oct 18, 2000 - Jens Axboe <axboe@suse.de>
+ -- Use quiet bit on packet commands not known to work
+
-------------------------------------------------------------------------*/
-#define REVISION "Revision: 3.11"
-#define VERSION "Id: cdrom.c 3.11 2000/06/12"
+#define REVISION "Revision: 3.12"
+#define VERSION "Id: cdrom.c 3.12 2000/10/18"
/* I use an error-log mask to give fine grain control over the type of
messages dumped to the system logs. The available masks include: */
@@ -701,6 +704,21 @@ static int cdrom_read_mech_status(struct cdrom_device_info *cdi,
struct cdrom_device_ops *cdo = cdi->ops;
int length;
+ /*
+ * Sanyo changer isn't spec compliant (doesn't use regular change
+ * LOAD_UNLOAD command, and it doesn't implement the mech status
+ * command below
+ */
+ if (cdi->sanyo_slot) {
+ buf->hdr.nslots = 3;
+ buf->hdr.curslot = cdi->sanyo_slot == 3 ? 0 : cdi->sanyo_slot;
+ for (length = 0; length < 3; length++) {
+ buf->slots[length].disc_present = 1;
+ buf->slots[length].change = 0;
+ }
+ return 0;
+ }
+
length = sizeof(struct cdrom_mechstat_header) +
cdi->capacity * sizeof(struct cdrom_slot);
@@ -767,9 +785,10 @@ static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot)
/* The Sanyo 3 CD changer uses byte 7 of the
GPCMD_TEST_UNIT_READY to command to switch CDs instead of
using the GPCMD_LOAD_UNLOAD opcode. */
- if (cdi->sanyo_slot && slot) {
+ if (cdi->sanyo_slot && -1 < slot) {
cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
cgc.cmd[7] = slot;
+ cgc.cmd[4] = cgc.cmd[8] = 0;
cdi->sanyo_slot = slot ? slot : 3;
}
@@ -953,6 +972,7 @@ void init_cdrom_command(struct cdrom_generic_command *cgc, void *buf, int len,
cgc->buffer = (char *) buf;
cgc->buflen = len;
cgc->data_direction = type;
+ cgc->timeout = 5*HZ;
}
/* DVD handling */
@@ -1860,6 +1880,48 @@ static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
return cdo->generic_packet(cdi, &cgc);
}
+static int cdrom_do_cmd(struct cdrom_device_info *cdi,
+ struct cdrom_generic_command *cgc)
+{
+ struct request_sense *usense, sense;
+ unsigned char *ubuf;
+ int ret;
+
+ if (cgc->data_direction == CGC_DATA_UNKNOWN)
+ return -EINVAL;
+
+ if (cgc->buflen < 0 || cgc->buflen >= 131072)
+ return -EINVAL;
+
+ if ((ubuf = cgc->buffer)) {
+ cgc->buffer = kmalloc(cgc->buflen, GFP_KERNEL);
+ if (cgc->buffer == NULL)
+ return -ENOMEM;
+ }
+
+ usense = cgc->sense;
+ cgc->sense = &sense;
+ if (usense && !access_ok(VERIFY_WRITE, usense, sizeof(*usense)))
+ return -EFAULT;
+
+ if (cgc->data_direction == CGC_DATA_READ) {
+ if (!access_ok(VERIFY_READ, ubuf, cgc->buflen))
+ return -EFAULT;
+ } else if (cgc->data_direction == CGC_DATA_WRITE) {
+ if (copy_from_user(cgc->buffer, ubuf, cgc->buflen)) {
+ kfree(cgc->buffer);
+ return -EFAULT;
+ }
+ }
+
+ ret = cdi->ops->generic_packet(cdi, cgc);
+ __copy_to_user(usense, cgc->sense, sizeof(*usense));
+ if (!ret && cgc->data_direction == CGC_DATA_READ)
+ __copy_to_user(ubuf, cgc->buffer, cgc->buflen);
+ kfree(cgc->buffer);
+ return ret;
+}
+
static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
unsigned long arg)
{
@@ -1923,7 +1985,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
}
case CDROMREADAUDIO: {
struct cdrom_read_audio ra;
- int lba, frames;
+ int lba;
IOCTL_IN(arg, struct cdrom_read_audio, ra);
@@ -1937,14 +1999,10 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
return -EINVAL;
/* FIXME: we need upper bound checking, too!! */
- if (lba < 0)
+ if (lba < 0 || ra.nframes <= 0)
return -EINVAL;
- /* do max 8 frames at the time */
- frames = ra.nframes > 8 ? 8 : ra.nframes;
-
- if ((cgc.buffer = (char *) kmalloc(CD_FRAMESIZE_RAW * frames,
- GFP_KERNEL)) == NULL)
+ if ((cgc.buffer = (char *) kmalloc(CD_FRAMESIZE_RAW, GFP_KERNEL)) == NULL)
return -ENOMEM;
if (!access_ok(VERIFY_WRITE, ra.buf, ra.nframes*CD_FRAMESIZE_RAW)) {
@@ -1953,13 +2011,12 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
}
cgc.data_direction = CGC_DATA_READ;
while (ra.nframes > 0) {
- ret = cdrom_read_block(cdi, &cgc, lba, frames, 1, CD_FRAMESIZE_RAW);
+ ret = cdrom_read_block(cdi, &cgc, lba, 1, 1, CD_FRAMESIZE_RAW);
if (ret) break;
- __copy_to_user(ra.buf, cgc.buffer,
- CD_FRAMESIZE_RAW * frames);
- ra.buf += (CD_FRAMESIZE_RAW * frames);
- ra.nframes -= frames;
- lba += frames;
+ __copy_to_user(ra.buf, cgc.buffer, CD_FRAMESIZE_RAW);
+ ra.buf += CD_FRAMESIZE_RAW;
+ ra.nframes--;
+ lba++;
}
kfree(cgc.buffer);
return ret;
@@ -2051,7 +2108,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
cgc.buffer = mask;
if ((ret = cdrom_mode_sense(cdi, &cgc,
GPMODE_AUDIO_CTL_PAGE, 1)))
- return ret;
+ return ret;
buffer[offset+9] = volctrl.channel0 & mask[offset+9];
buffer[offset+11] = volctrl.channel1 & mask[offset+11];
@@ -2117,52 +2174,11 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
}
case CDROM_SEND_PACKET: {
- __u8 *userbuf, copy = 0;
- struct request_sense *sense;
if (!CDROM_CAN(CDC_GENERIC_PACKET))
return -ENOSYS;
cdinfo(CD_DO_IOCTL, "entering CDROM_SEND_PACKET\n");
IOCTL_IN(arg, struct cdrom_generic_command, cgc);
- copy = !!cgc.buflen;
- userbuf = cgc.buffer;
- cgc.buffer = NULL;
- sense = cgc.sense;
- if (userbuf != NULL && copy) {
- /* usually commands just copy data one way, i.e.
- * we send a buffer to the drive and the command
- * specifies whether the drive will read or
- * write to that buffer. usually the buffers
- * are very small, so we don't loose that much
- * by doing a redundant copy each time. */
- if (!access_ok(VERIFY_WRITE, userbuf, cgc.buflen)) {
- printk("can't get write perms\n");
- return -EFAULT;
- }
- if (!access_ok(VERIFY_READ, userbuf, cgc.buflen)) {
- printk("can't get read perms\n");
- return -EFAULT;
- }
- }
- /* reasonable limits */
- if (cgc.buflen < 0 || cgc.buflen > 131072) {
- printk("invalid size given\n");
- return -EINVAL;
- }
- if (copy) {
- cgc.buffer = kmalloc(cgc.buflen, GFP_KERNEL);
- if (cgc.buffer == NULL)
- return -ENOMEM;
- __copy_from_user(cgc.buffer, userbuf, cgc.buflen);
- }
- ret = cdo->generic_packet(cdi, &cgc);
- if (copy && !ret)
- __copy_to_user(userbuf, cgc.buffer, cgc.buflen);
- /* copy back sense data */
- if (sense != NULL)
- if (copy_to_user(sense, cgc.sense, sizeof(struct request_sense)))
- ret = -EFAULT;
- kfree(cgc.buffer);
- return ret;
+ return cdrom_do_cmd(cdi, &cgc);
}
case CDROM_NEXT_WRITABLE: {
long next = 0;
@@ -2199,6 +2215,7 @@ int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type,
cgc.cmd[4] = (track & 0xff00) >> 8;
cgc.cmd[5] = track & 0xff;
cgc.cmd[8] = 8;
+ cgc.quiet = 1;
if ((ret = cdo->generic_packet(cdi, &cgc)))
return ret;
@@ -2220,6 +2237,7 @@ int cdrom_get_disc_info(kdev_t dev, disc_information *di)
init_cdrom_command(&cgc, di, sizeof(*di), CGC_DATA_READ);
cgc.cmd[0] = GPCMD_READ_DISC_INFO;
cgc.cmd[8] = cgc.buflen = 2;
+ cgc.quiet = 1;
if ((ret = cdo->generic_packet(cdi, &cgc)))
return ret;
@@ -2252,9 +2270,6 @@ int cdrom_get_last_written(kdev_t dev, long *last_written)
if (!CDROM_CAN(CDC_GENERIC_PACKET))
goto use_toc;
- if (!CDROM_CAN(CDC_CD_R | CDC_CD_RW | CDC_DVD_R | CDC_DVD_RAM))
- goto use_toc;
-
if ((ret = cdrom_get_disc_info(dev, &di)))
goto use_toc;
@@ -2558,10 +2573,11 @@ ctl_table cdrom_cdrom_table[] = {
/* Make sure that /proc/sys/dev is there */
ctl_table cdrom_root_table[] = {
+#ifdef CONFIG_PROC_FS
{CTL_DEV, "dev", NULL, 0, 0555, cdrom_cdrom_table},
+#endif /* CONFIG_PROC_FS */
{0}
};
-
static struct ctl_table_header *cdrom_sysctl_header;
static void cdrom_sysctl_register(void)
@@ -2572,9 +2588,8 @@ static void cdrom_sysctl_register(void)
return;
cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 1);
-#ifdef CONFIG_PROC_FS
cdrom_root_table->child->de->owner = THIS_MODULE;
-#endif /* CONFIG_PROC_FS */
+
/* set the defaults */
cdrom_sysctl_settings.autoclose = autoclose;
cdrom_sysctl_settings.autoeject = autoeject;