Re: [BUG] ub.c badness in current bk

From: Benjamin Herrenschmidt
Date: Fri Sep 17 2004 - 21:15:47 EST


On Sat, 2004-09-18 at 11:04, Benjamin Herrenschmidt wrote:
> Ok, here's a patch that works for me and makes more sense ;)
>
> .../...

And the real one without fuckup in media_change(), sorry, I sent
the wrong patch.


===== drivers/block/ub.c 1.5 vs edited =====
--- 1.5/drivers/block/ub.c 2004-08-24 10:02:30 +10:00
+++ edited/drivers/block/ub.c 2004-09-18 12:04:47 +10:00
@@ -1217,9 +1217,16 @@
goto error;
}

+ /*
+ * ``If the allocation length is eighteen or greater, and a device
+ * server returns less than eithteen bytes of data, the application
+ * client should assume that the bytes not transferred would have been
+ * zeroes had the device server returned those bytes.''
+ */
memset(&sc->top_sense, 0, UB_SENSE_SIZE);
scmd = &sc->top_rqs_cmd;
scmd->cdb[0] = REQUEST_SENSE;
+ scmd->cdb[4] = UB_SENSE_SIZE;
scmd->cdb_len = 6;
scmd->dir = UB_DIR_READ;
scmd->state = UB_CMDST_INIT;
@@ -1352,6 +1359,7 @@
*/
static void ub_revalidate(struct ub_dev *sc)
{
+ int retries;

sc->readonly = 0; /* XXX Query this from the device */

@@ -1364,8 +1372,21 @@
sc->capacity.bsize = 512;
sc->capacity.bshift = 0;

- if (ub_sync_tur(sc) != 0)
- return; /* Not ready */
+ /*
+ * Here's our equivalent of spinup. We probably need to better check
+ * the sense codes from TUR ? Anyway, some flash devices tend to want
+ * us to wait a little bit before beeing ready. We may want to do something
+ * closer to what sd.c does here. --BenH
+ */
+ retries = 0;
+ for (;;) {
+ if (ub_sync_tur(sc) == 0)
+ break;
+ if (++retries > 3)
+ return;
+ msleep(10); /* ahem ... */
+ }
+
sc->changed = 0;

if (ub_sync_read_cap(sc, &sc->capacity) != 0) {
@@ -1509,6 +1530,7 @@
static int ub_bd_media_changed(struct gendisk *disk)
{
struct ub_dev *sc = disk->private_data;
+ int ret;

if (!sc->removable)
return 0;
@@ -1531,7 +1553,9 @@
/* 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;
+ ret = sc->changed;
+ sc->changed = 0;
+ return ret;
}

static struct block_device_operations ub_bd_fops = {


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/