From: Peter Osterlund <petero2@telia.com>
To: linux-kernel@vger.kernel.org
Cc: Jens Axboe <axboe@suse.de>, Andrew Morton <akpm@osdl.org>,
Nigel Kukard <nkukard@lbsd.net>
Subject: [PATCH] DVD+RW support for 2.6.7-bk13
Date: 01 Jul 2004 15:45:27 +0200 [thread overview]
Message-ID: <m2hdsr6du0.fsf@telia.com> (raw)
This patch adds support for using DVD+RW drives as writable block
devices under the 2.6.7-bk13 kernel.
The patch is based on work from:
Andy Polyakov <appro@fy.chalmers.se> - Wrote the 2.4 patch
Nigel Kukard <nkukard@lbsd.net> - Initial porting to 2.6.x
It works for me using an Iomega Super DVD 8x USB drive.
Signed-off-by: Peter Osterlund <petero2@telia.com>
---
linux-petero/drivers/cdrom/cdrom.c | 80 +++++++++++++++++++++++++++++++++++++
linux-petero/drivers/ide/ide-cd.c | 2
linux-petero/drivers/scsi/sr.c | 1
linux-petero/include/linux/cdrom.h | 2
4 files changed, 85 insertions(+)
diff -puN drivers/cdrom/cdrom.c~dvd+rw drivers/cdrom/cdrom.c
--- linux/drivers/cdrom/cdrom.c~dvd+rw 2004-07-01 15:10:46.706913160 +0200
+++ linux-petero/drivers/cdrom/cdrom.c 2004-07-01 15:10:46.720911032 +0200
@@ -821,6 +821,41 @@ static int cdrom_ram_open_write(struct c
return ret;
}
+static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
+{
+ struct packet_command cgc;
+ char buffer[32];
+ int ret, mmc3_profile;
+
+ init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
+
+ cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
+ cgc.cmd[1] = 0;
+ cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
+ cgc.cmd[7] = 0; cgc.cmd [8] = 8; /* Allocation Length */
+ cgc.quiet = 1;
+
+ if ((ret = cdi->ops->generic_packet(cdi, &cgc))) {
+ mmc3_profile = 0xffff;
+ } else {
+ mmc3_profile = (buffer[6] << 8) | buffer[7];
+ printk(KERN_INFO "cdrom: %s: mmc-3 profile capable, current profile: %Xh\n",
+ cdi->name, mmc3_profile);
+ }
+ cdi->mmc3_profile = mmc3_profile;
+}
+
+static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
+{
+ switch (cdi->mmc3_profile) {
+ case 0x12: /* DVD-RAM */
+ case 0x1A: /* DVD+RW */
+ return 0;
+ default:
+ return 1;
+ }
+}
+
/*
* returns 0 for ok to open write, non-0 to disallow
*/
@@ -859,10 +894,50 @@ static int cdrom_open_write(struct cdrom
ret = cdrom_ram_open_write(cdi);
else if (CDROM_CAN(CDC_MO_DRIVE))
ret = mo_open_write(cdi);
+ else if (!cdrom_is_dvd_rw(cdi))
+ ret = 0;
return ret;
}
+static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi)
+{
+ struct packet_command cgc;
+
+ if (cdi->mmc3_profile != 0x1a) {
+ cdinfo(CD_CLOSE, "%s: No DVD+RW\n", cdi->name);
+ return;
+ }
+
+ if (!cdi->media_written) {
+ cdinfo(CD_CLOSE, "%s: DVD+RW media clean\n", cdi->name);
+ return;
+ }
+
+ printk(KERN_INFO "cdrom: %s: dirty DVD+RW media, \"finalizing\"\n",
+ cdi->name);
+
+ init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
+ cgc.cmd[0] = GPCMD_FLUSH_CACHE;
+ cgc.timeout = 30*HZ;
+ cdi->ops->generic_packet(cdi, &cgc);
+
+ init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
+ cgc.cmd[0] = GPCMD_CLOSE_TRACK;
+ cgc.timeout = 3000*HZ;
+ cgc.quiet = 1;
+ cdi->ops->generic_packet(cdi, &cgc);
+
+ init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
+ cgc.cmd[0] = GPCMD_CLOSE_TRACK;
+ cgc.cmd[2] = 2; /* Close session */
+ cgc.quiet = 1;
+ cgc.timeout = 3000*HZ;
+ cdi->ops->generic_packet(cdi, &cgc);
+
+ cdi->media_written = 0;
+}
+
static int cdrom_close_write(struct cdrom_device_info *cdi)
{
#if 0
@@ -895,6 +970,7 @@ int cdrom_open(struct cdrom_device_info
ret = open_for_data(cdi);
if (ret)
goto err;
+ cdrom_mmc3_profile(cdi);
if (fp->f_mode & FMODE_WRITE) {
ret = -EROFS;
if (!CDROM_CAN(CDC_RAM))
@@ -902,6 +978,7 @@ int cdrom_open(struct cdrom_device_info
if (cdrom_open_write(cdi))
goto err;
ret = 0;
+ cdi->media_written = 0;
}
}
@@ -1093,6 +1170,8 @@ int cdrom_release(struct cdrom_device_in
cdi->use_count--;
if (cdi->use_count == 0)
cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
+ if (cdi->use_count == 0)
+ cdrom_dvd_rw_close_write(cdi);
if (cdi->use_count == 0 &&
(cdo->capability & CDC_LOCK) && !keeplocked) {
cdinfo(CD_CLOSE, "Unlocking door!\n");
@@ -1299,6 +1378,7 @@ int media_changed(struct cdrom_device_in
if (cdi->ops->media_changed(cdi, CDSL_CURRENT)) {
cdi->mc_flags = 0x3; /* set bit on both queues */
ret |= 1;
+ cdi->media_written = 0;
}
cdi->mc_flags &= ~mask; /* clear bit */
return ret;
diff -puN drivers/scsi/sr.c~dvd+rw drivers/scsi/sr.c
--- linux/drivers/scsi/sr.c~dvd+rw 2004-07-01 15:10:46.708912856 +0200
+++ linux-petero/drivers/scsi/sr.c 2004-07-01 15:10:46.721910880 +0200
@@ -379,6 +379,7 @@ static int sr_init_command(struct scsi_c
return 0;
SCpnt->cmnd[0] = WRITE_10;
SCpnt->sc_data_direction = DMA_TO_DEVICE;
+ cd->cdi.media_written = 1;
} else if (rq_data_dir(SCpnt->request) == READ) {
SCpnt->cmnd[0] = READ_10;
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
diff -puN drivers/ide/ide-cd.c~dvd+rw drivers/ide/ide-cd.c
--- linux/drivers/ide/ide-cd.c~dvd+rw 2004-07-01 15:10:46.711912400 +0200
+++ linux-petero/drivers/ide/ide-cd.c 2004-07-01 15:10:46.724910424 +0200
@@ -1940,6 +1940,8 @@ static ide_startstop_t cdrom_start_write
info->dma = drive->using_dma ? 1 : 0;
info->cmd = WRITE;
+ info->devinfo.media_written = 1;
+
/* Start sending the write request to the drive. */
return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
}
diff -puN include/linux/cdrom.h~dvd+rw include/linux/cdrom.h
--- linux/include/linux/cdrom.h~dvd+rw 2004-07-01 15:10:46.713912096 +0200
+++ linux-petero/include/linux/cdrom.h 2004-07-01 15:10:46.725910272 +0200
@@ -947,6 +947,8 @@ struct cdrom_device_info {
__u8 reserved : 6; /* not used yet */
int cdda_method; /* see flags */
__u8 last_sense;
+ __u8 media_written; /* dirty flag, DVD+RW bookkeeping */
+ unsigned short mmc3_profile; /* current MMC3 profile */
int for_data;
int (*exit)(struct cdrom_device_info *);
int mrw_mode_page;
_
--
Peter Osterlund - petero2@telia.com
http://w1.894.telia.com/~u89404340
next reply other threads:[~2004-07-01 13:56 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-07-01 13:45 Peter Osterlund [this message]
2004-07-01 16:16 ` [PATCH] DVD+RW support for 2.6.7-bk13 Wakko Warner
2004-07-01 21:02 ` Peter Osterlund
2004-07-01 23:29 ` Wakko Warner
2004-07-02 14:58 ` Peter Osterlund
[not found] ` <20040702162028.28765ce1.akpm@osdl.org>
2004-07-03 0:22 ` Peter Osterlund
2004-09-01 18:40 ` Peter Osterlund
2004-09-01 18:47 ` Nigel Kukard
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=m2hdsr6du0.fsf@telia.com \
--to=petero2@telia.com \
--cc=akpm@osdl.org \
--cc=axboe@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=nkukard@lbsd.net \
/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.