drivers/s390/char/vmlogrdr.c

Source file repositories/reference/linux-study-clean/drivers/s390/char/vmlogrdr.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/vmlogrdr.c
Extension
.c
Size
21230 bytes
Lines
862
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations vmlogrdr_fops = {
	.owner   = THIS_MODULE,
	.open    = vmlogrdr_open,
	.release = vmlogrdr_release,
	.read    = vmlogrdr_read,
};


static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 *ipuser);
static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 *ipuser);
static void vmlogrdr_iucv_message_pending(struct iucv_path *,
					  struct iucv_message *);


static struct iucv_handler vmlogrdr_iucv_handler = {
	.path_complete	 = vmlogrdr_iucv_path_complete,
	.path_severed	 = vmlogrdr_iucv_path_severed,
	.message_pending = vmlogrdr_iucv_message_pending,
};


static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue);

/*
 * pointer to system service private structure
 * minor number 0 --> logrec
 * minor number 1 --> account
 * minor number 2 --> symptom
 */

static struct vmlogrdr_priv_t sys_ser[] = {
	{ .system_service = { '*', 'L', 'O', 'G', 'R', 'E', 'C', ' ' },
	  .internal_name  = "logrec",
	  .recording_name = "EREP",
	  .minor_num      = 0,
	  .buffer_free    = 1,
	  .priv_lock	  = __SPIN_LOCK_UNLOCKED(sys_ser[0].priv_lock),
	  .autorecording  = 1,
	  .autopurge      = 1,
	},
	{ .system_service = { '*', 'A', 'C', 'C', 'O', 'U', 'N', 'T' },
	  .internal_name  = "account",
	  .recording_name = "ACCOUNT",
	  .minor_num      = 1,
	  .buffer_free    = 1,
	  .priv_lock	  = __SPIN_LOCK_UNLOCKED(sys_ser[1].priv_lock),
	  .autorecording  = 1,
	  .autopurge      = 1,
	},
	{ .system_service = { '*', 'S', 'Y', 'M', 'P', 'T', 'O', 'M' },
	  .internal_name  = "symptom",
	  .recording_name = "SYMPTOM",
	  .minor_num      = 2,
	  .buffer_free    = 1,
	  .priv_lock	  = __SPIN_LOCK_UNLOCKED(sys_ser[2].priv_lock),
	  .autorecording  = 1,
	  .autopurge      = 1,
	}
};

#define MAXMINOR  ARRAY_SIZE(sys_ser)

static char FENCE[] = {"EOR"};
static int vmlogrdr_major = 0;
static struct cdev  *vmlogrdr_cdev = NULL;
static int recording_class_AB;


static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 *ipuser)
{
	struct vmlogrdr_priv_t * logptr = path->private;

	spin_lock(&logptr->priv_lock);
	logptr->connection_established = 1;
	spin_unlock(&logptr->priv_lock);
	wake_up(&conn_wait_queue);
}


static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 *ipuser)
{
	struct vmlogrdr_priv_t * logptr = path->private;
	u8 reason = (u8) ipuser[8];

	pr_err("vmlogrdr: connection severed with reason %i\n", reason);

	iucv_path_sever(path, NULL);
	kfree(path);
	logptr->path = NULL;

Annotation

Implementation Notes