Commit ff15d3ec authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: iSeries virtual cdrom module fix

From: Stephen Rothwell <sfr@canb.auug.org.au>

This patch fixes loading viocd as a module.  It would oops because I was
passing the address of a static buffer to dma_map_single and when loaded as
a module, this address is not valid for that purpose.

There are a couple of simple cleanups here as well.
parent d8932719
......@@ -132,7 +132,12 @@ struct cdrom_info {
char type[4];
char model[3];
};
static struct cdrom_info viocd_unitinfo[VIOCD_MAX_CD];
/*
* This needs to be allocated since it is passed to the
* Hypervisor and we may be a module.
*/
static struct cdrom_info *viocd_unitinfo;
static dma_addr_t unitinfo_dmaaddr;
struct disk_info {
struct gendisk *viocd_disk;
......@@ -141,7 +146,6 @@ struct disk_info {
static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
#define DEVICE_NR(di) ((di) - &viocd_diskinfo[0])
#define VIOCDI viocd_diskinfo[deviceno].viocd_info
static request_queue_t *viocd_queue;
static spinlock_t viocd_reqlock;
......@@ -184,18 +188,20 @@ struct block_device_operations viocd_fops = {
/* Get info on CD devices from OS/400 */
static void __init get_viocd_info(void)
{
dma_addr_t dmaaddr;
HvLpEvent_Rc hvrc;
int i;
struct viocd_waitevent we;
dmaaddr = dma_map_single(iSeries_vio_dev, viocd_unitinfo,
sizeof(viocd_unitinfo), DMA_FROM_DEVICE);
if (dmaaddr == (dma_addr_t)-1) {
printk(VIOCD_KERN_WARNING "error allocating tce\n");
viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev,
sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
&unitinfo_dmaaddr, GFP_ATOMIC);
if (viocd_unitinfo == NULL) {
printk(VIOCD_KERN_WARNING "error allocating unitinfo\n");
return;
}
memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD);
init_completion(&we.com);
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
......@@ -204,29 +210,34 @@ static void __init get_viocd_info(void)
HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
viopath_sourceinst(viopath_hostLp),
viopath_targetinst(viopath_hostLp),
(u64)&we, VIOVERSION << 16, dmaaddr, 0,
sizeof(viocd_unitinfo), 0);
(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0);
if (hvrc != HvLpEvent_Rc_Good) {
printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n",
(int)hvrc);
return;
goto error_ret;
}
wait_for_completion(&we.com);
dma_unmap_single(iSeries_vio_dev, dmaaddr, sizeof(viocd_unitinfo),
DMA_FROM_DEVICE);
if (we.rc) {
const struct vio_error_entry *err =
vio_lookup_rc(viocd_err_table, we.sub_result);
printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n",
we.rc, we.sub_result, err->msg);
return;
goto error_ret;
}
for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++)
viocd_numdev++;
return;
error_ret:
dma_free_coherent(iSeries_vio_dev,
sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
viocd_unitinfo, unitinfo_dmaaddr);
viocd_unitinfo = NULL;
}
static int viocd_open(struct cdrom_device_info *cdi, int purpose)
......@@ -307,10 +318,6 @@ static int send_request(struct request *req)
}
dmaaddr = sg_dma_address(&sg);
len = sg_dma_len(&sg);
if (dmaaddr == (dma_addr_t)-1) {
printk(VIOCD_KERN_WARNING "error allocating tce\n");
return -1;
}
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
HvLpEvent_Type_VirtualIo,
......@@ -604,7 +611,7 @@ static int __init viocd_init(void)
printk(VIOCD_KERN_WARNING
"Cannot create gendisk for %s!\n",
c->name);
unregister_cdrom(&VIOCDI);
unregister_cdrom(c);
continue;
}
gendisk->major = VIOCD_MAJOR;
......@@ -646,7 +653,10 @@ static void __exit viocd_exit(void)
put_disk(d->viocd_disk);
}
blk_cleanup_queue(viocd_queue);
if (viocd_unitinfo != NULL)
dma_free_coherent(iSeries_vio_dev,
sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
viocd_unitinfo, unitinfo_dmaaddr);
viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
vio_clearHandler(viomajorsubtype_cdio);
unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE);
......
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