aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/viodasd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-12 00:55:47 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-12 00:55:47 -0400
commite86908614f2c7fec401827e5cefd7a6ea9407f85 (patch)
treefcb5d9e52422b37bdaf0e647126ebdfc1680f162 /drivers/block/viodasd.c
parent547307420931344a868275bd7ea7a30f117a15a9 (diff)
parent9b4b8feb962f4b3e74768b7205f1f8f6cce87238 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (408 commits) [POWERPC] Add memchr() to the bootwrapper [POWERPC] Implement logging of unhandled signals [POWERPC] Add legacy serial support for OPB with flattened device tree [POWERPC] Use 1TB segments [POWERPC] XilinxFB: Allow fixed framebuffer base address [POWERPC] XilinxFB: Add support for custom screen resolution [POWERPC] XilinxFB: Use pdata to pass around framebuffer parameters [POWERPC] PCI: Add 64-bit physical address support to setup_indirect_pci [POWERPC] 4xx: Kilauea defconfig file [POWERPC] 4xx: Kilauea DTS [POWERPC] 4xx: Add AMCC Kilauea eval board support to platforms/40x [POWERPC] 4xx: Add AMCC 405EX support to cputable.c [POWERPC] Adjust TASK_SIZE on ppc32 systems to 3GB that are capable [POWERPC] Use PAGE_OFFSET to tell if an address is user/kernel in SW TLB handlers [POWERPC] 85xx: Enable FP emulation in MPC8560 ADS defconfig [POWERPC] 85xx: Killed <asm/mpc85xx.h> [POWERPC] 85xx: Add cpm nodes for 8541/8555 CDS [POWERPC] 85xx: Convert mpc8560ads to the new CPM binding. [POWERPC] mpc8272ads: Remove muram from the CPM reg property. [POWERPC] Make clockevents work on PPC601 processors ... Fixed up conflict in Documentation/powerpc/booting-without-of.txt manually.
Diffstat (limited to 'drivers/block/viodasd.c')
-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}