[PATCH] Forcing SCSI capacity for broken SD Card readers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everyone,

Short: Attached is an incomplete patch that allows user space to force
the capacity of an scsi device to a specific value. Any not over
my-dead-body objections with that?

Long: I was unfortunate and grabbed one of the cheaper USB SD card
readers that do not correctly detect >1GB capacity sd cards. This is a
known and common bug. See [1] or [2]. What's interesting is that this
card reader was sold to work with these cards explicitly, and I
figured it must have been tested only under Windows, which we all know
believes in the partition table more strongly than in what the device
reports. And indeed, my 2GB sd cards start to work if I simply ignore
the capacity reported by the device. I have been using this
successfully in the last half year with all my sd cards and now I'm
tired of patching the kernel for just that thing. Could you imagine to
merge that upstream? I doubt that any device will kill itself if this
interface is used incorrectly.

A simple user space program using the new interface is available at [3].

Please CC, me not on list.
[1] http://en.wikipedia.org/wiki/Secure_Digital#Standard-SD_cards_.28non-SDHC.29_with_greater_than_1_GB_capacity
[2] http://www.hjreggel.net/cardspeed/special-sd.html
[3] http://blog.clemens.endorphin.org/2009/03/patching-for-broken-sd-card-readers.html
--
Fruhwirth Clemens http://clemens.endorphin.org
diff -ru linux-2.6.28/drivers/scsi/sd.c linux-2.6.28/drivers/scsi/sd.c
--- linux-2.6.28/drivers/scsi/sd.c	2009-03-21 13:36:48.000000000 +0100
+++ linux-2.6.28/drivers/scsi/sd.c	2009-03-21 13:07:43.000000000 +0100
@@ -725,6 +725,19 @@
 	return 0;
 }
 
+static int scsi_ioctl_set_capacity(struct scsi_disk *sdkp, void __user *arg)
+{
+    int val, result;
+
+    result = get_user(val, (int __user *)arg);
+    if (result)
+	return result;
+    sdkp->capacity = val;
+    set_capacity(sdkp->disk, sdkp->capacity);
+
+    return 0;
+}
+
 /**
  *	sd_ioctl - process an ioctl
  *	@inode: only i_rdev/i_bdev members may be used
@@ -770,6 +786,11 @@
 		case SCSI_IOCTL_GET_IDLUN:
 		case SCSI_IOCTL_GET_BUS_NUMBER:
 			return scsi_ioctl(sdp, cmd, p);
+		case SCSI_IOCTL_SET_CAPACITY:
+			return scsi_ioctl_set_capacity(scsi_disk(disk), (int __user *)arg);
+		case SCSI_IOCTL_GET_CAPACITY:
+			return put_user(scsi_disk(disk)->capacity, (int __user *)arg);
+
 		default:
 			error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
 			if (error != -ENOTTY)
diff -ru linux-2.6.28/include/scsi/scsi_ioctl.h linux-2.6.28/include/scsi/scsi_ioctl.h
--- linux-2.6.28/include/scsi/scsi_ioctl.h	2008-12-25 00:26:37.000000000 +0100
+++ linux-2.6.28/include/scsi/scsi_ioctl.h	2009-03-21 12:48:45.000000000 +0100
@@ -11,6 +11,8 @@
    the cdrom */
 #define SCSI_IOCTL_DOORLOCK 0x5380		/* lock the eject mechanism */
 #define SCSI_IOCTL_DOORUNLOCK 0x5381		/* unlock the mechanism	  */
+#define SCSI_IOCTL_SET_CAPACITY 0x5388		/* set capacity */
+#define SCSI_IOCTL_GET_CAPACITY 0x5389		/* get capacity */
 
 #define	SCSI_REMOVAL_PREVENT	1
 #define	SCSI_REMOVAL_ALLOW	0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux