]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.xen/xen-blkfront-cdrom
Corrected links and text on ids.cgi
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.xen / xen-blkfront-cdrom
1 From: plc@novell.com
2 Subject: implement forwarding of CD-ROM specific commands
3 Patch-mainline: obsolete
4 References: fate#300964
5
6 --- sle11-2009-06-04.orig/drivers/cdrom/Makefile 2009-06-04 10:17:48.000000000 +0200
7 +++ sle11-2009-06-04/drivers/cdrom/Makefile 2009-06-04 10:47:04.000000000 +0200
8 @@ -9,6 +9,7 @@ obj-$(CONFIG_BLK_DEV_IDECD) +=
9 obj-$(CONFIG_BLK_DEV_SR) += cdrom.o
10 obj-$(CONFIG_PARIDE_PCD) += cdrom.o
11 obj-$(CONFIG_CDROM_PKTCDVD) += cdrom.o
12 +obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += cdrom.o
13
14 obj-$(CONFIG_VIOCD) += viocd.o cdrom.o
15 obj-$(CONFIG_GDROM) += gdrom.o cdrom.o
16 --- sle11-2009-06-04.orig/drivers/xen/blkfront/Makefile 2009-06-04 10:17:48.000000000 +0200
17 +++ sle11-2009-06-04/drivers/xen/blkfront/Makefile 2009-06-04 10:47:04.000000000 +0200
18 @@ -1,5 +1,5 @@
19
20 obj-$(CONFIG_XEN_BLKDEV_FRONTEND) := xenblk.o
21
22 -xenblk-objs := blkfront.o vbd.o
23 +xenblk-objs := blkfront.o vbd.o vcd.o
24
25 --- sle11-2009-06-04.orig/drivers/xen/blkfront/blkfront.c 2009-06-04 10:46:54.000000000 +0200
26 +++ sle11-2009-06-04/drivers/xen/blkfront/blkfront.c 2009-06-04 10:47:04.000000000 +0200
27 @@ -377,6 +377,8 @@ static void connect(struct blkfront_info
28 add_disk(info->gd);
29
30 info->is_ready = 1;
31 +
32 + register_vcd(info);
33 }
34
35 /**
36 @@ -407,6 +409,8 @@ static void blkfront_closing(struct xenb
37
38 xlvbd_sysfs_delif(info);
39
40 + unregister_vcd(info);
41 +
42 xlvbd_del(info);
43
44 out:
45 --- sle11-2009-06-04.orig/drivers/xen/blkfront/block.h 2009-06-04 10:21:09.000000000 +0200
46 +++ sle11-2009-06-04/drivers/xen/blkfront/block.h 2009-06-04 10:47:04.000000000 +0200
47 @@ -155,4 +155,8 @@ static inline void xlvbd_sysfs_delif(str
48 }
49 #endif
50
51 +/* Virtual cdrom block-device */
52 +extern void register_vcd(struct blkfront_info *info);
53 +extern void unregister_vcd(struct blkfront_info *info);
54 +
55 #endif /* __XEN_DRIVERS_BLOCK_H__ */
56 --- sle11-2009-06-04.orig/drivers/xen/blkfront/vbd.c 2009-06-04 10:21:09.000000000 +0200
57 +++ sle11-2009-06-04/drivers/xen/blkfront/vbd.c 2009-06-04 10:47:04.000000000 +0200
58 @@ -281,7 +281,8 @@ xlvbd_add(blkif_sector_t capacity, int v
59 goto out;
60 info->mi = mi;
61
62 - if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
63 + if (!(vdisk_info & VDISK_CDROM) &&
64 + (minor & ((1 << mi->type->partn_shift) - 1)) == 0)
65 nr_minors = 1 << mi->type->partn_shift;
66
67 gd = alloc_disk(nr_minors);
68 @@ -290,7 +291,7 @@ xlvbd_add(blkif_sector_t capacity, int v
69
70 offset = mi->index * mi->type->disks_per_major +
71 (minor >> mi->type->partn_shift);
72 - if (nr_minors > 1) {
73 + if (nr_minors > 1 || (vdisk_info & VDISK_CDROM)) {
74 if (offset < 26) {
75 sprintf(gd->disk_name, "%s%c",
76 mi->type->diskname, 'a' + offset );
77 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
78 +++ sle11-2009-06-04/drivers/xen/blkfront/vcd.c 2009-06-04 10:47:04.000000000 +0200
79 @@ -0,0 +1,476 @@
80 +/*******************************************************************************
81 +* vcd.c
82 +*
83 +* Implements CDROM cmd packet passing between frontend guest and backend driver.
84 +*
85 +* Copyright (c) 2008, Pat Campell plc@novell.com
86 +*
87 +* Permission is hereby granted, free of charge, to any person obtaining a copy
88 +* of this source file (the "Software"), to deal in the Software without
89 +* restriction, including without limitation the rights to use, copy, modify,
90 +* merge, publish, distribute, sublicense, and/or sell copies of the Software,
91 +* and to permit persons to whom the Software is furnished to do so, subject to
92 +* the following conditions:
93 +*
94 +* The above copyright notice and this permission notice shall be included in
95 +* all copies or substantial portions of the Software.
96 +*
97 +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
98 +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
99 +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
100 +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
101 +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
102 +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
103 +* IN THE SOFTWARE.
104 +*/
105 +
106 +#define REVISION "$Revision: 1.0 $"
107 +
108 +#include <linux/module.h>
109 +#include <linux/blkdev.h>
110 +#include <linux/list.h>
111 +#include <linux/cdrom.h>
112 +#include <xen/interface/io/cdromif.h>
113 +#include "block.h"
114 +
115 +/* List of cdrom_device_info, can have as many as blkfront supports */
116 +struct vcd_disk {
117 + struct list_head vcd_entry;
118 + struct cdrom_device_info vcd_cdrom_info;
119 + spinlock_t vcd_cdrom_info_lock;
120 +};
121 +static LIST_HEAD(vcd_disks);
122 +static DEFINE_SPINLOCK(vcd_disks_lock);
123 +
124 +static struct vcd_disk * xencdrom_get_list_entry(struct gendisk *disk)
125 +{
126 + struct vcd_disk * ret_vcd = NULL;
127 + struct vcd_disk * vcd;
128 +
129 + spin_lock(&vcd_disks_lock);
130 + list_for_each_entry(vcd, &vcd_disks, vcd_entry) {
131 + if (vcd->vcd_cdrom_info.disk == disk) {
132 + spin_lock(&vcd->vcd_cdrom_info_lock);
133 + ret_vcd = vcd;
134 + break;
135 + }
136 + }
137 + spin_unlock(&vcd_disks_lock);
138 + return ret_vcd;
139 +}
140 +
141 +static void submit_message(struct blkfront_info *info, void * sp)
142 +{
143 + struct request *req = NULL;
144 +
145 + req = blk_get_request(info->rq, READ, __GFP_WAIT);
146 + if (blk_rq_map_kern(info->rq, req, sp, PAGE_SIZE, __GFP_WAIT))
147 + goto out;
148 +
149 + req->rq_disk = info->gd;
150 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)
151 + req->cmd_type = REQ_TYPE_BLOCK_PC;
152 + req->cmd_flags |= REQ_NOMERGE;
153 +#else
154 + req->flags |= REQ_BLOCK_PC;
155 +#endif
156 + req->sector = 0;
157 + req->nr_sectors = 1;
158 + req->timeout = 60*HZ;
159 +
160 + blk_execute_rq(req->q, info->gd, req, 1);
161 +
162 +out:
163 + blk_put_request(req);
164 +}
165 +
166 +static int submit_cdrom_cmd(struct blkfront_info *info,
167 + struct packet_command * cgc)
168 +{
169 + int ret = 0;
170 + struct page *page;
171 + size_t size;
172 + union xen_block_packet *sp;
173 + struct xen_cdrom_packet *xcp;
174 + struct vcd_generic_command * vgc;
175 +
176 + if (cgc->buffer && cgc->buflen > MAX_PACKET_DATA) {
177 + printk(KERN_WARNING "%s() Packet buffer length is to large \n", __func__);
178 + return -EIO;
179 + }
180 +
181 + page = alloc_page(GFP_NOIO);
182 + if (!page) {
183 + printk(KERN_CRIT "%s() Unable to allocate page\n", __func__);
184 + return -ENOMEM;
185 + }
186 +
187 + size = PAGE_SIZE;
188 + memset(page_address(page), 0, PAGE_SIZE);
189 + sp = page_address(page);
190 + xcp = &(sp->xcp);
191 + xcp->type = XEN_TYPE_CDROM_PACKET;
192 + xcp->payload_offset = PACKET_PAYLOAD_OFFSET;
193 +
194 + vgc = (struct vcd_generic_command *)((char *)sp + xcp->payload_offset);
195 + memcpy(vgc->cmd, cgc->cmd, CDROM_PACKET_SIZE);
196 + vgc->stat = cgc->stat;
197 + vgc->data_direction = cgc->data_direction;
198 + vgc->quiet = cgc->quiet;
199 + vgc->timeout = cgc->timeout;
200 + if (cgc->sense) {
201 + vgc->sense_offset = PACKET_SENSE_OFFSET;
202 + memcpy((char *)sp + vgc->sense_offset, cgc->sense, sizeof(struct request_sense));
203 + }
204 + if (cgc->buffer) {
205 + vgc->buffer_offset = PACKET_BUFFER_OFFSET;
206 + memcpy((char *)sp + vgc->buffer_offset, cgc->buffer, cgc->buflen);
207 + vgc->buflen = cgc->buflen;
208 + }
209 +
210 + submit_message(info,sp);
211 +
212 + if (xcp->ret)
213 + ret = xcp->err;
214 +
215 + if (cgc->sense) {
216 + memcpy(cgc->sense, (char *)sp + PACKET_SENSE_OFFSET, sizeof(struct request_sense));
217 + }
218 + if (cgc->buffer && cgc->buflen) {
219 + memcpy(cgc->buffer, (char *)sp + PACKET_BUFFER_OFFSET, cgc->buflen);
220 + }
221 +
222 + __free_page(page);
223 + return ret;
224 +}
225 +
226 +
227 +static int xencdrom_open(struct cdrom_device_info *cdi, int purpose)
228 +{
229 + int ret = 0;
230 + struct page *page;
231 + struct blkfront_info *info;
232 + union xen_block_packet *sp;
233 + struct xen_cdrom_open *xco;
234 +
235 + info = cdi->disk->private_data;
236 +
237 + if (strlen(info->xbdev->otherend) > MAX_PACKET_DATA) {
238 + return -EIO;
239 + }
240 +
241 + page = alloc_page(GFP_NOIO);
242 + if (!page) {
243 + printk(KERN_CRIT "%s() Unable to allocate page\n", __func__);
244 + return -ENOMEM;
245 + }
246 +
247 + memset(page_address(page), 0, PAGE_SIZE);
248 + sp = page_address(page);
249 + xco = &(sp->xco);
250 + xco->type = XEN_TYPE_CDROM_OPEN;
251 + xco->payload_offset = sizeof(struct xen_cdrom_open);
252 + strcpy((char *)sp + xco->payload_offset, info->xbdev->otherend);
253 +
254 + submit_message(info,sp);
255 +
256 + if (xco->ret) {
257 + ret = xco->err;
258 + goto out;
259 + }
260 +
261 + if (xco->media_present)
262 + set_capacity(cdi->disk, xco->sectors);
263 +
264 +out:
265 + __free_page(page);
266 + return ret;
267 +}
268 +
269 +static void xencdrom_release(struct cdrom_device_info *cdi)
270 +{
271 +}
272 +
273 +static int xencdrom_media_changed(struct cdrom_device_info *cdi, int disc_nr)
274 +{
275 + int ret;
276 + struct page *page;
277 + struct blkfront_info *info;
278 + union xen_block_packet *sp;
279 + struct xen_cdrom_media_changed *xcmc;
280 +
281 + info = cdi->disk->private_data;
282 +
283 + page = alloc_page(GFP_NOIO);
284 + if (!page) {
285 + printk(KERN_CRIT "%s() Unable to allocate page\n", __func__);
286 + return -ENOMEM;
287 + }
288 +
289 + memset(page_address(page), 0, PAGE_SIZE);
290 + sp = page_address(page);
291 + xcmc = &(sp->xcmc);
292 + xcmc->type = XEN_TYPE_CDROM_MEDIA_CHANGED;
293 + submit_message(info,sp);
294 + ret = xcmc->media_changed;
295 +
296 + __free_page(page);
297 +
298 + return ret;
299 +}
300 +
301 +static int xencdrom_tray_move(struct cdrom_device_info *cdi, int position)
302 +{
303 + int ret;
304 + struct packet_command cgc;
305 + struct blkfront_info *info;
306 +
307 + info = cdi->disk->private_data;
308 + init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
309 + cgc.cmd[0] = GPCMD_START_STOP_UNIT;
310 + if (position)
311 + cgc.cmd[4] = 2;
312 + else
313 + cgc.cmd[4] = 3;
314 + ret = submit_cdrom_cmd(info, &cgc);
315 + return ret;
316 +}
317 +
318 +static int xencdrom_lock_door(struct cdrom_device_info *cdi, int lock)
319 +{
320 + int ret = 0;
321 + struct blkfront_info *info;
322 + struct packet_command cgc;
323 +
324 + info = cdi->disk->private_data;
325 + init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
326 + cgc.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
327 + cgc.cmd[4] = lock;
328 + ret = submit_cdrom_cmd(info, &cgc);
329 + return ret;
330 +}
331 +
332 +static int xencdrom_packet(struct cdrom_device_info *cdi,
333 + struct packet_command *cgc)
334 +{
335 + int ret = -EIO;
336 + struct blkfront_info *info;
337 +
338 + info = cdi->disk->private_data;
339 + ret = submit_cdrom_cmd(info, cgc);
340 + cgc->stat = ret;
341 + return ret;
342 +}
343 +
344 +static int xencdrom_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
345 + void *arg)
346 +{
347 + return -EINVAL;
348 +}
349 +
350 +/* Query backend to see if CDROM packets are supported */
351 +static int xencdrom_supported(struct blkfront_info *info)
352 +{
353 + struct page *page;
354 + union xen_block_packet *sp;
355 + struct xen_cdrom_support *xcs;
356 +
357 + page = alloc_page(GFP_NOIO);
358 + if (!page) {
359 + printk(KERN_CRIT "%s() Unable to allocate page\n", __func__);
360 + return -ENOMEM;
361 + }
362 +
363 + memset(page_address(page), 0, PAGE_SIZE);
364 + sp = page_address(page);
365 + xcs = &(sp->xcs);
366 + xcs->type = XEN_TYPE_CDROM_SUPPORT;
367 + submit_message(info,sp);
368 + return xcs->supported;
369 +}
370 +
371 +static struct cdrom_device_ops xencdrom_dops = {
372 + .open = xencdrom_open,
373 + .release = xencdrom_release,
374 + .media_changed = xencdrom_media_changed,
375 + .tray_move = xencdrom_tray_move,
376 + .lock_door = xencdrom_lock_door,
377 + .generic_packet = xencdrom_packet,
378 + .audio_ioctl = xencdrom_audio_ioctl,
379 + .capability = (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | \
380 + CDC_MEDIA_CHANGED | CDC_GENERIC_PACKET | CDC_DVD | \
381 + CDC_CD_R),
382 + .n_minors = 1,
383 +};
384 +
385 +static int xencdrom_block_open(struct inode *inode, struct file *file)
386 +{
387 + struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
388 + struct vcd_disk * vcd;
389 + int ret = 0;
390 +
391 + if ((vcd = xencdrom_get_list_entry(info->gd))) {
392 + ret = cdrom_open(&vcd->vcd_cdrom_info, inode, file);
393 + info->users = vcd->vcd_cdrom_info.use_count;
394 + spin_unlock(&vcd->vcd_cdrom_info_lock);
395 + }
396 + return ret;
397 +}
398 +
399 +static int xencdrom_block_release(struct inode *inode, struct file *file)
400 +{
401 + struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
402 + struct vcd_disk * vcd;
403 + int ret = 0;
404 +
405 + if ((vcd = xencdrom_get_list_entry(info->gd))) {
406 + ret = cdrom_release(&vcd->vcd_cdrom_info, file);
407 + spin_unlock(&vcd->vcd_cdrom_info_lock);
408 + if (vcd->vcd_cdrom_info.use_count == 0) {
409 + info->users = 1;
410 + blkif_release(inode, file);
411 + }
412 + }
413 + return ret;
414 +}
415 +
416 +static int xencdrom_block_ioctl(struct inode *inode, struct file *file,
417 + unsigned cmd, unsigned long arg)
418 +{
419 + struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
420 + struct vcd_disk * vcd;
421 + int ret = 0;
422 +
423 + if (!(vcd = xencdrom_get_list_entry(info->gd)))
424 + goto out;
425 +
426 + switch (cmd) {
427 + case 2285: /* SG_IO */
428 + ret = -ENOSYS;
429 + break;
430 + case CDROMEJECT:
431 + ret = xencdrom_tray_move(&vcd->vcd_cdrom_info, 1);
432 + break;
433 + case CDROMCLOSETRAY:
434 + ret = xencdrom_tray_move(&vcd->vcd_cdrom_info, 0);
435 + break;
436 + case CDROM_GET_CAPABILITY:
437 + ret = vcd->vcd_cdrom_info.ops->capability & ~vcd->vcd_cdrom_info.mask;
438 + break;
439 + case CDROM_SET_OPTIONS:
440 + ret = vcd->vcd_cdrom_info.options;
441 + break;
442 + case CDROM_SEND_PACKET:
443 + {
444 + struct packet_command * cgc = (struct packet_command *)arg;
445 + ret = submit_cdrom_cmd(info, cgc);
446 + }
447 + break;
448 + default:
449 + /* Not supported, augment supported above if necessary */
450 + printk( "%s():%d Unsupported IOCTL:%x \n", __func__, __LINE__, cmd);
451 + ret = -ENOTTY;
452 + break;
453 + }
454 + spin_unlock(&vcd->vcd_cdrom_info_lock);
455 +out:
456 + return ret;
457 +}
458 +
459 +/* Called as result of cdrom_open, vcd_cdrom_info_lock already held */
460 +static int xencdrom_block_media_changed(struct gendisk *disk)
461 +{
462 + struct vcd_disk * vcd;
463 + struct vcd_disk * ret_vcd = NULL;
464 + int ret = 0;
465 +
466 + spin_lock(&vcd_disks_lock);
467 + list_for_each_entry(vcd, &vcd_disks, vcd_entry) {
468 + if (vcd->vcd_cdrom_info.disk == disk) {
469 + ret_vcd = vcd;
470 + break;
471 + }
472 + }
473 + spin_unlock(&vcd_disks_lock);
474 + if (ret_vcd) {
475 + ret = cdrom_media_changed(&ret_vcd->vcd_cdrom_info);
476 + }
477 + return ret;
478 +}
479 +
480 +static struct block_device_operations xencdrom_bdops =
481 +{
482 + .owner = THIS_MODULE,
483 + .open = xencdrom_block_open,
484 + .release = xencdrom_block_release,
485 + .ioctl = xencdrom_block_ioctl,
486 + .media_changed = xencdrom_block_media_changed,
487 +};
488 +
489 +void register_vcd(struct blkfront_info *info)
490 +{
491 + struct gendisk * gd = info->gd;
492 + struct vcd_disk * vcd;
493 +
494 + /* Make sure this is for a CD device */
495 + if (!(gd->flags & GENHD_FL_CD))
496 + goto out;
497 +
498 + /* Make sure we have backend support */
499 + if (!xencdrom_supported(info)) {
500 + goto out;
501 + }
502 +
503 + /* Create new vcd_disk and fill in cdrom_info */
504 + vcd = (struct vcd_disk *)kzalloc(sizeof(struct vcd_disk), GFP_KERNEL);
505 + if (!vcd) {
506 + printk(KERN_INFO "%s(): Unable to allocate vcd struct!\n", __func__);
507 + goto out;
508 + }
509 + spin_lock_init(&vcd->vcd_cdrom_info_lock);
510 +
511 + vcd->vcd_cdrom_info.ops = &xencdrom_dops;
512 + vcd->vcd_cdrom_info.speed = 4;
513 + vcd->vcd_cdrom_info.capacity = 1;
514 + vcd->vcd_cdrom_info.options = 0;
515 + strcpy(vcd->vcd_cdrom_info.name, gd->disk_name);
516 + vcd->vcd_cdrom_info.mask = ( CDC_CD_RW | CDC_DVD_R | CDC_DVD_RAM |
517 + CDC_SELECT_DISC | CDC_SELECT_SPEED |
518 + CDC_MRW | CDC_MRW_W | CDC_RAM);
519 +
520 + if (register_cdrom(&(vcd->vcd_cdrom_info)) != 0) {
521 + printk(KERN_WARNING "%s() Cannot register blkdev as a cdrom %d!\n", __func__,
522 + gd->major);
523 + goto err_out;
524 + }
525 + xencdrom_bdops.owner = gd->fops->owner;
526 + gd->fops = &xencdrom_bdops;
527 + vcd->vcd_cdrom_info.disk = gd;
528 +
529 + spin_lock(&vcd_disks_lock);
530 + list_add(&(vcd->vcd_entry), &vcd_disks);
531 + spin_unlock(&vcd_disks_lock);
532 +out:
533 + return;
534 +err_out:
535 + kfree(vcd);
536 +}
537 +
538 +void unregister_vcd(struct blkfront_info *info) {
539 + struct gendisk * gd = info->gd;
540 + struct vcd_disk * vcd;
541 +
542 + spin_lock(&vcd_disks_lock);
543 + list_for_each_entry(vcd, &vcd_disks, vcd_entry) {
544 + if (vcd->vcd_cdrom_info.disk == gd) {
545 + spin_lock(&vcd->vcd_cdrom_info_lock);
546 + unregister_cdrom(&vcd->vcd_cdrom_info);
547 + list_del(&vcd->vcd_entry);
548 + spin_unlock(&vcd->vcd_cdrom_info_lock);
549 + kfree(vcd);
550 + break;
551 + }
552 + }
553 + spin_unlock(&vcd_disks_lock);
554 +}
555 +
556 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
557 +++ sle11-2009-06-04/include/xen/interface/io/cdromif.h 2009-06-04 10:47:04.000000000 +0200
558 @@ -0,0 +1,120 @@
559 +/******************************************************************************
560 + * cdromif.h
561 + *
562 + * Shared definitions between backend driver and Xen guest Virtual CDROM
563 + * block device.
564 + *
565 + * Copyright (c) 2008, Pat Campell plc@novell.com
566 + *
567 + * Permission is hereby granted, free of charge, to any person obtaining a copy
568 + * of this source file (the "Software"), to deal in the Software without
569 + * restriction, including without limitation the rights to use, copy, modify,
570 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
571 + * and to permit persons to whom the Software is furnished to do so, subject to
572 + * the following conditions:
573 + *
574 + * The above copyright notice and this permission notice shall be included in
575 + * all copies or substantial portions of the Software.
576 + *
577 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
578 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
579 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
580 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
581 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
582 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
583 + * IN THE SOFTWARE.
584 + */
585 +
586 +#ifndef __XEN_PUBLIC_IO_CDROMIF_H__
587 +#define __XEN_PUBLIC_IO_CDROMIF_H__
588 +
589 +/*
590 + * Queries backend for CDROM support
591 + */
592 +#define XEN_TYPE_CDROM_SUPPORT _IO('c', 1)
593 +
594 +struct xen_cdrom_support
595 +{
596 + uint32_t type;
597 + int8_t ret; /* returned, 0 succeded, -1 error */
598 + int8_t err; /* returned, backend errno */
599 + int8_t supported; /* returned, 1 supported */
600 +};
601 +
602 +/*
603 + * Opens backend device, returns drive geometry or
604 + * any encountered errors
605 + */
606 +#define XEN_TYPE_CDROM_OPEN _IO('c', 2)
607 +
608 +struct xen_cdrom_open
609 +{
610 + uint32_t type;
611 + int8_t ret;
612 + int8_t err;
613 + int8_t pad;
614 + int8_t media_present; /* returned */
615 + uint32_t sectors; /* returned */
616 + uint32_t sector_size; /* returned */
617 + int32_t payload_offset; /* offset to backend node name payload */
618 +};
619 +
620 +/*
621 + * Queries backend for media changed status
622 + */
623 +#define XEN_TYPE_CDROM_MEDIA_CHANGED _IO('c', 3)
624 +
625 +struct xen_cdrom_media_changed
626 +{
627 + uint32_t type;
628 + int8_t ret;
629 + int8_t err;
630 + int8_t media_changed; /* returned */
631 +};
632 +
633 +/*
634 + * Sends vcd generic CDROM packet to backend, followed
635 + * immediately by the vcd_generic_command payload
636 + */
637 +#define XEN_TYPE_CDROM_PACKET _IO('c', 4)
638 +
639 +struct xen_cdrom_packet
640 +{
641 + uint32_t type;
642 + int8_t ret;
643 + int8_t err;
644 + int8_t pad[2];
645 + int32_t payload_offset; /* offset to vcd_generic_command payload */
646 +};
647 +
648 +/* CDROM_PACKET_COMMAND, payload for XEN_TYPE_CDROM_PACKET */
649 +struct vcd_generic_command
650 +{
651 + uint8_t cmd[CDROM_PACKET_SIZE];
652 + uint8_t pad[4];
653 + uint32_t buffer_offset;
654 + uint32_t buflen;
655 + int32_t stat;
656 + uint32_t sense_offset;
657 + uint8_t data_direction;
658 + uint8_t pad1[3];
659 + int32_t quiet;
660 + int32_t timeout;
661 +};
662 +
663 +union xen_block_packet
664 +{
665 + uint32_t type;
666 + struct xen_cdrom_support xcs;
667 + struct xen_cdrom_open xco;
668 + struct xen_cdrom_media_changed xcmc;
669 + struct xen_cdrom_packet xcp;
670 +};
671 +
672 +#define PACKET_PAYLOAD_OFFSET (sizeof(struct xen_cdrom_packet))
673 +#define PACKET_SENSE_OFFSET (PACKET_PAYLOAD_OFFSET + sizeof(struct vcd_generic_command))
674 +#define PACKET_BUFFER_OFFSET (PACKET_SENSE_OFFSET + sizeof(struct request_sense))
675 +#define MAX_PACKET_DATA (PAGE_SIZE - sizeof(struct xen_cdrom_packet) - \
676 + sizeof(struct vcd_generic_command) - sizeof(struct request_sense))
677 +
678 +#endif