1 --- a/arch/powerpc/include/asm/ps3.h 2012-01-24 18:09:05.452290538 +0100
2 +++ b/arch/powerpc/include/asm/ps3.h 2012-01-24 18:37:24.181894425 +0100
4 PS3_MATCH_ID_SOUND = 9,
7 + PS3_MATCH_ID_STOR_NOR_FLASH = 12,
10 enum ps3_match_sub_id {
12 #define PS3_MODULE_ALIAS_GPU_FB "ps3:10:1"
13 #define PS3_MODULE_ALIAS_GPU_RAMDISK "ps3:10:2"
14 #define PS3_MODULE_ALIAS_LPM "ps3:11:0"
15 +#define PS3_MODULE_ALIAS_STOR_NOR_FLASH "ps3:12:0"
17 enum ps3_system_bus_device_type {
18 PS3_DEVICE_TYPE_IOC0 = 1,
19 --- a/arch/powerpc/platforms/ps3/platform.h 2012-01-12 20:42:45.000000000 +0100
20 +++ b/arch/powerpc/platforms/ps3/platform.h 2012-01-24 18:36:02.470631575 +0100
22 PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */
23 PS3_DEV_TYPE_SB_GPIO = 6,
24 PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */
25 + PS3_DEV_TYPE_STOR_NOR_FLASH = 254,
28 int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
29 --- a/arch/powerpc/platforms/ps3/device-init.c 2012-01-12 20:42:45.000000000 +0100
30 +++ b/arch/powerpc/platforms/ps3/device-init.c 2012-01-24 18:34:44.089470755 +0100
35 + case PS3_DEV_TYPE_STOR_NOR_FLASH:
36 + result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_NOR_FLASH);
38 + pr_debug("%s:%u ps3_setup_storage_dev failed\n",
39 + __func__, __LINE__);
44 pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
45 --- a/arch/powerpc/platforms/ps3/system-bus.c 2012-01-12 20:42:45.000000000 +0100
46 +++ b/arch/powerpc/platforms/ps3/system-bus.c 2012-01-24 19:25:53.073547395 +0100
48 case PS3_MATCH_ID_STOR_DISK:
49 case PS3_MATCH_ID_STOR_ROM:
50 case PS3_MATCH_ID_STOR_FLASH:
51 + case PS3_MATCH_ID_STOR_NOR_FLASH:
52 return ps3_open_hv_device_sb(dev);
54 case PS3_MATCH_ID_SOUND:
56 case PS3_MATCH_ID_STOR_DISK:
57 case PS3_MATCH_ID_STOR_ROM:
58 case PS3_MATCH_ID_STOR_FLASH:
59 + case PS3_MATCH_ID_STOR_NOR_FLASH:
60 return ps3_close_hv_device_sb(dev);
62 case PS3_MATCH_ID_SOUND:
63 --- a/arch/powerpc/platforms/ps3/Kconfig 2012-01-24 19:02:19.221491270 +0100
64 +++ b/arch/powerpc/platforms/ps3/Kconfig 2012-01-24 19:03:21.419302797 +0100
66 be disabled on the kernel command line using "ps3flash=off", to
67 not allocate this fixed buffer.
70 + tristate "PS3 Flash Storage Driver"
71 + depends on PPC_PS3 && BLOCK && PS3_FLASH!=y && PS3_FLASH!=m
74 + Include support for the PS3 Flash Storage.
76 + This support is required to access the PS3 flash.
77 + In general, all users will say Y or M.
80 + tristate "PS3 NOR Flash Storage Driver"
81 + depends on PPC_PS3 && BLOCK
84 + Include support for the PS3 NOR Flash Storage.
86 + This support is required to access the PS3 NOR flash.
87 + In general, all users will say Y or M.
90 tristate "PS3 Video RAM Storage Driver"
91 depends on FB_PS3=y && BLOCK && m
92 --- a/drivers/block/Makefile 2012-01-24 19:02:39.908639282 +0100
93 +++ b/drivers/block/Makefile 2012-01-24 18:32:56.294515362 +0100
95 obj-$(CONFIG_BLK_DEV_FD) += floppy.o
96 obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
97 obj-$(CONFIG_PS3_DISK) += ps3disk.o
98 +obj-$(CONFIG_PS3_FLASH_NG) += ps3flash.o
99 +obj-$(CONFIG_PS3_NOR_FLASH) += ps3nflash.o
100 obj-$(CONFIG_PS3_VRAM) += ps3vram.o
101 obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
102 obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
103 --- /dev/null 2012-11-28 15:48:49.557690341 +0100
104 +++ b/drivers/block/ps3flash.c 2013-02-14 11:18:29.076533279 +0100
107 + * PS3 Flash Storage Driver
109 + * Copyright (C) 2007 Sony Computer Entertainment Inc.
110 + * Copyright 2007 Sony Corp.
111 + * Copyright (C) 2011 graf_chokolo <grafchokolo@gmail.com>.
112 + * Copyright (C) 2011-2013 glevand <geoffrey.levand@mail.ru>.
114 + * This program is free software; you can redistribute it and/or modify it
115 + * under the terms of the GNU General Public License as published
116 + * by the Free Software Foundation; version 2 of the License.
118 + * This program is distributed in the hope that it will be useful, but
119 + * WITHOUT ANY WARRANTY; without even the implied warranty of
120 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
121 + * General Public License for more details.
123 + * You should have received a copy of the GNU General Public License along
124 + * with this program; if not, write to the Free Software Foundation, Inc.,
125 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
128 +#include <linux/blkdev.h>
129 +#include <linux/slab.h>
130 +#include <linux/module.h>
132 +#include <asm/lv1call.h>
133 +#include <asm/ps3stor.h>
134 +#include <asm/firmware.h>
137 +#define DEVICE_NAME "ps3flash"
139 +#define BOUNCE_SIZE (64*1024)
141 +#define PS3FLASH_MAX_NUM_REGS 8
143 +#define PS3FLASH_MINORS 16
146 +#define PS3FLASH_NAME "ps3flash%c"
149 +struct ps3flash_private {
150 + spinlock_t lock; /* Request queue spinlock */
151 + unsigned int blocking_factor;
152 + struct request *req;
155 + struct gendisk *gendisk[PS3FLASH_MAX_NUM_REGS];
156 + struct request_queue *queue[PS3FLASH_MAX_NUM_REGS];
161 +#define LV1_STORAGE_ATA_FLUSH_CACHE_EXT (0x31)
164 +static int ps3flash_major;
167 +static const struct block_device_operations ps3flash_fops = {
168 + .owner = THIS_MODULE,
171 +static unsigned int region_flags[] =
173 + 0x6, 0x2, 0x4, 0x4, 0x4, 0x0, 0x2, 0x0,
175 +module_param_array(region_flags, uint, NULL, S_IRUGO);
176 +MODULE_PARM_DESC(region_flags, "Region flags");
179 +static void ps3flash_scatter_gather(struct ps3_storage_device *dev,
180 + struct request *req, int gather)
182 + unsigned int offset = 0;
183 + struct req_iterator iter;
184 + struct bio_vec bvec;
185 + unsigned int i = 0;
189 + rq_for_each_segment(bvec, req, iter) {
190 + unsigned long flags;
191 + dev_dbg(&dev->sbd.core,
192 + "%s:%u: bio %u: %u segs %u sectors from %lu\n",
193 + __func__, __LINE__, i, bio_segments(iter.bio),
194 + bio_sectors(iter.bio), iter.bio->bi_iter.bi_sector);
196 + size = bvec.bv_len;
197 + buf = bvec_kmap_irq(&bvec, &flags);
199 + memcpy(dev->bounce_buf+offset, buf, size);
201 + memcpy(buf, dev->bounce_buf+offset, size);
203 + flush_kernel_dcache_page(bvec.bv_page);
204 + bvec_kunmap_irq(buf, &flags);
209 +static int ps3flash_submit_request_sg(struct ps3_storage_device *dev,
210 + struct request *req)
212 + struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
213 + int write = rq_data_dir(req), res;
214 + const char *op = write ? "write" : "read";
215 + u64 start_sector, sectors;
216 + unsigned int region_idx = MINOR(disk_devt(req->rq_disk)) / PS3FLASH_MINORS;
217 + unsigned int region_id = dev->regions[region_idx].id;
218 + unsigned int region_flags = dev->regions[region_idx].flags;
221 + unsigned int n = 0;
223 + struct req_iterator iter;
225 + rq_for_each_segment(bv, req, iter)
227 + dev_dbg(&dev->sbd.core,
228 + "%s:%u: %s req has %u bvecs for %u sectors\n",
229 + __func__, __LINE__, op, n, blk_rq_sectors(req));
232 + start_sector = blk_rq_pos(req) * priv->blocking_factor;
233 + sectors = blk_rq_sectors(req) * priv->blocking_factor;
234 + dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
235 + __func__, __LINE__, op, sectors, start_sector);
238 + ps3flash_scatter_gather(dev, req, 1);
240 + res = lv1_storage_write(dev->sbd.dev_id, region_id,
241 + start_sector, sectors, region_flags,
242 + dev->bounce_lpar, &dev->tag);
244 + res = lv1_storage_read(dev->sbd.dev_id, region_id,
245 + start_sector, sectors, region_flags,
246 + dev->bounce_lpar, &dev->tag);
249 + dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
250 + __LINE__, op, res);
251 + __blk_end_request_all(req, -EIO);
259 +static int ps3flash_submit_flush_request(struct ps3_storage_device *dev,
260 + struct request *req)
262 + struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
265 + dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__);
267 + res = lv1_storage_send_device_command(dev->sbd.dev_id,
268 + LV1_STORAGE_ATA_FLUSH_CACHE_EXT, 0, 0, 0,
271 + dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
272 + __func__, __LINE__, res);
273 + __blk_end_request_all(req, -EIO);
281 +static void ps3flash_do_request(struct ps3_storage_device *dev,
282 + struct request_queue *q)
284 + struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
285 + struct request *req;
287 + dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
289 + while ((req = blk_fetch_request(q))) {
290 + if (priv->is_vflash && (req->cmd_flags & REQ_FLUSH)) {
291 + if (ps3flash_submit_flush_request(dev, req))
293 + } else if (req->cmd_type == REQ_TYPE_FS) {
294 + if (ps3flash_submit_request_sg(dev, req))
297 + blk_dump_rq_flags(req, DEVICE_NAME " bad request");
298 + __blk_end_request_all(req, -EIO);
304 +static void ps3flash_request(struct request_queue *q)
306 + struct ps3_storage_device *dev = q->queuedata;
307 + struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
310 + dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
314 + ps3flash_do_request(dev, q);
317 +static irqreturn_t ps3flash_interrupt(int irq, void *data)
319 + struct ps3_storage_device *dev = data;
320 + struct ps3flash_private *priv;
321 + struct request *req;
322 + int res, read, error;
325 + struct request_queue *q;
328 + res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
330 + if (tag != dev->tag)
331 + dev_err(&dev->sbd.core,
332 + "%s:%u: tag mismatch, got %llx, expected %llx\n",
333 + __func__, __LINE__, tag, dev->tag);
336 + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
337 + __func__, __LINE__, res, status);
338 + return IRQ_HANDLED;
341 + priv = ps3_system_bus_get_drvdata(&dev->sbd);
344 + dev_dbg(&dev->sbd.core,
345 + "%s:%u non-block layer request completed\n", __func__,
347 + dev->lv1_status = status;
348 + complete(&dev->done);
349 + return IRQ_HANDLED;
352 + if (req->cmd_flags & REQ_FLUSH) {
356 + read = !rq_data_dir(req);
357 + op = read ? "read" : "write";
360 + dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
361 + __LINE__, op, status);
364 + dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
368 + ps3flash_scatter_gather(dev, req, 0);
371 + spin_lock(&priv->lock);
372 + __blk_end_request_all(req, error);
374 + old_queue = priv->next_queue;
376 + q = priv->queue[priv->next_queue];
378 + priv->next_queue++;
379 + if (priv->next_queue >= dev->num_regions)
380 + priv->next_queue = 0;
383 + ps3flash_do_request(dev, q);
387 + } while (old_queue != priv->next_queue);
388 + spin_unlock(&priv->lock);
390 + return IRQ_HANDLED;
393 +static int ps3flash_sync_cache(struct ps3_storage_device *dev)
397 + dev_dbg(&dev->sbd.core, "%s:%u: sync cache\n", __func__, __LINE__);
399 + res = ps3stor_send_command(dev, LV1_STORAGE_ATA_FLUSH_CACHE_EXT, 0, 0, 0, 0);
401 + dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
402 + __func__, __LINE__, res);
408 +static int ps3flash_probe(struct ps3_system_bus_device *_dev)
410 + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
411 + struct ps3flash_private *priv;
413 + unsigned int regidx, devidx;
414 + u64 lpar_id, flash_ext_flag, junk;
415 + struct request_queue *queue;
416 + struct gendisk *gendisk;
418 + BUG_ON(dev->num_regions > PS3FLASH_MAX_NUM_REGS);
420 + if (dev->blk_size < 512) {
421 + dev_err(&dev->sbd.core,
422 + "%s:%u: cannot handle block size %llu\n", __func__,
423 + __LINE__, dev->blk_size);
427 + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
433 + ps3_system_bus_set_drvdata(_dev, priv);
434 + spin_lock_init(&priv->lock);
436 + dev->bounce_size = BOUNCE_SIZE;
437 + dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
438 + if (!dev->bounce_buf) {
440 + goto fail_free_priv;
443 + for (regidx = 0; regidx < dev->num_regions; regidx++)
444 + dev->regions[regidx].flags = region_flags[regidx];
446 + error = ps3stor_setup(dev, ps3flash_interrupt);
448 + goto fail_free_bounce;
450 + priv->raw_capacity = dev->regions[0].size;
452 + error = lv1_get_logical_partition_id(&lpar_id);
454 + goto fail_teardown;
456 + error = lv1_read_repository_node(1, 0x0000000073797300ul /* sys */,
457 + 0x666c617368000000ul /* flash */,
458 + 0x6578740000000000ul /* ext */,
459 + 0, &flash_ext_flag, &junk);
461 + goto fail_teardown;
463 + priv->is_vflash = !(flash_ext_flag & 0x1);
465 + dev_info(&dev->sbd.core, "VFLASH is %s\n",
466 + priv->is_vflash ? "on" : "off");
468 + for (devidx = 0; devidx < dev->num_regions; devidx++)
470 + if (test_bit(devidx, &dev->accessible_regions) == 0)
473 + queue = blk_init_queue(ps3flash_request, &priv->lock);
475 + dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n",
476 + __func__, __LINE__);
481 + priv->queue[devidx] = queue;
482 + queue->queuedata = dev;
484 + blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
486 + blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
487 + blk_queue_segment_boundary(queue, -1UL);
488 + blk_queue_dma_alignment(queue, dev->blk_size-1);
489 + blk_queue_logical_block_size(queue, dev->blk_size);
491 + blk_queue_flush(queue, REQ_FLUSH);
493 + blk_queue_max_segments(queue, -1);
494 + blk_queue_max_segment_size(queue, dev->bounce_size);
496 + gendisk = alloc_disk(PS3FLASH_MINORS);
498 + dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n", __func__,
504 + priv->gendisk[devidx] = gendisk;
505 + gendisk->major = ps3flash_major;
506 + gendisk->first_minor = devidx * PS3FLASH_MINORS;
507 + gendisk->fops = &ps3flash_fops;
508 + gendisk->queue = queue;
509 + gendisk->private_data = dev;
510 + gendisk->driverfs_dev = &dev->sbd.core;
511 + snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3FLASH_NAME,
513 + priv->blocking_factor = dev->blk_size >> 9;
514 + set_capacity(gendisk,
515 + dev->regions[devidx].size*priv->blocking_factor);
517 + dev_info(&dev->sbd.core,
518 + "%s (%llu MiB total, %lu MiB region)\n",
519 + gendisk->disk_name, priv->raw_capacity >> 11,
520 + get_capacity(gendisk) >> 11);
528 + for (devidx = 0; devidx < dev->num_regions; devidx++)
530 + if (priv->gendisk[devidx]) {
531 + del_gendisk(priv->gendisk[devidx]);
532 + put_disk(priv->gendisk[devidx]);
535 + if (priv->queue[devidx])
536 + blk_cleanup_queue(priv->queue[devidx]);
539 + ps3stor_teardown(dev);
541 + kfree(dev->bounce_buf);
544 + ps3_system_bus_set_drvdata(_dev, NULL);
549 +static int ps3flash_remove(struct ps3_system_bus_device *_dev)
551 + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
552 + struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
553 + unsigned int devidx;
555 + for (devidx = 0; devidx < dev->num_regions; devidx++)
557 + if (priv->gendisk[devidx]) {
558 + del_gendisk(priv->gendisk[devidx]);
559 + put_disk(priv->gendisk[devidx]);
562 + if (priv->queue[devidx])
563 + blk_cleanup_queue(priv->queue[devidx]);
566 + if (priv->is_vflash) {
567 + dev_notice(&dev->sbd.core, "Synchronizing disk cache\n");
568 + ps3flash_sync_cache(dev);
571 + ps3stor_teardown(dev);
572 + kfree(dev->bounce_buf);
574 + ps3_system_bus_set_drvdata(_dev, NULL);
578 +static struct ps3_system_bus_driver ps3flash = {
579 + .match_id = PS3_MATCH_ID_STOR_FLASH,
580 + .core.name = DEVICE_NAME,
581 + .core.owner = THIS_MODULE,
582 + .probe = ps3flash_probe,
583 + .remove = ps3flash_remove,
584 + .shutdown = ps3flash_remove,
588 +static int __init ps3flash_init(void)
592 + if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
595 + error = register_blkdev(0, DEVICE_NAME);
597 + printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__,
601 + ps3flash_major = error;
603 + pr_info("%s:%u: registered block device major %d\n", __func__,
604 + __LINE__, ps3flash_major);
606 + error = ps3_system_bus_driver_register(&ps3flash);
608 + unregister_blkdev(ps3flash_major, DEVICE_NAME);
613 +static void __exit ps3flash_exit(void)
615 + ps3_system_bus_driver_unregister(&ps3flash);
616 + unregister_blkdev(ps3flash_major, DEVICE_NAME);
619 +module_init(ps3flash_init);
620 +module_exit(ps3flash_exit);
622 +MODULE_LICENSE("GPL");
623 +MODULE_DESCRIPTION("PS3 Flash Storage Driver");
624 +MODULE_AUTHOR("Sony Corporation");
625 +MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_FLASH);
626 --- /dev/null 2013-02-15 18:37:48.373100583 +0100
627 +++ b/drivers/block/ps3nflash.c 2013-02-15 23:15:44.710737431 +0100
630 + * PS3 Flash Storage Driver
632 + * Copyright (C) 2007 Sony Computer Entertainment Inc.
633 + * Copyright 2007 Sony Corp.
634 + * Copyright (C) 2011 graf_chokolo <grafchokolo@gmail.com>.
635 + * Copyright (C) 2011-2013 glevand <geoffrey.levand@mail.ru>.
637 + * This program is free software; you can redistribute it and/or modify it
638 + * under the terms of the GNU General Public License as published
639 + * by the Free Software Foundation; version 2 of the License.
641 + * This program is distributed in the hope that it will be useful, but
642 + * WITHOUT ANY WARRANTY; without even the implied warranty of
643 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
644 + * General Public License for more details.
646 + * You should have received a copy of the GNU General Public License along
647 + * with this program; if not, write to the Free Software Foundation, Inc.,
648 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
651 +#include <linux/blkdev.h>
652 +#include <linux/slab.h>
653 +#include <linux/module.h>
655 +#include <asm/lv1call.h>
656 +#include <asm/ps3stor.h>
657 +#include <asm/firmware.h>
660 +#define DEVICE_NAME "ps3nflash"
662 +#define BOUNCE_SIZE (64*1024)
664 +#define PS3NFLASH_MAX_NUM_REGS 8
666 +#define PS3NFLASH_MINORS 16
669 +#define PS3NFLASH_NAME "ps3nflash%c"
672 +struct ps3nflash_private {
673 + spinlock_t lock; /* Request queue spinlock */
674 + unsigned int blocking_factor;
675 + struct request *req;
677 + struct gendisk *gendisk[PS3NFLASH_MAX_NUM_REGS];
678 + struct request_queue *queue[PS3NFLASH_MAX_NUM_REGS];
683 +static int ps3nflash_major;
686 +static const struct block_device_operations ps3nflash_fops = {
687 + .owner = THIS_MODULE,
690 +static unsigned int region_flags[] =
692 + 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0,
694 +module_param_array(region_flags, uint, NULL, S_IRUGO);
695 +MODULE_PARM_DESC(region_flags, "Region flags");
698 +static void ps3nflash_scatter_gather(struct ps3_storage_device *dev,
699 + struct request *req, int gather)
701 + unsigned int offset = 0;
702 + struct req_iterator iter;
703 + struct bio_vec bvec;
704 + unsigned int i = 0;
708 + rq_for_each_segment(bvec, req, iter) {
709 + unsigned long flags;
710 + dev_dbg(&dev->sbd.core,
711 + "%s:%u: bio %u: %u segs %u sectors from %lu\n",
712 + __func__, __LINE__, i, bio_segments(iter.bio),
713 + bio_sectors(iter.bio), iter.bio->bi_iter.bi_sector);
715 + size = bvec.bv_len;
716 + buf = bvec_kmap_irq(&bvec, &flags);
718 + memcpy(dev->bounce_buf+offset, buf, size);
720 + memcpy(buf, dev->bounce_buf+offset, size);
722 + flush_kernel_dcache_page(bvec.bv_page);
723 + bvec_kunmap_irq(buf, &flags);
728 +static int ps3nflash_submit_request_sg(struct ps3_storage_device *dev,
729 + struct request *req)
731 + struct ps3nflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
732 + int write = rq_data_dir(req), res;
733 + const char *op = write ? "write" : "read";
734 + u64 start_sector, sectors;
735 + unsigned int region_idx = MINOR(disk_devt(req->rq_disk)) / PS3NFLASH_MINORS;
736 + unsigned int region_id = dev->regions[region_idx].id;
737 + unsigned int region_flags = dev->regions[region_idx].flags;
740 + unsigned int n = 0;
742 + struct req_iterator iter;
744 + rq_for_each_segment(bv, req, iter)
746 + dev_dbg(&dev->sbd.core,
747 + "%s:%u: %s req has %u bvecs for %u sectors\n",
748 + __func__, __LINE__, op, n, blk_rq_sectors(req));
751 + start_sector = blk_rq_pos(req) * priv->blocking_factor;
752 + sectors = blk_rq_sectors(req) * priv->blocking_factor;
753 + dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
754 + __func__, __LINE__, op, sectors, start_sector);
757 + ps3nflash_scatter_gather(dev, req, 1);
759 + res = lv1_storage_write(dev->sbd.dev_id, region_id,
760 + start_sector, sectors, region_flags,
761 + dev->bounce_lpar, &dev->tag);
763 + res = lv1_storage_read(dev->sbd.dev_id, region_id,
764 + start_sector, sectors, region_flags,
765 + dev->bounce_lpar, &dev->tag);
768 + dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
769 + __LINE__, op, res);
770 + __blk_end_request_all(req, -EIO);
778 +static void ps3nflash_do_request(struct ps3_storage_device *dev,
779 + struct request_queue *q)
781 + struct request *req;
783 + dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
785 + while ((req = blk_fetch_request(q))) {
786 + if (req->cmd_type == REQ_TYPE_FS) {
787 + if (ps3nflash_submit_request_sg(dev, req))
790 + blk_dump_rq_flags(req, DEVICE_NAME " bad request");
791 + __blk_end_request_all(req, -EIO);
797 +static void ps3nflash_request(struct request_queue *q)
799 + struct ps3_storage_device *dev = q->queuedata;
800 + struct ps3nflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
803 + dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
807 + ps3nflash_do_request(dev, q);
810 +static irqreturn_t ps3nflash_interrupt(int irq, void *data)
812 + struct ps3_storage_device *dev = data;
813 + struct ps3nflash_private *priv;
814 + struct request *req;
815 + int res, read, error;
818 + struct request_queue *q;
821 + res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
823 + if (tag != dev->tag)
824 + dev_err(&dev->sbd.core,
825 + "%s:%u: tag mismatch, got %llx, expected %llx\n",
826 + __func__, __LINE__, tag, dev->tag);
829 + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
830 + __func__, __LINE__, res, status);
831 + return IRQ_HANDLED;
834 + priv = ps3_system_bus_get_drvdata(&dev->sbd);
837 + dev_dbg(&dev->sbd.core,
838 + "%s:%u non-block layer request completed\n", __func__,
840 + dev->lv1_status = status;
841 + complete(&dev->done);
842 + return IRQ_HANDLED;
845 + read = !rq_data_dir(req);
846 + op = read ? "read" : "write";
849 + dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
850 + __LINE__, op, status);
853 + dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
857 + ps3nflash_scatter_gather(dev, req, 0);
860 + spin_lock(&priv->lock);
861 + __blk_end_request_all(req, error);
863 + old_queue = priv->next_queue;
865 + q = priv->queue[priv->next_queue];
867 + priv->next_queue++;
868 + if (priv->next_queue >= dev->num_regions)
869 + priv->next_queue = 0;
872 + ps3nflash_do_request(dev, q);
876 + } while (old_queue != priv->next_queue);
877 + spin_unlock(&priv->lock);
879 + return IRQ_HANDLED;
882 +static int ps3nflash_probe(struct ps3_system_bus_device *_dev)
884 + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
885 + struct ps3nflash_private *priv;
887 + unsigned int regidx, devidx;
888 + struct request_queue *queue;
889 + struct gendisk *gendisk;
891 + BUG_ON(dev->num_regions > PS3NFLASH_MAX_NUM_REGS);
893 + if (dev->blk_size < 512) {
894 + dev_err(&dev->sbd.core,
895 + "%s:%u: cannot handle block size %llu\n", __func__,
896 + __LINE__, dev->blk_size);
900 + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
906 + ps3_system_bus_set_drvdata(_dev, priv);
907 + spin_lock_init(&priv->lock);
909 + dev->bounce_size = BOUNCE_SIZE;
910 + dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
911 + if (!dev->bounce_buf) {
913 + goto fail_free_priv;
916 + for (regidx = 0; regidx < dev->num_regions; regidx++)
917 + dev->regions[regidx].flags = region_flags[regidx];
919 + error = ps3stor_setup(dev, ps3nflash_interrupt);
921 + goto fail_free_bounce;
923 + priv->raw_capacity = dev->regions[0].size;
925 + for (devidx = 0; devidx < dev->num_regions; devidx++)
927 + if (test_bit(devidx, &dev->accessible_regions) == 0)
930 + queue = blk_init_queue(ps3nflash_request, &priv->lock);
932 + dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n",
933 + __func__, __LINE__);
938 + priv->queue[devidx] = queue;
939 + queue->queuedata = dev;
941 + blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
943 + blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
944 + blk_queue_segment_boundary(queue, -1UL);
945 + blk_queue_dma_alignment(queue, dev->blk_size-1);
946 + blk_queue_logical_block_size(queue, dev->blk_size);
948 + blk_queue_flush(queue, REQ_FLUSH);
950 + blk_queue_max_segments(queue, -1);
951 + blk_queue_max_segment_size(queue, dev->bounce_size);
953 + gendisk = alloc_disk(PS3NFLASH_MINORS);
955 + dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n", __func__,
961 + priv->gendisk[devidx] = gendisk;
962 + gendisk->major = ps3nflash_major;
963 + gendisk->first_minor = devidx * PS3NFLASH_MINORS;
964 + gendisk->fops = &ps3nflash_fops;
965 + gendisk->queue = queue;
966 + gendisk->private_data = dev;
967 + gendisk->driverfs_dev = &dev->sbd.core;
968 + snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3NFLASH_NAME,
970 + priv->blocking_factor = dev->blk_size >> 9;
971 + set_capacity(gendisk,
972 + dev->regions[devidx].size*priv->blocking_factor);
974 + dev_info(&dev->sbd.core,
975 + "%s (%llu MiB total, %lu MiB region)\n",
976 + gendisk->disk_name, priv->raw_capacity >> 11,
977 + get_capacity(gendisk) >> 11);
985 + for (devidx = 0; devidx < dev->num_regions; devidx++)
987 + if (priv->gendisk[devidx]) {
988 + del_gendisk(priv->gendisk[devidx]);
989 + put_disk(priv->gendisk[devidx]);
992 + if (priv->queue[devidx])
993 + blk_cleanup_queue(priv->queue[devidx]);
995 + ps3stor_teardown(dev);
997 + kfree(dev->bounce_buf);
1000 + ps3_system_bus_set_drvdata(_dev, NULL);
1005 +static int ps3nflash_remove(struct ps3_system_bus_device *_dev)
1007 + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
1008 + struct ps3nflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
1009 + unsigned int devidx;
1011 + for (devidx = 0; devidx < dev->num_regions; devidx++)
1013 + if (priv->gendisk[devidx]) {
1014 + del_gendisk(priv->gendisk[devidx]);
1015 + put_disk(priv->gendisk[devidx]);
1018 + if (priv->queue[devidx])
1019 + blk_cleanup_queue(priv->queue[devidx]);
1022 + ps3stor_teardown(dev);
1023 + kfree(dev->bounce_buf);
1025 + ps3_system_bus_set_drvdata(_dev, NULL);
1029 +static struct ps3_system_bus_driver ps3nflash = {
1030 + .match_id = PS3_MATCH_ID_STOR_NOR_FLASH,
1031 + .core.name = DEVICE_NAME,
1032 + .core.owner = THIS_MODULE,
1033 + .probe = ps3nflash_probe,
1034 + .remove = ps3nflash_remove,
1035 + .shutdown = ps3nflash_remove,
1039 +static int __init ps3nflash_init(void)
1043 + if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
1046 + error = register_blkdev(0, DEVICE_NAME);
1048 + printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__,
1052 + ps3nflash_major = error;
1054 + pr_info("%s:%u: registered block device major %d\n", __func__,
1055 + __LINE__, ps3nflash_major);
1057 + error = ps3_system_bus_driver_register(&ps3nflash);
1059 + unregister_blkdev(ps3nflash_major, DEVICE_NAME);
1064 +static void __exit ps3nflash_exit(void)
1066 + ps3_system_bus_driver_unregister(&ps3nflash);
1067 + unregister_blkdev(ps3nflash_major, DEVICE_NAME);
1070 +module_init(ps3nflash_init);
1071 +module_exit(ps3nflash_exit);
1073 +MODULE_LICENSE("GPL");
1074 +MODULE_DESCRIPTION("PS3 NOR Flash Storage Driver");
1075 +MODULE_AUTHOR("Sony Corporation");
1076 +MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_NOR_FLASH);