diff options
Diffstat (limited to 'drivers/block/ps3disk.c')
| -rw-r--r-- | drivers/block/ps3disk.c | 102 |
1 files changed, 35 insertions, 67 deletions
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 4e1d9b31f60c..8892f218a814 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -1,21 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * PS3 Disk Storage Driver * * Copyright (C) 2007 Sony Computer Entertainment Inc. * Copyright 2007 Sony Corp. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published - * by the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include <linux/ata.h> @@ -41,7 +29,6 @@ struct ps3disk_private { spinlock_t lock; /* Request queue spinlock */ - struct request_queue *queue; struct blk_mq_tag_set tag_set; struct gendisk *gendisk; unsigned int blocking_factor; @@ -96,26 +83,16 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, unsigned int offset = 0; struct req_iterator iter; struct bio_vec bvec; - unsigned int i = 0; - size_t size; - void *buf; rq_for_each_segment(bvec, req, iter) { - unsigned long flags; - dev_dbg(&dev->sbd.core, "%s:%u: bio %u: %u sectors from %lu\n", - __func__, __LINE__, i, bio_sectors(iter.bio), + dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", + __func__, __LINE__, bio_sectors(iter.bio), iter.bio->bi_iter.bi_sector); - - size = bvec.bv_len; - buf = bvec_kmap_irq(&bvec, &flags); if (gather) - memcpy(dev->bounce_buf+offset, buf, size); + memcpy_from_bvec(dev->bounce_buf + offset, &bvec); else - memcpy(buf, dev->bounce_buf+offset, size); - offset += size; - flush_kernel_dcache_page(bvec.bv_page); - bvec_kunmap_irq(buf, &flags); - i++; + memcpy_to_bvec(&bvec, dev->bounce_buf + offset); + offset += bvec.bv_len; } } @@ -279,7 +256,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) blk_mq_end_request(req, error); spin_unlock(&priv->lock); - blk_mq_run_hw_queues(priv->queue, true); + blk_mq_run_hw_queues(priv->gendisk->queue, true); return IRQ_HANDLED; } @@ -409,7 +386,15 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) struct ps3disk_private *priv; int error; unsigned int devidx; - struct request_queue *queue; + struct queue_limits lim = { + .logical_block_size = dev->blk_size, + .max_hw_sectors = BOUNCE_SIZE >> 9, + .max_segments = -1, + .max_segment_size = BOUNCE_SIZE, + .dma_alignment = dev->blk_size - 1, + .features = BLK_FEAT_WRITE_CACHE | + BLK_FEAT_ROTATIONAL, + }; struct gendisk *gendisk; if (dev->blk_size < 512) { @@ -453,41 +438,23 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) ps3disk_identify(dev); - queue = blk_mq_init_sq_queue(&priv->tag_set, &ps3disk_mq_ops, 1, - BLK_MQ_F_SHOULD_MERGE); - if (IS_ERR(queue)) { - dev_err(&dev->sbd.core, "%s:%u: blk_mq_init_queue failed\n", - __func__, __LINE__); - error = PTR_ERR(queue); + error = blk_mq_alloc_sq_tag_set(&priv->tag_set, &ps3disk_mq_ops, 1, 0); + if (error) goto fail_teardown; - } - - priv->queue = queue; - queue->queuedata = dev; - - 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_logical_block_size(queue, dev->blk_size); - - blk_queue_write_cache(queue, true, false); - blk_queue_max_segments(queue, -1); - blk_queue_max_segment_size(queue, dev->bounce_size); - - gendisk = alloc_disk(PS3DISK_MINORS); - if (!gendisk) { - dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n", __func__, - __LINE__); - error = -ENOMEM; - goto fail_cleanup_queue; + gendisk = blk_mq_alloc_disk(&priv->tag_set, &lim, dev); + if (IS_ERR(gendisk)) { + dev_err(&dev->sbd.core, "%s:%u: blk_mq_alloc_disk failed\n", + __func__, __LINE__); + error = PTR_ERR(gendisk); + goto fail_free_tag_set; } priv->gendisk = gendisk; gendisk->major = ps3disk_major; gendisk->first_minor = devidx * PS3DISK_MINORS; + gendisk->minors = PS3DISK_MINORS; gendisk->fops = &ps3disk_fops; - gendisk->queue = queue; gendisk->private_data = dev; snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3DISK_NAME, devidx+'a'); @@ -496,15 +463,18 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) dev->regions[dev->region_idx].size*priv->blocking_factor); dev_info(&dev->sbd.core, - "%s is a %s (%llu MiB total, %lu MiB for OtherOS)\n", + "%s is a %s (%llu MiB total, %llu MiB for OtherOS)\n", gendisk->disk_name, priv->model, priv->raw_capacity >> 11, get_capacity(gendisk) >> 11); - device_add_disk(&dev->sbd.core, gendisk, NULL); - return 0; + error = device_add_disk(&dev->sbd.core, gendisk, NULL); + if (error) + goto fail_cleanup_disk; -fail_cleanup_queue: - blk_cleanup_queue(queue); + return 0; +fail_cleanup_disk: + put_disk(gendisk); +fail_free_tag_set: blk_mq_free_tag_set(&priv->tag_set); fail_teardown: ps3stor_teardown(dev); @@ -520,7 +490,7 @@ fail: return error; } -static int ps3disk_remove(struct ps3_system_bus_device *_dev) +static void ps3disk_remove(struct ps3_system_bus_device *_dev) { struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd); @@ -530,16 +500,14 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev) &ps3disk_mask); mutex_unlock(&ps3disk_mask_mutex); del_gendisk(priv->gendisk); - blk_cleanup_queue(priv->queue); - blk_mq_free_tag_set(&priv->tag_set); put_disk(priv->gendisk); + blk_mq_free_tag_set(&priv->tag_set); dev_notice(&dev->sbd.core, "Synchronizing disk cache\n"); ps3disk_sync_cache(dev); ps3stor_teardown(dev); kfree(dev->bounce_buf); kfree(priv); ps3_system_bus_set_drvdata(_dev, NULL); - return 0; } static struct ps3_system_bus_driver ps3disk = { |
