1 /* 2 * PS3 FLASH ROM Storage Driver 3 * 4 * Copyright (C) 2007 Sony Computer Entertainment Inc. 5 * Copyright 2007 Sony Corp. 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published 9 * by the Free Software Foundation; version 2 of the License. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #include <linux/fs.h> 22 #include <linux/miscdevice.h> 23 #include <linux/uaccess.h> 24 25 #include <asm/lv1call.h> 26 #include <asm/ps3stor.h> 27 28 29 #define DEVICE_NAME "ps3flash" 30 31 #define FLASH_BLOCK_SIZE (256*1024) 32 33 34 struct ps3flash_private { 35 struct mutex mutex; /* Bounce buffer mutex */ 36 }; 37 38 static struct ps3_storage_device *ps3flash_dev; 39 40 static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev, 41 u64 lpar, u64 start_sector, 42 u64 sectors, int write) 43 { 44 u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, 45 write); 46 if (res) { 47 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, 48 __LINE__, write ? "write" : "read", res); 49 return -EIO; 50 } 51 return sectors; 52 } 53 54 static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev, 55 u64 start_sector, u64 sectors, 56 unsigned int sector_offset) 57 { 58 u64 max_sectors, lpar; 59 60 max_sectors = dev->bounce_size / dev->blk_size; 61 if (sectors > max_sectors) { 62 dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %lu\n", 63 __func__, __LINE__, max_sectors); 64 sectors = max_sectors; 65 } 66 67 lpar = dev->bounce_lpar + sector_offset * dev->blk_size; 68 return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, 69 0); 70 } 71 72 static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev, 73 u64 start_sector) 74 { 75 u64 sectors = dev->bounce_size / dev->blk_size; 76 return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector, 77 sectors, 1); 78 } 79 80 static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) 81 { 82 struct ps3_storage_device *dev = ps3flash_dev; 83 loff_t res; 84 85 mutex_lock(&file->f_mapping->host->i_mutex); 86 switch (origin) { 87 case 1: 88 offset += file->f_pos; 89 break; 90 case 2: 91 offset += dev->regions[dev->region_idx].size*dev->blk_size; 92 break; 93 } 94 if (offset < 0) { 95 res = -EINVAL; 96 goto out; 97 } 98 99 file->f_pos = offset; 100 res = file->f_pos; 101 102 out: 103 mutex_unlock(&file->f_mapping->host->i_mutex); 104 return res; 105 } 106 107 static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, 108 loff_t *pos) 109 { 110 struct ps3_storage_device *dev = ps3flash_dev; 111 struct ps3flash_private *priv = dev->sbd.core.driver_data; 112 u64 size, start_sector, end_sector, offset; 113 ssize_t sectors_read; 114 size_t remaining, n; 115 116 dev_dbg(&dev->sbd.core, 117 "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n", 118 __func__, __LINE__, count, *pos, buf); 119 120 size = dev->regions[dev->region_idx].size*dev->blk_size; 121 if (*pos >= size || !count) 122 return 0; 123 124 if (*pos + count > size) { 125 dev_dbg(&dev->sbd.core, 126 "%s:%u Truncating count from %zu to %llu\n", __func__, 127 __LINE__, count, size - *pos); 128 count = size - *pos; 129 } 130 131 start_sector = *pos / dev->blk_size; 132 offset = *pos % dev->blk_size; 133 end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size); 134 135 remaining = count; 136 do { 137 mutex_lock(&priv->mutex); 138 139 sectors_read = ps3flash_read_sectors(dev, start_sector, 140 end_sector-start_sector, 141 0); 142 if (sectors_read < 0) { 143 mutex_unlock(&priv->mutex); 144 goto fail; 145 } 146 147 n = min(remaining, sectors_read*dev->blk_size-offset); 148 dev_dbg(&dev->sbd.core, 149 "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n", 150 __func__, __LINE__, n, dev->bounce_buf+offset, buf); 151 if (copy_to_user(buf, dev->bounce_buf+offset, n)) { 152 mutex_unlock(&priv->mutex); 153 sectors_read = -EFAULT; 154 goto fail; 155 } 156 157 mutex_unlock(&priv->mutex); 158 159 *pos += n; 160 buf += n; 161 remaining -= n; 162 start_sector += sectors_read; 163 offset = 0; 164 } while (remaining > 0); 165 166 return count; 167 168 fail: 169 return sectors_read; 170 } 171 172 static ssize_t ps3flash_write(struct file *file, const char __user *buf, 173 size_t count, loff_t *pos) 174 { 175 struct ps3_storage_device *dev = ps3flash_dev; 176 struct ps3flash_private *priv = dev->sbd.core.driver_data; 177 u64 size, chunk_sectors, start_write_sector, end_write_sector, 178 end_read_sector, start_read_sector, head, tail, offset; 179 ssize_t res; 180 size_t remaining, n; 181 unsigned int sec_off; 182 183 dev_dbg(&dev->sbd.core, 184 "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n", 185 __func__, __LINE__, count, *pos, buf); 186 187 size = dev->regions[dev->region_idx].size*dev->blk_size; 188 if (*pos >= size || !count) 189 return 0; 190 191 if (*pos + count > size) { 192 dev_dbg(&dev->sbd.core, 193 "%s:%u Truncating count from %zu to %llu\n", __func__, 194 __LINE__, count, size - *pos); 195 count = size - *pos; 196 } 197 198 chunk_sectors = dev->bounce_size / dev->blk_size; 199 200 start_write_sector = *pos / dev->bounce_size * chunk_sectors; 201 offset = *pos % dev->bounce_size; 202 end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) * 203 chunk_sectors; 204 205 end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size); 206 start_read_sector = (*pos + count) / dev->blk_size; 207 208 /* 209 * As we have to write in 256 KiB chunks, while we can read in blk_size 210 * (usually 512 bytes) chunks, we perform the following steps: 211 * 1. Read from start_write_sector to end_read_sector ("head") 212 * 2. Read from start_read_sector to end_write_sector ("tail") 213 * 3. Copy data to buffer 214 * 4. Write from start_write_sector to end_write_sector 215 * All of this is complicated by using only one 256 KiB bounce buffer. 216 */ 217 218 head = end_read_sector - start_write_sector; 219 tail = end_write_sector - start_read_sector; 220 221 remaining = count; 222 do { 223 mutex_lock(&priv->mutex); 224 225 if (end_read_sector >= start_read_sector) { 226 /* Merge head and tail */ 227 dev_dbg(&dev->sbd.core, 228 "Merged head and tail: %lu sectors at %lu\n", 229 chunk_sectors, start_write_sector); 230 res = ps3flash_read_sectors(dev, start_write_sector, 231 chunk_sectors, 0); 232 if (res < 0) 233 goto fail; 234 } else { 235 if (head) { 236 /* Read head */ 237 dev_dbg(&dev->sbd.core, 238 "head: %lu sectors at %lu\n", head, 239 start_write_sector); 240 res = ps3flash_read_sectors(dev, 241 start_write_sector, 242 head, 0); 243 if (res < 0) 244 goto fail; 245 } 246 if (start_read_sector < 247 start_write_sector+chunk_sectors) { 248 /* Read tail */ 249 dev_dbg(&dev->sbd.core, 250 "tail: %lu sectors at %lu\n", tail, 251 start_read_sector); 252 sec_off = start_read_sector-start_write_sector; 253 res = ps3flash_read_sectors(dev, 254 start_read_sector, 255 tail, sec_off); 256 if (res < 0) 257 goto fail; 258 } 259 } 260 261 n = min(remaining, dev->bounce_size-offset); 262 dev_dbg(&dev->sbd.core, 263 "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n", 264 __func__, __LINE__, n, buf, dev->bounce_buf+offset); 265 if (copy_from_user(dev->bounce_buf+offset, buf, n)) { 266 res = -EFAULT; 267 goto fail; 268 } 269 270 res = ps3flash_write_chunk(dev, start_write_sector); 271 if (res < 0) 272 goto fail; 273 274 mutex_unlock(&priv->mutex); 275 276 *pos += n; 277 buf += n; 278 remaining -= n; 279 start_write_sector += chunk_sectors; 280 head = 0; 281 offset = 0; 282 } while (remaining > 0); 283 284 return count; 285 286 fail: 287 mutex_unlock(&priv->mutex); 288 return res; 289 } 290 291 292 static irqreturn_t ps3flash_interrupt(int irq, void *data) 293 { 294 struct ps3_storage_device *dev = data; 295 int res; 296 u64 tag, status; 297 298 res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status); 299 300 if (tag != dev->tag) 301 dev_err(&dev->sbd.core, 302 "%s:%u: tag mismatch, got %lx, expected %lx\n", 303 __func__, __LINE__, tag, dev->tag); 304 305 if (res) { 306 dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n", 307 __func__, __LINE__, res, status); 308 } else { 309 dev->lv1_status = status; 310 complete(&dev->done); 311 } 312 return IRQ_HANDLED; 313 } 314 315 316 static const struct file_operations ps3flash_fops = { 317 .owner = THIS_MODULE, 318 .llseek = ps3flash_llseek, 319 .read = ps3flash_read, 320 .write = ps3flash_write, 321 }; 322 323 static struct miscdevice ps3flash_misc = { 324 .minor = MISC_DYNAMIC_MINOR, 325 .name = DEVICE_NAME, 326 .fops = &ps3flash_fops, 327 }; 328 329 static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) 330 { 331 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); 332 struct ps3flash_private *priv; 333 int error; 334 unsigned long tmp; 335 336 tmp = dev->regions[dev->region_idx].start*dev->blk_size; 337 if (tmp % FLASH_BLOCK_SIZE) { 338 dev_err(&dev->sbd.core, 339 "%s:%u region start %lu is not aligned\n", __func__, 340 __LINE__, tmp); 341 return -EINVAL; 342 } 343 tmp = dev->regions[dev->region_idx].size*dev->blk_size; 344 if (tmp % FLASH_BLOCK_SIZE) { 345 dev_err(&dev->sbd.core, 346 "%s:%u region size %lu is not aligned\n", __func__, 347 __LINE__, tmp); 348 return -EINVAL; 349 } 350 351 /* use static buffer, kmalloc cannot allocate 256 KiB */ 352 if (!ps3flash_bounce_buffer.address) 353 return -ENODEV; 354 355 if (ps3flash_dev) { 356 dev_err(&dev->sbd.core, 357 "Only one FLASH device is supported\n"); 358 return -EBUSY; 359 } 360 361 ps3flash_dev = dev; 362 363 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 364 if (!priv) { 365 error = -ENOMEM; 366 goto fail; 367 } 368 369 dev->sbd.core.driver_data = priv; 370 mutex_init(&priv->mutex); 371 372 dev->bounce_size = ps3flash_bounce_buffer.size; 373 dev->bounce_buf = ps3flash_bounce_buffer.address; 374 375 error = ps3stor_setup(dev, ps3flash_interrupt); 376 if (error) 377 goto fail_free_priv; 378 379 ps3flash_misc.parent = &dev->sbd.core; 380 error = misc_register(&ps3flash_misc); 381 if (error) { 382 dev_err(&dev->sbd.core, "%s:%u: misc_register failed %d\n", 383 __func__, __LINE__, error); 384 goto fail_teardown; 385 } 386 387 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n", 388 __func__, __LINE__, ps3flash_misc.minor); 389 return 0; 390 391 fail_teardown: 392 ps3stor_teardown(dev); 393 fail_free_priv: 394 kfree(priv); 395 dev->sbd.core.driver_data = NULL; 396 fail: 397 ps3flash_dev = NULL; 398 return error; 399 } 400 401 static int ps3flash_remove(struct ps3_system_bus_device *_dev) 402 { 403 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); 404 405 misc_deregister(&ps3flash_misc); 406 ps3stor_teardown(dev); 407 kfree(dev->sbd.core.driver_data); 408 dev->sbd.core.driver_data = NULL; 409 ps3flash_dev = NULL; 410 return 0; 411 } 412 413 414 static struct ps3_system_bus_driver ps3flash = { 415 .match_id = PS3_MATCH_ID_STOR_FLASH, 416 .core.name = DEVICE_NAME, 417 .core.owner = THIS_MODULE, 418 .probe = ps3flash_probe, 419 .remove = ps3flash_remove, 420 .shutdown = ps3flash_remove, 421 }; 422 423 424 static int __init ps3flash_init(void) 425 { 426 return ps3_system_bus_driver_register(&ps3flash); 427 } 428 429 static void __exit ps3flash_exit(void) 430 { 431 ps3_system_bus_driver_unregister(&ps3flash); 432 } 433 434 module_init(ps3flash_init); 435 module_exit(ps3flash_exit); 436 437 MODULE_LICENSE("GPL"); 438 MODULE_DESCRIPTION("PS3 FLASH ROM Storage Driver"); 439 MODULE_AUTHOR("Sony Corporation"); 440 MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_FLASH); 441