0001
0002
0003
0004
0005
0006
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];
0042 u32 pktlen;
0043 u32 blocks;
0044 u32 block_size;
0045 u32 proto;
0046 u32 in_out;
0047 u64 buffer;
0048 u32 arglen;
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,
0060 DIR_READ = 1
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
0074
0075
0076 scsi_dev->use_10_for_ms = 1;
0077
0078
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;
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
0215
0216
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
0271
0272
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
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
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,
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
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);