First of all, no USB device worked because the hub things
were on was not recognized. It looks like the reason is that
drivers/base/core.c:found_match() returns nonzero now
while it returned 0 earlier (before 2.5.39).
Phenomenon:
An attempt to match 1-1:0 with usbscanner would return an
error, and then an attempt to match it with hub would
succeed. In the present code the first error causes
the loops in bus_for_each_dev and bus_for_each_drv to abort.
So, maybe found_match() must return the opposite of the
present return code, to continue scanning if something is
wrong, and to stop when the right match has been found.
diff -u --recursive --new-file -X /linux/dontdiff a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c Sat Oct 12 19:28:37 2002
+++ b/drivers/base/core.c Mon Oct 14 22:59:45 2002
@@ -54,7 +54,7 @@
*/
static int found_match(struct device * dev, struct device_driver * drv)
{
- int error = 0;
+ int error;
if (!(error = probe(dev,get_driver(drv)))) {
pr_debug("bound device '%s' to driver '%s'\n",
@@ -64,7 +64,7 @@
put_driver(drv);
dev->driver = NULL;
}
- return error;
+ return !error;
}
/**
With such a change the USB devices were found, and I got photographs
off the first CF card. Then exchanged cards and wanted to use the second
one, of a different capacity.
But /proc/partitions continued to show the old capacity, also after a dd
and also after a mount. And also after a BLKRRPART ioctl.
Not only is media_change broken, also partition rereading is.
Repairing the ioctl is easy:
diff -u --recursive --new-file -X /linux/dontdiff a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c Tue Oct 8 21:57:34 2002
+++ b/fs/block_dev.c Mon Oct 14 23:13:52 2002
@@ -808,6 +808,10 @@
return -EACCES;
if (down_trylock(&bdev->bd_sem))
return -EBUSY;
+
+ /* make sure rescan_partitions will actually do something */
+ bdev->bd_invalidated = 1;
+
res = rescan_partitions(disk, bdev);
up(&bdev->bd_sem);
return res;
Indeed, when bdev->bd_invalidated is zero, rescan_partitions() doesnt
do anything, so that is why the ioctl failed.
But why was media change broken? I looked at check_scsidisk_media_change.
It contains some silly code that has been there since 0.99, and recently
got the comment "what is this for??". It can be deleted.
diff -u --recursive --new-file -X /linux/dontdiff a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c Sat Oct 12 19:28:46 2002
+++ b/drivers/scsi/sd.c Mon Oct 14 23:18:36 2002
@@ -337,7 +337,9 @@
* quietly refuse to do anything to a changed disc until
* the changed bit has been reset
*/
- /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
+#if 0
+ printk("SCSI disk has been changed. Prohibiting further I/O.\n");
+#endif
return 0;
}
SCSI_LOG_HLQUEUE(2, sd_dskname(dsk_nr, nbuff));
@@ -717,7 +719,6 @@
static int check_scsidisk_media_change(kdev_t full_dev)
{
int retval;
- int flag = 0; /* <<<< what is this for?? */
Scsi_Disk * sdkp;
Scsi_Device * sdp;
int dsk_nr = DEVICE_NR(full_dev);
@@ -775,8 +776,7 @@
sdkp->media_present = 1;
retval = sdp->changed;
- if (!flag)
- sdp->changed = 0;
+ sdp->changed = 0;
return retval;
}
Concerning the media change:
US_FL_START_STOP no longer does anything in usb-storage.
The START_STOP command from sd.c is changed into a TEST_UNIT_READY
in usb.c, and the device reports that it is ready.
No media change is seen.
I removed the USB device and inserted it elsewhere.
It was recognized as the same device (it would be, also
if it had been a different one: only vendor+productid is checked,
the thing has no serial number, and the CF card inside does not
influence this GUID either.
[Thus, recognizing a device after removal+insertion is broken
and cannot be repaired, there is not enough information.]
Then I tried to force a detection of media change by removing
the device and doing a BLKRRPART. That caused a kernel crash.
BUG at drivers/base/core:251. (BUG_ON(dev->present)).
Another funny effect was caused by the fact that disk sizes
are now stored both in bdev->bd_inode->i_size and in gendisk.
During a partition table reread on a changed disk the value
in bdev->bd_inode->i_size was used, causing lots of I/O errors
since the new disk was smaller than the old one. Amusing
error messages:
end_request: I/O error, dev 08:10, sector 63480
Buffer I/O error on device sd(8,16), logical block 7935
as if the code was not clear what block it was reading.
(And getting the size right is important for efi.c -
it reads the last sector.)
Let me leave these last ones for Al.
Below a typo fix and removal of an annoying debugging message.
diff -u --recursive --new-file -X /linux/dontdiff a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
--- a/Documentation/block/biodoc.txt Sun Jun 9 07:27:48 2002
+++ b/Documentation/block/biodoc.txt Fri Oct 11 02:25:23 2002
@@ -1175,7 +1175,7 @@
8.12. Multiple block-size transfers for faster raw i/o (Shailabh Nagar,
Badari)
8.13 Priority based i/o scheduler - prepatches (Arjan van de Ven)
-8.14 IDE Taskfile i/o patch (Andre Hedrik)
+8.14 IDE Taskfile i/o patch (Andre Hedrick)
8.15 Multi-page writeout and readahead patches (Andrew Morton)
8.16 Direct i/o patches for 2.5 using kvec and bio (Badari Pulavarthy)
diff -u --recursive --new-file -X /linux/dontdiff a/fs/partitions/ldm.c b/fs/partitions/ldm.c
--- a/fs/partitions/ldm.c Sat Oct 12 19:28:49 2002
+++ b/fs/partitions/ldm.c Mon Oct 14 18:56:14 2002
@@ -561,7 +561,9 @@
}
if (*(u16*) (data + 0x01FE) != cpu_to_le16 (MSDOS_LABEL_MAGIC)) {
+#if 0
ldm_debug ("No MS-DOS partition table found.");
+#endif
goto out;
}
@@ -574,8 +576,10 @@
if (result)
ldm_debug ("Parsed partition table successfully.");
+#if 0
else
ldm_debug ("Found an MS-DOS partition table, not a dynamic disk.");
+#endif
out:
put_dev_sector (sect);
return result;
Andries
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/