memstick: fix MSProHG 8-bit interface mode support
[pandora-kernel.git] / drivers / memstick / core / mspro_block.c
index 44b1817..d2d2318 100644 (file)
@@ -30,6 +30,8 @@ module_param(major, int, 0644);
 #define MSPRO_BLOCK_SIGNATURE        0xa5c3
 #define MSPRO_BLOCK_MAX_ATTRIBUTES   41
 
+#define MSPRO_BLOCK_PART_SHIFT 3
+
 enum {
        MSPRO_BLOCK_ID_SYSINFO         = 0x10,
        MSPRO_BLOCK_ID_MODELNAME       = 0x15,
@@ -195,7 +197,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp)
 static int mspro_block_disk_release(struct gendisk *disk)
 {
        struct mspro_block_data *msb = disk->private_data;
-       int disk_id = disk->first_minor >> MEMSTICK_PART_SHIFT;
+       int disk_id = disk->first_minor >> MSPRO_BLOCK_PART_SHIFT;
 
        mutex_lock(&mspro_block_disk_lock);
 
@@ -877,6 +879,7 @@ static int mspro_block_switch_interface(struct memstick_dev *card)
        struct mspro_block_data *msb = memstick_get_drvdata(card);
        int rc = 0;
 
+try_again:
        if (msb->caps & MEMSTICK_CAP_PAR4)
                rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR4);
        else
@@ -930,6 +933,18 @@ static int mspro_block_switch_interface(struct memstick_dev *card)
                rc = memstick_set_rw_addr(card);
                if (!rc)
                        rc = mspro_block_set_interface(card, msb->system);
+
+               if (!rc) {
+                       msleep(150);
+                       rc = mspro_block_wait_for_ced(card);
+                       if (rc)
+                               return rc;
+
+                       if (msb->caps & MEMSTICK_CAP_PAR8) {
+                               msb->caps &= ~MEMSTICK_CAP_PAR8;
+                               goto try_again;
+                       }
+               }
        }
        return rc;
 }
@@ -1117,14 +1132,16 @@ static int mspro_block_init_card(struct memstick_dev *card)
                return -EIO;
 
        msb->caps = host->caps;
-       rc = mspro_block_switch_interface(card);
+
+       msleep(150);
+       rc = mspro_block_wait_for_ced(card);
        if (rc)
                return rc;
 
-       msleep(200);
-       rc = mspro_block_wait_for_ced(card);
+       rc = mspro_block_switch_interface(card);
        if (rc)
                return rc;
+
        dev_dbg(&card->dev, "card activated\n");
        if (msb->system != MEMSTICK_SYS_SERIAL)
                msb->caps |= MEMSTICK_CAP_AUTO_GET_INT;
@@ -1192,12 +1209,12 @@ static int mspro_block_init_disk(struct memstick_dev *card)
        if (rc)
                return rc;
 
-       if ((disk_id << MEMSTICK_PART_SHIFT) > 255) {
+       if ((disk_id << MSPRO_BLOCK_PART_SHIFT) > 255) {
                rc = -ENOSPC;
                goto out_release_id;
        }
 
-       msb->disk = alloc_disk(1 << MEMSTICK_PART_SHIFT);
+       msb->disk = alloc_disk(1 << MSPRO_BLOCK_PART_SHIFT);
        if (!msb->disk) {
                rc = -ENOMEM;
                goto out_release_id;
@@ -1220,7 +1237,7 @@ static int mspro_block_init_disk(struct memstick_dev *card)
                                   MSPRO_BLOCK_MAX_PAGES * msb->page_size);
 
        msb->disk->major = major;
-       msb->disk->first_minor = disk_id << MEMSTICK_PART_SHIFT;
+       msb->disk->first_minor = disk_id << MSPRO_BLOCK_PART_SHIFT;
        msb->disk->fops = &ms_block_bdops;
        msb->usage_count = 1;
        msb->disk->private_data = msb;
@@ -1416,7 +1433,7 @@ out_unlock:
 
 static struct memstick_device_id mspro_block_id_tbl[] = {
        {MEMSTICK_MATCH_ALL, MEMSTICK_TYPE_PRO, MEMSTICK_CATEGORY_STORAGE_DUO,
-        MEMSTICK_CLASS_GENERIC_DUO},
+        MEMSTICK_CLASS_DUO},
        {}
 };