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

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: