1 /* sunvdc.c: Sun LDOM Virtual Disk Client.
3 * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/types.h>
9 #include <linux/blkdev.h>
10 #include <linux/hdreg.h>
11 #include <linux/genhd.h>
12 #include <linux/slab.h>
13 #include <linux/spinlock.h>
14 #include <linux/completion.h>
15 #include <linux/delay.h>
16 #include <linux/init.h>
17 #include <linux/list.h>
22 #define DRV_MODULE_NAME "sunvdc"
23 #define PFX DRV_MODULE_NAME ": "
24 #define DRV_MODULE_VERSION "1.0"
25 #define DRV_MODULE_RELDATE "June 25, 2007"
27 static char version
[] __devinitdata
=
28 DRV_MODULE_NAME
".c:v" DRV_MODULE_VERSION
" (" DRV_MODULE_RELDATE
")\n";
29 MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
30 MODULE_DESCRIPTION("Sun LDOM virtual disk client driver");
31 MODULE_LICENSE("GPL");
32 MODULE_VERSION(DRV_MODULE_VERSION
);
34 #define VDC_TX_RING_SIZE 256
36 #define WAITING_FOR_LINK_UP 0x01
37 #define WAITING_FOR_TX_SPACE 0x02
38 #define WAITING_FOR_GEN_CMD 0x04
39 #define WAITING_FOR_ANY -1
41 struct vdc_req_entry
{
46 struct vio_driver_state vio
;
50 struct vdc_completion
*cmp
;
54 struct vdc_req_entry rq_arr
[VDC_TX_RING_SIZE
];
56 unsigned long ring_cookies
;
61 /* The server fills these in for us in the disk attribute
70 struct vio_disk_geom geom
;
71 struct vio_disk_vtoc label
;
74 static inline struct vdc_port
*to_vdc_port(struct vio_driver_state
*vio
)
76 return container_of(vio
, struct vdc_port
, vio
);
79 /* Ordered from largest major to lowest */
80 static struct vio_version vdc_versions
[] = {
81 { .major
= 1, .minor
= 0 },
84 #define VDCBLK_NAME "vdisk"
86 #define PARTITION_SHIFT 3
88 static inline u32
vdc_tx_dring_avail(struct vio_dring_state
*dr
)
90 return vio_dring_avail(dr
, VDC_TX_RING_SIZE
);
93 static int vdc_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
)
95 struct gendisk
*disk
= bdev
->bd_disk
;
96 struct vdc_port
*port
= disk
->private_data
;
98 geo
->heads
= (u8
) port
->geom
.num_hd
;
99 geo
->sectors
= (u8
) port
->geom
.num_sec
;
100 geo
->cylinders
= port
->geom
.num_cyl
;
105 static struct block_device_operations vdc_fops
= {
106 .owner
= THIS_MODULE
,
107 .getgeo
= vdc_getgeo
,
110 static void vdc_finish(struct vio_driver_state
*vio
, int err
, int waiting_for
)
113 (waiting_for
== -1 ||
114 vio
->cmp
->waiting_for
== waiting_for
)) {
116 complete(&vio
->cmp
->com
);
121 static void vdc_handshake_complete(struct vio_driver_state
*vio
)
123 vdc_finish(vio
, 0, WAITING_FOR_LINK_UP
);
126 static int vdc_handle_unknown(struct vdc_port
*port
, void *arg
)
128 struct vio_msg_tag
*pkt
= arg
;
130 printk(KERN_ERR PFX
"Received unknown msg [%02x:%02x:%04x:%08x]\n",
131 pkt
->type
, pkt
->stype
, pkt
->stype_env
, pkt
->sid
);
132 printk(KERN_ERR PFX
"Resetting connection.\n");
134 ldc_disconnect(port
->vio
.lp
);
139 static int vdc_send_attr(struct vio_driver_state
*vio
)
141 struct vdc_port
*port
= to_vdc_port(vio
);
142 struct vio_disk_attr_info pkt
;
144 memset(&pkt
, 0, sizeof(pkt
));
146 pkt
.tag
.type
= VIO_TYPE_CTRL
;
147 pkt
.tag
.stype
= VIO_SUBTYPE_INFO
;
148 pkt
.tag
.stype_env
= VIO_ATTR_INFO
;
149 pkt
.tag
.sid
= vio_send_sid(vio
);
151 pkt
.xfer_mode
= VIO_DRING_MODE
;
152 pkt
.vdisk_block_size
= port
->vdisk_block_size
;
153 pkt
.max_xfer_size
= port
->max_xfer_size
;
155 viodbg(HS
, "SEND ATTR xfer_mode[0x%x] blksz[%u] max_xfer[%lu]\n",
156 pkt
.xfer_mode
, pkt
.vdisk_block_size
, pkt
.max_xfer_size
);
158 return vio_ldc_send(&port
->vio
, &pkt
, sizeof(pkt
));
161 static int vdc_handle_attr(struct vio_driver_state
*vio
, void *arg
)
163 struct vdc_port
*port
= to_vdc_port(vio
);
164 struct vio_disk_attr_info
*pkt
= arg
;
166 viodbg(HS
, "GOT ATTR stype[0x%x] ops[%lx] disk_size[%lu] disk_type[%x] "
167 "xfer_mode[0x%x] blksz[%u] max_xfer[%lu]\n",
168 pkt
->tag
.stype
, pkt
->operations
,
169 pkt
->vdisk_size
, pkt
->vdisk_type
,
170 pkt
->xfer_mode
, pkt
->vdisk_block_size
,
173 if (pkt
->tag
.stype
== VIO_SUBTYPE_ACK
) {
174 switch (pkt
->vdisk_type
) {
175 case VD_DISK_TYPE_DISK
:
176 case VD_DISK_TYPE_SLICE
:
180 printk(KERN_ERR PFX
"%s: Bogus vdisk_type 0x%x\n",
181 vio
->name
, pkt
->vdisk_type
);
185 if (pkt
->vdisk_block_size
> port
->vdisk_block_size
) {
186 printk(KERN_ERR PFX
"%s: BLOCK size increased "
189 port
->vdisk_block_size
, pkt
->vdisk_block_size
);
193 port
->operations
= pkt
->operations
;
194 port
->vdisk_size
= pkt
->vdisk_size
;
195 port
->vdisk_type
= pkt
->vdisk_type
;
196 if (pkt
->max_xfer_size
< port
->max_xfer_size
)
197 port
->max_xfer_size
= pkt
->max_xfer_size
;
198 port
->vdisk_block_size
= pkt
->vdisk_block_size
;
201 printk(KERN_ERR PFX
"%s: Attribute NACK\n", vio
->name
);
207 static void vdc_end_special(struct vdc_port
*port
, struct vio_disk_desc
*desc
)
209 int err
= desc
->status
;
211 vdc_finish(&port
->vio
, -err
, WAITING_FOR_GEN_CMD
);
214 static void vdc_end_request(struct request
*req
, int uptodate
, int num_sectors
)
216 if (end_that_request_first(req
, uptodate
, num_sectors
))
218 add_disk_randomness(req
->rq_disk
);
219 end_that_request_last(req
, uptodate
);
222 static void vdc_end_one(struct vdc_port
*port
, struct vio_dring_state
*dr
,
225 struct vio_disk_desc
*desc
= vio_dring_entry(dr
, index
);
226 struct vdc_req_entry
*rqe
= &port
->rq_arr
[index
];
229 if (unlikely(desc
->hdr
.state
!= VIO_DESC_DONE
))
232 ldc_unmap(port
->vio
.lp
, desc
->cookies
, desc
->ncookies
);
233 desc
->hdr
.state
= VIO_DESC_FREE
;
234 dr
->cons
= (index
+ 1) & (VDC_TX_RING_SIZE
- 1);
238 vdc_end_special(port
, desc
);
244 vdc_end_request(req
, !desc
->status
, desc
->size
>> 9);
246 if (blk_queue_stopped(port
->disk
->queue
))
247 blk_start_queue(port
->disk
->queue
);
250 static int vdc_ack(struct vdc_port
*port
, void *msgbuf
)
252 struct vio_dring_state
*dr
= &port
->vio
.drings
[VIO_DRIVER_TX_RING
];
253 struct vio_dring_data
*pkt
= msgbuf
;
255 if (unlikely(pkt
->dring_ident
!= dr
->ident
||
256 pkt
->start_idx
!= pkt
->end_idx
||
257 pkt
->start_idx
>= VDC_TX_RING_SIZE
))
260 vdc_end_one(port
, dr
, pkt
->start_idx
);
265 static int vdc_nack(struct vdc_port
*port
, void *msgbuf
)
267 /* XXX Implement me XXX */
271 static void vdc_event(void *arg
, int event
)
273 struct vdc_port
*port
= arg
;
274 struct vio_driver_state
*vio
= &port
->vio
;
278 spin_lock_irqsave(&vio
->lock
, flags
);
280 if (unlikely(event
== LDC_EVENT_RESET
||
281 event
== LDC_EVENT_UP
)) {
282 vio_link_state_change(vio
, event
);
283 spin_unlock_irqrestore(&vio
->lock
, flags
);
287 if (unlikely(event
!= LDC_EVENT_DATA_READY
)) {
288 printk(KERN_WARNING PFX
"Unexpected LDC event %d\n", event
);
289 spin_unlock_irqrestore(&vio
->lock
, flags
);
296 struct vio_msg_tag tag
;
300 err
= ldc_read(vio
->lp
, &msgbuf
, sizeof(msgbuf
));
301 if (unlikely(err
< 0)) {
302 if (err
== -ECONNRESET
)
308 viodbg(DATA
, "TAG [%02x:%02x:%04x:%08x]\n",
311 msgbuf
.tag
.stype_env
,
313 err
= vio_validate_sid(vio
, &msgbuf
.tag
);
317 if (likely(msgbuf
.tag
.type
== VIO_TYPE_DATA
)) {
318 if (msgbuf
.tag
.stype
== VIO_SUBTYPE_ACK
)
319 err
= vdc_ack(port
, &msgbuf
);
320 else if (msgbuf
.tag
.stype
== VIO_SUBTYPE_NACK
)
321 err
= vdc_nack(port
, &msgbuf
);
323 err
= vdc_handle_unknown(port
, &msgbuf
);
324 } else if (msgbuf
.tag
.type
== VIO_TYPE_CTRL
) {
325 err
= vio_control_pkt_engine(vio
, &msgbuf
);
327 err
= vdc_handle_unknown(port
, &msgbuf
);
333 vdc_finish(&port
->vio
, err
, WAITING_FOR_ANY
);
334 spin_unlock_irqrestore(&vio
->lock
, flags
);
337 static int __vdc_tx_trigger(struct vdc_port
*port
)
339 struct vio_dring_state
*dr
= &port
->vio
.drings
[VIO_DRIVER_TX_RING
];
340 struct vio_dring_data hdr
= {
342 .type
= VIO_TYPE_DATA
,
343 .stype
= VIO_SUBTYPE_INFO
,
344 .stype_env
= VIO_DRING_DATA
,
345 .sid
= vio_send_sid(&port
->vio
),
347 .dring_ident
= dr
->ident
,
348 .start_idx
= dr
->prod
,
353 hdr
.seq
= dr
->snd_nxt
;
356 err
= vio_ldc_send(&port
->vio
, &hdr
, sizeof(hdr
));
362 if ((delay
<<= 1) > 128)
364 } while (err
== -EAGAIN
);
369 static int __send_request(struct request
*req
)
371 struct vdc_port
*port
= req
->rq_disk
->private_data
;
372 struct vio_dring_state
*dr
= &port
->vio
.drings
[VIO_DRIVER_TX_RING
];
373 struct scatterlist sg
[port
->ring_cookies
];
374 struct vdc_req_entry
*rqe
;
375 struct vio_disk_desc
*desc
;
376 unsigned int map_perm
;
381 map_perm
= LDC_MAP_SHADOW
| LDC_MAP_DIRECT
| LDC_MAP_IO
;
383 if (rq_data_dir(req
) == READ
) {
384 map_perm
|= LDC_MAP_W
;
387 map_perm
|= LDC_MAP_R
;
391 nsg
= blk_rq_map_sg(req
->q
, req
, sg
);
394 for (i
= 0; i
< nsg
; i
++)
397 if (unlikely(vdc_tx_dring_avail(dr
) < 1)) {
398 blk_stop_queue(port
->disk
->queue
);
403 desc
= vio_dring_cur(dr
);
405 err
= ldc_map_sg(port
->vio
.lp
, sg
, nsg
,
406 desc
->cookies
, port
->ring_cookies
,
409 printk(KERN_ERR PFX
"ldc_map_sg() failure, err=%d.\n", err
);
413 rqe
= &port
->rq_arr
[dr
->prod
];
416 desc
->hdr
.ack
= VIO_ACK_ENABLE
;
417 desc
->req_id
= port
->req_id
;
418 desc
->operation
= op
;
419 if (port
->vdisk_type
== VD_DISK_TYPE_DISK
) {
425 desc
->offset
= (req
->sector
<< 9) / port
->vdisk_block_size
;
427 desc
->ncookies
= err
;
429 /* This has to be a non-SMP write barrier because we are writing
430 * to memory which is shared with the peer LDOM.
433 desc
->hdr
.state
= VIO_DESC_READY
;
435 err
= __vdc_tx_trigger(port
);
437 printk(KERN_ERR PFX
"vdc_tx_trigger() failure, err=%d\n", err
);
440 dr
->prod
= (dr
->prod
+ 1) & (VDC_TX_RING_SIZE
- 1);
447 static void do_vdc_request(struct request_queue
*q
)
450 struct request
*req
= elv_next_request(q
);
455 blkdev_dequeue_request(req
);
456 if (__send_request(req
) < 0)
457 vdc_end_request(req
, 0, req
->hard_nr_sectors
);
461 static int generic_request(struct vdc_port
*port
, u8 op
, void *buf
, int len
)
463 struct vio_dring_state
*dr
;
464 struct vio_completion comp
;
465 struct vio_disk_desc
*desc
;
466 unsigned int map_perm
;
471 if (!(((u64
)1 << ((u64
)op
- 1)) & port
->operations
))
486 op_len
= sizeof(u32
);
487 map_perm
= LDC_MAP_W
;
491 op_len
= sizeof(u32
);
492 map_perm
= LDC_MAP_R
;
496 op_len
= sizeof(struct vio_disk_vtoc
);
497 map_perm
= LDC_MAP_W
;
501 op_len
= sizeof(struct vio_disk_vtoc
);
502 map_perm
= LDC_MAP_R
;
505 case VD_OP_GET_DISKGEOM
:
506 op_len
= sizeof(struct vio_disk_geom
);
507 map_perm
= LDC_MAP_W
;
510 case VD_OP_SET_DISKGEOM
:
511 op_len
= sizeof(struct vio_disk_geom
);
512 map_perm
= LDC_MAP_R
;
517 map_perm
= LDC_MAP_RW
;
520 case VD_OP_GET_DEVID
:
521 op_len
= sizeof(struct vio_disk_devid
);
522 map_perm
= LDC_MAP_W
;
531 map_perm
|= LDC_MAP_SHADOW
| LDC_MAP_DIRECT
| LDC_MAP_IO
;
533 op_len
= (op_len
+ 7) & ~7;
534 req_buf
= kzalloc(op_len
, GFP_KERNEL
);
541 if (map_perm
& LDC_MAP_R
)
542 memcpy(req_buf
, buf
, len
);
544 spin_lock_irqsave(&port
->vio
.lock
, flags
);
546 dr
= &port
->vio
.drings
[VIO_DRIVER_TX_RING
];
548 /* XXX If we want to use this code generically we have to
549 * XXX handle TX ring exhaustion etc.
551 desc
= vio_dring_cur(dr
);
553 err
= ldc_map_single(port
->vio
.lp
, req_buf
, op_len
,
554 desc
->cookies
, port
->ring_cookies
,
557 spin_unlock_irqrestore(&port
->vio
.lock
, flags
);
562 init_completion(&comp
.com
);
563 comp
.waiting_for
= WAITING_FOR_GEN_CMD
;
564 port
->vio
.cmp
= &comp
;
566 desc
->hdr
.ack
= VIO_ACK_ENABLE
;
567 desc
->req_id
= port
->req_id
;
568 desc
->operation
= op
;
573 desc
->ncookies
= err
;
575 /* This has to be a non-SMP write barrier because we are writing
576 * to memory which is shared with the peer LDOM.
579 desc
->hdr
.state
= VIO_DESC_READY
;
581 err
= __vdc_tx_trigger(port
);
584 dr
->prod
= (dr
->prod
+ 1) & (VDC_TX_RING_SIZE
- 1);
585 spin_unlock_irqrestore(&port
->vio
.lock
, flags
);
587 wait_for_completion(&comp
.com
);
590 port
->vio
.cmp
= NULL
;
591 spin_unlock_irqrestore(&port
->vio
.lock
, flags
);
594 if (map_perm
& LDC_MAP_W
)
595 memcpy(buf
, req_buf
, len
);
602 static int __devinit
vdc_alloc_tx_ring(struct vdc_port
*port
)
604 struct vio_dring_state
*dr
= &port
->vio
.drings
[VIO_DRIVER_TX_RING
];
605 unsigned long len
, entry_size
;
609 entry_size
= sizeof(struct vio_disk_desc
) +
610 (sizeof(struct ldc_trans_cookie
) * port
->ring_cookies
);
611 len
= (VDC_TX_RING_SIZE
* entry_size
);
613 ncookies
= VIO_MAX_RING_COOKIES
;
614 dring
= ldc_alloc_exp_dring(port
->vio
.lp
, len
,
615 dr
->cookies
, &ncookies
,
620 return PTR_ERR(dring
);
623 dr
->entry_size
= entry_size
;
624 dr
->num_entries
= VDC_TX_RING_SIZE
;
625 dr
->prod
= dr
->cons
= 0;
626 dr
->pending
= VDC_TX_RING_SIZE
;
627 dr
->ncookies
= ncookies
;
632 static void vdc_free_tx_ring(struct vdc_port
*port
)
634 struct vio_dring_state
*dr
= &port
->vio
.drings
[VIO_DRIVER_TX_RING
];
637 ldc_free_exp_dring(port
->vio
.lp
, dr
->base
,
638 (dr
->entry_size
* dr
->num_entries
),
639 dr
->cookies
, dr
->ncookies
);
648 static int probe_disk(struct vdc_port
*port
)
650 struct vio_completion comp
;
651 struct request_queue
*q
;
655 init_completion(&comp
.com
);
657 comp
.waiting_for
= WAITING_FOR_LINK_UP
;
658 port
->vio
.cmp
= &comp
;
660 vio_port_up(&port
->vio
);
662 wait_for_completion(&comp
.com
);
666 err
= generic_request(port
, VD_OP_GET_VTOC
,
667 &port
->label
, sizeof(port
->label
));
669 printk(KERN_ERR PFX
"VD_OP_GET_VTOC returns error %d\n", err
);
673 err
= generic_request(port
, VD_OP_GET_DISKGEOM
,
674 &port
->geom
, sizeof(port
->geom
));
676 printk(KERN_ERR PFX
"VD_OP_GET_DISKGEOM returns "
681 port
->vdisk_size
= ((u64
)port
->geom
.num_cyl
*
682 (u64
)port
->geom
.num_hd
*
683 (u64
)port
->geom
.num_sec
);
685 q
= blk_init_queue(do_vdc_request
, &port
->vio
.lock
);
687 printk(KERN_ERR PFX
"%s: Could not allocate queue.\n",
691 g
= alloc_disk(1 << PARTITION_SHIFT
);
693 printk(KERN_ERR PFX
"%s: Could not allocate gendisk.\n",
695 blk_cleanup_queue(q
);
701 blk_queue_max_hw_segments(q
, port
->ring_cookies
);
702 blk_queue_max_phys_segments(q
, port
->ring_cookies
);
703 blk_queue_max_sectors(q
, port
->max_xfer_size
);
704 g
->major
= vdc_major
;
705 g
->first_minor
= port
->vio
.vdev
->dev_no
<< PARTITION_SHIFT
;
706 strcpy(g
->disk_name
, port
->disk_name
);
710 g
->private_data
= port
;
711 g
->driverfs_dev
= &port
->vio
.vdev
->dev
;
713 set_capacity(g
, port
->vdisk_size
);
715 printk(KERN_INFO PFX
"%s: %u sectors (%u MB)\n",
717 port
->vdisk_size
, (port
->vdisk_size
>> (20 - 9)));
724 static struct ldc_channel_config vdc_ldc_cfg
= {
727 .mode
= LDC_MODE_UNRELIABLE
,
730 static struct vio_driver_ops vdc_vio_ops
= {
731 .send_attr
= vdc_send_attr
,
732 .handle_attr
= vdc_handle_attr
,
733 .handshake_complete
= vdc_handshake_complete
,
736 static void print_version(void)
738 static int version_printed
;
740 if (version_printed
++ == 0)
741 printk(KERN_INFO
"%s", version
);
744 static int __devinit
vdc_port_probe(struct vio_dev
*vdev
,
745 const struct vio_device_id
*id
)
747 struct mdesc_handle
*hp
;
748 struct vdc_port
*port
;
756 if ((vdev
->dev_no
<< PARTITION_SHIFT
) & ~(u64
)MINORMASK
) {
757 printk(KERN_ERR PFX
"Port id [%lu] too large.\n",
759 goto err_out_release_mdesc
;
762 port
= kzalloc(sizeof(*port
), GFP_KERNEL
);
765 printk(KERN_ERR PFX
"Cannot allocate vdc_port.\n");
766 goto err_out_release_mdesc
;
769 if (vdev
->dev_no
>= 26)
770 snprintf(port
->disk_name
, sizeof(port
->disk_name
),
772 'a' + ((int)vdev
->dev_no
/ 26) - 1,
773 'a' + ((int)vdev
->dev_no
% 26));
775 snprintf(port
->disk_name
, sizeof(port
->disk_name
),
776 VDCBLK_NAME
"%c", 'a' + ((int)vdev
->dev_no
% 26));
778 err
= vio_driver_init(&port
->vio
, vdev
, VDEV_DISK
,
779 vdc_versions
, ARRAY_SIZE(vdc_versions
),
780 &vdc_vio_ops
, port
->disk_name
);
782 goto err_out_free_port
;
784 port
->vdisk_block_size
= 512;
785 port
->max_xfer_size
= ((128 * 1024) / port
->vdisk_block_size
);
786 port
->ring_cookies
= ((port
->max_xfer_size
*
787 port
->vdisk_block_size
) / PAGE_SIZE
) + 2;
789 err
= vio_ldc_alloc(&port
->vio
, &vdc_ldc_cfg
, port
);
791 goto err_out_free_port
;
793 err
= vdc_alloc_tx_ring(port
);
795 goto err_out_free_ldc
;
797 err
= probe_disk(port
);
799 goto err_out_free_tx_ring
;
801 dev_set_drvdata(&vdev
->dev
, port
);
807 err_out_free_tx_ring
:
808 vdc_free_tx_ring(port
);
811 vio_ldc_free(&port
->vio
);
816 err_out_release_mdesc
:
821 static int vdc_port_remove(struct vio_dev
*vdev
)
823 struct vdc_port
*port
= dev_get_drvdata(&vdev
->dev
);
826 del_timer_sync(&port
->vio
.timer
);
828 vdc_free_tx_ring(port
);
829 vio_ldc_free(&port
->vio
);
831 dev_set_drvdata(&vdev
->dev
, NULL
);
838 static struct vio_device_id vdc_port_match
[] = {
844 MODULE_DEVICE_TABLE(vio
, vdc_port_match
);
846 static struct vio_driver vdc_port_driver
= {
847 .id_table
= vdc_port_match
,
848 .probe
= vdc_port_probe
,
849 .remove
= vdc_port_remove
,
852 .owner
= THIS_MODULE
,
856 static int __init
vdc_init(void)
860 err
= register_blkdev(0, VDCBLK_NAME
);
866 err
= vio_register_driver(&vdc_port_driver
);
868 goto out_unregister_blkdev
;
872 out_unregister_blkdev
:
873 unregister_blkdev(vdc_major
, VDCBLK_NAME
);
880 static void __exit
vdc_exit(void)
882 vio_unregister_driver(&vdc_port_driver
);
883 unregister_blkdev(vdc_major
, VDCBLK_NAME
);
886 module_init(vdc_init
);
887 module_exit(vdc_exit
);