[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:

revīziju iesūtīja
Paul Mackerras

vecāks
b833b481c1
revīzija
7465ce0db3
@@ -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();
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user