From: Pat LaVarre <p.lavarre@ieee.org>
To: axboe@suse.de
Cc: linux-scsi@vger.kernel.org
Subject: [PATCH] CDC_MMC_WR
Date: 10 Oct 2003 18:38:04 -0600 [thread overview]
Message-ID: <1065832684.2877.37.camel@patehci2> (raw)
Jens A:
> > > Please add ...
> > > to cdrom.c instead ... GPCMD_GET_CONFIGURATION
> >
> > Happily will do. I'll continue to reply
> > as I progress or not.
>
> Great, thanks.
Please tell me what we think of this new patch?
You can see I've guessed I now should launch a new thread. The
linux-scsi thread "writable mmc profiles actually are writable" walked
us thru every painful step of me learning to write this patch.
So far I see Three design goals:
a) Add CDC_MMC_WR, masked by default, to: include/cdrom.h, to
drivers/ide/ide-cd.c, and to drivers/scsi/sr.c.
b) Correct device->writeable in sr.c sometime after
drivers/cdrom/cdrom.c discovers it was wrong.
c) Teach cdrom.c to discover CDC_MMC_WR.
That last goal I see divide into Eight changes to cdrom.c:
c1) Refuse to pass thru writes only if CDC_MMC_WR, no matter
CDC_DVD_RAM.
c2) Define cdrom_get_cdc and call cdrom_get_cdc only if register_cdrom
succeeds, just before register_cdrom does succeed.
c3) In cdrom_get_cdc, say &= ~CDC_MMC_WR if ide-cd or sr said &=
~CDC_DVD_RAM.
c4) In cdrom_get_cdc, also say &= ~CDC_MMC_WR if cdrom_get_capabilities
ok and cdrom_get_configuration ok and the profile fetched is any one of
the seven standard "random writable" profiles of mmc except not the
x001A dvd+rw profile that maybe can't be overwritten more than 1000
times in place, per Andy Polyakov's:
http://fy.chalmers.se/~appro/linux/DVD+RW/#udf
c5) Define cdrom_get_capabilities in terms of cdrom_mode_sense by
block-copy-edit of other cdrom.c source.
c6) Define cdrom_get_configuration in terms of cdo->generic_packet by
block-copy-edit of other cdrom.c source
c7) Add a line of text to /proc/sys/dev/cdrom/info to reveal CDC_MMC_WR.
c8) Update change history, REVISION, VERSION.
Please tell me what we think of this new patch?
Pat LaVarre
diff -Nur linux-2.6.0-test7/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- linux-2.6.0-test7/drivers/cdrom/cdrom.c 2003-10-08 13:24:02.000000000 -0600
+++ linux/drivers/cdrom/cdrom.c 2003-10-10 18:05:25.343260848 -0600
@@ -228,10 +228,13 @@
3.12 Oct 18, 2000 - Jens Axboe <axboe@suse.de>
-- Use quiet bit on packet commands not known to work
+ 3.13 Oct 10, 2003 - Jens Axboe <axboe@suse.de>
+ -- Pass writes thru to all CDC_MMC_WR profiles, not just CDC_DVD_RAM.
+
-------------------------------------------------------------------------*/
-#define REVISION "Revision: 3.12"
-#define VERSION "Id: cdrom.c 3.12 2000/10/18"
+#define REVISION "Revision: 3.13"
+#define VERSION "Id: cdrom.c 3.13 2003/10/10"
/* 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: */
@@ -313,6 +316,7 @@
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
/* Not-exported routines. */
+static void cdrom_get_cdc(struct cdrom_device_info *cdi);
static int open_for_data(struct cdrom_device_info * cdi);
static int check_for_audio_disc(struct cdrom_device_info * cdi,
struct cdrom_device_ops * cdo);
@@ -381,6 +385,8 @@
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
cdi->next = topCdromPtr;
topCdromPtr = cdi;
+
+ cdrom_get_cdc(cdi);
return 0;
}
#undef ENSURE
@@ -408,6 +414,71 @@
return 0;
}
+static int cdrom_get_capabilities(struct cdrom_device_info *cdi)
+{
+ struct cdrom_generic_command cgc0;
+ struct cdrom_generic_command * cgc = &cgc0;
+ u_char buf[0x18]; /* ide-cd length = x18, sr length = x80 */
+ int ret;
+ memset(cgc, 0, sizeof *cgc);
+ memset(&buf[0], 0, sizeof(buf));
+ cgc->buffer = buf;
+ cgc->buflen = sizeof buf;
+ ret = cdrom_mode_sense(cdi, cgc, GPMODE_CAPABILITIES_PAGE, 0);
+ return ret;
+}
+
+static int cdrom_get_configuration(struct cdrom_device_info *cdi)
+{
+ struct cdrom_generic_command cgc0;
+ struct cdrom_generic_command * cgc = &cgc0;
+ struct cdrom_device_ops *cdo = cdi->ops;
+ u_char buf[8];
+ int ret;
+ int profile;
+ memset(cgc, 0, sizeof *cgc);
+ memset(&buf[0], 0, sizeof(buf));
+ cgc->buffer = buf;
+ cgc->buflen = sizeof buf;
+ cgc->cmd[0] = GPCMD_GET_CONFIGURATION;
+ cgc->cmd[7] = cgc->buflen >> 8;
+ cgc->cmd[8] = cgc->buflen & 0xff;
+ cgc->data_direction = CGC_DATA_READ;
+ ret = cdo->generic_packet(cdi, cgc);
+ if (ret) return ret;
+ profile = buf[6] << 8 | buf[7];
+ cdinfo(CD_REG_UNREG, "profile x%04X\n", profile);
+ switch (profile) {
+ case 0x0001: /* Non-Removable Disk */
+ case 0x0002: /* Removable Disk */
+ case 0x0003: /* Magneto-Optical Erasable */
+ case 0x0005: /* AS-MO */
+ case 0x0012: /* DVD-RAM */
+ case 0x0022: /* DDCD-RW */
+ cdi->mask &= ~CDC_MMC_WR;
+ break;
+ case 0x001A: /* DVD+RW = not very rewritable in place */
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+static void cdrom_get_cdc(struct cdrom_device_info *cdi)
+{
+ cdinfo(CD_REG_UNREG, "cdrom_get_cdc\n");
+ if (CDROM_CAN(CDC_DVD_RAM)) {
+ cdi->mask &= ~CDC_MMC_WR;
+ } else if (cdrom_get_capabilities(cdi)) {
+ cdinfo(CD_WARNING, "GET_CAPABILITIES not\n");
+ } else {
+ if (cdrom_get_configuration(cdi)) {
+ cdinfo(CD_WARNING, "GET_CONFIGURATION not\n");
+ }
+ }
+}
+
/* We use the open-option O_NONBLOCK to indicate that the
* purpose of opening is only for subsequent ioctl() calls; no device
* integrity checks are performed.
@@ -426,8 +497,9 @@
if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS))
ret = cdi->ops->open(cdi, 1);
else {
- if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_DVD_RAM))
+ if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_MMC_WR)) {
return -EROFS;
+ }
ret = open_for_data(cdi);
}
@@ -2406,6 +2478,10 @@
for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0);
+ pos += sprintf(info+pos, "\nTolerates random write:");
+ for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
+ pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MMC_WR) != 0);
+
strcpy(info+pos,"\n\n");
return proc_dostring(ctl, write, filp, buffer, lenp);
diff -Nur linux-2.6.0-test7/include/linux/cdrom.h linux/include/linux/cdrom.h
--- linux-2.6.0-test7/include/linux/cdrom.h 2003-10-08 13:24:00.000000000 -0600
+++ linux/include/linux/cdrom.h 2003-10-10 15:37:16.000000000 -0600
@@ -388,6 +388,7 @@
#define CDC_DVD_R 0x10000 /* drive can write DVD-R */
#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */
#define CDC_MO_DRIVE 0x40000 /* drive is an MO device */
+#define CDC_MMC_WR 0x80000 /* profile includes random write */
/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
#define CDS_NO_INFO 0 /* if not implemented */
diff -Nur linux-2.6.0-test7/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.6.0-test7/drivers/ide/ide-cd.c 2003-10-08 13:24:04.000000000 -0600
+++ linux/drivers/ide/ide-cd.c 2003-10-10 15:36:33.000000000 -0600
@@ -2822,7 +2822,7 @@
CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET |
CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R |
CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
- CDC_GENERIC_PACKET | CDC_MO_DRIVE,
+ CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MMC_WR,
.generic_packet = ide_cdrom_packet,
};
@@ -2832,7 +2832,7 @@
struct cdrom_device_info *devinfo = &info->devinfo;
devinfo->ops = &ide_cdrom_dops;
- devinfo->mask = 0;
+ devinfo->mask = CDC_MMC_WR;
devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed;
devinfo->capacity = nslots;
devinfo->handle = (void *) drive;
diff -Nur linux-2.6.0-test7/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- linux-2.6.0-test7/drivers/scsi/sr.c 2003-10-08 13:24:03.000000000 -0600
+++ linux/drivers/scsi/sr.c 2003-10-10 15:48:12.000000000 -0600
@@ -67,7 +67,8 @@
(CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
- CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET)
+ CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
+ CDC_MMC_WR)
static int sr_probe(struct device *);
static int sr_remove(struct device *);
@@ -327,8 +328,12 @@
}
if (rq_data_dir(SCpnt->request) == WRITE) {
- if (!cd->device->writeable)
- return 0;
+ if (!cd->device->writeable) {
+ if ((cd->cdi.mask & CDC_MMC_WR) != 0) {
+ return 0;
+ }
+ cd->device->writeable = 1;
+ }
SCpnt->cmnd[0] = WRITE_10;
SCpnt->sc_data_direction = SCSI_DATA_WRITE;
} else if (rq_data_dir(SCpnt->request) == READ) {
@@ -550,7 +555,7 @@
cd->cdi.ops = &sr_dops;
cd->cdi.handle = cd;
- cd->cdi.mask = 0;
+ cd->cdi.mask = CDC_MMC_WR;
cd->cdi.capacity = 1;
sprintf(cd->cdi.name, "sr%d", minor);
next reply other threads:[~2003-10-11 0:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-10-11 0:38 Pat LaVarre [this message]
2003-10-11 8:21 ` [PATCH] CDC_MMC_WR Jens Axboe
2003-10-13 15:02 ` Pat LaVarre
2003-10-20 22:58 ` Pat LaVarre
2003-10-27 20:40 ` Pat LaVarre
-- strict thread matches above, loose matches on Subject: below --
2003-10-12 13:33 Pat LaVarre
2003-10-12 15:02 Pat LaVarre
2003-10-12 19:19 Pat LaVarre
2003-11-01 0:51 Pat LaVarre
2003-11-06 16:32 ` Pat LaVarre
2003-11-06 17:44 ` Pat LaVarre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1065832684.2877.37.camel@patehci2 \
--to=p.lavarre@ieee.org \
--cc=axboe@suse.de \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.