#include <linux/ata.h>
#include <linux/blkdev.h>
+#include <linux/slab.h>
#include <asm/lv1call.h>
#include <asm/ps3stor.h>
static int ps3disk_major;
-static struct block_device_operations ps3disk_fops = {
+static const struct block_device_operations ps3disk_fops = {
.owner = THIS_MODULE,
};
dev_dbg(&dev->sbd.core,
"%s:%u: bio %u: %u segs %u sectors from %lu\n",
__func__, __LINE__, i, bio_segments(iter.bio),
- bio_sectors(iter.bio),
- (unsigned long)iter.bio->bi_sector);
+ bio_sectors(iter.bio), iter.bio->bi_sector);
size = bvec->bv_len;
buf = bvec_kmap_irq(bvec, &flags);
static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
struct request *req)
{
- struct ps3disk_private *priv = dev->sbd.core.driver_data;
+ struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
int write = rq_data_dir(req), res;
const char *op = write ? "write" : "read";
u64 start_sector, sectors;
rq_for_each_segment(bv, req, iter)
n++;
dev_dbg(&dev->sbd.core,
- "%s:%u: %s req has %u bvecs for %lu sectors %lu hard sectors\n",
- __func__, __LINE__, op, n, req->nr_sectors,
- req->hard_nr_sectors);
+ "%s:%u: %s req has %u bvecs for %u sectors\n",
+ __func__, __LINE__, op, n, blk_rq_sectors(req));
#endif
- start_sector = req->sector * priv->blocking_factor;
- sectors = req->nr_sectors * priv->blocking_factor;
- dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n",
+ start_sector = blk_rq_pos(req) * priv->blocking_factor;
+ sectors = blk_rq_sectors(req) * priv->blocking_factor;
+ dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
__func__, __LINE__, op, sectors, start_sector);
if (write) {
if (res) {
dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
__LINE__, op, res);
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
return 0;
}
static int ps3disk_submit_flush_request(struct ps3_storage_device *dev,
struct request *req)
{
- struct ps3disk_private *priv = dev->sbd.core.driver_data;
+ struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
u64 res;
dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__);
LV1_STORAGE_ATA_HDDOUT, 0, 0, 0,
0, &dev->tag);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
__func__, __LINE__, res);
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
return 0;
}
dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
- while ((req = elv_next_request(q))) {
+ while ((req = blk_fetch_request(q))) {
if (blk_fs_request(req)) {
if (ps3disk_submit_request_sg(dev, req))
break;
- } else if (req->cmd_type == REQ_TYPE_FLUSH) {
+ } else if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+ req->cmd[0] == REQ_LB_OP_FLUSH) {
if (ps3disk_submit_flush_request(dev, req))
break;
} else {
blk_dump_rq_flags(req, DEVICE_NAME " bad request");
- end_request(req, 0);
+ __blk_end_request_all(req, -EIO);
continue;
}
}
static void ps3disk_request(struct request_queue *q)
{
struct ps3_storage_device *dev = q->queuedata;
- struct ps3disk_private *priv = dev->sbd.core.driver_data;
+ struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
if (priv->req) {
dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
struct ps3_storage_device *dev = data;
struct ps3disk_private *priv;
struct request *req;
- int res, read, uptodate;
+ int res, read, error;
u64 tag, status;
- unsigned long num_sectors;
const char *op;
res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
if (tag != dev->tag)
dev_err(&dev->sbd.core,
- "%s:%u: tag mismatch, got %lx, expected %lx\n",
+ "%s:%u: tag mismatch, got %llx, expected %llx\n",
__func__, __LINE__, tag, dev->tag);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
__func__, __LINE__, res, status);
return IRQ_HANDLED;
}
- priv = dev->sbd.core.driver_data;
+ priv = ps3_system_bus_get_drvdata(&dev->sbd);
req = priv->req;
if (!req) {
dev_dbg(&dev->sbd.core,
return IRQ_HANDLED;
}
- if (req->cmd_type == REQ_TYPE_FLUSH) {
+ if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+ req->cmd[0] == REQ_LB_OP_FLUSH) {
read = 0;
- num_sectors = req->hard_cur_sectors;
op = "flush";
} else {
read = !rq_data_dir(req);
- num_sectors = req->nr_sectors;
op = read ? "read" : "write";
}
if (status) {
- dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
+ dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
__LINE__, op, status);
- uptodate = 0;
+ error = -EIO;
} else {
dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
__LINE__, op);
- uptodate = 1;
+ error = 0;
if (read)
ps3disk_scatter_gather(dev, req, 0);
}
spin_lock(&priv->lock);
- if (!end_that_request_first(req, uptodate, num_sectors)) {
- add_disk_randomness(req->rq_disk);
- blkdev_dequeue_request(req);
- end_that_request_last(req, uptodate);
- }
+ __blk_end_request_all(req, error);
priv->req = NULL;
ps3disk_do_request(dev, priv->queue);
spin_unlock(&priv->lock);
res = ps3stor_send_command(dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
__func__, __LINE__, res);
return -EIO;
}
static int ps3disk_identify(struct ps3_storage_device *dev)
{
- struct ps3disk_private *priv = dev->sbd.core.driver_data;
+ struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
struct lv1_ata_cmnd_block ata_cmnd;
u16 *id = dev->bounce_buf;
u64 res;
sizeof(ata_cmnd), ata_cmnd.buffer,
ata_cmnd.arglen);
if (res) {
- dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%lx\n",
+ dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%llx\n",
__func__, __LINE__, res);
return -EIO;
}
dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
- memset(req->cmd, 0, sizeof(req->cmd));
- req->cmd_type = REQ_TYPE_FLUSH;
+ req->cmd_type = REQ_TYPE_LINUX_BLOCK;
+ req->cmd[0] = REQ_LB_OP_FLUSH;
}
-static int ps3disk_issue_flush(struct request_queue *q, struct gendisk *gendisk,
- sector_t *sector)
-{
- struct ps3_storage_device *dev = q->queuedata;
- struct request *req;
- int res;
-
- dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
-
- req = blk_get_request(q, WRITE, __GFP_WAIT);
- ps3disk_prepare_flush(q, req);
- res = blk_execute_rq(q, gendisk, req, 0);
- if (res)
- dev_err(&dev->sbd.core, "%s:%u: flush request failed %d\n",
- __func__, __LINE__, res);
- blk_put_request(req);
- return res;
-}
-
-
static unsigned long ps3disk_mask;
static DEFINE_MUTEX(ps3disk_mask_mutex);
if (dev->blk_size < 512) {
dev_err(&dev->sbd.core,
- "%s:%u: cannot handle block size %lu\n", __func__,
+ "%s:%u: cannot handle block size %llu\n", __func__,
__LINE__, dev->blk_size);
return -EINVAL;
}
goto fail;
}
- dev->sbd.core.driver_data = priv;
+ ps3_system_bus_set_drvdata(_dev, priv);
spin_lock_init(&priv->lock);
dev->bounce_size = BOUNCE_SIZE;
blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
- blk_queue_max_sectors(queue, dev->bounce_size >> 9);
+ blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
blk_queue_segment_boundary(queue, -1UL);
blk_queue_dma_alignment(queue, dev->blk_size-1);
- blk_queue_hardsect_size(queue, dev->blk_size);
+ blk_queue_logical_block_size(queue, dev->blk_size);
- blk_queue_issue_flush_fn(queue, ps3disk_issue_flush);
blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
ps3disk_prepare_flush);
- blk_queue_max_phys_segments(queue, -1);
- blk_queue_max_hw_segments(queue, -1);
+ blk_queue_max_segments(queue, -1);
blk_queue_max_segment_size(queue, dev->bounce_size);
gendisk = alloc_disk(PS3DISK_MINORS);
dev->regions[dev->region_idx].size*priv->blocking_factor);
dev_info(&dev->sbd.core,
- "%s is a %s (%lu MiB total, %lu MiB for OtherOS)\n",
+ "%s is a %s (%llu MiB total, %lu MiB for OtherOS)\n",
gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
get_capacity(gendisk) >> 11);
kfree(dev->bounce_buf);
fail_free_priv:
kfree(priv);
- dev->sbd.core.driver_data = NULL;
+ ps3_system_bus_set_drvdata(_dev, NULL);
fail:
mutex_lock(&ps3disk_mask_mutex);
__clear_bit(devidx, &ps3disk_mask);
static int ps3disk_remove(struct ps3_system_bus_device *_dev)
{
struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
- struct ps3disk_private *priv = dev->sbd.core.driver_data;
+ struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
mutex_lock(&ps3disk_mask_mutex);
- __clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS,
+ __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
&ps3disk_mask);
mutex_unlock(&ps3disk_mask_mutex);
del_gendisk(priv->gendisk);
ps3stor_teardown(dev);
kfree(dev->bounce_buf);
kfree(priv);
- dev->sbd.core.driver_data = NULL;
+ ps3_system_bus_set_drvdata(_dev, NULL);
return 0;
}