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

[PATCH] ppc64: viotape integration

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 3faf8f63
...@@ -237,6 +237,8 @@ static void probe_bus_iseries(void) ...@@ -237,6 +237,8 @@ static void probe_bus_iseries(void)
vio_register_device_iseries("viodasd", i); vio_register_device_iseries("viodasd", i);
for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
vio_register_device_iseries("viocd", i); vio_register_device_iseries("viocd", i);
for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
vio_register_device_iseries("viotape", i);
} }
#endif #endif
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/ioctls.h> #include <asm/ioctls.h>
#include <asm/vio.h>
#include <asm/iSeries/vio.h> #include <asm/iSeries/vio.h>
#include <asm/iSeries/HvLpEvent.h> #include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h> #include <asm/iSeries/HvCallEvent.h>
...@@ -216,7 +217,7 @@ static const struct vio_error_entry viotape_err_table[] = { ...@@ -216,7 +217,7 @@ static const struct vio_error_entry viotape_err_table[] = {
}; };
/* Maximum number of tapes we support */ /* Maximum number of tapes we support */
#define VIOTAPE_MAX_TAPE 8 #define VIOTAPE_MAX_TAPE HVMAXARCHITECTEDVIRTUALTAPES
#define MAX_PARTITIONS 4 #define MAX_PARTITIONS 4
/* defines for current tape state */ /* defines for current tape state */
...@@ -238,6 +239,8 @@ static struct mtget viomtget[VIOTAPE_MAX_TAPE]; ...@@ -238,6 +239,8 @@ static struct mtget viomtget[VIOTAPE_MAX_TAPE];
static struct class_simple *tape_class; static struct class_simple *tape_class;
static struct device *tape_device[VIOTAPE_MAX_TAPE];
/* /*
* maintain the current state of each tape (and partition) * maintain the current state of each tape (and partition)
* so that we know when to write EOF marks. * so that we know when to write EOF marks.
...@@ -262,6 +265,7 @@ struct op_struct { ...@@ -262,6 +265,7 @@ struct op_struct {
int rc; int rc;
int non_blocking; int non_blocking;
struct completion com; struct completion com;
struct device *dev;
struct op_struct *next; struct op_struct *next;
}; };
...@@ -459,7 +463,8 @@ static ssize_t viotap_write(struct file *file, const char *buf, ...@@ -459,7 +463,8 @@ static ssize_t viotap_write(struct file *file, const char *buf,
down(&reqSem); down(&reqSem);
/* Allocate a DMA buffer */ /* Allocate a DMA buffer */
op->buffer = dma_alloc_coherent(iSeries_vio_dev, count, &op->dmaaddr, op->dev = tape_device[devi.devno];
op->buffer = dma_alloc_coherent(op->dev, count, &op->dmaaddr,
GFP_ATOMIC); GFP_ATOMIC);
if (op->buffer == NULL) { if (op->buffer == NULL) {
...@@ -509,7 +514,7 @@ static ssize_t viotap_write(struct file *file, const char *buf, ...@@ -509,7 +514,7 @@ static ssize_t viotap_write(struct file *file, const char *buf,
} }
free_dma: free_dma:
dma_free_coherent(iSeries_vio_dev, count, op->buffer, op->dmaaddr); dma_free_coherent(op->dev, count, op->buffer, op->dmaaddr);
up_sem: up_sem:
up(&reqSem); up(&reqSem);
free_op: free_op:
...@@ -550,7 +555,8 @@ static ssize_t viotap_read(struct file *file, char *buf, size_t count, ...@@ -550,7 +555,8 @@ static ssize_t viotap_read(struct file *file, char *buf, size_t count,
chg_state(devi.devno, VIOT_READING, file); chg_state(devi.devno, VIOT_READING, file);
/* Allocate a DMA buffer */ /* Allocate a DMA buffer */
op->buffer = dma_alloc_coherent(iSeries_vio_dev, count, &op->dmaaddr, op->dev = tape_device[devi.devno];
op->buffer = dma_alloc_coherent(op->dev, count, &op->dmaaddr,
GFP_ATOMIC); GFP_ATOMIC);
if (op->buffer == NULL) { if (op->buffer == NULL) {
ret = -EFAULT; ret = -EFAULT;
...@@ -588,7 +594,7 @@ static ssize_t viotap_read(struct file *file, char *buf, size_t count, ...@@ -588,7 +594,7 @@ static ssize_t viotap_read(struct file *file, char *buf, size_t count,
} }
free_dma: free_dma:
dma_free_coherent(iSeries_vio_dev, count, op->buffer, op->dmaaddr); dma_free_coherent(op->dev, count, op->buffer, op->dmaaddr);
up_sem: up_sem:
up(&reqSem); up(&reqSem);
free_op: free_op:
...@@ -910,7 +916,7 @@ static void vioHandleTapeEvent(struct HvLpEvent *event) ...@@ -910,7 +916,7 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
break; break;
case viotapewrite: case viotapewrite:
if (op->non_blocking) { if (op->non_blocking) {
dma_free_coherent(iSeries_vio_dev, op->count, dma_free_coherent(op->dev, op->count,
op->buffer, op->dmaaddr); op->buffer, op->dmaaddr);
free_op_struct(op); free_op_struct(op);
up(&reqSem); up(&reqSem);
...@@ -936,12 +942,70 @@ static void vioHandleTapeEvent(struct HvLpEvent *event) ...@@ -936,12 +942,70 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
} }
} }
static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
char tapename[32];
int i = vdev->unit_address;
int j;
if (i >= viotape_numdev)
return -ENODEV;
tape_device[i] = &vdev->dev;
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
"iseries!vt%d", i);
class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
NULL, "iseries!nvt%d", i);
devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
"iseries/vt%d", i);
devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i | 0x80),
S_IFCHR | S_IRUSR | S_IWUSR, "iseries/nvt%d", i);
sprintf(tapename, "iseries/vt%d", i);
state[i].dev_handle = devfs_register_tape(tapename);
printk(VIOTAPE_KERN_INFO "tape %s is iSeries "
"resource %10.10s type %4.4s, model %3.3s\n",
tapename, viotape_unitinfo[i].rsrcname,
viotape_unitinfo[i].type, viotape_unitinfo[i].model);
return 0;
}
static int viotape_remove(struct vio_dev *vdev)
{
int i = vdev->unit_address;
devfs_remove("iseries/nvt%d", i);
devfs_remove("iseries/vt%d", i);
devfs_unregister_tape(state[i].dev_handle);
class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i | 0x80));
class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i));
return 0;
}
/**
* viotape_device_table: Used by vio.c to match devices that we
* support.
*/
static struct vio_device_id viotape_device_table[] __devinitdata = {
{ "viotape", "" },
{ 0, }
};
MODULE_DEVICE_TABLE(vio, viotape_device_table);
static struct vio_driver viotape_driver = {
.name = "viotape",
.id_table = viotape_device_table,
.probe = viotape_probe,
.remove = viotape_remove
};
int __init viotap_init(void) int __init viotap_init(void)
{ {
int ret; int ret;
char tapename[32];
int i;
struct proc_dir_entry *e; struct proc_dir_entry *e;
op_struct_list = NULL; op_struct_list = NULL;
...@@ -993,31 +1057,9 @@ int __init viotap_init(void) ...@@ -993,31 +1057,9 @@ int __init viotap_init(void)
goto unreg_class; goto unreg_class;
} }
for (i = 0; i < viotape_numdev; i++) { ret = vio_register_driver(&viotape_driver);
int j; if (ret)
goto unreg_class;
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i),
NULL, "iseries!vt%d", i);
class_simple_device_add(tape_class,
MKDEV(VIOTAPE_MAJOR, i | 0x80),
NULL, "iseries!nvt%d", i);
devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i),
S_IFCHR | S_IRUSR | S_IWUSR,
"iseries/vt%d", i);
devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i | 0x80),
S_IFCHR | S_IRUSR | S_IWUSR,
"iseries/nvt%d", i);
sprintf(tapename, "iseries/vt%d", i);
state[i].dev_handle = devfs_register_tape(tapename);
printk(VIOTAPE_KERN_INFO "tape %s is iSeries "
"resource %10.10s type %4.4s, model %3.3s\n",
tapename, viotape_unitinfo[i].rsrcname,
viotape_unitinfo[i].type,
viotape_unitinfo[i].model);
}
e = create_proc_entry("iSeries/viotape", S_IFREG|S_IRUGO, NULL); e = create_proc_entry("iSeries/viotape", S_IFREG|S_IRUGO, NULL);
if (e) { if (e) {
...@@ -1064,17 +1106,10 @@ static int chg_state(int index, unsigned char new_state, struct file *file) ...@@ -1064,17 +1106,10 @@ static int chg_state(int index, unsigned char new_state, struct file *file)
/* Cleanup */ /* Cleanup */
static void __exit viotap_exit(void) static void __exit viotap_exit(void)
{ {
int i, ret; int ret;
remove_proc_entry("iSeries/viotape", NULL); remove_proc_entry("iSeries/viotape", NULL);
vio_unregister_driver(&viotape_driver);
for (i = 0; i < viotape_numdev; ++i) {
devfs_remove("iseries/nvt%d", i);
devfs_remove("iseries/vt%d", i);
devfs_unregister_tape(state[i].dev_handle);
class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i | 0x80));
class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i));
}
class_simple_destroy(tape_class); class_simple_destroy(tape_class);
ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape"); ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape");
if (ret < 0) if (ret < 0)
......
...@@ -68,6 +68,7 @@ typedef u8 HvAgentId; // Hypervisor DevFn ...@@ -68,6 +68,7 @@ typedef u8 HvAgentId; // Hypervisor DevFn
#define HVMAXARCHITECTEDVIRTUALLANS 16 #define HVMAXARCHITECTEDVIRTUALLANS 16
#define HVMAXARCHITECTEDVIRTUALDISKS 32 #define HVMAXARCHITECTEDVIRTUALDISKS 32
#define HVMAXARCHITECTEDVIRTUALCDROMS 8 #define HVMAXARCHITECTEDVIRTUALCDROMS 8
#define HVMAXARCHITECTEDVIRTUALTAPES 8
#define HVCHUNKSIZE 256 * 1024 #define HVCHUNKSIZE 256 * 1024
#define HVPAGESIZE 4 * 1024 #define HVPAGESIZE 4 * 1024
#define HVLPMINMEGSPRIMARY 256 #define HVLPMINMEGSPRIMARY 256
......
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