Guest User

PS3 STEP 3 Sony a New Hacking Dev

a guest
Sep 30th, 2012
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.38 KB | None | 0 0
  1. Step 3 :
  2.  
  3. Welcome to the world of Sony
  4.  
  5. I just want to say a hello to Geo (no the one you are thinking) and tell him that
  6.  
  7. Remember 2OFive ? Are you making a new dongle, the first commercial one was not enough ? Sony Still keep the dongle plan alive (win money with commercial hacking/piracy) ? SONY MAKE.BELIEVE PIRACY ;)
  8.  
  9. Anyway
  10.  
  11. Back to the past
  12.  
  13. +#define DEVICE_NAME "ps3disk"
  14. +
  15. +#define BOUNCE_SIZE (64*1024)
  16. +
  17. +#define PS3DISK_MAX_DISKS 16
  18. +#define PS3DISK_MINORS 16
  19. +
  20. +#define KERNEL_SECTOR_SIZE 512
  21. +
  22. +
  23. +#define PS3DISK_NAME "ps3d%c"
  24. +
  25. +
  26. +struct ps3disk_private {
  27. + spinlock_t lock; /* Request queue spinlock */
  28. + struct request_queue *queue;
  29. + struct gendisk *gendisk;
  30. + unsigned int blocking_factor;
  31. + struct request *req;
  32. + u64 raw_capacity;
  33. + unsigned char model[ATA_ID_PROD_LEN+1];
  34. +};
  35. +#define ps3disk_priv(dev) ((dev)->sbd.core.driver_data)
  36. +
  37. +
  38. +#define LV1_STORAGE_SEND_ATA_COMMAND (2)
  39. +#define LV1_STORAGE_ATA_HDDOUT (0x23)
  40. +
  41. +struct lv1_ata_cmnd_block {
  42. + u16 features;
  43. + u16 sector_count;
  44. + u16 LBA_low;
  45. + u16 LBA_mid;
  46. + u16 LBA_high;
  47. + u8 device;
  48. + u8 command;
  49. + u32 is_ext;
  50. + u32 proto;
  51. + u32 in_out;
  52. + u32 size;
  53. + u64 buffer;
  54. + u32 arglen;
  55. +};
  56. +
  57. +enum lv1_ata_proto {
  58. + NON_DATA_PROTO = 0,
  59. + PIO_DATA_IN_PROTO = 1,
  60. + PIO_DATA_OUT_PROTO = 2,
  61. + DMA_PROTO = 3
  62. +};
  63. +
  64. +enum lv1_ata_in_out {
  65. + DIR_WRITE = 0, /* memory -> device */
  66. + DIR_READ = 1 /* device -> memory */
  67. +};
  68. +
  69. +static int ps3disk_major;
  70. +
  71. +
  72. +static struct block_device_operations ps3disk_fops = {
  73. + .owner = THIS_MODULE,
  74. +};
  75. +
  76. +
  77. +static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
  78. + struct request *req, int gather)
  79. +{
  80. + unsigned int sectors = 0, offset = 0;
  81. + struct bio *bio;
  82. + sector_t sector;
  83. + struct bio_vec *bvec;
  84. + unsigned int i = 0, j;
  85. + size_t size;
  86. + void *buf;
  87. +
  88. + rq_for_each_bio(bio, req) {
  89. + sector = bio->bi_sector;
  90. + dev_dbg(&dev->sbd.core,
  91. + "%s:%u: bio %u: %u segs %u sectors from %lu\n",
  92. + __func__, __LINE__, i, bio_segments(bio),
  93. + bio_sectors(bio), sector);
  94. + bio_for_each_segment(bvec, bio, j) {
  95. + size = bio_cur_sectors(bio)*KERNEL_SECTOR_SIZE;
  96. + buf = __bio_kmap_atomic(bio, j, KM_IRQ0);
  97. + if (gather)
  98. + memcpy(dev->bounce_buf+offset, buf, size);
  99. + else
  100. + memcpy(buf, dev->bounce_buf+offset, size);
  101. + offset += size;
  102. + flush_kernel_dcache_page(bio_iovec_idx(bio, j)->bv_page);
  103. + __bio_kunmap_atomic(bio, KM_IRQ0);
  104. + }
  105. + sectors += bio_sectors(bio);
  106. + i++;
  107. + }
  108. +}
  109. +
  110. +static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
  111. + struct request *req)
  112. +{
  113. + struct ps3disk_private *priv = ps3disk_priv(dev);
  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 *bio;
  122. + rq_for_each_bio(bio, req)
  123. + n++;
  124. + dev_dbg(&dev->sbd.core,
  125. + "%s:%u: %s req has %u bios for %lu sectors %lu hard sectors\n",
  126. + __func__, __LINE__, op, n, req->nr_sectors,
  127. + req->hard_nr_sectors);
  128. +#endif
  129. +
  130. + start_sector = req->sector*priv->blocking_factor;
  131. + sectors = req->nr_sectors*priv->blocking_factor;
  132. + dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n",
  133. + __func__, __LINE__, op, sectors, start_sector);
  134. +
  135. + if (write) {
  136. + ps3disk_scatter_gather(dev, req, 1);
  137. +
  138. + res = lv1_storage_write(dev->sbd.dev_id, region_id,
  139. + start_sector, sectors, 0,
  140. + dev->bounce_lpar, &dev->tag);
  141. + } else {
  142. + res = lv1_storage_read(dev->sbd.dev_id, region_id,
  143. + start_sector, sectors, 0,
  144. + dev->bounce_lpar, &dev->tag);
  145. + }
  146. + if (res) {
  147. + dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
  148. + __LINE__, op, res);
  149. + end_request(req, 0);
  150. + return 0;
  151. + }
  152. +
  153. + priv->req = req;
  154. + return 1;
  155. +}
  156. +
  157. +static int ps3disk_submit_flush_request(struct ps3_storage_device *dev,
  158. + struct request *req)
  159. +{
  160. + struct ps3disk_private *priv = ps3disk_priv(dev);
  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%lx\n",
  170. + __func__, __LINE__, res);
  171. + end_request(req, 0);
  172. + return 0;
  173. + }
  174. +
  175. + priv->req = req;
  176. + return 1;
  177. +}
  178. +
  179. +static void ps3disk_do_request(struct ps3_storage_device *dev,
  180. + request_queue_t *q)
  181. +{
  182. + struct request *req;
  183. +
  184. + dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
  185. +
  186. + while ((req = elv_next_request(q))) {
  187. + if (blk_fs_request(req)) {
  188. + if (ps3disk_submit_request_sg(dev, req))
  189. + break;
  190. + } else if (req->cmd_type == REQ_TYPE_FLUSH) {
  191. + if (ps3disk_submit_flush_request(dev, req))
  192. + break;
  193. + } else {
  194. + blk_dump_rq_flags(req, DEVICE_NAME " bad request");
  195. + end_request(req, 0);
  196. + continue;
  197. + }
  198. + }
  199. +}
  200. +
  201. +static void ps3disk_request(request_queue_t *q)
  202. +{
  203. + struct ps3_storage_device *dev = q->queuedata;
  204. + struct ps3disk_private *priv = ps3disk_priv(dev);
  205. +
  206. + if (priv->req) {
  207. + dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
  208. + return;
  209. + }
  210. +
  211. + ps3disk_do_request(dev, q);
  212. +}
  213. +
  214. +static irqreturn_t ps3disk_interrupt(int irq, void *data)
  215. +{
  216. + struct ps3_storage_device *dev = data;
  217. + struct ps3disk_private *priv;
  218. + struct request *req;
  219. + int res, read, uptodate;
  220. + u64 tag, status;
  221. + unsigned long num_sectors;
  222. + const char *op;
  223. +
  224. + res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
  225. +
  226. + if (tag != dev->tag)
  227. + dev_err(&dev->sbd.core,
  228. + "%s:%u: tag mismatch, got %lx, expected %lx\n",
  229. + __func__, __LINE__, tag, dev->tag);
  230. +
  231. + if (res) {
  232. + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
  233. + __func__, __LINE__, res, status);
  234. + return IRQ_HANDLED;
  235. + }
  236. +
  237. + priv = ps3disk_priv(dev);
  238. + req = priv->req;
  239. + if (!req) {
  240. + dev_dbg(&dev->sbd.core,
  241. + "%s:%u non-block layer request completed\n", __func__,
  242. + __LINE__);
  243. + dev->lv1_status = status;
  244. + complete(&dev->done);
  245. + return IRQ_HANDLED;
  246. + }
  247. +
  248. + if (req->cmd_type == REQ_TYPE_FLUSH) {
  249. + read = 0;
  250. + num_sectors = req->hard_cur_sectors;
  251. + op = "flush";
  252. + } else {
  253. + read = !rq_data_dir(req);
  254. + num_sectors = req->nr_sectors;
  255. + op = read ? "read" : "write";
  256. + }
  257. + if (status) {
  258. + dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
  259. + __LINE__, op, status);
  260. + uptodate = 0;
  261. + } else {
  262. + dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
  263. + __LINE__, op);
  264. + uptodate = 1;
  265. + if (read)
  266. + ps3disk_scatter_gather(dev, req, 0);
  267. + }
  268. +
  269. + spin_lock(&priv->lock);
  270. + if (!end_that_request_first(req, uptodate, num_sectors)) {
  271. + add_disk_randomness(req->rq_disk);
  272. + blkdev_dequeue_request(req);
  273. + end_that_request_last(req, uptodate);
  274. + }
  275. + priv->req = NULL;
  276. + ps3disk_do_request(dev, priv->queue);
  277. + spin_unlock(&priv->lock);
  278. +
  279. + return IRQ_HANDLED;
  280. +}
  281. +
  282. +static int ps3disk_sync_cache(struct ps3_storage_device *dev)
  283. +{
  284. + u64 res;
  285. +
  286. + dev_dbg(&dev->sbd.core, "%s:%u: sync cache\n", __func__, __LINE__);
  287. +
  288. + res = ps3stor_send_command(dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0);
  289. + if (res) {
  290. + dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n",
  291. + __func__, __LINE__, res);
  292. + return -EIO;
  293. + }
  294. + return 0;
  295. +}
  296. +
  297. +
  298. +/* ATA helpers copied from drivers/ata/libata-core.c */
  299. +
  300. +static void swap_buf_le16(u16 *buf, unsigned int buf_words)
  301. +{
  302. +#ifdef __BIG_ENDIAN
  303. + unsigned int i;
  304. +
  305. + for (i = 0; i < buf_words; i++)
  306. + buf[i] = le16_to_cpu(buf[i]);
  307. +#endif /* __BIG_ENDIAN */
  308. +}
  309. +
  310. +static u64 ata_id_n_sectors(const u16 *id)
  311. +{
  312. + if (ata_id_has_lba(id)) {
  313. + if (ata_id_has_lba48(id))
  314. + return ata_id_u64(id, 100);
  315. + else
  316. + return ata_id_u32(id, 60);
  317. + } else {
  318. + if (ata_id_current_chs_valid(id))
  319. + return ata_id_u32(id, 57);
  320. + else
  321. + return id[1] * id[3] * id[6];
  322. + }
  323. +}
  324. +
  325. +static void ata_id_string(const u16 *id, unsigned char *s, unsigned int ofs,
  326. + unsigned int len)
  327. +{
  328. + unsigned int c;
  329. +
  330. + while (len > 0) {
  331. + c = id[ofs] >> 8;
  332. + *s = c;
  333. + s++;
  334. +
  335. + c = id[ofs] & 0xff;
  336. + *s = c;
  337. + s++;
  338. +
  339. + ofs++;
  340. + len -= 2;
  341. + }
  342. +}
  343. +
  344. +static void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs,
  345. + unsigned int len)
  346. +{
  347. + unsigned char *p;
  348. +
  349. + WARN_ON(!(len & 1));
  350. +
  351. + ata_id_string(id, s, ofs, len - 1);
  352. +
  353. + p = s + strnlen(s, len - 1);
  354. + while (p > s && p[-1] == ' ')
  355. + p--;
  356. + *p = '\0';
  357. +}
  358. +
  359. +static int ps3disk_identify(struct ps3_storage_device *dev)
  360. +{
  361. + struct ps3disk_private *priv = ps3disk_priv(dev);
  362. + struct lv1_ata_cmnd_block ata_cmnd;
  363. + u16 *id = dev->bounce_buf;
  364. + u64 res;
  365. +
  366. + dev_dbg(&dev->sbd.core, "%s:%u: identify disk\n", __func__, __LINE__);
  367. +
  368. + memset(&ata_cmnd, 0, sizeof(struct lv1_ata_cmnd_block));
  369. + ata_cmnd.command = ATA_CMD_ID_ATA;
  370. + ata_cmnd.sector_count = 1;
  371. + ata_cmnd.size = ata_cmnd.arglen = ATA_ID_WORDS * 2;
  372. + ata_cmnd.buffer = dev->bounce_lpar;
  373. + ata_cmnd.proto = PIO_DATA_IN_PROTO;
  374. + ata_cmnd.in_out = DIR_READ;
  375. +
  376. + res = ps3stor_send_command(dev, LV1_STORAGE_SEND_ATA_COMMAND,
  377. + ps3_mm_phys_to_lpar(__pa(&ata_cmnd)),
  378. + sizeof(ata_cmnd), ata_cmnd.buffer,
  379. + ata_cmnd.arglen);
  380. + if (res) {
  381. + dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%lx\n",
  382. + __func__, __LINE__, res);
  383. + return -EIO;
  384. + }
  385. +
  386. + swap_buf_le16(id, ATA_ID_WORDS);
  387. +
  388. + /* All we're interested in are raw capacity and model name */
  389. + priv->raw_capacity = ata_id_n_sectors(id);
  390. + ata_id_c_string(id, priv->model, ATA_ID_PROD, sizeof(priv->model));
  391. + return 0;
  392. +}
  393. +
  394. +static void ps3disk_prepare_flush(request_queue_t *q, struct request *req)
  395. +{
  396. + struct ps3_storage_device *dev = q->queuedata;
  397. +
  398. + dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
  399. +
  400. + memset(req->cmd, 0, sizeof(req->cmd));
  401. + req->cmd_type = REQ_TYPE_FLUSH;
  402. +}
  403. +
  404. +static int ps3disk_issue_flush(request_queue_t *q, struct gendisk *gendisk,
  405. + sector_t *sector)
  406. +{
  407. + struct ps3_storage_device *dev = q->queuedata;
  408. + struct request *req;
  409. + int res;
  410. +
  411. + dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
  412. +
  413. + req = blk_get_request(q, WRITE, __GFP_WAIT);
  414. + ps3disk_prepare_flush(q, req);
  415. + res = blk_execute_rq(q, gendisk, req, 0);
  416. + if (res)
  417. + dev_err(&dev->sbd.core, "%s:%u: flush request failed %d\n",
  418. + __func__, __LINE__, res);
  419. + blk_put_request(req);
  420. + return res;
  421. +}
  422. +
  423. +
  424. +static unsigned long ps3disk_mask;
  425. +
  426. +static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
  427. +{
  428. + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
  429. + struct ps3disk_private *priv;
  430. + int error;
  431. + unsigned int devidx;
  432. + struct request_queue *queue;
  433. + struct gendisk *gendisk;
  434. +
  435. + if (dev->blk_size < KERNEL_SECTOR_SIZE) {
  436. + dev_err(&dev->sbd.core,
  437. + "%s:%u: cannot handle block size %lu\n", __func__,
  438. + __LINE__, dev->blk_size);
  439. + return -EINVAL;
  440. + }
  441. +
  442. + BUILD_BUG_ON(PS3DISK_MAX_DISKS > BITS_PER_LONG);
  443. + devidx = find_first_zero_bit(&ps3disk_mask, PS3DISK_MAX_DISKS);
  444. + if (devidx >= PS3DISK_MAX_DISKS) {
  445. + dev_err(&dev->sbd.core, "%s:%u: Too many disks\n", __func__,
  446. + __LINE__);
  447. + return -ENOSPC;
  448. + }
  449. + __set_bit(devidx, &ps3disk_mask);
  450. +
  451. + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  452. + if (!priv) {
  453. + error = -ENOMEM;
  454. + goto fail;
  455. + }
  456. +
  457. + ps3disk_priv(dev) = priv;
  458. + spin_lock_init(&priv->lock);
  459. +
  460. + dev->bounce_size = BOUNCE_SIZE;
  461. + dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
  462. + if (!dev->bounce_buf) {
  463. + error = -ENOMEM;
  464. + goto fail_free_priv;
  465. + }
  466. +
  467. + error = ps3stor_setup(dev, ps3disk_interrupt);
  468. + if (error)
  469. + goto fail_free_bounce;
  470. +
  471. + ps3disk_identify(dev);
  472. +
  473. + queue = blk_init_queue(ps3disk_request, &priv->lock);
  474. + if (!queue) {
  475. + dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n",
  476. + __func__, __LINE__);
  477. + error = -ENOMEM;
  478. + goto fail_teardown;
  479. + }
  480. +
  481. + priv->queue = queue;
  482. + queue->queuedata = dev;
  483. +
  484. + blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
  485. +
  486. + blk_queue_max_sectors(queue, dev->bounce_size/KERNEL_SECTOR_SIZE);
  487. + blk_queue_segment_boundary(queue, -1UL);
  488. + blk_queue_dma_alignment(queue, dev->blk_size-1);
  489. + blk_queue_hardsect_size(queue, dev->blk_size);
  490. +
  491. + blk_queue_issue_flush_fn(queue, ps3disk_issue_flush);
  492. + blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
  493. + ps3disk_prepare_flush);
  494. +
  495. + blk_queue_max_phys_segments(queue, -1);
  496. + blk_queue_max_hw_segments(queue, -1);
  497. + blk_queue_max_segment_size(queue, dev->bounce_size);
  498. +
  499. + gendisk = alloc_disk(PS3DISK_MINORS);
  500. + if (!gendisk) {
  501. + dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n", __func__,
  502. + __LINE__);
  503. + error = -ENOMEM;
  504. + goto fail_cleanup_queue;
  505. + }
  506. +
  507. + priv->gendisk = gendisk;
  508. + gendisk->major = ps3disk_major;
  509. + gendisk->first_minor = devidx * PS3DISK_MINORS;
  510. + gendisk->fops = &ps3disk_fops;
  511. + gendisk->queue = queue;
  512. + gendisk->private_data = dev;
  513. + gendisk->driverfs_dev = &dev->sbd.core;
  514. + snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3DISK_NAME,
  515. + devidx+'a');
  516. + priv->blocking_factor = dev->blk_size/KERNEL_SECTOR_SIZE;
  517. + set_capacity(gendisk,
  518. + dev->regions[dev->region_idx].size*priv->blocking_factor);
  519. +
  520. + dev_info(&dev->sbd.core,
  521. + "%s is a %s (%lu MiB total, %lu MiB for OtherOS)\n",
  522. + gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
  523. + get_capacity(gendisk) >> 11);
  524. +
  525. + add_disk(gendisk);
  526. + return 0;
  527. +
  528. +fail_cleanup_queue:
  529. + blk_cleanup_queue(queue);
  530. +fail_teardown:
  531. + ps3stor_teardown(dev);
  532. +fail_free_bounce:
  533. + kfree(dev->bounce_buf);
  534. +fail_free_priv:
  535. + kfree(priv);
  536. + ps3disk_priv(dev) = NULL;
  537. +fail:
  538. + __clear_bit(devidx, &ps3disk_mask);
  539. + return error;
  540. +}
  541. +
  542. +static int ps3disk_remove(struct ps3_system_bus_device *_dev)
  543. +{
  544. + struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
  545. + struct ps3disk_private *priv = ps3disk_priv(dev);
  546. +
  547. + __clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS,
  548. + &ps3disk_mask);
  549. + del_gendisk(priv->gendisk);
  550. + blk_cleanup_queue(priv->queue);
  551. + put_disk(priv->gendisk);
  552. + dev_notice(&dev->sbd.core, "Synchronizing disk cache\n");
  553. + ps3disk_sync_cache(dev);
  554. + ps3stor_teardown(dev);
  555. + kfree(dev->bounce_buf);
  556. + kfree(priv);
  557. + ps3disk_priv(dev) = NULL;
  558. + return 0;
  559. +}
  560. +
  561. +static struct ps3_system_bus_driver ps3disk = {
  562. + .match_id = PS3_MATCH_ID_STOR_DISK,
  563. + .core.name = DEVICE_NAME,
  564. + .core.owner = THIS_MODULE,
  565. + .probe = ps3disk_probe,
  566. + .remove = ps3disk_remove,
  567. + .shutdown = ps3disk_remove,
  568. +};
  569. +
  570. +
  571. +static int __init ps3disk_init(void)
  572. +{
  573. + int error;
  574. +
  575. + if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
  576. + return -ENODEV;
  577. +
  578. + error = register_blkdev(0, DEVICE_NAME);
  579. + if (error <= 0) {
  580. + printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__,
  581. + __LINE__, error);
  582. + return error;
  583. + }
  584. + ps3disk_major = error;
  585. +
  586. + pr_info("%s:%u: registered block device major %d\n", __func__,
  587. + __LINE__, ps3disk_major);
  588. +
  589. + error = ps3_system_bus_driver_register(&ps3disk);
  590. + if (error)
  591. + unregister_blkdev(ps3disk_major, DEVICE_NAME);
  592. +
  593. + return error;
  594. +}
  595. +
  596. +static void __exit ps3disk_exit(void)
  597. +{
  598. + ps3_system_bus_driver_unregister(&ps3disk);
  599. + unregister_blkdev(ps3disk_major, DEVICE_NAME);
  600. +}
  601. +
  602. +module_init(ps3disk_init);
  603. +module_exit(ps3disk_exit);
  604. +
  605. +MODULE_LICENSE("GPL");
  606. +MODULE_DESCRIPTION("PS3 Disk Storage Driver");
  607. +MODULE_AUTHOR("Sony Corporation");
  608. +MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_DISK);
Add Comment
Please, Sign In to add comment