Bug#284600: Patch for ub
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I found this patch applied to 2.6.10-rc1 from Pete Zaitcev.
- --
Ramón Rey Vicente <ramon.rey en hispalinux.es>
JID rreylinux@jabber.org - GPG public key id 0x9F28E377
GPG Fingerprint 0BC2 8014 2445 51E8 DE87 C888 C385 A9D3 9F28 E377
Planet AUGCyL - http://augcyl.org/planet/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFB2tH6w4Wp058o43cRAtsqAKDKBw9zCBY+IkiNb12J7nQ0GrZ6MgCcCtmL
vf+NyPqkHx2GnlLpTXicVY0=
=ycCz
-----END PGP SIGNATURE-----
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/11/04 12:02:00-08:00 zaitcev@redhat.com
# [PATCH] USB: Patch for ub
#
# This is a relatively small changeset, to address small nagging problems.
# Andrew pointed me at the double registration specifically, so I had to do
# something about it. At least now Fabio's box won't collapse if he configures
# UB by mistake. Also, a few people complained that the help text was
# misleading.
#
# I have not done anything about the oops on disconnect which happens to
# Martin Schlemmer. It's next. After that I can get to Peter Jones' CD
# burning patch and doing resets.
#
# - Fix double kobject registration and eventual oops on unplug if a device
# is not cooperating.
# - Add a reference to usb-storage into the configuration help.
# - Just upping timeouts fixes my ZIP drive.
# - Max out the diag (trace) file size.
# - Set capacity to zero in case the media is absent. It works in 2.4.10-rc1.
# Either Al fixed the block layer, or the whole thing was a bug in ub.c
# (and sd.c) and a big misunderstanding.
#
# Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
# Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
#
# drivers/block/Kconfig
# 2004/11/01 16:09:13-08:00 zaitcev@redhat.com +2 -0
# USB: Patch for ub
#
# drivers/block/ub.c
# 2004/11/02 23:59:07-08:00 zaitcev@redhat.com +37 -25
# USB: Patch for ub
#
diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig
--- a/drivers/block/Kconfig 2005-01-04 09:09:03 -08:00
+++ b/drivers/block/Kconfig 2005-01-04 09:09:03 -08:00
@@ -308,6 +308,8 @@
This driver supports certain USB attached storage devices
such as flash keys.
+ Warning: Enabling this cripples the usb-storage driver.
+
If unsure, say N.
config BLK_DEV_RAM
diff -Nru a/drivers/block/ub.c b/drivers/block/ub.c
--- a/drivers/block/ub.c 2005-01-04 09:09:03 -08:00
+++ b/drivers/block/ub.c 2005-01-04 09:09:03 -08:00
@@ -8,13 +8,11 @@
* and is not licensed separately. See file COPYING for details.
*
* TODO (sorted by decreasing priority)
- * -- ZIP does "ub: resid 18 len 0 act 0" and whole transport quits (toggles?)
+ * -- Do resets with usb_device_reset (needs a thread context, use khubd)
* -- set readonly flag for CDs, set removable flag for CF readers
* -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
* -- support pphaneuf's SDDR-75 with two LUNs (also broken capacity...)
* -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
- * -- do something about spin-down devices, they are extremely dangerous
- * (ZIP is one. Needs spin-up command as well.)
* -- verify the 13 conditions and do bulk resets
* -- normal pool of commands instead of cmdv[]?
* -- kill last_pipe and simply do two-state clearing on both pipes
@@ -105,13 +103,11 @@
#define UB_MAX_SECTORS 64
/*
- * A second ought to be enough for a 32K transfer (UB_MAX_SECTORS)
- * even if a webcam hogs the bus (famous last words).
- * Some CDs need a second to spin up though.
- * ZIP drive rejects commands when it's not spinning,
- * so it does not need long timeouts either.
+ * A second is more than enough for a 32K transfer (UB_MAX_SECTORS)
+ * even if a webcam hogs the bus, but some devices need time to spin up.
*/
#define UB_URB_TIMEOUT (HZ*2)
+#define UB_DATA_TIMEOUT (HZ*5) /* ZIP does spin-ups in the data phase */
#define UB_CTRL_TIMEOUT (HZ/2) /* 500ms ought to be enough to clear a stall */
/*
@@ -188,7 +184,7 @@
*/
#define SCMD_ST_HIST_SZ 8
-#define SCMD_TRACE_SZ 15 /* No more than 256 (trace_index) */
+#define SCMD_TRACE_SZ 63 /* Less than 4KB of 61-byte lines */
struct ub_scsi_cmd_trace {
int hcur;
@@ -267,6 +263,7 @@
int changed; /* Media was changed */
int removable;
int readonly;
+ int first_open; /* Kludge. See ub_bd_open. */
char name[8];
struct usb_device *dev;
struct usb_interface *intf;
@@ -888,9 +885,6 @@
int pipe;
int rc;
-/* P3 */ /** printk("ub: urb status %d pipe 0x%08x len %d act %d\n",
- urb->status, urb->pipe, urb->transfer_buffer_length, urb->actual_length); **/
-
if (atomic_read(&sc->poison)) {
/* A little too simplistic, I feel... */
goto Bad_End;
@@ -959,9 +953,12 @@
ub_cmdtr_state(sc, cmd);
return;
}
- if (urb->status != 0)
+ if (urb->status != 0) {
+ printk("ub: cmd #%d cmd status (%d)\n", cmd->tag, urb->status); /* P3 */
goto Bad_End;
+ }
if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
+ printk("ub: cmd #%d xferred %d\n", cmd->tag, urb->actual_length); /* P3 */
/* XXX Must do reset here to unconfuse the device */
goto Bad_End;
}
@@ -993,7 +990,7 @@
return;
}
- sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
+ sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT;
add_timer(&sc->work_timer);
cmd->state = UB_CMDST_DATA;
@@ -1379,12 +1376,7 @@
sc->readonly = 0; /* XXX Query this from the device */
- /*
- * XXX sd.c sets capacity to zero in such case. However, it doesn't
- * work for us. In case of zero capacity, block layer refuses to
- * have the /dev/uba opened (why?) Set capacity to some random value.
- */
- sc->capacity.nsec = 50;
+ sc->capacity.nsec = 0;
sc->capacity.bsize = 512;
sc->capacity.bshift = 0;
@@ -1399,7 +1391,7 @@
* We keep this because sd.c has retries for capacity.
*/
if (ub_sync_read_cap(sc, &sc->capacity) != 0) {
- sc->capacity.nsec = 100;
+ sc->capacity.nsec = 0;
sc->capacity.bsize = 512;
sc->capacity.bshift = 0;
}
@@ -1428,6 +1420,26 @@
sc->openc++;
spin_unlock_irqrestore(&ub_lock, flags);
+ /*
+ * This is a workaround for a specific problem in our block layer.
+ * In 2.6.9, register_disk duplicates the code from rescan_partitions.
+ * However, if we do add_disk with a device which persistently reports
+ * a changed media, add_disk calls register_disk, which does do_open,
+ * which will call rescan_paritions for changed media. After that,
+ * register_disk attempts to do it all again and causes double kobject
+ * registration and a eventually an oops on module removal.
+ *
+ * The bottom line is, Al Viro says that we should not allow
+ * bdev->bd_invalidated to be set when doing add_disk no matter what.
+ */
+ if (sc->first_open) {
+ if (sc->changed) {
+ sc->first_open = 0;
+ rc = -ENOMEDIUM;
+ goto err_open;
+ }
+ }
+
if (sc->removable || sc->readonly)
check_disk_change(inode->i_bdev);
@@ -1467,6 +1479,8 @@
spin_lock_irqsave(&ub_lock, flags);
--sc->openc;
+ if (sc->openc == 0)
+ sc->first_open = 0;
if (sc->openc == 0 && atomic_read(&sc->poison))
ub_cleanup(sc);
spin_unlock_irqrestore(&ub_lock, flags);
@@ -1559,13 +1573,9 @@
*/
if (ub_sync_tur(sc) != 0) {
sc->changed = 1;
- /* P3 */ printk("%s: made changed\n", sc->name);
return 1;
}
- /* The sd.c clears this before returning (one-shot flag). Why? */
- /* P3 */ printk("%s: %s changed\n", sc->name,
- sc->changed? "is": "was not");
return sc->changed;
}
@@ -1919,6 +1929,8 @@
}
sc->removable = 1; /* XXX Query this from the device */
+ sc->changed = 1; /* ub_revalidate clears only */
+ sc->first_open = 1;
ub_revalidate(sc);
/* This is pretty much a long term P3 */
Reply to: