Users (ps3disk, ps3flash and ps3rom) retain the old behavior. That is: they still only provide access to the first accessible region.
Signed-off-by: Andre Heider <a.hei...@gmail.com> --- arch/powerpc/include/asm/ps3stor.h | 4 ++-- drivers/block/ps3disk.c | 15 +++++++++++++-- drivers/char/ps3flash.c | 23 +++++++++++++++++------ drivers/ps3/ps3stor_lib.c | 25 ++++++++++++------------- drivers/scsi/ps3rom.c | 11 +++++++---- 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/include/asm/ps3stor.h b/arch/powerpc/include/asm/ps3stor.h index d51e53c..9871c05 100644 --- a/arch/powerpc/include/asm/ps3stor.h +++ b/arch/powerpc/include/asm/ps3stor.h @@ -51,7 +51,6 @@ struct ps3_storage_device { unsigned int num_regions; unsigned long accessible_regions; - unsigned int region_idx; /* first accessible region */ struct ps3_storage_region regions[0]; /* Must be last */ }; @@ -63,7 +62,8 @@ static inline struct ps3_storage_device *to_ps3_storage_device(struct device *de extern int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler); extern void ps3stor_teardown(struct ps3_storage_device *dev); -extern u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, +extern u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, + unsigned int region_idx, u64 lpar, u64 start_sector, u64 sectors, int write); extern u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 8e1ce2e..96e00ff 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -42,6 +42,7 @@ struct ps3disk_private { spinlock_t lock; /* Request queue spinlock */ struct request_queue *queue; struct gendisk *gendisk; + unsigned int region_idx; /* first accessible region */ unsigned int blocking_factor; struct request *req; u64 raw_capacity; @@ -125,7 +126,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, int write = rq_data_dir(req), res; const char *op = write ? "write" : "read"; u64 start_sector, sectors; - unsigned int region_id = dev->regions[dev->region_idx].id; + unsigned int region_id = dev->regions[priv->region_idx].id; #ifdef DEBUG unsigned int n = 0; @@ -408,6 +409,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) unsigned int devidx; struct request_queue *queue; struct gendisk *gendisk; + unsigned int region_idx; if (dev->blk_size < 512) { dev_err(&dev->sbd.core, @@ -482,6 +484,14 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) } priv->gendisk = gendisk; + + /* find first accessible region */ + for (region_idx = 0; region_idx < dev->num_regions; region_idx++) + if (test_bit(region_idx, &dev->accessible_regions)) { + priv->region_idx = region_idx; + break; + } + gendisk->major = ps3disk_major; gendisk->first_minor = devidx * PS3DISK_MINORS; gendisk->fops = &ps3disk_fops; @@ -492,7 +502,8 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) devidx+'a'); priv->blocking_factor = dev->blk_size >> 9; set_capacity(gendisk, - dev->regions[dev->region_idx].size*priv->blocking_factor); + dev->regions[priv->region_idx].size * + priv->blocking_factor); dev_info(&dev->sbd.core, "%s is a %s (%llu MiB total, %lu MiB for OtherOS)\n", diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index b1e8659..47b1dc7 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c @@ -36,6 +36,7 @@ struct ps3flash_private { struct mutex mutex; /* Bounce buffer mutex */ u64 chunk_sectors; + unsigned int region_idx; /* first accessible region */ int tag; /* Start sector of buffer, -1 if invalid */ bool dirty; }; @@ -46,7 +47,8 @@ static int ps3flash_read_write_sectors(struct ps3_storage_device *dev, u64 start_sector, int write) { struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); - u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, + u64 res = ps3stor_read_write_sectors(dev, priv->region_idx, + dev->bounce_lpar, start_sector, priv->chunk_sectors, write); if (res) { @@ -98,6 +100,7 @@ static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector) static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) { struct ps3_storage_device *dev = ps3flash_dev; + struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); loff_t res; mutex_lock(&file->f_mapping->host->i_mutex); @@ -106,7 +109,7 @@ static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) offset += file->f_pos; break; case 2: - offset += dev->regions[dev->region_idx].size*dev->blk_size; + offset += dev->regions[priv->region_idx].size*dev->blk_size; break; } if (offset < 0) { @@ -136,7 +139,7 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, "%s:%u: Reading %zu bytes at position %lld to U0x%p/K0x%p\n", __func__, __LINE__, count, *pos, userbuf, kernelbuf); - size = dev->regions[dev->region_idx].size*dev->blk_size; + size = dev->regions[priv->region_idx].size*dev->blk_size; if (*pos >= size || !count) return 0; @@ -205,7 +208,7 @@ static ssize_t ps3flash_write(const char __user *userbuf, "%s:%u: Writing %zu bytes at position %lld from U0x%p/K0x%p\n", __func__, __LINE__, count, *pos, userbuf, kernelbuf); - size = dev->regions[dev->region_idx].size*dev->blk_size; + size = dev->regions[priv->region_idx].size*dev->blk_size; if (*pos >= size || !count) return 0; @@ -359,6 +362,7 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); struct ps3flash_private *priv; int error; + unsigned int region_idx; unsigned long tmp; /* use static buffer, kmalloc cannot allocate 256 KiB */ @@ -391,14 +395,21 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) if (error) goto fail_free_priv; - tmp = dev->regions[dev->region_idx].start*dev->blk_size; + /* find first accessible region */ + for (region_idx = 0; region_idx < dev->num_regions; region_idx++) + if (test_bit(region_idx, &dev->accessible_regions)) { + priv->region_idx = region_idx; + break; + } + + tmp = dev->regions[priv->region_idx].start*dev->blk_size; if (tmp % FLASH_BLOCK_SIZE) { dev_err(&dev->sbd.core, "%s:%u region start %lu is not aligned\n", __func__, __LINE__, tmp); return -EINVAL; } - tmp = dev->regions[dev->region_idx].size*dev->blk_size; + tmp = dev->regions[priv->region_idx].size*dev->blk_size; if (tmp % FLASH_BLOCK_SIZE) { dev_err(&dev->sbd.core, "%s:%u region size %lu is not aligned\n", __func__, diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c index af0afa1..5bbc023 100644 --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c @@ -101,9 +101,8 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev) "%s:%u: checking accessibility of region %u\n", __func__, __LINE__, i); - dev->region_idx = i; - res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, 0, 1, - 0); + res = ps3stor_read_write_sectors(dev, i, dev->bounce_lpar, + 0, 1, 0); if (res) { dev_dbg(&dev->sbd.core, "%s:%u: read failed, " "region %u is not accessible\n", __func__, @@ -117,6 +116,11 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev) /* We can access at least one region */ error = 0; + + dev_info(&dev->sbd.core, + "Accessible region found: #%u start %llu size %llu\n", + i, dev->regions[i].start, dev->regions[i].size); + } if (error) return error; @@ -124,15 +128,8 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev) n = hweight_long(dev->accessible_regions); if (n > 1) dev_info(&dev->sbd.core, - "%s:%u: %lu accessible regions found. Only the first " - "one will be used\n", + "%s:%u: %lu accessible regions found\n", __func__, __LINE__, n); - dev->region_idx = __ffs(dev->accessible_regions); - dev_info(&dev->sbd.core, - "First accessible region has index %u start %llu size %llu\n", - dev->region_idx, dev->regions[dev->region_idx].start, - dev->regions[dev->region_idx].size); - return 0; } @@ -264,6 +261,7 @@ EXPORT_SYMBOL_GPL(ps3stor_teardown); /** * ps3stor_read_write_sectors - read/write from/to a storage device * @dev: Pointer to a struct ps3_storage_device + * @region_idx: Index of the region to access * @lpar: HV logical partition address * @start_sector: First sector to read/write * @sectors: Number of sectors to read/write @@ -272,10 +270,11 @@ EXPORT_SYMBOL_GPL(ps3stor_teardown); * Returns 0 for success, -1 in case of failure to submit the command, or * an LV1 status value in case of other errors */ -u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, +u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, + unsigned int region_idx, u64 lpar, u64 start_sector, u64 sectors, int write) { - unsigned int region_id = dev->regions[dev->region_idx].id; + unsigned int region_id = dev->regions[region_idx].id; const char *op = write ? "write" : "read"; int res; diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index cd178b9..68db03c 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -39,6 +39,7 @@ #define PS3ROM_MAX_SECTORS (BOUNCE_SIZE >> 9) +#define PS3ROM_REGION_IDX 0 struct ps3rom_private { struct ps3_storage_device *dev; @@ -177,8 +178,9 @@ static int ps3rom_read_request(struct ps3_storage_device *dev, __func__, __LINE__, sectors, start_sector); res = lv1_storage_read(dev->sbd.dev_id, - dev->regions[dev->region_idx].id, start_sector, - sectors, 0, dev->bounce_lpar, &dev->tag); + dev->regions[PS3ROM_REGION_IDX].id, + start_sector, sectors, 0, + dev->bounce_lpar, &dev->tag); if (res) { dev_err(&dev->sbd.core, "%s:%u: read failed %d\n", __func__, __LINE__, res); @@ -200,8 +202,9 @@ static int ps3rom_write_request(struct ps3_storage_device *dev, scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size); res = lv1_storage_write(dev->sbd.dev_id, - dev->regions[dev->region_idx].id, start_sector, - sectors, 0, dev->bounce_lpar, &dev->tag); + dev->regions[PS3ROM_REGION_IDX].id, + start_sector, sectors, 0, + dev->bounce_lpar, &dev->tag); if (res) { dev_err(&dev->sbd.core, "%s:%u: write failed %d\n", __func__, __LINE__, res); -- 1.7.5.4 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev