Commit 14925120 authored by Stephen Rothwell's avatar Stephen Rothwell Committed by Linus Torvalds

[PATCH] ppc64 iSeries virtual DVD-RAM

This patch adds the ability to use DVD-RAM drives to the iSeries virtual
cdrom driver.  This version adresses (hopefully) Jens comments on the
previous one.
Signed-off-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ec2a9baf
...@@ -121,7 +121,10 @@ struct capability_entry { ...@@ -121,7 +121,10 @@ struct capability_entry {
}; };
static struct capability_entry capability_table[] __initdata = { static struct capability_entry capability_table[] __initdata = {
{ "6330", CDC_LOCK | CDC_DVD_RAM }, { "6330", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
{ "6331", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
{ "6333", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
{ "632A", CDC_LOCK | CDC_DVD_RAM | CDC_RAM },
{ "6321", CDC_LOCK }, { "6321", CDC_LOCK },
{ "632B", 0 }, { "632B", 0 },
{ NULL , CDC_LOCK }, { NULL , CDC_LOCK },
...@@ -332,10 +335,19 @@ static int send_request(struct request *req) ...@@ -332,10 +335,19 @@ static int send_request(struct request *req)
struct disk_info *diskinfo = req->rq_disk->private_data; struct disk_info *diskinfo = req->rq_disk->private_data;
u64 len; u64 len;
dma_addr_t dmaaddr; dma_addr_t dmaaddr;
int direction;
u16 cmd;
struct scatterlist sg; struct scatterlist sg;
BUG_ON(req->nr_phys_segments > 1); BUG_ON(req->nr_phys_segments > 1);
BUG_ON(rq_data_dir(req) != READ);
if (rq_data_dir(req) == READ) {
direction = DMA_FROM_DEVICE;
cmd = viomajorsubtype_cdio | viocdread;
} else {
direction = DMA_TO_DEVICE;
cmd = viomajorsubtype_cdio | viocdwrite;
}
if (blk_rq_map_sg(req->q, req, &sg) == 0) { if (blk_rq_map_sg(req->q, req, &sg) == 0) {
printk(VIOCD_KERN_WARNING printk(VIOCD_KERN_WARNING
...@@ -343,7 +355,7 @@ static int send_request(struct request *req) ...@@ -343,7 +355,7 @@ static int send_request(struct request *req)
return -1; return -1;
} }
if (dma_map_sg(diskinfo->dev, &sg, 1, DMA_FROM_DEVICE) == 0) { if (dma_map_sg(diskinfo->dev, &sg, 1, direction) == 0) {
printk(VIOCD_KERN_WARNING "error allocating sg tce\n"); printk(VIOCD_KERN_WARNING "error allocating sg tce\n");
return -1; return -1;
} }
...@@ -351,8 +363,7 @@ static int send_request(struct request *req) ...@@ -351,8 +363,7 @@ static int send_request(struct request *req)
len = sg_dma_len(&sg); len = sg_dma_len(&sg);
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
HvLpEvent_Type_VirtualIo, HvLpEvent_Type_VirtualIo, cmd,
viomajorsubtype_cdio | viocdread,
HvLpEvent_AckInd_DoAck, HvLpEvent_AckInd_DoAck,
HvLpEvent_AckType_ImmediateAck, HvLpEvent_AckType_ImmediateAck,
viopath_sourceinst(viopath_hostLp), viopath_sourceinst(viopath_hostLp),
...@@ -457,6 +468,41 @@ static int viocd_lock_door(struct cdrom_device_info *cdi, int locking) ...@@ -457,6 +468,41 @@ static int viocd_lock_door(struct cdrom_device_info *cdi, int locking)
return 0; return 0;
} }
static int viocd_packet(struct cdrom_device_info *cdi,
struct packet_command *cgc)
{
unsigned int buflen = cgc->buflen;
int ret = -EIO;
switch (cgc->cmd[0]) {
case GPCMD_READ_DISC_INFO:
{
disc_information *di = (disc_information *)cgc->buffer;
if (buflen >= 2) {
di->disc_information_length = cpu_to_be16(1);
ret = 0;
}
if (buflen >= 3)
di->erasable =
(cdi->ops->capability & ~cdi->mask
& (CDC_DVD_RAM | CDC_RAM)) != 0;
}
break;
default:
if (cgc->sense) {
/* indicate Unknown code */
cgc->sense->sense_key = 0x05;
cgc->sense->asc = 0x20;
cgc->sense->ascq = 0x00;
}
break;
}
cgc->stat = ret;
return ret;
}
/* This routine handles incoming CD LP events */ /* This routine handles incoming CD LP events */
static void vio_handle_cd_event(struct HvLpEvent *event) static void vio_handle_cd_event(struct HvLpEvent *event)
{ {
...@@ -510,6 +556,7 @@ static void vio_handle_cd_event(struct HvLpEvent *event) ...@@ -510,6 +556,7 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
case viocdclose: case viocdclose:
break; break;
case viocdwrite:
case viocdread: case viocdread:
/* /*
* Since this is running in interrupt mode, we need to * Since this is running in interrupt mode, we need to
...@@ -518,7 +565,8 @@ static void vio_handle_cd_event(struct HvLpEvent *event) ...@@ -518,7 +565,8 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
di = &viocd_diskinfo[bevent->disk]; di = &viocd_diskinfo[bevent->disk];
spin_lock_irqsave(&viocd_reqlock, flags); spin_lock_irqsave(&viocd_reqlock, flags);
dma_unmap_single(di->dev, bevent->token, bevent->len, dma_unmap_single(di->dev, bevent->token, bevent->len,
DMA_FROM_DEVICE); ((event->xSubtype & VIOMINOR_SUBTYPE_MASK) == viocdread)
? DMA_FROM_DEVICE : DMA_TO_DEVICE);
req = (struct request *)bevent->event.xCorrelationToken; req = (struct request *)bevent->event.xCorrelationToken;
rwreq--; rwreq--;
...@@ -555,7 +603,8 @@ static struct cdrom_device_ops viocd_dops = { ...@@ -555,7 +603,8 @@ static struct cdrom_device_ops viocd_dops = {
.release = viocd_release, .release = viocd_release,
.media_changed = viocd_media_changed, .media_changed = viocd_media_changed,
.lock_door = viocd_lock_door, .lock_door = viocd_lock_door,
.capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM .generic_packet = viocd_packet,
.capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
}; };
static int __init find_capability(const char *type) static int __init find_capability(const char *type)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment