/****************************************************************************** * file operations * *****************************************************************************/ static int mon_open(struct inode *inode, struct file *filp) { struct mon_private *monpriv; int rc; /* * only one user allowed */ rc = -EBUSY; if (test_and_set_bit(MON_IN_USE, &mon_in_use)) goto out; rc = -ENOMEM; monpriv = mon_alloc_mem(); if (!monpriv) goto out_use; /* * Connect to *MONITOR service */ monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL); if (!monpriv->path) goto out_priv; rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler, MON_SERVICE, NULL, user_data_connect, monpriv); if (rc) { pr_err("Connecting to the z/VM *MONITOR system service " "failed with rc=%i\n", rc); rc = -EIO; goto out_path; } /* * Wait for connection confirmation */ wait_event(mon_conn_wait_queue, atomic_read(&monpriv->iucv_connected) || atomic_read(&monpriv->iucv_severed)); if (atomic_read(&monpriv->iucv_severed)) { atomic_set(&monpriv->iucv_severed, 0); atomic_set(&monpriv->iucv_connected, 0); rc = -EIO; goto out_path; } filp->private_data = monpriv; dev_set_drvdata(monreader_device, monpriv); return nonseekable_open(inode, filp); out_path: iucv_path_free(monpriv->path); out_priv: mon_free_mem(monpriv); out_use: clear_bit(MON_IN_USE, &mon_in_use); out: return rc; }
static struct mon_private *mon_alloc_mem(void) { int i; struct mon_private *monpriv; monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); if (!monpriv) return NULL; for (i = 0; i < MON_MSGLIM; i++) { monpriv->msg_array[i] = kzalloc(sizeof(struct mon_msg), GFP_KERNEL); if (!monpriv->msg_array[i]) { mon_free_mem(monpriv); return NULL; } } return monpriv; }
static struct mon_private *mon_alloc_mem(void) { int i; struct mon_private *monpriv; monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); if (!monpriv) { P_ERROR("no memory for monpriv\n"); return NULL; } for (i = 0; i < MON_MSGLIM; i++) { monpriv->msg_array[i] = kzalloc(sizeof(struct mon_msg), GFP_KERNEL); if (!monpriv->msg_array[i]) { P_ERROR("open, no memory for msg_array\n"); mon_free_mem(monpriv); return NULL; } } return monpriv; }