root/drivers/block/ps3disk.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ps3disk_scatter_gather
  2. ps3disk_submit_request_sg
  3. ps3disk_submit_flush_request
  4. ps3disk_do_request
  5. ps3disk_queue_rq
  6. ps3disk_interrupt
  7. ps3disk_sync_cache
  8. swap_buf_le16
  9. ata_id_n_sectors
  10. ata_id_string
  11. ata_id_c_string
  12. ps3disk_identify
  13. ps3disk_probe
  14. ps3disk_remove
  15. ps3disk_init
  16. ps3disk_exit

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

/* [<][>][^][v][top][bottom][index][help] */