Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * PS3 BD/DVD/CD-ROM Storage Driver
0004  *
0005  * Copyright (C) 2007 Sony Computer Entertainment Inc.
0006  * Copyright 2007 Sony Corp.
0007  */
0008 
0009 #include <linux/cdrom.h>
0010 #include <linux/highmem.h>
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 
0014 #include <scsi/scsi.h>
0015 #include <scsi/scsi_cmnd.h>
0016 #include <scsi/scsi_dbg.h>
0017 #include <scsi/scsi_device.h>
0018 #include <scsi/scsi_host.h>
0019 #include <scsi/scsi_eh.h>
0020 
0021 #include <asm/lv1call.h>
0022 #include <asm/ps3stor.h>
0023 
0024 
0025 #define DEVICE_NAME         "ps3rom"
0026 
0027 #define BOUNCE_SIZE         (64*1024)
0028 
0029 #define PS3ROM_MAX_SECTORS      (BOUNCE_SIZE >> 9)
0030 
0031 
0032 struct ps3rom_private {
0033     struct ps3_storage_device *dev;
0034     struct scsi_cmnd *curr_cmd;
0035 };
0036 
0037 
0038 #define LV1_STORAGE_SEND_ATAPI_COMMAND  (1)
0039 
0040 struct lv1_atapi_cmnd_block {
0041     u8  pkt[32];    /* packet command block           */
0042     u32 pktlen;     /* should be 12 for ATAPI 8020    */
0043     u32 blocks;
0044     u32 block_size;
0045     u32 proto;      /* transfer mode                  */
0046     u32 in_out;     /* transfer direction             */
0047     u64 buffer;     /* parameter except command block */
0048     u32 arglen;     /* length above                   */
0049 };
0050 
0051 enum lv1_atapi_proto {
0052     NON_DATA_PROTO     = 0,
0053     PIO_DATA_IN_PROTO  = 1,
0054     PIO_DATA_OUT_PROTO = 2,
0055     DMA_PROTO = 3
0056 };
0057 
0058 enum lv1_atapi_in_out {
0059     DIR_WRITE = 0,      /* memory -> device */
0060     DIR_READ = 1        /* device -> memory */
0061 };
0062 
0063 
0064 static int ps3rom_slave_configure(struct scsi_device *scsi_dev)
0065 {
0066     struct ps3rom_private *priv = shost_priv(scsi_dev->host);
0067     struct ps3_storage_device *dev = priv->dev;
0068 
0069     dev_dbg(&dev->sbd.core, "%s:%u: id %u, lun %llu, channel %u\n", __func__,
0070         __LINE__, scsi_dev->id, scsi_dev->lun, scsi_dev->channel);
0071 
0072     /*
0073      * ATAPI SFF8020 devices use MODE_SENSE_10,
0074      * so we can prohibit MODE_SENSE_6
0075      */
0076     scsi_dev->use_10_for_ms = 1;
0077 
0078     /* we don't support {READ,WRITE}_6 */
0079     scsi_dev->use_10_for_rw = 1;
0080 
0081     return 0;
0082 }
0083 
0084 static int ps3rom_atapi_request(struct ps3_storage_device *dev,
0085                 struct scsi_cmnd *cmd)
0086 {
0087     struct lv1_atapi_cmnd_block atapi_cmnd;
0088     unsigned char opcode = cmd->cmnd[0];
0089     int res;
0090     u64 lpar;
0091 
0092     dev_dbg(&dev->sbd.core, "%s:%u: send ATAPI command 0x%02x\n", __func__,
0093         __LINE__, opcode);
0094 
0095     memset(&atapi_cmnd, 0, sizeof(struct lv1_atapi_cmnd_block));
0096     memcpy(&atapi_cmnd.pkt, cmd->cmnd, 12);
0097     atapi_cmnd.pktlen = 12;
0098     atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */
0099     atapi_cmnd.blocks = atapi_cmnd.arglen = scsi_bufflen(cmd);
0100     atapi_cmnd.buffer = dev->bounce_lpar;
0101 
0102     switch (cmd->sc_data_direction) {
0103     case DMA_FROM_DEVICE:
0104         if (scsi_bufflen(cmd) >= CD_FRAMESIZE)
0105             atapi_cmnd.proto = DMA_PROTO;
0106         else
0107             atapi_cmnd.proto = PIO_DATA_IN_PROTO;
0108         atapi_cmnd.in_out = DIR_READ;
0109         break;
0110 
0111     case DMA_TO_DEVICE:
0112         if (scsi_bufflen(cmd) >= CD_FRAMESIZE)
0113             atapi_cmnd.proto = DMA_PROTO;
0114         else
0115             atapi_cmnd.proto = PIO_DATA_OUT_PROTO;
0116         atapi_cmnd.in_out = DIR_WRITE;
0117         scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
0118         break;
0119 
0120     default:
0121         atapi_cmnd.proto = NON_DATA_PROTO;
0122         break;
0123     }
0124 
0125     lpar = ps3_mm_phys_to_lpar(__pa(&atapi_cmnd));
0126     res = lv1_storage_send_device_command(dev->sbd.dev_id,
0127                           LV1_STORAGE_SEND_ATAPI_COMMAND,
0128                           lpar, sizeof(atapi_cmnd),
0129                           atapi_cmnd.buffer,
0130                           atapi_cmnd.arglen, &dev->tag);
0131     if (res == LV1_DENIED_BY_POLICY) {
0132         dev_dbg(&dev->sbd.core,
0133             "%s:%u: ATAPI command 0x%02x denied by policy\n",
0134             __func__, __LINE__, opcode);
0135         return DID_ERROR << 16;
0136     }
0137 
0138     if (res) {
0139         dev_err(&dev->sbd.core,
0140             "%s:%u: ATAPI command 0x%02x failed %d\n", __func__,
0141             __LINE__, opcode, res);
0142         return DID_ERROR << 16;
0143     }
0144 
0145     return 0;
0146 }
0147 
0148 static inline unsigned int srb10_lba(const struct scsi_cmnd *cmd)
0149 {
0150     return cmd->cmnd[2] << 24 | cmd->cmnd[3] << 16 | cmd->cmnd[4] << 8 |
0151            cmd->cmnd[5];
0152 }
0153 
0154 static inline unsigned int srb10_len(const struct scsi_cmnd *cmd)
0155 {
0156     return cmd->cmnd[7] << 8 | cmd->cmnd[8];
0157 }
0158 
0159 static int ps3rom_read_request(struct ps3_storage_device *dev,
0160                    struct scsi_cmnd *cmd, u32 start_sector,
0161                    u32 sectors)
0162 {
0163     int res;
0164 
0165     dev_dbg(&dev->sbd.core, "%s:%u: read %u sectors starting at %u\n",
0166         __func__, __LINE__, sectors, start_sector);
0167 
0168     res = lv1_storage_read(dev->sbd.dev_id,
0169                    dev->regions[dev->region_idx].id, start_sector,
0170                    sectors, 0, dev->bounce_lpar, &dev->tag);
0171     if (res) {
0172         dev_err(&dev->sbd.core, "%s:%u: read failed %d\n", __func__,
0173             __LINE__, res);
0174         return DID_ERROR << 16;
0175     }
0176 
0177     return 0;
0178 }
0179 
0180 static int ps3rom_write_request(struct ps3_storage_device *dev,
0181                 struct scsi_cmnd *cmd, u32 start_sector,
0182                 u32 sectors)
0183 {
0184     int res;
0185 
0186     dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n",
0187         __func__, __LINE__, sectors, start_sector);
0188 
0189     scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
0190 
0191     res = lv1_storage_write(dev->sbd.dev_id,
0192                 dev->regions[dev->region_idx].id, start_sector,
0193                 sectors, 0, dev->bounce_lpar, &dev->tag);
0194     if (res) {
0195         dev_err(&dev->sbd.core, "%s:%u: write failed %d\n", __func__,
0196             __LINE__, res);
0197         return DID_ERROR << 16;
0198     }
0199 
0200     return 0;
0201 }
0202 
0203 static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd)
0204 {
0205     struct ps3rom_private *priv = shost_priv(cmd->device->host);
0206     struct ps3_storage_device *dev = priv->dev;
0207     unsigned char opcode;
0208     int res;
0209 
0210     priv->curr_cmd = cmd;
0211 
0212     opcode = cmd->cmnd[0];
0213     /*
0214      * While we can submit READ/WRITE SCSI commands as ATAPI commands,
0215      * it's recommended for various reasons (performance, error handling,
0216      * ...) to use lv1_storage_{read,write}() instead
0217      */
0218     switch (opcode) {
0219     case READ_10:
0220         res = ps3rom_read_request(dev, cmd, srb10_lba(cmd),
0221                       srb10_len(cmd));
0222         break;
0223 
0224     case WRITE_10:
0225         res = ps3rom_write_request(dev, cmd, srb10_lba(cmd),
0226                        srb10_len(cmd));
0227         break;
0228 
0229     default:
0230         res = ps3rom_atapi_request(dev, cmd);
0231         break;
0232     }
0233 
0234     if (res) {
0235         scsi_build_sense(cmd, 0, ILLEGAL_REQUEST, 0, 0);
0236         cmd->result = res;
0237         priv->curr_cmd = NULL;
0238         scsi_done(cmd);
0239     }
0240 
0241     return 0;
0242 }
0243 
0244 static DEF_SCSI_QCMD(ps3rom_queuecommand)
0245 
0246 static int decode_lv1_status(u64 status, unsigned char *sense_key,
0247                  unsigned char *asc, unsigned char *ascq)
0248 {
0249     if (((status >> 24) & 0xff) != SAM_STAT_CHECK_CONDITION)
0250         return -1;
0251 
0252     *sense_key = (status >> 16) & 0xff;
0253     *asc       = (status >>  8) & 0xff;
0254     *ascq      =  status        & 0xff;
0255     return 0;
0256 }
0257 
0258 static irqreturn_t ps3rom_interrupt(int irq, void *data)
0259 {
0260     struct ps3_storage_device *dev = data;
0261     struct Scsi_Host *host;
0262     struct ps3rom_private *priv;
0263     struct scsi_cmnd *cmd;
0264     int res;
0265     u64 tag, status;
0266     unsigned char sense_key, asc, ascq;
0267 
0268     res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
0269     /*
0270      * status = -1 may mean that ATAPI transport completed OK, but
0271      * ATAPI command itself resulted CHECK CONDITION
0272      * so, upper layer should issue REQUEST_SENSE to check the sense data
0273      */
0274 
0275     if (tag != dev->tag)
0276         dev_err(&dev->sbd.core,
0277             "%s:%u: tag mismatch, got %llx, expected %llx\n",
0278             __func__, __LINE__, tag, dev->tag);
0279 
0280     if (res) {
0281         dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
0282             __func__, __LINE__, res, status);
0283         return IRQ_HANDLED;
0284     }
0285 
0286     host = ps3_system_bus_get_drvdata(&dev->sbd);
0287     priv = shost_priv(host);
0288     cmd = priv->curr_cmd;
0289 
0290     if (!status) {
0291         /* OK, completed */
0292         if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
0293             int len;
0294 
0295             len = scsi_sg_copy_from_buffer(cmd,
0296                                dev->bounce_buf,
0297                                dev->bounce_size);
0298 
0299             scsi_set_resid(cmd, scsi_bufflen(cmd) - len);
0300         }
0301         cmd->result = DID_OK << 16;
0302         goto done;
0303     }
0304 
0305     if (cmd->cmnd[0] == REQUEST_SENSE) {
0306         /* SCSI spec says request sense should never get error */
0307         dev_err(&dev->sbd.core, "%s:%u: end error without autosense\n",
0308             __func__, __LINE__);
0309         cmd->result = DID_ERROR << 16 | SAM_STAT_CHECK_CONDITION;
0310         goto done;
0311     }
0312 
0313     if (decode_lv1_status(status, &sense_key, &asc, &ascq)) {
0314         cmd->result = DID_ERROR << 16;
0315         goto done;
0316     }
0317 
0318     scsi_build_sense(cmd, 0, sense_key, asc, ascq);
0319 
0320 done:
0321     priv->curr_cmd = NULL;
0322     scsi_done(cmd);
0323     return IRQ_HANDLED;
0324 }
0325 
0326 static struct scsi_host_template ps3rom_host_template = {
0327     .name =         DEVICE_NAME,
0328     .slave_configure =  ps3rom_slave_configure,
0329     .queuecommand =     ps3rom_queuecommand,
0330     .can_queue =        1,
0331     .this_id =      7,
0332     .sg_tablesize =     SG_ALL,
0333     .emulated =             1,      /* only sg driver uses this */
0334     .max_sectors =      PS3ROM_MAX_SECTORS,
0335     .module =       THIS_MODULE,
0336 };
0337 
0338 
0339 static int ps3rom_probe(struct ps3_system_bus_device *_dev)
0340 {
0341     struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
0342     int error;
0343     struct Scsi_Host *host;
0344     struct ps3rom_private *priv;
0345 
0346     if (dev->blk_size != CD_FRAMESIZE) {
0347         dev_err(&dev->sbd.core,
0348             "%s:%u: cannot handle block size %llu\n", __func__,
0349             __LINE__, dev->blk_size);
0350         return -EINVAL;
0351     }
0352 
0353     dev->bounce_size = BOUNCE_SIZE;
0354     dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
0355     if (!dev->bounce_buf)
0356         return -ENOMEM;
0357 
0358     error = ps3stor_setup(dev, ps3rom_interrupt);
0359     if (error)
0360         goto fail_free_bounce;
0361 
0362     host = scsi_host_alloc(&ps3rom_host_template,
0363                    sizeof(struct ps3rom_private));
0364     if (!host) {
0365         dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed\n",
0366             __func__, __LINE__);
0367         error = -ENOMEM;
0368         goto fail_teardown;
0369     }
0370 
0371     priv = shost_priv(host);
0372     ps3_system_bus_set_drvdata(&dev->sbd, host);
0373     priv->dev = dev;
0374 
0375     /* One device/LUN per SCSI bus */
0376     host->max_id = 1;
0377     host->max_lun = 1;
0378 
0379     error = scsi_add_host(host, &dev->sbd.core);
0380     if (error) {
0381         dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed %d\n",
0382             __func__, __LINE__, error);
0383         error = -ENODEV;
0384         goto fail_host_put;
0385     }
0386 
0387     scsi_scan_host(host);
0388     return 0;
0389 
0390 fail_host_put:
0391     scsi_host_put(host);
0392     ps3_system_bus_set_drvdata(&dev->sbd, NULL);
0393 fail_teardown:
0394     ps3stor_teardown(dev);
0395 fail_free_bounce:
0396     kfree(dev->bounce_buf);
0397     return error;
0398 }
0399 
0400 static void ps3rom_remove(struct ps3_system_bus_device *_dev)
0401 {
0402     struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
0403     struct Scsi_Host *host = ps3_system_bus_get_drvdata(&dev->sbd);
0404 
0405     scsi_remove_host(host);
0406     ps3stor_teardown(dev);
0407     scsi_host_put(host);
0408     ps3_system_bus_set_drvdata(&dev->sbd, NULL);
0409     kfree(dev->bounce_buf);
0410 }
0411 
0412 static struct ps3_system_bus_driver ps3rom = {
0413     .match_id   = PS3_MATCH_ID_STOR_ROM,
0414     .core.name  = DEVICE_NAME,
0415     .core.owner = THIS_MODULE,
0416     .probe      = ps3rom_probe,
0417     .remove     = ps3rom_remove
0418 };
0419 
0420 
0421 static int __init ps3rom_init(void)
0422 {
0423     return ps3_system_bus_driver_register(&ps3rom);
0424 }
0425 
0426 static void __exit ps3rom_exit(void)
0427 {
0428     ps3_system_bus_driver_unregister(&ps3rom);
0429 }
0430 
0431 module_init(ps3rom_init);
0432 module_exit(ps3rom_exit);
0433 
0434 MODULE_LICENSE("GPL");
0435 MODULE_DESCRIPTION("PS3 BD/DVD/CD-ROM Storage Driver");
0436 MODULE_AUTHOR("Sony Corporation");
0437 MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_ROM);