aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2007-10-11 00:59:54 -0400
committerPaul Mackerras <paulus@samba.org>2007-10-11 06:40:48 -0400
commit8251b4c481bca72568e9c1042ea11189838e5f6d (patch)
tree41991f93aec12592885ac33a5312dcf4024ebe5f /drivers/block
parent7465ce0db310d2fa29f721da7e3aacd1dad7090f (diff)
[POWERPC] iSeries: Move viodasd probing
This way we only have entries in the device tree for disks that actually exist. A slight complication is that disks may be attached to LPARs at runtime. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Acked-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/viodasd.c77
1 files changed, 25 insertions, 52 deletions
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index af3969a9c963..e824b672e05a 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -74,53 +74,9 @@ enum {
74static DEFINE_SPINLOCK(viodasd_spinlock); 74static DEFINE_SPINLOCK(viodasd_spinlock);
75 75
76#define VIOMAXREQ 16 76#define VIOMAXREQ 16
77#define VIOMAXBLOCKDMA 12
78 77
79#define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0]) 78#define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0])
80 79
81struct open_data {
82 u64 disk_size;
83 u16 max_disk;
84 u16 cylinders;
85 u16 tracks;
86 u16 sectors;
87 u16 bytes_per_sector;
88};
89
90struct rw_data {
91 u64 offset;
92 struct {
93 u32 token;
94 u32 reserved;
95 u64 len;
96 } dma_info[VIOMAXBLOCKDMA];
97};
98
99struct vioblocklpevent {
100 struct HvLpEvent event;
101 u32 reserved;
102 u16 version;
103 u16 sub_result;
104 u16 disk;
105 u16 flags;
106 union {
107 struct open_data open_data;
108 struct rw_data rw_data;
109 u64 changed;
110 } u;
111};
112
113#define vioblockflags_ro 0x0001
114
115enum vioblocksubtype {
116 vioblockopen = 0x0001,
117 vioblockclose = 0x0002,
118 vioblockread = 0x0003,
119 vioblockwrite = 0x0004,
120 vioblockflush = 0x0005,
121 vioblockcheck = 0x0007
122};
123
124struct viodasd_waitevent { 80struct viodasd_waitevent {
125 struct completion com; 81 struct completion com;
126 int rc; 82 int rc;
@@ -429,7 +385,7 @@ static void do_viodasd_request(struct request_queue *q)
429 * Probe a single disk and fill in the viodasd_device structure 385 * Probe a single disk and fill in the viodasd_device structure
430 * for it. 386 * for it.
431 */ 387 */
432static void probe_disk(struct viodasd_device *d) 388static int probe_disk(struct viodasd_device *d)
433{ 389{
434 HvLpEvent_Rc hvrc; 390 HvLpEvent_Rc hvrc;
435 struct viodasd_waitevent we; 391 struct viodasd_waitevent we;
@@ -453,14 +409,14 @@ retry:
453 0, 0, 0); 409 0, 0, 0);
454 if (hvrc != 0) { 410 if (hvrc != 0) {
455 printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc); 411 printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc);
456 return; 412 return 0;
457 } 413 }
458 414
459 wait_for_completion(&we.com); 415 wait_for_completion(&we.com);
460 416
461 if (we.rc != 0) { 417 if (we.rc != 0) {
462 if (flags != 0) 418 if (flags != 0)
463 return; 419 return 0;
464 /* try again with read only flag set */ 420 /* try again with read only flag set */
465 flags = vioblockflags_ro; 421 flags = vioblockflags_ro;
466 goto retry; 422 goto retry;
@@ -490,15 +446,32 @@ retry:
490 if (hvrc != 0) { 446 if (hvrc != 0) {
491 printk(VIOD_KERN_WARNING 447 printk(VIOD_KERN_WARNING
492 "bad rc sending event to OS/400 %d\n", (int)hvrc); 448 "bad rc sending event to OS/400 %d\n", (int)hvrc);
493 return; 449 return 0;
494 } 450 }
451
452 if (d->dev == NULL) {
453 /* this is when we reprobe for new disks */
454 if (vio_create_viodasd(dev_no) == NULL) {
455 printk(VIOD_KERN_WARNING
456 "cannot allocate virtual device for disk %d\n",
457 dev_no);
458 return 0;
459 }
460 /*
461 * The vio_create_viodasd will have recursed into this
462 * routine with d->dev set to the new vio device and
463 * will finish the setup of the disk below.
464 */
465 return 1;
466 }
467
495 /* create the request queue for the disk */ 468 /* create the request queue for the disk */
496 spin_lock_init(&d->q_lock); 469 spin_lock_init(&d->q_lock);
497 q = blk_init_queue(do_viodasd_request, &d->q_lock); 470 q = blk_init_queue(do_viodasd_request, &d->q_lock);
498 if (q == NULL) { 471 if (q == NULL) {
499 printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n", 472 printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n",
500 dev_no); 473 dev_no);
501 return; 474 return 0;
502 } 475 }
503 g = alloc_disk(1 << PARTITION_SHIFT); 476 g = alloc_disk(1 << PARTITION_SHIFT);
504 if (g == NULL) { 477 if (g == NULL) {
@@ -506,7 +479,7 @@ retry:
506 "cannot allocate disk structure for disk %d\n", 479 "cannot allocate disk structure for disk %d\n",
507 dev_no); 480 dev_no);
508 blk_cleanup_queue(q); 481 blk_cleanup_queue(q);
509 return; 482 return 0;
510 } 483 }
511 484
512 d->disk = g; 485 d->disk = g;
@@ -538,6 +511,7 @@ retry:
538 511
539 /* register us in the global list */ 512 /* register us in the global list */
540 add_disk(g); 513 add_disk(g);
514 return 1;
541} 515}
542 516
543/* returns the total number of scatterlist elements converted */ 517/* returns the total number of scatterlist elements converted */
@@ -718,8 +692,7 @@ static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
718 struct viodasd_device *d = &viodasd_devices[vdev->unit_address]; 692 struct viodasd_device *d = &viodasd_devices[vdev->unit_address];
719 693
720 d->dev = &vdev->dev; 694 d->dev = &vdev->dev;
721 probe_disk(d); 695 if (!probe_disk(d))
722 if (d->disk == NULL)
723 return -ENODEV; 696 return -ENODEV;
724 return 0; 697 return 0;
725} 698}