[POWERPC] iSeries: Move detection of virtual tapes

Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties).  This way viotape.c gets
all the information about the devices from the device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Šī revīzija ir iekļauta:
Stephen Rothwell
2007-10-11 14:58:31 +10:00
revīziju iesūtīja Paul Mackerras
vecāks b833b481c1
revīzija 7465ce0db3
4 mainīti faili ar 192 papildinājumiem un 129 dzēšanām

Parādīt failu

@@ -92,47 +92,6 @@ struct viot_devinfo_struct {
#define VIOTAPOP_SETPART 14
#define VIOTAPOP_UNLOAD 15
struct viotapelpevent {
struct HvLpEvent event;
u32 reserved;
u16 version;
u16 sub_type_result;
u16 tape;
u16 flags;
u32 token;
u64 len;
union {
struct {
u32 tape_op;
u32 count;
} op;
struct {
u32 type;
u32 resid;
u32 dsreg;
u32 gstat;
u32 erreg;
u32 file_no;
u32 block_no;
} get_status;
struct {
u32 block_no;
} get_pos;
} u;
};
enum viotapesubtype {
viotapeopen = 0x0001,
viotapeclose = 0x0002,
viotaperead = 0x0003,
viotapewrite = 0x0004,
viotapegetinfo = 0x0005,
viotapeop = 0x0006,
viotapegetpos = 0x0007,
viotapesetpos = 0x0008,
viotapegetstatus = 0x0009
};
enum viotaperc {
viotape_InvalidRange = 0x0601,
viotape_InvalidToken = 0x0602,
@@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
#define VIOT_WRITING 2
/* Our info on the tapes */
struct tape_descr {
char rsrcname[10];
char type[4];
char model[3];
};
static struct tape_descr *viotape_unitinfo;
static dma_addr_t viotape_unitinfo_token;
static struct {
const char *rsrcname;
const char *type;
const char *model;
} viotape_unitinfo[VIOTAPE_MAX_TAPE];
static struct mtget viomtget[VIOTAPE_MAX_TAPE];
@@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
return -err->errno;
}
/* Get info on all tapes from OS/400 */
static int get_viotape_info(void)
{
HvLpEvent_Rc hvrc;
int i;
size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
struct op_struct *op = get_op_struct();
if (op == NULL)
return -ENOMEM;
viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
GFP_ATOMIC);
if (viotape_unitinfo == NULL) {
free_op_struct(op);
return -ENOMEM;
}
memset(viotape_unitinfo, 0, len);
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
HvLpEvent_Type_VirtualIo,
viomajorsubtype_tape | viotapegetinfo,
HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
viopath_sourceinst(viopath_hostLp),
viopath_targetinst(viopath_hostLp),
(u64) (unsigned long) op, VIOVERSION << 16,
viotape_unitinfo_token, len, 0, 0);
if (hvrc != HvLpEvent_Rc_Good) {
printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
(int)hvrc);
free_op_struct(op);
return -EIO;
}
wait_for_completion(&op->com);
free_op_struct(op);
for (i = 0;
((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
i++)
viotape_numdev++;
return 0;
}
/* Write */
static ssize_t viotap_write(struct file *file, const char *buf,
size_t count, loff_t * ppos)
@@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
op = (struct op_struct *)event->xCorrelationToken;
switch (tapeminor) {
case viotapegetinfo:
case viotapeopen:
case viotapeclose:
op->rc = tevent->sub_type_result;
@@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
int i = vdev->unit_address;
int j;
struct device_node *node = vdev->dev.archdata.of_node;
if (i >= viotape_numdev)
if (i > VIOTAPE_MAX_TAPE)
return -ENODEV;
if (!node)
return -ENODEV;
if (i >= viotape_numdev)
viotape_numdev = i + 1;
tape_device[i] = &vdev->dev;
viotape_unitinfo[i].rsrcname = of_get_property(node,
"linux,vio_rsrcname", NULL);
viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
NULL);
viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
NULL);
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
@@ -1044,11 +964,6 @@ int __init viotap_init(void)
goto unreg_chrdev;
}
if ((ret = get_viotape_info()) < 0) {
printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
goto unreg_class;
}
ret = vio_register_driver(&viotape_driver);
if (ret)
goto unreg_class;
@@ -1102,9 +1017,6 @@ static void __exit viotap_exit(void)
vio_unregister_driver(&viotape_driver);
class_destroy(tape_class);
unregister_chrdev(VIOTAPE_MAJOR, "viotape");
if (viotape_unitinfo)
iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
viotape_unitinfo, viotape_unitinfo_token);
viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
vio_clearHandler(viomajorsubtype_tape);
clear_op_struct_pool();