linux/drivers/block/ps3disk.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * PS3 Disk Storage Driver
   4 *
   5 * Copyright (C) 2007 Sony Computer Entertainment Inc.
   6 * Copyright 2007 Sony Corp.
   7 */
   8
   9#include <linux/ata.h>
  10#include <linux/blk-mq.h>
  11#include <linux/slab.h>
  12#include <linux/module.h>
  13
  14#include <asm/lv1call.h>
  15#include <asm/ps3stor.h>
  16#include <asm/firmware.h>
  17
  18
  19#define DEVICE_NAME             "ps3disk"
  20
  21#define BOUNCE_SIZE             (64*1024)
  22
  23#define PS3DISK_MAX_DISKS       16
  24#define PS3DISK_MINORS          16
  25
  26
  27#define PS3DISK_NAME            "ps3d%c"
  28
  29
  30struct ps3disk_private {
  31        spinlock_t lock;                /* Request queue spinlock */
  32        struct blk_mq_tag_set tag_set;
  33        struct gendisk *gendisk;
  34        unsigned int blocking_factor;
  35        struct request *req;
  36        u64 raw_capacity;
  37        unsigned char model[ATA_ID_PROD_LEN+1];
  38};
  39
  40
  41#define LV1_STORAGE_SEND_ATA_COMMAND    (2)
  42#define LV1_STORAGE_ATA_HDDOUT          (0x23)
  43
  44struct lv1_ata_cmnd_block {
  45        u16     features;
  46        u16     sector_count;
  47        u16     LBA_low;
  48        u16     LBA_mid;
  49        u16     LBA_high;
  50        u8      device;
  51        u8      command;
  52        u32     is_ext;
  53        u32     proto;
  54        u32     in_out;
  55        u32     size;
  56        u64     buffer;
  57        u32     arglen;
  58};
  59
  60enum lv1_ata_proto {
  61        NON_DATA_PROTO     = 0,
  62        PIO_DATA_IN_PROTO  = 1,
  63        PIO_DATA_OUT_PROTO = 2,
  64        DMA_PROTO = 3
  65};
  66
  67enum lv1_ata_in_out {
  68        DIR_WRITE = 0,                  /* memory -> device */
  69        DIR_READ = 1                    /* device -> memory */
  70};
  71
  72static int ps3disk_major;
  73
  74
  75static const struct block_device_operations ps3disk_fops = {
  76        .owner          = THIS_MODULE,
  77};
  78
  79
  80static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
  81                                   struct request *req, int gather)
  82{
  83        unsigned int offset = 0;
  84        struct req_iterator iter;
  85        struct bio_vec bvec;
  86        unsigned int i = 0;
  87        size_t size;
  88        void *buf;
  89
  90        rq_for_each_segment(bvec, req, iter) {
  91                unsigned long flags;
  92                dev_dbg(&dev->sbd.core, "%s:%u: bio %u: %u sectors from %llu\n",
  93                        __func__, __LINE__, i, bio_sectors(iter.bio),
  94                        iter.bio->bi_iter.bi_sector);
  95
  96                size = bvec.bv_len;
  97                buf = bvec_kmap_irq(&bvec, &flags);
  98                if (gather)
  99                        memcpy(dev->bounce_buf+offset, buf, size);
 100                else
 101                        memcpy(buf, dev->bounce_buf+offset, size);
 102                offset += size;
 103                flush_kernel_dcache_page(bvec.bv_page);
 104                bvec_kunmap_irq(buf, &flags);
 105                i++;
 106        }
 107}
 108
 109static blk_status_t ps3disk_submit_request_sg(struct ps3_storage_device *dev,
 110                                              struct request *req)
 111{
 112        struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
 113        int write = rq_data_dir(req), res;
 114        const char *op = write ? "write" : "read";
 115        u64 start_sector, sectors;
 116        unsigned int region_id = dev->regions[dev->region_idx].id;
 117
 118#ifdef DEBUG
 119        unsigned int n = 0;
 120        struct bio_vec bv;
 121        struct req_iterator iter;
 122
 123        rq_for_each_segment(bv, req, iter)
 124                n++;
 125        dev_dbg(&dev->sbd.core,
 126                "%s:%u: %s req has %u bvecs for %u sectors\n",
 127                __func__, __LINE__, op, n, blk_rq_sectors(req));
 128#endif
 129
 130        start_sector = blk_rq_pos(req) * priv->blocking_factor;
 131        sectors = blk_rq_sectors(req) * priv->blocking_factor;
 132        dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
 133                __func__, __LINE__, op, sectors, start_sector);
 134
 135        if (write) {
 136                ps3disk_scatter_gather(dev, req, 1);
 137
 138                res = lv1_storage_write(dev->sbd.dev_id, region_id,
 139                                        start_sector, sectors, 0,
 140                                        dev->bounce_lpar, &dev->tag);
 141        } else {
 142                res = lv1_storage_read(dev->sbd.dev_id, region_id,
 143                                       start_sector, sectors, 0,
 144                                       dev->bounce_lpar, &dev->tag);
 145        }
 146        if (res) {
 147                dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
 148                        __LINE__, op, res);
 149                return BLK_STS_IOERR;
 150        }
 151
 152        priv->req = req;
 153        return BLK_STS_OK;
 154}
 155
 156static blk_status_t ps3disk_submit_flush_request(struct ps3_storage_device *dev,
 157                                                 struct request *req)
 158{
 159        struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
 160        u64 res;
 161
 162        dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__);
 163
 164        res = lv1_storage_send_device_command(dev->sbd.dev_id,
 165                                              LV1_STORAGE_ATA_HDDOUT, 0, 0, 0,
 166                                              0, &dev->tag);
 167        if (res) {
 168                dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
 169                        __func__, __LINE__, res);
 170                return BLK_STS_IOERR;
 171        }
 172
 173        priv->req = req;
 174        return BLK_STS_OK;
 175}
 176
 177static blk_status_t ps3disk_do_request(struct ps3_storage_device *dev,
 178                                       struct request *req)
 179{
 180        dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
 181
 182        switch (req_op(req)) {
 183        case REQ_OP_FLUSH:
 184                return ps3disk_submit_flush_request(dev, req);
 185        case REQ_OP_READ:
 186        case REQ_OP_WRITE:
 187                return ps3disk_submit_request_sg(dev, req);
 188        default:
 189                blk_dump_rq_flags(req, DEVICE_NAME " bad request");
 190                return BLK_STS_IOERR;
 191        }
 192}
 193
 194static blk_status_t ps3disk_queue_rq(struct blk_mq_hw_ctx *hctx,
 195                                     const struct blk_mq_queue_data *bd)
 196{
 197        struct request_queue *q = hctx->queue;
 198        struct ps3_storage_device *dev = q->queuedata;
 199        struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
 200        blk_status_t ret;
 201
 202        blk_mq_start_request(bd->rq);
 203
 204        spin_lock_irq(&priv->lock);
 205        ret = ps3disk_do_request(dev, bd->rq);
 206        spin_unlock_irq(&priv->lock);
 207
 208        return ret;
 209}
 210
 211static irqreturn_t ps3disk_interrupt(int irq, void *data)
 212{
 213        struct ps3_storage_device *dev = data;
 214        struct ps3disk_private *priv;
 215        struct request *req;
 216        int res, read;
 217        blk_status_t error;
 218        u64 tag, status;
 219        const char *op;
 220
 221        res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
 222
 223        if (tag != dev->tag)
 224                dev_err(&dev->sbd.core,
 225                        "%s:%u: tag mismatch, got %llx, expected %llx\n",
 226                        __func__, __LINE__, tag, dev->tag);
 227
 228        if (res) {
 229                dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
 230                        __func__, __LINE__, res, status);
 231                return IRQ_HANDLED;
 232        }
 233
 234        priv = ps3_system_bus_get_drvdata(&dev->sbd);
 235        req = priv->req;
 236        if (!req) {
 237                dev_dbg(&dev->sbd.core,
 238                        "%s:%u non-block layer request completed\n", __func__,
 239                        __LINE__);
 240                dev->lv1_status = status;
 241                complete(&dev->done);
 242                return IRQ_HANDLED;
 243        }
 244
 245        if (req_op(req) == REQ_OP_FLUSH) {
 246                read = 0;
 247                op = "flush";
 248        } else {
 249                read = !rq_data_dir(req);
 250                op = read ? "read" : "write";
 251        }
 252        if (status) {
 253                dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
 254                        __LINE__, op, status);
 255                error = BLK_STS_IOERR;
 256        } else {
 257                dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
 258                        __LINE__, op);
 259                error = 0;
 260                if (read)
 261                        ps3disk_scatter_gather(dev, req, 0);
 262        }
 263
 264        spin_lock(&priv->lock);
 265        priv->req = NULL;
 266        blk_mq_end_request(req, error);
 267        spin_unlock(&priv->lock);
 268
 269        blk_mq_run_hw_queues(priv->gendisk->queue, true);
 270        return IRQ_HANDLED;
 271}
 272
 273static int ps3disk_sync_cache(struct ps3_storage_device *dev)
 274{
 275        u64 res;
 276
 277        dev_dbg(&dev->sbd.core, "%s:%u: sync cache\n", __func__, __LINE__);
 278
 279        res = ps3stor_send_command(dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0);
 280        if (res) {
 281                dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
 282                        __func__, __LINE__, res);
 283                return -EIO;
 284        }
 285        return 0;
 286}
 287
 288
 289/* ATA helpers copied from drivers/ata/libata-core.c */
 290
 291static void swap_buf_le16(u16 *buf, unsigned int buf_words)
 292{
 293#ifdef __BIG_ENDIAN
 294        unsigned int i;
 295
 296        for (i = 0; i < buf_words; i++)
 297                buf[i] = le16_to_cpu(buf[i]);
 298#endif /* __BIG_ENDIAN */
 299}
 300
 301static u64 ata_id_n_sectors(const u16 *id)
 302{
 303        if (ata_id_has_lba(id)) {
 304                if (ata_id_has_lba48(id))
 305                        return ata_id_u64(id, 100);
 306                else
 307                        return ata_id_u32(id, 60);
 308        } else {
 309                if (ata_id_current_chs_valid(id))
 310                        return ata_id_u32(id, 57);
 311                else
 312                        return id[1] * id[3] * id[6];
 313        }
 314}
 315
 316static void ata_id_string(const u16 *id, unsigned char *s, unsigned int ofs,
 317                          unsigned int len)
 318{
 319        unsigned int c;
 320
 321        while (len > 0) {
 322                c = id[ofs] >> 8;
 323                *s = c;
 324                s++;
 325
 326                c = id[ofs] & 0xff;
 327                *s = c;
 328                s++;
 329
 330                ofs++;
 331                len -= 2;
 332        }
 333}
 334
 335static void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs,
 336                            unsigned int len)
 337{
 338        unsigned char *p;
 339
 340        WARN_ON(!(len & 1));
 341
 342        ata_id_string(id, s, ofs, len - 1);
 343
 344        p = s + strnlen(s, len - 1);
 345        while (p > s && p[-1] == ' ')
 346                p--;
 347        *p = '\0';
 348}
 349
 350static int ps3disk_identify(struct ps3_storage_device *dev)
 351{
 352        struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
 353        struct lv1_ata_cmnd_block ata_cmnd;
 354        u16 *id = dev->bounce_buf;
 355        u64 res;
 356
 357        dev_dbg(&dev->sbd.core, "%s:%u: identify disk\n", __func__, __LINE__);
 358
 359        memset(&ata_cmnd, 0, sizeof(struct lv1_ata_cmnd_block));
 360        ata_cmnd.command = ATA_CMD_ID_ATA;
 361        ata_cmnd.sector_count = 1;
 362        ata_cmnd.size = ata_cmnd.arglen = ATA_ID_WORDS * 2;
 363        ata_cmnd.buffer = dev->bounce_lpar;
 364        ata_cmnd.proto = PIO_DATA_IN_PROTO;
 365        ata_cmnd.in_out = DIR_READ;
 366
 367        res = ps3stor_send_command(dev, LV1_STORAGE_SEND_ATA_COMMAND,
 368                                   ps3_mm_phys_to_lpar(__pa(&ata_cmnd)),
 369                                   sizeof(ata_cmnd), ata_cmnd.buffer,
 370                                   ata_cmnd.arglen);
 371        if (res) {
 372                dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%llx\n",
 373                        __func__, __LINE__, res);
 374                return -EIO;
 375        }
 376
 377        swap_buf_le16(id, ATA_ID_WORDS);
 378
 379        /* All we're interested in are raw capacity and model name */
 380        priv->raw_capacity = ata_id_n_sectors(id);
 381        ata_id_c_string(id, priv->model, ATA_ID_PROD, sizeof(priv->model));
 382        return 0;
 383}
 384
 385static unsigned long ps3disk_mask;
 386
 387static DEFINE_MUTEX(ps3disk_mask_mutex);
 388
 389static const struct blk_mq_ops ps3disk_mq_ops = {
 390        .queue_rq       = ps3disk_queue_rq,
 391};
 392
 393static int ps3disk_probe(struct ps3_system_bus_device *_dev)
 394{
 395        struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
 396        struct ps3disk_private *priv;
 397        int error;
 398        unsigned int devidx;
 399        struct request_queue *queue;
 400        struct gendisk *gendisk;
 401
 402        if (dev->blk_size < 512) {
 403                dev_err(&dev->sbd.core,
 404                        "%s:%u: cannot handle block size %llu\n", __func__,
 405                        __LINE__, dev->blk_size);
 406                return -EINVAL;
 407        }
 408
 409        BUILD_BUG_ON(PS3DISK_MAX_DISKS > BITS_PER_LONG);
 410        mutex_lock(&ps3disk_mask_mutex);
 411        devidx = find_first_zero_bit(&ps3disk_mask, PS3DISK_MAX_DISKS);
 412        if (devidx >= PS3DISK_MAX_DISKS) {
 413                dev_err(&dev->sbd.core, "%s:%u: Too many disks\n", __func__,
 414                        __LINE__);
 415                mutex_unlock(&ps3disk_mask_mutex);
 416                return -ENOSPC;
 417        }
 418        __set_bit(devidx, &ps3disk_mask);
 419        mutex_unlock(&ps3disk_mask_mutex);
 420
 421        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 422        if (!priv) {
 423                error = -ENOMEM;
 424                goto fail;
 425        }
 426
 427        ps3_system_bus_set_drvdata(_dev, priv);
 428        spin_lock_init(&priv->lock);
 429
 430        dev->bounce_size = BOUNCE_SIZE;
 431        dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
 432        if (!dev->bounce_buf) {
 433                error = -ENOMEM;
 434                goto fail_free_priv;
 435        }
 436
 437        error = ps3stor_setup(dev, ps3disk_interrupt);
 438        if (error)
 439                goto fail_free_bounce;
 440
 441        ps3disk_identify(dev);
 442
 443        error = blk_mq_alloc_sq_tag_set(&priv->tag_set, &ps3disk_mq_ops, 1,
 444                                        BLK_MQ_F_SHOULD_MERGE);
 445        if (error)
 446                goto fail_teardown;
 447
 448        gendisk = blk_mq_alloc_disk(&priv->tag_set, dev);
 449        if (IS_ERR(gendisk)) {
 450                dev_err(&dev->sbd.core, "%s:%u: blk_mq_alloc_disk failed\n",
 451                        __func__, __LINE__);
 452                error = PTR_ERR(gendisk);
 453                goto fail_free_tag_set;
 454        }
 455
 456        queue = gendisk->queue;
 457
 458        blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
 459        blk_queue_dma_alignment(queue, dev->blk_size-1);
 460        blk_queue_logical_block_size(queue, dev->blk_size);
 461
 462        blk_queue_write_cache(queue, true, false);
 463
 464        blk_queue_max_segments(queue, -1);
 465        blk_queue_max_segment_size(queue, dev->bounce_size);
 466
 467        priv->gendisk = gendisk;
 468        gendisk->major = ps3disk_major;
 469        gendisk->first_minor = devidx * PS3DISK_MINORS;
 470        gendisk->minors = PS3DISK_MINORS;
 471        gendisk->fops = &ps3disk_fops;
 472        gendisk->private_data = dev;
 473        snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3DISK_NAME,
 474                 devidx+'a');
 475        priv->blocking_factor = dev->blk_size >> 9;
 476        set_capacity(gendisk,
 477                     dev->regions[dev->region_idx].size*priv->blocking_factor);
 478
 479        dev_info(&dev->sbd.core,
 480                 "%s is a %s (%llu MiB total, %llu MiB for OtherOS)\n",
 481                 gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
 482                 get_capacity(gendisk) >> 11);
 483
 484        device_add_disk(&dev->sbd.core, gendisk, NULL);
 485        return 0;
 486
 487fail_free_tag_set:
 488        blk_mq_free_tag_set(&priv->tag_set);
 489fail_teardown:
 490        ps3stor_teardown(dev);
 491fail_free_bounce:
 492        kfree(dev->bounce_buf);
 493fail_free_priv:
 494        kfree(priv);
 495        ps3_system_bus_set_drvdata(_dev, NULL);
 496fail:
 497        mutex_lock(&ps3disk_mask_mutex);
 498        __clear_bit(devidx, &ps3disk_mask);
 499        mutex_unlock(&ps3disk_mask_mutex);
 500        return error;
 501}
 502
 503static void ps3disk_remove(struct ps3_system_bus_device *_dev)
 504{
 505        struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
 506        struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
 507
 508        mutex_lock(&ps3disk_mask_mutex);
 509        __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
 510                    &ps3disk_mask);
 511        mutex_unlock(&ps3disk_mask_mutex);
 512        del_gendisk(priv->gendisk);
 513        blk_cleanup_disk(priv->gendisk);
 514        blk_mq_free_tag_set(&priv->tag_set);
 515        dev_notice(&dev->sbd.core, "Synchronizing disk cache\n");
 516        ps3disk_sync_cache(dev);
 517        ps3stor_teardown(dev);
 518        kfree(dev->bounce_buf);
 519        kfree(priv);
 520        ps3_system_bus_set_drvdata(_dev, NULL);
 521}
 522
 523static struct ps3_system_bus_driver ps3disk = {
 524        .match_id       = PS3_MATCH_ID_STOR_DISK,
 525        .core.name      = DEVICE_NAME,
 526        .core.owner     = THIS_MODULE,
 527        .probe          = ps3disk_probe,
 528        .remove         = ps3disk_remove,
 529        .shutdown       = ps3disk_remove,
 530};
 531
 532
 533static int __init ps3disk_init(void)
 534{
 535        int error;
 536
 537        if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
 538                return -ENODEV;
 539
 540        error = register_blkdev(0, DEVICE_NAME);
 541        if (error <= 0) {
 542                printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__,
 543                       __LINE__, error);
 544                return error;
 545        }
 546        ps3disk_major = error;
 547
 548        pr_info("%s:%u: registered block device major %d\n", __func__,
 549                __LINE__, ps3disk_major);
 550
 551        error = ps3_system_bus_driver_register(&ps3disk);
 552        if (error)
 553                unregister_blkdev(ps3disk_major, DEVICE_NAME);
 554
 555        return error;
 556}
 557
 558static void __exit ps3disk_exit(void)
 559{
 560        ps3_system_bus_driver_unregister(&ps3disk);
 561        unregister_blkdev(ps3disk_major, DEVICE_NAME);
 562}
 563
 564module_init(ps3disk_init);
 565module_exit(ps3disk_exit);
 566
 567MODULE_LICENSE("GPL");
 568MODULE_DESCRIPTION("PS3 Disk Storage Driver");
 569MODULE_AUTHOR("Sony Corporation");
 570MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_DISK);
 571