aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/ps3/device-init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/ps3/device-init.c')
-rw-r--r--arch/powerpc/platforms/ps3/device-init.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 825ebb2cbc2a..e23a5a874ad3 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -273,55 +273,58 @@ static int ps3stor_wait_for_completion(u64 dev_id, u64 tag,
273 273
274static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) 274static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
275{ 275{
276 int error = -ENODEV;
276 int result; 277 int result;
277 const u64 notification_dev_id = (u64)-1LL; 278 const u64 notification_dev_id = (u64)-1LL;
278 const unsigned int timeout = HZ; 279 const unsigned int timeout = HZ;
279 u64 lpar; 280 u64 lpar;
280 u64 tag; 281 u64 tag;
282 void *buf;
283 enum ps3_notify_type {
284 notify_device_ready = 0,
285 notify_region_probe = 1,
286 notify_region_update = 2,
287 };
281 struct { 288 struct {
282 u64 operation_code; /* must be zero */ 289 u64 operation_code; /* must be zero */
283 u64 event_mask; /* 1 = device ready */ 290 u64 event_mask; /* OR of 1UL << enum ps3_notify_type */
284 } *notify_cmd; 291 } *notify_cmd;
285 struct { 292 struct {
286 u64 event_type; /* notify_device_ready */ 293 u64 event_type; /* enum ps3_notify_type */
287 u64 bus_id; 294 u64 bus_id;
288 u64 dev_id; 295 u64 dev_id;
289 u64 dev_type; 296 u64 dev_type;
290 u64 dev_port; 297 u64 dev_port;
291 } *notify_event; 298 } *notify_event;
292 enum {
293 notify_device_ready = 1
294 };
295 299
296 pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__, 300 pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__,
297 __LINE__, repo->bus_id, repo->dev_id, repo->dev_type); 301 __LINE__, repo->bus_id, repo->dev_id, repo->dev_type);
298 302
299 notify_cmd = kzalloc(512, GFP_KERNEL); 303 buf = kzalloc(512, GFP_KERNEL);
300 notify_event = (void *)notify_cmd; 304 if (!buf)
301 if (!notify_cmd)
302 return -ENOMEM; 305 return -ENOMEM;
303 306
304 lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd)); 307 lpar = ps3_mm_phys_to_lpar(__pa(buf));
308 notify_cmd = buf;
309 notify_event = buf;
305 310
306 result = lv1_open_device(repo->bus_id, notification_dev_id, 0); 311 result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
307 if (result) { 312 if (result) {
308 printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__, 313 printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
309 __LINE__, ps3_result(result)); 314 __LINE__, ps3_result(result));
310 result = -ENODEV;
311 goto fail_free; 315 goto fail_free;
312 } 316 }
313 317
314 /* Setup and write the request for device notification. */ 318 /* Setup and write the request for device notification. */
315 319
316 notify_cmd->operation_code = 0; /* must be zero */ 320 notify_cmd->operation_code = 0; /* must be zero */
317 notify_cmd->event_mask = 0x01; /* device ready */ 321 notify_cmd->event_mask = 1UL << notify_region_probe;
318 322
319 result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar, 323 result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
320 &tag); 324 &tag);
321 if (result) { 325 if (result) {
322 printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__, 326 printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
323 ps3_result(result)); 327 ps3_result(result));
324 result = -ENODEV;
325 goto fail_close; 328 goto fail_close;
326 } 329 }
327 330
@@ -332,13 +335,11 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
332 if (result) { 335 if (result) {
333 printk(KERN_ERR "%s:%u: write not completed %s\n", __func__, 336 printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
334 __LINE__, ps3_result(result)); 337 __LINE__, ps3_result(result));
335 result = -ENODEV;
336 goto fail_close; 338 goto fail_close;
337 } 339 }
338 340
339 /* Loop here processing the requested notification events. */ 341 /* Loop here processing the requested notification events. */
340 342
341 result = -ENODEV;
342 while (1) { 343 while (1) {
343 memset(notify_event, 0, sizeof(*notify_event)); 344 memset(notify_event, 0, sizeof(*notify_event));
344 345
@@ -358,7 +359,7 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
358 break; 359 break;
359 } 360 }
360 361
361 if (notify_event->event_type != notify_device_ready || 362 if (notify_event->event_type != notify_region_probe ||
362 notify_event->bus_id != repo->bus_id) { 363 notify_event->bus_id != repo->bus_id) {
363 pr_debug("%s:%u: bad notify_event: event %lu, " 364 pr_debug("%s:%u: bad notify_event: event %lu, "
364 "dev_id %lu, dev_type %lu\n", 365 "dev_id %lu, dev_type %lu\n",
@@ -386,9 +387,9 @@ static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
386fail_close: 387fail_close:
387 lv1_close_device(repo->bus_id, notification_dev_id); 388 lv1_close_device(repo->bus_id, notification_dev_id);
388fail_free: 389fail_free:
389 kfree(notify_cmd); 390 kfree(buf);
390 pr_debug(" <- %s:%u\n", __func__, __LINE__); 391 pr_debug(" <- %s:%u\n", __func__, __LINE__);
391 return result; 392 return error;
392} 393}
393 394
394static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, 395static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,