diff options
Diffstat (limited to 'drivers/ps3')
-rw-r--r-- | drivers/ps3/ps3stor_lib.c | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c index 18066d555397..af0afa1db4a8 100644 --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c | |||
@@ -23,6 +23,65 @@ | |||
23 | #include <asm/lv1call.h> | 23 | #include <asm/lv1call.h> |
24 | #include <asm/ps3stor.h> | 24 | #include <asm/ps3stor.h> |
25 | 25 | ||
26 | /* | ||
27 | * A workaround for flash memory I/O errors when the internal hard disk | ||
28 | * has not been formatted for OtherOS use. Delay disk close until flash | ||
29 | * memory is closed. | ||
30 | */ | ||
31 | |||
32 | static struct ps3_flash_workaround { | ||
33 | int flash_open; | ||
34 | int disk_open; | ||
35 | struct ps3_system_bus_device *disk_sbd; | ||
36 | } ps3_flash_workaround; | ||
37 | |||
38 | static int ps3stor_open_hv_device(struct ps3_system_bus_device *sbd) | ||
39 | { | ||
40 | int error = ps3_open_hv_device(sbd); | ||
41 | |||
42 | if (error) | ||
43 | return error; | ||
44 | |||
45 | if (sbd->match_id == PS3_MATCH_ID_STOR_FLASH) | ||
46 | ps3_flash_workaround.flash_open = 1; | ||
47 | |||
48 | if (sbd->match_id == PS3_MATCH_ID_STOR_DISK) | ||
49 | ps3_flash_workaround.disk_open = 1; | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static int ps3stor_close_hv_device(struct ps3_system_bus_device *sbd) | ||
55 | { | ||
56 | int error; | ||
57 | |||
58 | if (sbd->match_id == PS3_MATCH_ID_STOR_DISK | ||
59 | && ps3_flash_workaround.disk_open | ||
60 | && ps3_flash_workaround.flash_open) { | ||
61 | ps3_flash_workaround.disk_sbd = sbd; | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | error = ps3_close_hv_device(sbd); | ||
66 | |||
67 | if (error) | ||
68 | return error; | ||
69 | |||
70 | if (sbd->match_id == PS3_MATCH_ID_STOR_DISK) | ||
71 | ps3_flash_workaround.disk_open = 0; | ||
72 | |||
73 | if (sbd->match_id == PS3_MATCH_ID_STOR_FLASH) { | ||
74 | ps3_flash_workaround.flash_open = 0; | ||
75 | |||
76 | if (ps3_flash_workaround.disk_sbd) { | ||
77 | ps3_close_hv_device(ps3_flash_workaround.disk_sbd); | ||
78 | ps3_flash_workaround.disk_open = 0; | ||
79 | ps3_flash_workaround.disk_sbd = NULL; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | return 0; | ||
84 | } | ||
26 | 85 | ||
27 | static int ps3stor_probe_access(struct ps3_storage_device *dev) | 86 | static int ps3stor_probe_access(struct ps3_storage_device *dev) |
28 | { | 87 | { |
@@ -90,7 +149,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler) | |||
90 | int error, res, alignment; | 149 | int error, res, alignment; |
91 | enum ps3_dma_page_size page_size; | 150 | enum ps3_dma_page_size page_size; |
92 | 151 | ||
93 | error = ps3_open_hv_device(&dev->sbd); | 152 | error = ps3stor_open_hv_device(&dev->sbd); |
94 | if (error) { | 153 | if (error) { |
95 | dev_err(&dev->sbd.core, | 154 | dev_err(&dev->sbd.core, |
96 | "%s:%u: ps3_open_hv_device failed %d\n", __func__, | 155 | "%s:%u: ps3_open_hv_device failed %d\n", __func__, |
@@ -166,7 +225,7 @@ fail_free_irq: | |||
166 | fail_sb_event_receive_port_destroy: | 225 | fail_sb_event_receive_port_destroy: |
167 | ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq); | 226 | ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq); |
168 | fail_close_device: | 227 | fail_close_device: |
169 | ps3_close_hv_device(&dev->sbd); | 228 | ps3stor_close_hv_device(&dev->sbd); |
170 | fail: | 229 | fail: |
171 | return error; | 230 | return error; |
172 | } | 231 | } |
@@ -193,7 +252,7 @@ void ps3stor_teardown(struct ps3_storage_device *dev) | |||
193 | "%s:%u: destroy event receive port failed %d\n", | 252 | "%s:%u: destroy event receive port failed %d\n", |
194 | __func__, __LINE__, error); | 253 | __func__, __LINE__, error); |
195 | 254 | ||
196 | error = ps3_close_hv_device(&dev->sbd); | 255 | error = ps3stor_close_hv_device(&dev->sbd); |
197 | if (error) | 256 | if (error) |
198 | dev_err(&dev->sbd.core, | 257 | dev_err(&dev->sbd.core, |
199 | "%s:%u: ps3_close_hv_device failed %d\n", __func__, | 258 | "%s:%u: ps3_close_hv_device failed %d\n", __func__, |