xref: /openbmc/linux/drivers/block/sunvdc.c (revision 609e478b)
1 /* sunvdc.c: Sun LDOM Virtual Disk Client.
2  *
3  * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
4  */
5 
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/cdrom.h>
13 #include <linux/slab.h>
14 #include <linux/spinlock.h>
15 #include <linux/completion.h>
16 #include <linux/delay.h>
17 #include <linux/init.h>
18 #include <linux/list.h>
19 #include <linux/scatterlist.h>
20 
21 #include <asm/vio.h>
22 #include <asm/ldc.h>
23 
24 #define DRV_MODULE_NAME		"sunvdc"
25 #define PFX DRV_MODULE_NAME	": "
26 #define DRV_MODULE_VERSION	"1.1"
27 #define DRV_MODULE_RELDATE	"February 13, 2013"
28 
29 static char version[] =
30 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
31 MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
32 MODULE_DESCRIPTION("Sun LDOM virtual disk client driver");
33 MODULE_LICENSE("GPL");
34 MODULE_VERSION(DRV_MODULE_VERSION);
35 
36 #define VDC_TX_RING_SIZE	512
37 
38 #define WAITING_FOR_LINK_UP	0x01
39 #define WAITING_FOR_TX_SPACE	0x02
40 #define WAITING_FOR_GEN_CMD	0x04
41 #define WAITING_FOR_ANY		-1
42 
43 struct vdc_req_entry {
44 	struct request		*req;
45 };
46 
47 struct vdc_port {
48 	struct vio_driver_state	vio;
49 
50 	struct gendisk		*disk;
51 
52 	struct vdc_completion	*cmp;
53 
54 	u64			req_id;
55 	u64			seq;
56 	struct vdc_req_entry	rq_arr[VDC_TX_RING_SIZE];
57 
58 	unsigned long		ring_cookies;
59 
60 	u64			max_xfer_size;
61 	u32			vdisk_block_size;
62 
63 	/* The server fills these in for us in the disk attribute
64 	 * ACK packet.
65 	 */
66 	u64			operations;
67 	u32			vdisk_size;
68 	u8			vdisk_type;
69 	u8			vdisk_mtype;
70 
71 	char			disk_name[32];
72 
73 	struct vio_disk_vtoc	label;
74 };
75 
76 static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio)
77 {
78 	return container_of(vio, struct vdc_port, vio);
79 }
80 
81 /* Ordered from largest major to lowest */
82 static struct vio_version vdc_versions[] = {
83 	{ .major = 1, .minor = 1 },
84 	{ .major = 1, .minor = 0 },
85 };
86 
87 static inline int vdc_version_supported(struct vdc_port *port,
88 					u16 major, u16 minor)
89 {
90 	return port->vio.ver.major == major && port->vio.ver.minor >= minor;
91 }
92 
93 #define VDCBLK_NAME	"vdisk"
94 static int vdc_major;
95 #define PARTITION_SHIFT	3
96 
97 static inline u32 vdc_tx_dring_avail(struct vio_dring_state *dr)
98 {
99 	return vio_dring_avail(dr, VDC_TX_RING_SIZE);
100 }
101 
102 static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo)
103 {
104 	struct gendisk *disk = bdev->bd_disk;
105 	sector_t nsect = get_capacity(disk);
106 	sector_t cylinders = nsect;
107 
108 	geo->heads = 0xff;
109 	geo->sectors = 0x3f;
110 	sector_div(cylinders, geo->heads * geo->sectors);
111 	geo->cylinders = cylinders;
112 	if ((sector_t)(geo->cylinders + 1) * geo->heads * geo->sectors < nsect)
113 		geo->cylinders = 0xffff;
114 
115 	return 0;
116 }
117 
118 /* Add ioctl/CDROM_GET_CAPABILITY to support cdrom_id in udev
119  * when vdisk_mtype is VD_MEDIA_TYPE_CD or VD_MEDIA_TYPE_DVD.
120  * Needed to be able to install inside an ldom from an iso image.
121  */
122 static int vdc_ioctl(struct block_device *bdev, fmode_t mode,
123 		     unsigned command, unsigned long argument)
124 {
125 	int i;
126 	struct gendisk *disk;
127 
128 	switch (command) {
129 	case CDROMMULTISESSION:
130 		pr_debug(PFX "Multisession CDs not supported\n");
131 		for (i = 0; i < sizeof(struct cdrom_multisession); i++)
132 			if (put_user(0, (char __user *)(argument + i)))
133 				return -EFAULT;
134 		return 0;
135 
136 	case CDROM_GET_CAPABILITY:
137 		disk = bdev->bd_disk;
138 
139 		if (bdev->bd_disk && (disk->flags & GENHD_FL_CD))
140 			return 0;
141 		return -EINVAL;
142 
143 	default:
144 		pr_debug(PFX "ioctl %08x not supported\n", command);
145 		return -EINVAL;
146 	}
147 }
148 
149 static const struct block_device_operations vdc_fops = {
150 	.owner		= THIS_MODULE,
151 	.getgeo		= vdc_getgeo,
152 	.ioctl		= vdc_ioctl,
153 };
154 
155 static void vdc_finish(struct vio_driver_state *vio, int err, int waiting_for)
156 {
157 	if (vio->cmp &&
158 	    (waiting_for == -1 ||
159 	     vio->cmp->waiting_for == waiting_for)) {
160 		vio->cmp->err = err;
161 		complete(&vio->cmp->com);
162 		vio->cmp = NULL;
163 	}
164 }
165 
166 static void vdc_handshake_complete(struct vio_driver_state *vio)
167 {
168 	vdc_finish(vio, 0, WAITING_FOR_LINK_UP);
169 }
170 
171 static int vdc_handle_unknown(struct vdc_port *port, void *arg)
172 {
173 	struct vio_msg_tag *pkt = arg;
174 
175 	printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n",
176 	       pkt->type, pkt->stype, pkt->stype_env, pkt->sid);
177 	printk(KERN_ERR PFX "Resetting connection.\n");
178 
179 	ldc_disconnect(port->vio.lp);
180 
181 	return -ECONNRESET;
182 }
183 
184 static int vdc_send_attr(struct vio_driver_state *vio)
185 {
186 	struct vdc_port *port = to_vdc_port(vio);
187 	struct vio_disk_attr_info pkt;
188 
189 	memset(&pkt, 0, sizeof(pkt));
190 
191 	pkt.tag.type = VIO_TYPE_CTRL;
192 	pkt.tag.stype = VIO_SUBTYPE_INFO;
193 	pkt.tag.stype_env = VIO_ATTR_INFO;
194 	pkt.tag.sid = vio_send_sid(vio);
195 
196 	pkt.xfer_mode = VIO_DRING_MODE;
197 	pkt.vdisk_block_size = port->vdisk_block_size;
198 	pkt.max_xfer_size = port->max_xfer_size;
199 
200 	viodbg(HS, "SEND ATTR xfer_mode[0x%x] blksz[%u] max_xfer[%llu]\n",
201 	       pkt.xfer_mode, pkt.vdisk_block_size, pkt.max_xfer_size);
202 
203 	return vio_ldc_send(&port->vio, &pkt, sizeof(pkt));
204 }
205 
206 static int vdc_handle_attr(struct vio_driver_state *vio, void *arg)
207 {
208 	struct vdc_port *port = to_vdc_port(vio);
209 	struct vio_disk_attr_info *pkt = arg;
210 
211 	viodbg(HS, "GOT ATTR stype[0x%x] ops[%llx] disk_size[%llu] disk_type[%x] "
212 	       "mtype[0x%x] xfer_mode[0x%x] blksz[%u] max_xfer[%llu]\n",
213 	       pkt->tag.stype, pkt->operations,
214 	       pkt->vdisk_size, pkt->vdisk_type, pkt->vdisk_mtype,
215 	       pkt->xfer_mode, pkt->vdisk_block_size,
216 	       pkt->max_xfer_size);
217 
218 	if (pkt->tag.stype == VIO_SUBTYPE_ACK) {
219 		switch (pkt->vdisk_type) {
220 		case VD_DISK_TYPE_DISK:
221 		case VD_DISK_TYPE_SLICE:
222 			break;
223 
224 		default:
225 			printk(KERN_ERR PFX "%s: Bogus vdisk_type 0x%x\n",
226 			       vio->name, pkt->vdisk_type);
227 			return -ECONNRESET;
228 		}
229 
230 		if (pkt->vdisk_block_size > port->vdisk_block_size) {
231 			printk(KERN_ERR PFX "%s: BLOCK size increased "
232 			       "%u --> %u\n",
233 			       vio->name,
234 			       port->vdisk_block_size, pkt->vdisk_block_size);
235 			return -ECONNRESET;
236 		}
237 
238 		port->operations = pkt->operations;
239 		port->vdisk_type = pkt->vdisk_type;
240 		if (vdc_version_supported(port, 1, 1)) {
241 			port->vdisk_size = pkt->vdisk_size;
242 			port->vdisk_mtype = pkt->vdisk_mtype;
243 		}
244 		if (pkt->max_xfer_size < port->max_xfer_size)
245 			port->max_xfer_size = pkt->max_xfer_size;
246 		port->vdisk_block_size = pkt->vdisk_block_size;
247 		return 0;
248 	} else {
249 		printk(KERN_ERR PFX "%s: Attribute NACK\n", vio->name);
250 
251 		return -ECONNRESET;
252 	}
253 }
254 
255 static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc)
256 {
257 	int err = desc->status;
258 
259 	vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD);
260 }
261 
262 static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
263 			unsigned int index)
264 {
265 	struct vio_disk_desc *desc = vio_dring_entry(dr, index);
266 	struct vdc_req_entry *rqe = &port->rq_arr[index];
267 	struct request *req;
268 
269 	if (unlikely(desc->hdr.state != VIO_DESC_DONE))
270 		return;
271 
272 	ldc_unmap(port->vio.lp, desc->cookies, desc->ncookies);
273 	desc->hdr.state = VIO_DESC_FREE;
274 	dr->cons = (index + 1) & (VDC_TX_RING_SIZE - 1);
275 
276 	req = rqe->req;
277 	if (req == NULL) {
278 		vdc_end_special(port, desc);
279 		return;
280 	}
281 
282 	rqe->req = NULL;
283 
284 	__blk_end_request(req, (desc->status ? -EIO : 0), desc->size);
285 
286 	/* restart blk queue when ring is half emptied */
287 	if (blk_queue_stopped(port->disk->queue) &&
288 	    vdc_tx_dring_avail(dr) * 100 / VDC_TX_RING_SIZE >= 50)
289 		blk_start_queue(port->disk->queue);
290 }
291 
292 static int vdc_ack(struct vdc_port *port, void *msgbuf)
293 {
294 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
295 	struct vio_dring_data *pkt = msgbuf;
296 
297 	if (unlikely(pkt->dring_ident != dr->ident ||
298 		     pkt->start_idx != pkt->end_idx ||
299 		     pkt->start_idx >= VDC_TX_RING_SIZE))
300 		return 0;
301 
302 	vdc_end_one(port, dr, pkt->start_idx);
303 
304 	return 0;
305 }
306 
307 static int vdc_nack(struct vdc_port *port, void *msgbuf)
308 {
309 	/* XXX Implement me XXX */
310 	return 0;
311 }
312 
313 static void vdc_event(void *arg, int event)
314 {
315 	struct vdc_port *port = arg;
316 	struct vio_driver_state *vio = &port->vio;
317 	unsigned long flags;
318 	int err;
319 
320 	spin_lock_irqsave(&vio->lock, flags);
321 
322 	if (unlikely(event == LDC_EVENT_RESET ||
323 		     event == LDC_EVENT_UP)) {
324 		vio_link_state_change(vio, event);
325 		spin_unlock_irqrestore(&vio->lock, flags);
326 		return;
327 	}
328 
329 	if (unlikely(event != LDC_EVENT_DATA_READY)) {
330 		printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event);
331 		spin_unlock_irqrestore(&vio->lock, flags);
332 		return;
333 	}
334 
335 	err = 0;
336 	while (1) {
337 		union {
338 			struct vio_msg_tag tag;
339 			u64 raw[8];
340 		} msgbuf;
341 
342 		err = ldc_read(vio->lp, &msgbuf, sizeof(msgbuf));
343 		if (unlikely(err < 0)) {
344 			if (err == -ECONNRESET)
345 				vio_conn_reset(vio);
346 			break;
347 		}
348 		if (err == 0)
349 			break;
350 		viodbg(DATA, "TAG [%02x:%02x:%04x:%08x]\n",
351 		       msgbuf.tag.type,
352 		       msgbuf.tag.stype,
353 		       msgbuf.tag.stype_env,
354 		       msgbuf.tag.sid);
355 		err = vio_validate_sid(vio, &msgbuf.tag);
356 		if (err < 0)
357 			break;
358 
359 		if (likely(msgbuf.tag.type == VIO_TYPE_DATA)) {
360 			if (msgbuf.tag.stype == VIO_SUBTYPE_ACK)
361 				err = vdc_ack(port, &msgbuf);
362 			else if (msgbuf.tag.stype == VIO_SUBTYPE_NACK)
363 				err = vdc_nack(port, &msgbuf);
364 			else
365 				err = vdc_handle_unknown(port, &msgbuf);
366 		} else if (msgbuf.tag.type == VIO_TYPE_CTRL) {
367 			err = vio_control_pkt_engine(vio, &msgbuf);
368 		} else {
369 			err = vdc_handle_unknown(port, &msgbuf);
370 		}
371 		if (err < 0)
372 			break;
373 	}
374 	if (err < 0)
375 		vdc_finish(&port->vio, err, WAITING_FOR_ANY);
376 	spin_unlock_irqrestore(&vio->lock, flags);
377 }
378 
379 static int __vdc_tx_trigger(struct vdc_port *port)
380 {
381 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
382 	struct vio_dring_data hdr = {
383 		.tag = {
384 			.type		= VIO_TYPE_DATA,
385 			.stype		= VIO_SUBTYPE_INFO,
386 			.stype_env	= VIO_DRING_DATA,
387 			.sid		= vio_send_sid(&port->vio),
388 		},
389 		.dring_ident		= dr->ident,
390 		.start_idx		= dr->prod,
391 		.end_idx		= dr->prod,
392 	};
393 	int err, delay;
394 
395 	hdr.seq = dr->snd_nxt;
396 	delay = 1;
397 	do {
398 		err = vio_ldc_send(&port->vio, &hdr, sizeof(hdr));
399 		if (err > 0) {
400 			dr->snd_nxt++;
401 			break;
402 		}
403 		udelay(delay);
404 		if ((delay <<= 1) > 128)
405 			delay = 128;
406 	} while (err == -EAGAIN);
407 
408 	return err;
409 }
410 
411 static int __send_request(struct request *req)
412 {
413 	struct vdc_port *port = req->rq_disk->private_data;
414 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
415 	struct scatterlist sg[port->ring_cookies];
416 	struct vdc_req_entry *rqe;
417 	struct vio_disk_desc *desc;
418 	unsigned int map_perm;
419 	int nsg, err, i;
420 	u64 len;
421 	u8 op;
422 
423 	map_perm = LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_IO;
424 
425 	if (rq_data_dir(req) == READ) {
426 		map_perm |= LDC_MAP_W;
427 		op = VD_OP_BREAD;
428 	} else {
429 		map_perm |= LDC_MAP_R;
430 		op = VD_OP_BWRITE;
431 	}
432 
433 	sg_init_table(sg, port->ring_cookies);
434 	nsg = blk_rq_map_sg(req->q, req, sg);
435 
436 	len = 0;
437 	for (i = 0; i < nsg; i++)
438 		len += sg[i].length;
439 
440 	desc = vio_dring_cur(dr);
441 
442 	err = ldc_map_sg(port->vio.lp, sg, nsg,
443 			 desc->cookies, port->ring_cookies,
444 			 map_perm);
445 	if (err < 0) {
446 		printk(KERN_ERR PFX "ldc_map_sg() failure, err=%d.\n", err);
447 		return err;
448 	}
449 
450 	rqe = &port->rq_arr[dr->prod];
451 	rqe->req = req;
452 
453 	desc->hdr.ack = VIO_ACK_ENABLE;
454 	desc->req_id = port->req_id;
455 	desc->operation = op;
456 	if (port->vdisk_type == VD_DISK_TYPE_DISK) {
457 		desc->slice = 0xff;
458 	} else {
459 		desc->slice = 0;
460 	}
461 	desc->status = ~0;
462 	desc->offset = (blk_rq_pos(req) << 9) / port->vdisk_block_size;
463 	desc->size = len;
464 	desc->ncookies = err;
465 
466 	/* This has to be a non-SMP write barrier because we are writing
467 	 * to memory which is shared with the peer LDOM.
468 	 */
469 	wmb();
470 	desc->hdr.state = VIO_DESC_READY;
471 
472 	err = __vdc_tx_trigger(port);
473 	if (err < 0) {
474 		printk(KERN_ERR PFX "vdc_tx_trigger() failure, err=%d\n", err);
475 	} else {
476 		port->req_id++;
477 		dr->prod = (dr->prod + 1) & (VDC_TX_RING_SIZE - 1);
478 	}
479 
480 	return err;
481 }
482 
483 static void do_vdc_request(struct request_queue *rq)
484 {
485 	struct request *req;
486 
487 	while ((req = blk_peek_request(rq)) != NULL) {
488 		struct vdc_port *port;
489 		struct vio_dring_state *dr;
490 
491 		port = req->rq_disk->private_data;
492 		dr = &port->vio.drings[VIO_DRIVER_TX_RING];
493 		if (unlikely(vdc_tx_dring_avail(dr) < 1))
494 			goto wait;
495 
496 		blk_start_request(req);
497 
498 		if (__send_request(req) < 0) {
499 			blk_requeue_request(rq, req);
500 wait:
501 			/* Avoid pointless unplugs. */
502 			blk_stop_queue(rq);
503 			break;
504 		}
505 	}
506 }
507 
508 static int generic_request(struct vdc_port *port, u8 op, void *buf, int len)
509 {
510 	struct vio_dring_state *dr;
511 	struct vio_completion comp;
512 	struct vio_disk_desc *desc;
513 	unsigned int map_perm;
514 	unsigned long flags;
515 	int op_len, err;
516 	void *req_buf;
517 
518 	if (!(((u64)1 << (u64)op) & port->operations))
519 		return -EOPNOTSUPP;
520 
521 	switch (op) {
522 	case VD_OP_BREAD:
523 	case VD_OP_BWRITE:
524 	default:
525 		return -EINVAL;
526 
527 	case VD_OP_FLUSH:
528 		op_len = 0;
529 		map_perm = 0;
530 		break;
531 
532 	case VD_OP_GET_WCE:
533 		op_len = sizeof(u32);
534 		map_perm = LDC_MAP_W;
535 		break;
536 
537 	case VD_OP_SET_WCE:
538 		op_len = sizeof(u32);
539 		map_perm = LDC_MAP_R;
540 		break;
541 
542 	case VD_OP_GET_VTOC:
543 		op_len = sizeof(struct vio_disk_vtoc);
544 		map_perm = LDC_MAP_W;
545 		break;
546 
547 	case VD_OP_SET_VTOC:
548 		op_len = sizeof(struct vio_disk_vtoc);
549 		map_perm = LDC_MAP_R;
550 		break;
551 
552 	case VD_OP_GET_DISKGEOM:
553 		op_len = sizeof(struct vio_disk_geom);
554 		map_perm = LDC_MAP_W;
555 		break;
556 
557 	case VD_OP_SET_DISKGEOM:
558 		op_len = sizeof(struct vio_disk_geom);
559 		map_perm = LDC_MAP_R;
560 		break;
561 
562 	case VD_OP_SCSICMD:
563 		op_len = 16;
564 		map_perm = LDC_MAP_RW;
565 		break;
566 
567 	case VD_OP_GET_DEVID:
568 		op_len = sizeof(struct vio_disk_devid);
569 		map_perm = LDC_MAP_W;
570 		break;
571 
572 	case VD_OP_GET_EFI:
573 	case VD_OP_SET_EFI:
574 		return -EOPNOTSUPP;
575 		break;
576 	};
577 
578 	map_perm |= LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_IO;
579 
580 	op_len = (op_len + 7) & ~7;
581 	req_buf = kzalloc(op_len, GFP_KERNEL);
582 	if (!req_buf)
583 		return -ENOMEM;
584 
585 	if (len > op_len)
586 		len = op_len;
587 
588 	if (map_perm & LDC_MAP_R)
589 		memcpy(req_buf, buf, len);
590 
591 	spin_lock_irqsave(&port->vio.lock, flags);
592 
593 	dr = &port->vio.drings[VIO_DRIVER_TX_RING];
594 
595 	/* XXX If we want to use this code generically we have to
596 	 * XXX handle TX ring exhaustion etc.
597 	 */
598 	desc = vio_dring_cur(dr);
599 
600 	err = ldc_map_single(port->vio.lp, req_buf, op_len,
601 			     desc->cookies, port->ring_cookies,
602 			     map_perm);
603 	if (err < 0) {
604 		spin_unlock_irqrestore(&port->vio.lock, flags);
605 		kfree(req_buf);
606 		return err;
607 	}
608 
609 	init_completion(&comp.com);
610 	comp.waiting_for = WAITING_FOR_GEN_CMD;
611 	port->vio.cmp = &comp;
612 
613 	desc->hdr.ack = VIO_ACK_ENABLE;
614 	desc->req_id = port->req_id;
615 	desc->operation = op;
616 	desc->slice = 0;
617 	desc->status = ~0;
618 	desc->offset = 0;
619 	desc->size = op_len;
620 	desc->ncookies = err;
621 
622 	/* This has to be a non-SMP write barrier because we are writing
623 	 * to memory which is shared with the peer LDOM.
624 	 */
625 	wmb();
626 	desc->hdr.state = VIO_DESC_READY;
627 
628 	err = __vdc_tx_trigger(port);
629 	if (err >= 0) {
630 		port->req_id++;
631 		dr->prod = (dr->prod + 1) & (VDC_TX_RING_SIZE - 1);
632 		spin_unlock_irqrestore(&port->vio.lock, flags);
633 
634 		wait_for_completion(&comp.com);
635 		err = comp.err;
636 	} else {
637 		port->vio.cmp = NULL;
638 		spin_unlock_irqrestore(&port->vio.lock, flags);
639 	}
640 
641 	if (map_perm & LDC_MAP_W)
642 		memcpy(buf, req_buf, len);
643 
644 	kfree(req_buf);
645 
646 	return err;
647 }
648 
649 static int vdc_alloc_tx_ring(struct vdc_port *port)
650 {
651 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
652 	unsigned long len, entry_size;
653 	int ncookies;
654 	void *dring;
655 
656 	entry_size = sizeof(struct vio_disk_desc) +
657 		(sizeof(struct ldc_trans_cookie) * port->ring_cookies);
658 	len = (VDC_TX_RING_SIZE * entry_size);
659 
660 	ncookies = VIO_MAX_RING_COOKIES;
661 	dring = ldc_alloc_exp_dring(port->vio.lp, len,
662 				    dr->cookies, &ncookies,
663 				    (LDC_MAP_SHADOW |
664 				     LDC_MAP_DIRECT |
665 				     LDC_MAP_RW));
666 	if (IS_ERR(dring))
667 		return PTR_ERR(dring);
668 
669 	dr->base = dring;
670 	dr->entry_size = entry_size;
671 	dr->num_entries = VDC_TX_RING_SIZE;
672 	dr->prod = dr->cons = 0;
673 	dr->pending = VDC_TX_RING_SIZE;
674 	dr->ncookies = ncookies;
675 
676 	return 0;
677 }
678 
679 static void vdc_free_tx_ring(struct vdc_port *port)
680 {
681 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
682 
683 	if (dr->base) {
684 		ldc_free_exp_dring(port->vio.lp, dr->base,
685 				   (dr->entry_size * dr->num_entries),
686 				   dr->cookies, dr->ncookies);
687 		dr->base = NULL;
688 		dr->entry_size = 0;
689 		dr->num_entries = 0;
690 		dr->pending = 0;
691 		dr->ncookies = 0;
692 	}
693 }
694 
695 static int probe_disk(struct vdc_port *port)
696 {
697 	struct vio_completion comp;
698 	struct request_queue *q;
699 	struct gendisk *g;
700 	int err;
701 
702 	init_completion(&comp.com);
703 	comp.err = 0;
704 	comp.waiting_for = WAITING_FOR_LINK_UP;
705 	port->vio.cmp = &comp;
706 
707 	vio_port_up(&port->vio);
708 
709 	wait_for_completion(&comp.com);
710 	if (comp.err)
711 		return comp.err;
712 
713 	err = generic_request(port, VD_OP_GET_VTOC,
714 			      &port->label, sizeof(port->label));
715 	if (err < 0) {
716 		printk(KERN_ERR PFX "VD_OP_GET_VTOC returns error %d\n", err);
717 		return err;
718 	}
719 
720 	if (vdc_version_supported(port, 1, 1)) {
721 		/* vdisk_size should be set during the handshake, if it wasn't
722 		 * then the underlying disk is reserved by another system
723 		 */
724 		if (port->vdisk_size == -1)
725 			return -ENODEV;
726 	} else {
727 		struct vio_disk_geom geom;
728 
729 		err = generic_request(port, VD_OP_GET_DISKGEOM,
730 				      &geom, sizeof(geom));
731 		if (err < 0) {
732 			printk(KERN_ERR PFX "VD_OP_GET_DISKGEOM returns "
733 			       "error %d\n", err);
734 			return err;
735 		}
736 		port->vdisk_size = ((u64)geom.num_cyl *
737 				    (u64)geom.num_hd *
738 				    (u64)geom.num_sec);
739 	}
740 
741 	q = blk_init_queue(do_vdc_request, &port->vio.lock);
742 	if (!q) {
743 		printk(KERN_ERR PFX "%s: Could not allocate queue.\n",
744 		       port->vio.name);
745 		return -ENOMEM;
746 	}
747 	g = alloc_disk(1 << PARTITION_SHIFT);
748 	if (!g) {
749 		printk(KERN_ERR PFX "%s: Could not allocate gendisk.\n",
750 		       port->vio.name);
751 		blk_cleanup_queue(q);
752 		return -ENOMEM;
753 	}
754 
755 	port->disk = g;
756 
757 	/* Each segment in a request is up to an aligned page in size. */
758 	blk_queue_segment_boundary(q, PAGE_SIZE - 1);
759 	blk_queue_max_segment_size(q, PAGE_SIZE);
760 
761 	blk_queue_max_segments(q, port->ring_cookies);
762 	blk_queue_max_hw_sectors(q, port->max_xfer_size);
763 	g->major = vdc_major;
764 	g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT;
765 	strcpy(g->disk_name, port->disk_name);
766 
767 	g->fops = &vdc_fops;
768 	g->queue = q;
769 	g->private_data = port;
770 	g->driverfs_dev = &port->vio.vdev->dev;
771 
772 	set_capacity(g, port->vdisk_size);
773 
774 	if (vdc_version_supported(port, 1, 1)) {
775 		switch (port->vdisk_mtype) {
776 		case VD_MEDIA_TYPE_CD:
777 			pr_info(PFX "Virtual CDROM %s\n", port->disk_name);
778 			g->flags |= GENHD_FL_CD;
779 			g->flags |= GENHD_FL_REMOVABLE;
780 			set_disk_ro(g, 1);
781 			break;
782 
783 		case VD_MEDIA_TYPE_DVD:
784 			pr_info(PFX "Virtual DVD %s\n", port->disk_name);
785 			g->flags |= GENHD_FL_CD;
786 			g->flags |= GENHD_FL_REMOVABLE;
787 			set_disk_ro(g, 1);
788 			break;
789 
790 		case VD_MEDIA_TYPE_FIXED:
791 			pr_info(PFX "Virtual Hard disk %s\n", port->disk_name);
792 			break;
793 		}
794 	}
795 
796 	pr_info(PFX "%s: %u sectors (%u MB) protocol %d.%d\n",
797 	       g->disk_name,
798 	       port->vdisk_size, (port->vdisk_size >> (20 - 9)),
799 	       port->vio.ver.major, port->vio.ver.minor);
800 
801 	add_disk(g);
802 
803 	return 0;
804 }
805 
806 static struct ldc_channel_config vdc_ldc_cfg = {
807 	.event		= vdc_event,
808 	.mtu		= 64,
809 	.mode		= LDC_MODE_UNRELIABLE,
810 };
811 
812 static struct vio_driver_ops vdc_vio_ops = {
813 	.send_attr		= vdc_send_attr,
814 	.handle_attr		= vdc_handle_attr,
815 	.handshake_complete	= vdc_handshake_complete,
816 };
817 
818 static void print_version(void)
819 {
820 	static int version_printed;
821 
822 	if (version_printed++ == 0)
823 		printk(KERN_INFO "%s", version);
824 }
825 
826 static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
827 {
828 	struct mdesc_handle *hp;
829 	struct vdc_port *port;
830 	int err;
831 
832 	print_version();
833 
834 	hp = mdesc_grab();
835 
836 	err = -ENODEV;
837 	if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) {
838 		printk(KERN_ERR PFX "Port id [%llu] too large.\n",
839 		       vdev->dev_no);
840 		goto err_out_release_mdesc;
841 	}
842 
843 	port = kzalloc(sizeof(*port), GFP_KERNEL);
844 	err = -ENOMEM;
845 	if (!port) {
846 		printk(KERN_ERR PFX "Cannot allocate vdc_port.\n");
847 		goto err_out_release_mdesc;
848 	}
849 
850 	if (vdev->dev_no >= 26)
851 		snprintf(port->disk_name, sizeof(port->disk_name),
852 			 VDCBLK_NAME "%c%c",
853 			 'a' + ((int)vdev->dev_no / 26) - 1,
854 			 'a' + ((int)vdev->dev_no % 26));
855 	else
856 		snprintf(port->disk_name, sizeof(port->disk_name),
857 			 VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26));
858 	port->vdisk_size = -1;
859 
860 	err = vio_driver_init(&port->vio, vdev, VDEV_DISK,
861 			      vdc_versions, ARRAY_SIZE(vdc_versions),
862 			      &vdc_vio_ops, port->disk_name);
863 	if (err)
864 		goto err_out_free_port;
865 
866 	port->vdisk_block_size = 512;
867 	port->max_xfer_size = ((128 * 1024) / port->vdisk_block_size);
868 	port->ring_cookies = ((port->max_xfer_size *
869 			       port->vdisk_block_size) / PAGE_SIZE) + 2;
870 
871 	err = vio_ldc_alloc(&port->vio, &vdc_ldc_cfg, port);
872 	if (err)
873 		goto err_out_free_port;
874 
875 	err = vdc_alloc_tx_ring(port);
876 	if (err)
877 		goto err_out_free_ldc;
878 
879 	err = probe_disk(port);
880 	if (err)
881 		goto err_out_free_tx_ring;
882 
883 	dev_set_drvdata(&vdev->dev, port);
884 
885 	mdesc_release(hp);
886 
887 	return 0;
888 
889 err_out_free_tx_ring:
890 	vdc_free_tx_ring(port);
891 
892 err_out_free_ldc:
893 	vio_ldc_free(&port->vio);
894 
895 err_out_free_port:
896 	kfree(port);
897 
898 err_out_release_mdesc:
899 	mdesc_release(hp);
900 	return err;
901 }
902 
903 static int vdc_port_remove(struct vio_dev *vdev)
904 {
905 	struct vdc_port *port = dev_get_drvdata(&vdev->dev);
906 
907 	if (port) {
908 		del_timer_sync(&port->vio.timer);
909 
910 		vdc_free_tx_ring(port);
911 		vio_ldc_free(&port->vio);
912 
913 		dev_set_drvdata(&vdev->dev, NULL);
914 
915 		kfree(port);
916 	}
917 	return 0;
918 }
919 
920 static const struct vio_device_id vdc_port_match[] = {
921 	{
922 		.type = "vdc-port",
923 	},
924 	{},
925 };
926 MODULE_DEVICE_TABLE(vio, vdc_port_match);
927 
928 static struct vio_driver vdc_port_driver = {
929 	.id_table	= vdc_port_match,
930 	.probe		= vdc_port_probe,
931 	.remove		= vdc_port_remove,
932 	.name		= "vdc_port",
933 };
934 
935 static int __init vdc_init(void)
936 {
937 	int err;
938 
939 	err = register_blkdev(0, VDCBLK_NAME);
940 	if (err < 0)
941 		goto out_err;
942 
943 	vdc_major = err;
944 
945 	err = vio_register_driver(&vdc_port_driver);
946 	if (err)
947 		goto out_unregister_blkdev;
948 
949 	return 0;
950 
951 out_unregister_blkdev:
952 	unregister_blkdev(vdc_major, VDCBLK_NAME);
953 	vdc_major = 0;
954 
955 out_err:
956 	return err;
957 }
958 
959 static void __exit vdc_exit(void)
960 {
961 	vio_unregister_driver(&vdc_port_driver);
962 	unregister_blkdev(vdc_major, VDCBLK_NAME);
963 }
964 
965 module_init(vdc_init);
966 module_exit(vdc_exit);
967