osdir.com
mailing list archive

Subject: Re: Time to conclude the Sony USB mass storage thread - msg#00227

List: linux.scsi

Date: Prev Next Index Thread: Prev Next Index
On Fri, Nov 14, 2003 at 09:58:23AM -0800, Patrick Mansfield wrote:
> On Fri, Nov 14, 2003 at 09:35:03AM -0800, Matthew Dharm wrote:
> > I think I'd rather tweak the structure in slave_configure, where it will be
> > easier to add more logic if people decide we need it in the future.
>
> Unlike scsi_devinfo/dev_flags, we can't override slave_configure changes
> (unless you add other code).

It's not immediately clear how we can override it if it's
scsi_devinfo/dev_flags. Can you elaborate?

Matt

--
Matthew Dharm Home: mdharm-usb@xxxxxxxxxxxxxxxxxx
Maintainer, Linux USB Mass Storage Driver

E: You run this ship with Windows?! YOU IDIOT!
L: Give me a break, it came bundled with the computer!
-- ESR and Lan Solaris
User Friendly, 12/8/1998

Attachment: pgpNNOZV3olfm.pgp
Description: PGP signature

Was this page helpful?
Yes No
Thread at a glance:

Previous Message by Date: click to view message preview

Re: [PATCH] CDC_WR

The inline patch of this post sketches how we might choose to teach cdrom.ko to interpret MMC features ... after we decide what interpretation we like. As is, this code clearly still needs work e.g. it says more cdrom.ko devices are writable then we mean to consider writable, and it goes badly wrong if ever a device reports more than xFFFF bytes of features available. Meanwhile, for the sake of development, as yet this patch conveniently spits out a dump of all the "feature code"s and "profile"s. For example, the dmesg I saw from a device that mixes not-current profile x0002 "Removable Disk" together with not-current feature code "x0020 "Random Writable" ... despite not actually supporting much rewrite in place was: hdc: ATAPI 48X DVD-ROM CD-R/RW drive, 2048kB Cache, UDMA(33) cdrom: entering register_cdrom Uniform CD-ROM driver Revision: 3.12 cdrom: drive "/dev/hdc" registered cdrom: may be writable cdrom: feature code x0000 cdrom: profile x0010 cdrom: profile x000A cdrom: profile x0009 cdrom: profile x0008 cdrom: profile x0002 // Removable Disk cdrom: feature code x0001 cdrom: feature code x0002 cdrom: feature code x0003 cdrom: feature code x0010 cdrom: feature code x001D cdrom: feature code x001E cdrom: feature code x001F cdrom: feature code x0020 // Random Writable cdrom: feature code x0021 cdrom: feature code x0023 cdrom: feature code x0024 cdrom: feature code x0026 cdrom: feature code x0027 cdrom: feature code x0028 cdrom: feature code x002A cdrom: feature code x002B cdrom: feature code x002D cdrom: feature code x002E cdrom: feature code x0100 cdrom: feature code x0101 cdrom: feature code x0103 cdrom: feature code x0104 cdrom: feature code x0105 cdrom: feature code x0106 cdrom: feature code x0107 cdrom: entering cdrom_open ... Pat LaVarre diff -Nur linux-2.6.0-test9/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- linux-2.6.0-test9/drivers/cdrom/cdrom.c 2003-10-25 12:43:01.000000000 -0600 +++ linux/drivers/cdrom/cdrom.c 2003-11-13 15:50:38.000000000 -0700 @@ -251,6 +251,9 @@ /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */ /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */ +#undef ERRLOGMASK +#define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) + #include <linux/config.h> #include <linux/module.h> #include <linux/fs.h> @@ -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,114 @@ return 0; } +/* Interpret the MMC feature x0000 "Profile List". */ + +static int cdrom_profile_list(struct cdrom_device_info *cdi, + u_char * buf, int len) +{ + int offset; + for (offset = 4; (offset + 4) <= len; offset += 4) { + int profile = buf[offset] << 8 | buf[offset + 1]; + 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 */ + break; + case 0x001A: /* DVD+RW = not much rewrite in place */ + default: + cdi->mask |= CDC_WR; + break; + } + } + return 0; +} + +/* Interpret an MMC feature. */ + +static int cdrom_feature(struct cdrom_device_info *cdi, + u_char * buf, int len) +{ + int feature_code = buf[0] << 8 | buf[1]; + cdinfo(CD_REG_UNREG, "feature code x%04X\n", feature_code); + switch (feature_code) { + case 0x0000: /* "Profile List" */ + cdrom_profile_list(cdi, buf, len); + break; + case 0x0020: /* "Random Writable" */ + cdi->mask &= ~CDC_WR; + break; + default: + break; + } + return 0; +} + +/* Interpret each MMC feature in order per mmc4r02f.pdf. */ + +static int cdrom_each_feature(struct cdrom_device_info *cdi, + u_char * buf, int len) +{ + int ret = 0; + int offset; + int step; + for (offset = 8; (offset + 4) <= len; offset += step) { + step = (3 + 1 + buf[offset + 3]); + if ((offset + step) <= len) { + ret |= cdrom_feature(cdi, &buf[offset], step); + } + } + return ret; +} + +/* Fetch the first few available MMC "feature"s. */ + +static int cdrom_get_configuration(struct cdrom_device_info *cdi) +{ + struct cdrom_generic_command cgc; + struct cdrom_device_ops *cdo = cdi->ops; + u_char part[8]; + int ret; + init_cdrom_command(&cgc, part, 8, CGC_DATA_READ); + cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* 0x46 */ + cgc.cmd[7] = cgc.buflen >> 8; + cgc.cmd[8] = cgc.buflen & 0xff; + ret = cdo->generic_packet(cdi, &cgc); + if (!ret) { + int len = (4 + 0 + (part[0] << 24 | part[1] << 16 | + part[2] << 8 | part[3])); + u_char * whole = kmalloc(len, GFP_KERNEL); + if (!whole) + return -ENOMEM; + init_cdrom_command(&cgc, whole, len, CGC_DATA_READ); + cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* 0x46 */ + cgc.cmd[7] = cgc.buflen >> 8; + cgc.cmd[8] = cgc.buflen & 0xff; + ret = cdo->generic_packet(cdi, &cgc); + if (!ret) { + ret = cdrom_each_feature(cdi, whole, len); + } + kfree(whole); + } + return ret; +} + +/* Tweak cdi->mask to agree with MMC "feature" descriptors. */ + +static void cdrom_get_cdc(struct cdrom_device_info *cdi) +{ + if (CDROM_CAN(CDC_WR) && !CDROM_CAN(CDC_DVD_RAM)) { + cdinfo(CD_REG_UNREG, "may be writable\n"); + cdi->mask |= CDC_WR; /* guess not */ + if (cdrom_get_configuration(cdi)) { + cdinfo(CD_REG_UNREG, "indeterminate features\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,7 +540,7 @@ 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_WR)) return -EROFS; ret = open_for_data(cdi); @@ -2406,6 +2520,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_WR) != 0); + strcpy(info+pos,"\n\n"); return proc_dostring(ctl, write, filp, buffer, lenp); diff -Nur linux-2.6.0-test9/include/linux/cdrom.h linux/include/linux/cdrom.h --- linux-2.6.0-test9/include/linux/cdrom.h 2003-10-25 12:42:47.000000000 -0600 +++ linux/include/linux/cdrom.h 2003-11-10 08:28:59.000000000 -0700 @@ -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_WR 0x80000 /* drive tolerates 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-test9/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c --- linux-2.6.0-test9/drivers/ide/ide-cd.c 2003-10-25 12:43:32.000000000 -0600 +++ linux/drivers/ide/ide-cd.c 2003-11-10 08:41:52.000000000 -0700 @@ -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_WR, .generic_packet = ide_cdrom_packet, }; diff -Nur linux-2.6.0-test9/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- linux-2.6.0-test9/drivers/scsi/sr.c 2003-10-25 12:43:12.000000000 -0600 +++ linux/drivers/scsi/sr.c 2003-11-10 08:46:04.000000000 -0700 @@ -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_WR) static int sr_probe(struct device *); static int sr_remove(struct device *); @@ -327,8 +328,9 @@ } if (rq_data_dir(SCpnt->request) == WRITE) { - if (!cd->device->writeable) + if ((cd->cdi.mask & CDC_WR) != 0) { return 0; + } SCpnt->cmnd[0] = WRITE_10; SCpnt->sc_data_direction = SCSI_DATA_WRITE; } else if (rq_data_dir(SCpnt->request) == READ) { @@ -557,6 +559,7 @@ sdev->sector_size = 2048; /* A guess, just in case */ /* FIXME: need to handle a get_capabilities failure properly ?? */ + cd->device->writeable = 1; /* = ((cd->cdi.mask & CDC_WR) == 0); */ get_capabilities(cd); sr_vendor_init(cd); @@ -564,6 +567,7 @@ "%s/cd", sdev->devfs_name); disk->driverfs_dev = &sdev->sdev_gendev; register_cdrom(&cd->cdi); + cd->device->writeable = ((cd->cdi.mask & CDC_WR) == 0); set_capacity(disk, cd->capacity); disk->private_data = &cd->driver; disk->queue = sdev->request_queue; @@ -788,8 +792,6 @@ if ((buffer[n + 3] & 0x20) == 0) { /* can't write DVD-RAM media */ cd->cdi.mask |= CDC_DVD_RAM; - } else { - cd->device->writeable = 1; } if ((buffer[n + 3] & 0x10) == 0) /* can't write DVD-R media */ - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html

Next Message by Date: click to view message preview

Re: [usb-storage] mode sense blacklist how

// Everyone: I think I'm seeing hints that possibly we've carried this reply-to-all convention a little too far by now. Not sure how to fix that. // Dmitri K: > > To accomodate this device are we asking Dmitri K to give one last shot > > to telling us if kernel crash, boot fs crash, or other is the result of > > each of the twelve ... > > ? > > I'll be away for the next 4 days. I'll try to test it now, > if not I'll report when I come back ... > What exactly do you want me to do? Step-by-step instructions follow, in case you choose to try them. I see we have committed to teaching usb-storage to blacklist mode sense, despite thereby breaking sd devices that write-protect disks by implementing mode sense as described in the fiction authored by t10. Therefore I cannot know who among "we" besides me still cares that the sample Sony stick you're sharing with us chokes over how we used to try mode sense. As for me, yes I remain curious. I'd like you (and all the world's engineers) to learn to explore such matters. > What exactly do you want me to do? First step in learning to explore this way is to install some tool for trying SG_IO from the command line, such as the download/ patch/ make instructions of: http://groups.google.com/groups?q=plscsi+sed+make Newsgroups: mlist.linux.scsi Subject: Re: [PATCH/RFT] mode sense madness always use page 8 Date: 2003-10-30 16:20:20 PST You know you've finished decrypting that post when you get as far as: sudo ./plscsi -w Next you can proceed to try the twelve Sony stick experiments suggested by that Win XP SP1 trace of an Iomega Zip with disk absent. I think I remember translating from those experiments as posted to bash and plscsi syntax requires just substituting -x for -y, thus yielding: export PLSCSI=/dev/sda sudo plscsi -i xC0 -x "1A 00:1C:00 C0 00" // Mode Sense (6) sudo plscsi -i xC0 -x "1A 00:3F:00 C0 00" // Mode Sense (6) sudo plscsi -i x0C -x "1A 00:00:00 0C 00" // Mode Sense (6) sudo plscsi -i x0C -x "1A 00:3F:00 0C 00" // Mode Sense (6) sudo plscsi -p -i xC0 -x "5A 00 1C:00:00:00 00 00:C0 00 00:00" // Mode Sense (10) sudo plscsi -p -i xC0 -x "5A 00 3F:00:00:00 00 00:C0 00 00:00" // Mode Sense (10) sudo plscsi -p -i x0C -x "5A 00 00:00:00:00 00 00:0C 00 00:00" // Mode Sense (10) sudo plscsi -p -i x0C -x "5A 00 3F:00:00:00 00 00:0C 00 00:00" // Mode Sense (10) sudo plscsi -p -i xC4 -x "5A 00 1C:00:00:00 00 00:C4 00 00:00" // Mode Sense (10) sudo plscsi -p -i xC4 -x "5A 00 3F:00:00:00 00 00:C4 00 00:00" // Mode Sense (10) sudo plscsi -p -i x10 -x "5A 00 00:00:00:00 00 00:10 00 00:00" // Mode Sense (10) sudo plscsi -p -i x10 -x "5A 00 3F:00:00:00 00 00:10 00 00:00" // Mode Sense (10) I trust already you understand, running plscsi with root or even just device-write privilege by design can and does crash your kernel on occasion, thus smashing automounted or manually mounted fs. plscsi in effect gives you a way of typing out some of the code of a module at the command line. Entering a mistyped or misconceived line of plscsi can hurt you as deeply as loading an untested .ko. I wonder if already you understand, you might like the results better if you only try talking while you device has no disk inserted, or at least while disk not mounted, and preferably while you have no automounter talking to your device. > From: Dmitri Katchalov ... > I'll be away for the next 4 days. Soon I will discover if I replied quickly enough to catch you. :) Pat LaVarre - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html

Previous Message by Thread: click to view message preview

Re: Time to conclude the Sony USB mass storage thread

On Fri, Nov 14, 2003 at 09:35:03AM -0800, Matthew Dharm wrote: > I'm strongly attempted to agree with you guys.... blacklisting looks like > the way to go. > > I'm concerned about the names, tho.... BLIST_MS_SKIP_PAGE_08 sounds more > general than it is -- as I understand it, this flag will only affect sd.c, > tho it looks much more general. We can change the name. > I think I'd rather tweak the structure in slave_configure, where it will be > easier to add more logic if people decide we need it in the future. Unlike scsi_devinfo/dev_flags, we can't override slave_configure changes (unless you add other code). -- Patrick Mansfield - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html

Next Message by Thread: click to view message preview

Re: Time to conclude the Sony USB mass storage thread

On Fri, Nov 14, 2003 at 10:52:12AM -0800, Matthew Dharm wrote: > It's not immediately clear how we can override it if it's > scsi_devinfo/dev_flags. Can you elaborate? The same way you can set it is the same way it can be cleared. If we want to allow all standard scsi core usage, as if there were not special flag settings at all, and including using MODE SENSE 6, use ("model" is synonymous with SCSI product): echo "vendor:model:0" > /proc/scsi/device_info If we want MODE SENSE 10, default cache write through (if the device can't do MODE SENSE page 8), use BLIST_USE_10_BYTE_MS | BLIST_MS_SKIP_PAGE_08 (0x8000 | 0x2000): echo "vendor:model:0xa000" > /proc/scsi/device_info The above can also be done at boot time or scsi_mod load time, on boot use: scsi_mod.dev_flags=vendor:model:0xa000 For scsi_mod as a module just drop the "scsi_mod." prefix. The above does not allow us to send a variant of the MODE SENSE, like the Sony really wants - MODE SENSE with a 10 byte (or larger) buffer - but that would require a patch like the other one I sent, or command filtering code, plus other code to enable/disable its use. We still need a sysfs attribute to eventually replace the proc one - this should be done by using module_param_call instead of module_param_string (we need a special callout to parse the string, I did not understand module_param_call when I added module_param usage), plus code to always (not just for modules) add sysfs parameters for all module_param entries. The device specific flags override any other settings - the shost->flags or the scsi_default_dev_flags. We don't have any deletion method other than reboot, but the last setting added overrides earlier settings, and so you can even overide static entries in scsi_devinfo.c. -- Patrick Mansfield - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
Sign up for updates to this mailing list. email:
Loading Comments...
Home | News | Patents | Sitemap | FAQ | advertise

Advertising by