Loading drivers/char/ps3flash.c +17 −30 Original line number Original line Diff line number Diff line Loading @@ -41,10 +41,11 @@ struct ps3flash_private { static struct ps3_storage_device *ps3flash_dev; static struct ps3_storage_device *ps3flash_dev; static int ps3flash_read_write_sectors(struct ps3_storage_device *dev, static int ps3flash_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, u64 start_sector, u64 sectors, u64 start_sector, int write) int write) { { u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, start_sector, priv->chunk_sectors, write); write); if (res) { if (res) { dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, Loading @@ -62,8 +63,7 @@ static int ps3flash_writeback(struct ps3_storage_device *dev) if (!priv->dirty || priv->tag < 0) if (!priv->dirty || priv->tag < 0) return 0; return 0; res = ps3flash_read_write_sectors(dev, dev->bounce_lpar, priv->tag, res = ps3flash_read_write_sectors(dev, priv->tag, 1); priv->chunk_sectors, 1); if (res) if (res) return res; return res; Loading @@ -71,17 +71,12 @@ static int ps3flash_writeback(struct ps3_storage_device *dev) return 0; return 0; } } static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector, static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector) u64 sectors) { { struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); unsigned int tag, offset; u64 lpar; int res; int res; offset = start_sector % priv->chunk_sectors; if (start_sector == priv->tag) tag = start_sector - offset; if (tag == priv->tag) return 0; return 0; res = ps3flash_writeback(dev); res = ps3flash_writeback(dev); Loading @@ -90,15 +85,11 @@ static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector, priv->tag = -1; priv->tag = -1; lpar = dev->bounce_lpar + offset * dev->blk_size; res = ps3flash_read_write_sectors(dev, start_sector, 0); res = ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, 0); if (res) if (res) return res; return res; /* We don't bother caching reads smaller than the chunk size */ priv->tag = start_sector; if (sectors == priv->chunk_sectors) priv->tag = tag; return 0; return 0; } } Loading Loading @@ -134,7 +125,7 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, { { struct ps3_storage_device *dev = ps3flash_dev; struct ps3_storage_device *dev = ps3flash_dev; struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); u64 size, start_sector, end_sector, offset, sectors; u64 size, sector, offset; int res; int res; size_t remaining, n; size_t remaining, n; const void *src; const void *src; Loading @@ -154,24 +145,20 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, count = size - *pos; count = size - *pos; } } start_sector = *pos / dev->blk_size; sector = *pos / dev->bounce_size * priv->chunk_sectors; offset = *pos % dev->bounce_size; offset = *pos % dev->bounce_size; end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size); remaining = count; remaining = count; do { do { sectors = min(end_sector - start_sector, n = min_t(u64, remaining, dev->bounce_size - offset); priv->chunk_sectors - src = dev->bounce_buf + offset; start_sector % priv->chunk_sectors); mutex_lock(&priv->mutex); mutex_lock(&priv->mutex); res = ps3flash_fetch(dev, start_sector, sectors); res = ps3flash_fetch(dev, sector); if (res) if (res) goto fail; goto fail; n = min_t(u64, remaining, dev->bounce_size - offset); src = dev->bounce_buf + offset; dev_dbg(&dev->sbd.core, dev_dbg(&dev->sbd.core, "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n", "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n", __func__, __LINE__, n, src, userbuf, kernelbuf); __func__, __LINE__, n, src, userbuf, kernelbuf); Loading @@ -191,7 +178,7 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, *pos += n; *pos += n; remaining -= n; remaining -= n; start_sector += sectors; sector += priv->chunk_sectors; offset = 0; offset = 0; } while (remaining > 0); } while (remaining > 0); Loading Loading @@ -233,17 +220,17 @@ static ssize_t ps3flash_write(const char __user *userbuf, remaining = count; remaining = count; do { do { n = min_t(u64, remaining, dev->bounce_size - offset); n = min_t(u64, remaining, dev->bounce_size - offset); dst = dev->bounce_buf + offset; mutex_lock(&priv->mutex); mutex_lock(&priv->mutex); if (n != dev->bounce_size) if (n != dev->bounce_size) res = ps3flash_fetch(dev, sector, priv->chunk_sectors); res = ps3flash_fetch(dev, sector); else if (sector != priv->tag) else if (sector != priv->tag) res = ps3flash_writeback(dev); res = ps3flash_writeback(dev); if (res) if (res) goto fail; goto fail; dst = dev->bounce_buf + offset; dev_dbg(&dev->sbd.core, dev_dbg(&dev->sbd.core, "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n", "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n", __func__, __LINE__, n, userbuf, kernelbuf, dst); __func__, __LINE__, n, userbuf, kernelbuf, dst); Loading Loading
drivers/char/ps3flash.c +17 −30 Original line number Original line Diff line number Diff line Loading @@ -41,10 +41,11 @@ struct ps3flash_private { static struct ps3_storage_device *ps3flash_dev; static struct ps3_storage_device *ps3flash_dev; static int ps3flash_read_write_sectors(struct ps3_storage_device *dev, static int ps3flash_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, u64 start_sector, u64 sectors, u64 start_sector, int write) int write) { { u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, start_sector, priv->chunk_sectors, write); write); if (res) { if (res) { dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, Loading @@ -62,8 +63,7 @@ static int ps3flash_writeback(struct ps3_storage_device *dev) if (!priv->dirty || priv->tag < 0) if (!priv->dirty || priv->tag < 0) return 0; return 0; res = ps3flash_read_write_sectors(dev, dev->bounce_lpar, priv->tag, res = ps3flash_read_write_sectors(dev, priv->tag, 1); priv->chunk_sectors, 1); if (res) if (res) return res; return res; Loading @@ -71,17 +71,12 @@ static int ps3flash_writeback(struct ps3_storage_device *dev) return 0; return 0; } } static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector, static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector) u64 sectors) { { struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); unsigned int tag, offset; u64 lpar; int res; int res; offset = start_sector % priv->chunk_sectors; if (start_sector == priv->tag) tag = start_sector - offset; if (tag == priv->tag) return 0; return 0; res = ps3flash_writeback(dev); res = ps3flash_writeback(dev); Loading @@ -90,15 +85,11 @@ static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector, priv->tag = -1; priv->tag = -1; lpar = dev->bounce_lpar + offset * dev->blk_size; res = ps3flash_read_write_sectors(dev, start_sector, 0); res = ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, 0); if (res) if (res) return res; return res; /* We don't bother caching reads smaller than the chunk size */ priv->tag = start_sector; if (sectors == priv->chunk_sectors) priv->tag = tag; return 0; return 0; } } Loading Loading @@ -134,7 +125,7 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, { { struct ps3_storage_device *dev = ps3flash_dev; struct ps3_storage_device *dev = ps3flash_dev; struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); u64 size, start_sector, end_sector, offset, sectors; u64 size, sector, offset; int res; int res; size_t remaining, n; size_t remaining, n; const void *src; const void *src; Loading @@ -154,24 +145,20 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, count = size - *pos; count = size - *pos; } } start_sector = *pos / dev->blk_size; sector = *pos / dev->bounce_size * priv->chunk_sectors; offset = *pos % dev->bounce_size; offset = *pos % dev->bounce_size; end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size); remaining = count; remaining = count; do { do { sectors = min(end_sector - start_sector, n = min_t(u64, remaining, dev->bounce_size - offset); priv->chunk_sectors - src = dev->bounce_buf + offset; start_sector % priv->chunk_sectors); mutex_lock(&priv->mutex); mutex_lock(&priv->mutex); res = ps3flash_fetch(dev, start_sector, sectors); res = ps3flash_fetch(dev, sector); if (res) if (res) goto fail; goto fail; n = min_t(u64, remaining, dev->bounce_size - offset); src = dev->bounce_buf + offset; dev_dbg(&dev->sbd.core, dev_dbg(&dev->sbd.core, "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n", "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n", __func__, __LINE__, n, src, userbuf, kernelbuf); __func__, __LINE__, n, src, userbuf, kernelbuf); Loading @@ -191,7 +178,7 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf, *pos += n; *pos += n; remaining -= n; remaining -= n; start_sector += sectors; sector += priv->chunk_sectors; offset = 0; offset = 0; } while (remaining > 0); } while (remaining > 0); Loading Loading @@ -233,17 +220,17 @@ static ssize_t ps3flash_write(const char __user *userbuf, remaining = count; remaining = count; do { do { n = min_t(u64, remaining, dev->bounce_size - offset); n = min_t(u64, remaining, dev->bounce_size - offset); dst = dev->bounce_buf + offset; mutex_lock(&priv->mutex); mutex_lock(&priv->mutex); if (n != dev->bounce_size) if (n != dev->bounce_size) res = ps3flash_fetch(dev, sector, priv->chunk_sectors); res = ps3flash_fetch(dev, sector); else if (sector != priv->tag) else if (sector != priv->tag) res = ps3flash_writeback(dev); res = ps3flash_writeback(dev); if (res) if (res) goto fail; goto fail; dst = dev->bounce_buf + offset; dev_dbg(&dev->sbd.core, dev_dbg(&dev->sbd.core, "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n", "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n", __func__, __LINE__, n, userbuf, kernelbuf, dst); __func__, __LINE__, n, userbuf, kernelbuf, dst); Loading