drivers/scsi/scsi_proc.c

Source file repositories/reference/linux-study-clean/drivers/scsi/scsi_proc.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/scsi_proc.c
Extension
.c
Size
13617 bytes
Lines
577
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

struct scsi_proc_entry {
	struct list_head	entry;
	const struct scsi_host_template *sht;
	struct proc_dir_entry	*proc_dir;
	unsigned int		present;
};

static ssize_t proc_scsi_host_write(struct file *file, const char __user *buf,
                           size_t count, loff_t *ppos)
{
	struct Scsi_Host *shost = pde_data(file_inode(file));
	ssize_t ret = -ENOMEM;
	char *page;
    
	if (count > PROC_BLOCK_SIZE)
		return -EOVERFLOW;

	if (!shost->hostt->write_info)
		return -EINVAL;

	page = (char *)__get_free_page(GFP_KERNEL);
	if (page) {
		ret = -EFAULT;
		if (copy_from_user(page, buf, count))
			goto out;
		ret = shost->hostt->write_info(shost, page, count);
	}
out:
	free_page((unsigned long)page);
	return ret;
}

static int proc_scsi_show(struct seq_file *m, void *v)
{
	struct Scsi_Host *shost = m->private;
	return shost->hostt->show_info(m, shost);
}

static int proc_scsi_host_open(struct inode *inode, struct file *file)
{
	return single_open_size(file, proc_scsi_show, pde_data(inode),
				4 * PAGE_SIZE);
}

static struct scsi_proc_entry *
__scsi_lookup_proc_entry(const struct scsi_host_template *sht)
{
	struct scsi_proc_entry *e;

	lockdep_assert_held(&global_host_template_mutex);

	list_for_each_entry(e, &scsi_proc_list, entry)
		if (e->sht == sht)
			return e;

	return NULL;
}

static struct scsi_proc_entry *
scsi_lookup_proc_entry(const struct scsi_host_template *sht)
{
	struct scsi_proc_entry *e;

	mutex_lock(&global_host_template_mutex);
	e = __scsi_lookup_proc_entry(sht);
	mutex_unlock(&global_host_template_mutex);

	return e;
}

/**
 * scsi_template_proc_dir() - returns the procfs dir for a SCSI host template
 * @sht: SCSI host template pointer.
 */
struct proc_dir_entry *
scsi_template_proc_dir(const struct scsi_host_template *sht)
{
	struct scsi_proc_entry *e = scsi_lookup_proc_entry(sht);

	return e ? e->proc_dir : NULL;
}
EXPORT_SYMBOL_GPL(scsi_template_proc_dir);

static const struct proc_ops proc_scsi_ops = {
	.proc_open	= proc_scsi_host_open,
	.proc_release	= single_release,
	.proc_read	= seq_read,
	.proc_lseek	= seq_lseek,
	.proc_write	= proc_scsi_host_write
};

Annotation

Implementation Notes